commit e5c4b6aa13b242f6c3fe23059316288e1b1e2261 Author: ExtraNetwork Date: Tue May 12 17:04:54 2026 +0300 first commit diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..8e86a02 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,102 @@ +kind: pipeline +type: docker +name: api-extranetwork + +# Sadece main branch'te tetiklenir +trigger: + branch: + - main + event: + - push + +steps: + # ------------------------------------------------------- + # 1. Bağımlılıkları kur + # ------------------------------------------------------- + - name: composer-install + image: composer:2.2 + volumes: + - name: composer-cache + path: /root/.composer/cache + commands: + - composer install --no-dev --optimize-autoloader --no-interaction --prefer-dist + + # ------------------------------------------------------- + # 2. PHP Unit testlerini çalıştır + # ------------------------------------------------------- + - name: tests + image: php:7.3-cli + commands: + - apt-get update -qq + - apt-get install -y --no-install-recommends libzip-dev libpng-dev libxml2-dev libonig-dev > /dev/null 2>&1 + - docker-php-ext-install pdo pdo_mysql zip mbstring > /dev/null 2>&1 + - cp .env.example .env + - php artisan key:generate + - vendor/bin/phpunit --no-coverage --stop-on-failure + environment: + DB_CONNECTION: sqlite + DB_DATABASE: ":memory:" + depends_on: + - composer-install + + # ------------------------------------------------------- + # 3. Docker image build & Gitea Container Registry'e push + # ------------------------------------------------------- + - name: docker-build-push + image: plugins/docker + settings: + registry: git.extranetwork.net + repo: git.extranetwork.net/gitea/api-extranetwork + username: + from_secret: GITEA_USER + password: + from_secret: GITEA_TOKEN + tags: + - latest + - ${DRONE_COMMIT_SHA:0:8} + build_args: + - APP_ENV=production + depends_on: + - tests + when: + branch: + - main + event: + - push + + # ------------------------------------------------------- + # 4. SSH ile sunucuya deploy et + # ------------------------------------------------------- + - name: deploy + image: appleboy/drone-ssh + settings: + host: + from_secret: DEPLOY_HOST + user: + from_secret: DEPLOY_USER + key: + from_secret: DEPLOY_SSH_KEY + port: 22 + script: + - cd /opt/api.extranetwork.com + - docker compose pull + - docker compose up -d --remove-orphans + - docker compose exec -T app php artisan migrate --force + - docker compose exec -T app php artisan config:cache + - docker compose exec -T app php artisan route:cache + - docker compose exec -T app php artisan view:cache + - echo "Deploy tamamlandı - $(date)" + depends_on: + - docker-build-push + when: + branch: + - main + event: + - push + +# ------------------------------------------------------- +# Uçucu volume (composer cache pipeline içinde paylaşılır) +# ------------------------------------------------------- +volumes: + - name: composer-cache + temp: {} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a7f46ec --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_size = 2 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c9a76b4 --- /dev/null +++ b/.env.example @@ -0,0 +1,54 @@ +APP_NAME=Lumen +APP_ENV=local +APP_KEY=bae48aba23b3e4395b7f1b484dd25192 +APP_DEBUG=true +APP_URL=http://api.extranetwork.local +APP_TIMEZONE=Europe/Istanbul +CLIENT_SERVER=http://www.extranetwork.com + +LOG_CHANNEL=stack +LOG_SLACK_WEBHOOK_URL= + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=enw_20201106 +DB_USERNAME=root +DB_PASSWORD=1722 + +MAIL_DRIVER=log +MAIL_HOST=smtp.yandex.com.tr +MAIL_PORT=465 +MAIL_USERNAME=noreply@extranetwork.com +MAIL_PASSWORD=8KSLQzxuGg4vEfSFkaA4 +MAIL_ENCRYPTION=ssl + + +JWT_SECRET=JhbGciOiJIUzI1N0eXAiOiJKV1QiLC + + +CACHE_DRIVER=redis +SESSION_DRIVER=redis +QUEUE_DRIVER=sync +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + + +FILESYSTEM_DRIVER=C:\www\api.extranetwork.com\public +IMAGE_URL=http://api.extranetwork.local +GOOGLE_APPLICATION_CREDENTIALS='' + +QUEUE_CONNECTION=database +APP_LANGUAGE_JSON_STORED_FOLDER=C:\www\www.extranetwork.com\public +MAIN_HOST_ADDRESS=http://myweb.extranetwork.local + +MYWEB_LANGUAGE_JSON_STORED_FOLDER=C:\www\www.myweb.com\resources\lang\ +BOOKING_ENGINE_LANGUAGE_JSON_STORED_FOLDER=C:\www\be.extranetwork.com\resources\lang\ +BOOKING_ENGINE_URL=http://be.extranetwork.local +ZIP_FILES_URL=http://api.extranetwork.local/property-zip-files/ +PAYMENT_FORM_LINK=http://be.extranetwork.local/link/ +ENW_CONTACT_FORM_MAILTO= + +STRIPE_ENWKEY=sk_test_51HuYHvEa9cmPdLq3ANG7ZYaGB9zMuhQZlwH19axJRauZsMnnpnuGBN1h8iAfr9kNVWe4FWcEcvZiMjn3hhBELHHx00hiBgjO41 +PROPERTY_FILES_URL=http://local-api.extranetwork.com/property-files/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1eeeaaf --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +/vendor +/.idea +/.vscode +Homestead.json +Homestead.yaml +.env +composer.lock + +# Büyük SQL dosyaları +*.sql + +# Public upload klasörleri +/public/property-photos/ +/public/property-files/ +/public/property-zip-files/ +/public/property-map/ +/public/property-group/ +/public/property-catalog/ +/public/property-web-content/ +/public/property-web-popup/ +/public/blog/ + +# Storage (log, cache vs.) +/storage/logs/* +!/storage/logs/.gitignore +/storage/framework/cache/data/ +/storage/framework/sessions/ +/storage/framework/views/ + +/resources/lang/ + +# OS +.DS_Store +Thumbs.db + +# Node +node_modules/ +npm-debug.log diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..fcd4cf0 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,6 @@ +php: + preset: laravel + disabled: + - unused_use +js: true +css: true diff --git a/API_FLOW.md b/API_FLOW.md new file mode 100644 index 0000000..4414c7d --- /dev/null +++ b/API_FLOW.md @@ -0,0 +1,391 @@ +# API Akış Şeması — ExtraNetWork + +300+ endpoint, 60+ controller, 9 channel manager entegrasyonu, 3 metasearch entegrasyonu. + +--- + +## 1. Middleware Zinciri + +```mermaid +graph LR + A[Client] --> B[cors] + B --> C[LanguageSetting] + C --> D{Public?} + D -->|Evet| Z[Controller] + D -->|Hayır| E[jwt.auth] + E --> F[userRoutePermissionAuthorize] + F --> G[property] + G --> H{Wizard gerekli mi?} + H -->|Evet| I[contentWizard] + H -->|Hayır| J{Channel sync?} + I --> J + J -->|Evet| K[checkPropertyChannelConnection] + J -->|Hayır| Z + K --> Z + Z --> S[Service] + S --> R[Repository] + R --> DB[(MySQL)] +``` + +| Middleware | Amaç | +| -------------------------------- | ---------------------------------------------- | +| `cors` | CORS başlıkları | +| `LanguageSetting` | TR/EN/DE dil seçimi | +| `jwt.auth` | JWT + `api_access_token` doğrulama | +| `userRoutePermissionAuthorize` | RBAC permission kontrolü | +| `property` | `user_property_mapping` ile property ownership | +| `contentWizard` | Onboarding tamamlanma kontrolü | +| `checkPropertyChannelConnection` | Channel bağlantı durumu | +| `bookingEngineToken` | BookingEngine widget token | +| `myWebToken` | MyWeb template token | + +--- + +## 2. Genel Request Lifecycle + +```mermaid +sequenceDiagram + participant C as Client + participant MW as Middleware Stack + participant Ctrl as Controller + participant Svc as Service + participant Repo as Repository + participant DB as MySQL + + C->>MW: HTTP + authToken + MW->>MW: cors → lang → jwt → permission → property → wizard + MW->>Ctrl: Request + credentials + property + Ctrl->>Ctrl: Validator->validate(params) + Ctrl->>Svc: business call + Svc->>Repo: findByCriteria / create / update + Repo->>DB: SQL + DB-->>Repo: rows + Repo-->>Svc: data + Svc-->>Ctrl: ['status','data','message'] + Ctrl-->>C: apiResponse(status, message, data, code) +``` + +--- + +## 3. Auth Akışı (Login / Refresh / Logout) + +```mermaid +sequenceDiagram + participant U as User + participant A as AuthController + participant J as JwtService + participant T as ApiAccessTokenService + participant M as UserPropertyMappingService + participant DB + + U->>A: POST auth/login {email, password, remember_me} + A->>DB: user where email & status=1 + A->>A: Hash::check + A->>J: jwtCreate(user_id, remember_me, day_counter=5) + J-->>A: {token, exp} + A->>T: create({token: md5(jwt), expire_date, user_id, invalidate=0}) + A->>M: select(user_property_mapping where user_id, status=1) + M-->>A: property_list + A-->>U: {token, expire_time, locale, property_list, user} + + Note over U,A: Refresh + U->>A: GET auth/refresh-token (authToken header) + A->>T: token bul (md5, expire>now, invalidate=0) + A->>J: jwtCreate(day_counter=0.5) + A->>T: update aynı token row + A-->>U: {new token, expire_time} + + Note over U,A: Logout + U->>A: POST logout (authToken header) + A->>T: update invalidate=1 + A-->>U: 200 Logged out +``` + +--- + +## 4. Property Erişim Kontrolü + +```mermaid +graph TD + A[Request + property_id] --> B[jwt.auth ✓] + B --> C[userRoutePermissionAuthorize] + C -->|permission yok| X[403] + C --> D[PropertyMiddleware] + D --> E{user_property_mapping
user_id+property_id+status=1} + E -->|yok| X + E --> F{Wizard route?} + F -->|Evet| G{property.wizard_status
= complete?} + G -->|Hayır| Y[422 Wizard incomplete] + G --> H[Controller] + F -->|Hayır| H + H --> I[Service: property_id ile scope] + I --> J[(DB)] +``` + +--- + +## 5. Booking Lifecycle (BookingEngine) + +```mermaid +sequenceDiagram + participant G as Guest + participant BE as BookingEngine Widget + participant API as BookingEngine\BookingController + participant Inv as Inventory/Rate + participant Pay as PaymentLinkController + participant DB + + G->>BE: arama (checkin/checkout, pax) + BE->>API: POST /v1/search + API->>Inv: availability + rates + Inv->>DB: property_room_rate_mapping + availability + API-->>BE: rate listesi + + G->>BE: oda seç + BE->>API: POST /v1/booking + API->>DB: insert booking + booking_contact + booking_room + booking_room_pax + API-->>BE: booking_code (status=2 Pending) + + G->>BE: ödemeyi onayla + BE->>API: POST /v1/bookingConfirm + API->>Pay: paymentLinkInitialize + Pay->>DB: insert payment_transaction (status=2 Start) + Pay-->>BE: redirect URL + + G->>Pay: 3D Secure / POS + Pay->>API: callback /paymentRedirect/{code} + API->>DB: payment_transaction.status=1, booking.status=1 + API->>API: send confirmation email + API-->>G: confirmation page +``` + +**Status kodları:** + +- `booking.status`: 0=İptal/Refund, 1=Confirmed, 2=Pending +- `booking_payment.status`: 0=İptal, 1=Confirmed, 2=Pending +- `payment_transaction.status`: 0=Error, 1=Success, 2=Start, 3=Pending, 4=Cancel/Refund, 5=Manual + +--- + +## 6. Channel Sync Akışı + +```mermaid +graph TD + A[Property Manager] -->|property/property-channel-mapping/add| B[PropertyChannelMappingController] + B --> C[(property_channel_mapping)] + C --> D[Job: PropertyCatalogServiceJob] + D --> E{Channel?} + E -->|Reseliva| R1[ChannelManager/Reseliva] + E -->|Channex| R2[ChannelManager/Channex] + E -->|HotelRunner| R3[ChannelManager/HotelRunner] + E -->|ElektraWeb| R4[ChannelManager/ElektraWeb] + E -->|Athena/Fina/SistemOtel/1C/HyperGuest| R5[Diğer Adapters] + R1 & R2 & R3 & R4 & R5 --> X[Remote Channel API] + X --> L[Sync log + status update] + L --> N[Dashboard'da görünür] +``` + +--- + +## 7. Inventory & Rate Update (Channel-Connection-Protected) + +```mermaid +sequenceDiagram + participant M as Manager + participant API as PropertyRoomRateMappingController + participant CC as checkPropertyChannelConnection + participant DB + participant Ch as Remote Channel + + M->>API: POST property/room-rate-mapping/bulk-update + API->>CC: Channel bağlı mı? + CC->>DB: property_channel_mapping.status + alt Bağlı değil + CC-->>M: 403 Channel disconnected + else Bağlı + API->>DB: update room_rate_mapping (price/availability) + API->>Ch: push update + Ch-->>API: ack + API-->>M: success + end +``` + +--- + +## 8. Wizard Onboarding + +```mermaid +graph TD + A[property/create] --> B[(property: wizard incomplete)] + B --> C1[contact/update] + B --> C2[room/add-room-bed] + B --> C3[room-fact-mapping/update] + B --> C4[room-photo-mapping/update] + B --> C5[awards-certificates/list] + B --> C6[fact/get-subcategory-facts] + B --> C7[executive/list] + C1 & C2 & C3 & C4 & C5 & C6 & C7 --> D[property/update/content-code] + D --> E[(wizard_status = complete)] + E --> F[Diğer property endpoint'leri açılır] +``` + +--- + +## 9. Web Site Builder (MyWeb) + +```mermaid +sequenceDiagram + participant M as Manager + participant API as PropertyWebController + participant DB + participant FS as FileStorage/CDN + participant V as Visitor + participant MyW as MyWebContentController + + M->>API: web/create → property_web + M->>API: web/update-content → component & content + M->>API: web/meta-tag/sync + M->>API: web/popup/create + M->>API: web/publish → status=PUBLISHED + API->>FS: assets + + V->>MyW: web/home (myWebToken) + MyW->>DB: property_web_content + components + MyW-->>V: render data (frontend tarafı şablonlar) +``` + +--- + +## 10. Reputation Management + +```mermaid +graph TD + A[reputation-management/channel/get] --> B[(reputation_channels)] + A --> C[reputation-management/channel/sync] + C --> J[Job: PropertyReviewServiceJob] + J --> D{Source} + D -->|TripAdvisor| T[TripAdvisor API] + D -->|Google| G[Google Places API] + D -->|Booking| BK[Booking API] + T & G & BK --> R[(reviews)] + R --> AN[Job: PropertyReviewAnalyzeServiceJob
NLP/sentiment] + AN --> S[(review_statistics)] + S --> RS[reputation-management/review/statistics] +``` + +--- + +## 11. CPA (Competitor Price Analysis) + +```mermaid +graph TD + A[cpa/property/competitor/create] --> B[(property_competitors)] + B --> C[cpa/property/competitor/sync] + C --> D[Crawler/OTA API] + D --> E[(competitor_prices günlük)] + E --> F[cpa/property/competitor/analysis] + F --> G[cpa/property/best-available-price] + F --> H[cpa/property/promotion-available] + F --> I[cpa/property/quick-pricing/rate] + G & H & I --> J[Manager dashboard önerileri] +``` + +--- + +## 12. Endpoint Domain Özet Tablosu + +| # | Domain | Controller(lar) | Endpoint | Açıklama | +| --: | ------------------- | ----------------------------------------------------- | -------: | ------------------------------------------------------------------------------------ | +| 1 | Auth | AuthController | 3 | login / refresh / logout | +| 2 | User | UserController | 17 | register, profile, password, mapping | +| 3 | Property | PropertyController | 12 | CRUD + dashboard + raporlar | +| 4 | Property Info | Contact, Brand, Config, Executive | 14 | Detay bilgi yönetimi | +| 5 | Content | Content, Fact, FactMapping, AdditionalInfo | 11 | Property metadata | +| 6 | Photo | PropertyPhoto + Category + Mapping | 11 | Foto yönetimi & CDN | +| 7 | Place | PropertyPlaceController | 15 | Tesis içi yer/alan | +| 8 | Awards | PropertyAwardCertificates | 5 | Sertifikalar | +| 9 | Room | PropertyRoom + Type/View/Bed/Size | 20+ | Oda yapısı | +| 10 | Rate | PropertyRoomRate + Mapping/Channel/Setup/Inclusion | 27 | Rate & inventory | +| 11 | Channel | PropertyChannel + Mapping/Group/Contact/Category | 23 | OTA dağıtım | +| 12 | Cancellation Policy | PropertyCancellationPolicy | 5 | İptal kuralları | +| 13 | Pricing Policy | PropertyPersonPricingPolicy | 7 | Yetişkin/çocuk fiyat | +| 14 | Booking | PropertyBookingController + Ticket | 11 | Rezervasyon ops | +| 15 | Payment | PaymentController + PaymentLink | 16 | Ödeme + manual link + taksit | +| 16 | Offer | PropertyOfferController | 11 | Teklif yönetimi | +| 17 | Promotion | PropertyPromotionController | 7 | Promosyon & kampanya | +| 18 | Coupon/Addon | PropertyCoupon + Addon | 4 | Ek ürün/kupon | +| 19 | CPA | CompetitorPriceAnalysis + Group + QuickPricing | 15+ | Rakip analizi | +| 20 | Web Builder | PropertyWebController + Content/Popup/Component | 30+ | Website yönetimi | +| 21 | MyWeb | MyWebContentController | 22+ | Public site render | +| 22 | Booking Engine | BookingEngine\BookingController + Search | 17 | Embedded widget | +| 23 | Channel Manager | 9 entegrasyon adapter'ı | 21 | Reseliva, Channex, HotelRunner, ElektraWeb, Athena, Fina, SistemOtel, 1C, HyperGuest | +| 24 | MetaSearch | Trivago, Yandex, Google | 8 | Meta arama | +| 25 | Reputation | ReputationManagementController | 4 | Yorum & istatistik | +| 26 | AI | AIController | 1 | OpenAI | +| 27 | Export | ExportPdfController | 5 | PDF/Excel | +| 28 | Utility | Language, Currency, Destination, Chain, Test, Contact | 11 | Referans veri | + +**Toplam:** ~300+ endpoint, ~60 controller dosyası. + +--- + +## 13. Auth Header Konvansiyonu + +| Tip | Header | Doğrulayan | +| --------------- | ----------------------------- | ------------------------------ | +| App API | `authToken: ` | `JwtMiddleware` | +| BookingEngine | `bookingEngineToken: ` | `BookingEngineTokenMiddleware` | +| MyWeb | `myWebToken: ` | `MyWebTokenMiddleware` | +| Channel Manager | partner-specific header | İlgili adapter | + +--- + +## 14. Body Konvansiyonu + +| Endpoint Tipi | Body Şeması | +| ------------------ | -------------------------------------------------------------------------- | +| Login | `{ "email", "password", "remember_me", "locale", "onesignal_key" }` (flat) | +| Tüm App API (POST) | `{ "params": { ... } }` (controller'lar `$this->request->params` okur) | +| BookingEngine | `{ "params": { ... } }` veya path param | +| ChannelManager | adapter'a özel JSON şeması | + +--- + +## 15. Asenkron Olaylar (Queue Driver: database) + +| Job | Tetikleyici | Görev | +| --------------------------------- | ----------------------- | ---------------- | +| `PropertyCatalogServiceJob` | property/channel update | Catalog senkronu | +| `PropertyReviewServiceJob` | reputation sync | Review fetch | +| `PropertyReviewAnalyzeServiceJob` | review save | NLP/sentiment | +| `SlackLogJob` | sistem logu | Slack bildirim | + +Mail kuyrukları: `userCreateMail`, `UserForgotPassword`. + +--- + +## 16. Status Kodları Özeti + +| Tablo | Alan | Değerler | +| ------------------- | ---------- | --------------------------------------------------------------- | +| user | status | 0 inaktif / 1 aktif | +| user | user_type | 0 normal / 1 admin | +| api_access_token | invalidate | 0 geçerli / 1 iptal | +| booking | status | 0 İptal / 1 Onaylı / 2 Pending | +| booking_payment | status | 0 İptal / 1 Onaylı / 2 Pending | +| payment_transaction | status | 0 Error / 1 Success / 2 Start / 3 Pending / 4 Cancel / 5 Manual | +| property | status | 0 inaktif / 1 aktif | + +--- + +## 17. Hızlı Bakış: Tipik İstek Hayatı + +``` +1. Client → POST /app/v1/property/info/get (Header: authToken) +2. cors → LanguageSetting → jwt.auth → userRoutePermissionAuthorize → property +3. PropertyController@getProperty +4. PropertyService->select(criteria scoped to property_id) +5. PropertyRepository->findByCriteria +6. MySQL property + relations (with: 'propertyContact', 'propertyType', ...) +7. apiResponse(1, null, $data, 200) +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5c24dd4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,82 @@ +FROM php:7.3-apache-buster + +# Debian Buster EOL olduğu için repo adreslerini archive'a taşıyoruz +RUN sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list \ + && sed -i 's|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' /etc/apt/sources.list \ + && sed -i '/buster-updates/d' /etc/apt/sources.list \ + && apt-get update + +# Sistem paketleri + PHP extension kurulumu +RUN apt-get install -y --no-install-recommends \ + git \ + unzip \ + zip \ + nano \ + curl \ + libzip-dev \ + libpng-dev \ + libjpeg-dev \ + libfreetype6-dev \ + libxml2-dev \ + zlib1g-dev \ + libonig-dev \ + && docker-php-ext-configure gd \ + --with-freetype-dir=/usr/include/ \ + --with-jpeg-dir=/usr/include/ \ + && docker-php-ext-install \ + pdo \ + pdo_mysql \ + gd \ + zip \ + mbstring \ + exif \ + && rm -rf /var/lib/apt/lists/* + +# Composer 2.2 kurulumu - PHP 7.3 için güvenli sürüm +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php composer-setup.php --2.2 --install-dir=/usr/local/bin --filename=composer \ + && php -r "unlink('composer-setup.php');" + +# Apache modları +RUN a2enmod rewrite + +# Apache VirtualHost ayarı +RUN cat > /etc/apache2/sites-available/000-default.conf <<'EOF' + + ServerName localhost + ServerAdmin webmaster@localhost + + DocumentRoot /var/www/html/public + + + Options FollowSymLinks + AllowOverride All + Require all granted + + + + AllowOverride All + Require all granted + + + Alias /uploads /home/uploads + + + Options FollowSymLinks + AllowOverride None + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + +EOF + +# Upload klasörü +RUN mkdir -p /home/uploads \ + && chown -R www-data:www-data /home/uploads \ + && chmod -R 775 /home/uploads + +WORKDIR /var/www/html + +CMD ["apache2-foreground"] diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md new file mode 100644 index 0000000..22efe74 --- /dev/null +++ b/PROJECT_SUMMARY.md @@ -0,0 +1,233 @@ +# ExtraNetWork API — Teknik Özet + +## Genel Bilgiler + +| Özellik | Değer | +| ------------- | ----------------------------------------- | +| Framework | Laravel Lumen 5.8 | +| PHP | >= 7.1.3 | +| App Versiyonu | 1.5.22 | +| Veritabanı | MySQL (`utf8mb4`, host: `mysql-master`) | +| Queue Driver | Database (jobs tablosu) | +| Mail Driver | SMTP — Gmail (`noreply@extranetwork.com`) | + +--- + +## Mimari + +``` +app/ +├── Http/Controllers/ → 86 Controller +├── Core/ +│ ├── Service/ → 142 Service +│ ├── Repository/ → 176 Repository +│ └── Validator/ → 132 Validator +├── Models/ → 196 Model +├── Jobs/ → 6 Job +├── Events/ → 2 Event +├── Listeners/ → 1 Listener +├── Channels/ → OneSignal push +└── Http/Middleware/ → 11 Middleware +``` + +**Katmanlı mimari:** Controller → Service → Repository → Model + +--- + +## Servisler & URL'ler + +| Servis | URL | +| -------------- | ------------------------------ | +| API | `https://api.extranetwork.com` | +| Web | `https://www.extranetwork.com` | +| Client App | `https://app.extranetwork.com` | +| Booking Engine | `https://be.extranetwork.com` | +| Image CDN | `https://cdn.extranetwork.com` | + +--- + +## Veritabanı (100+ tablo) + +### Ana Tablolar + +| Grup | Tablolar | +| --------------- | --------------------------------------------------------------------------------------------------------- | +| Kullanıcı | `user`, `permission`, `permission_group`, `user_property_mapping` | +| Mülk (Property) | `property`, `property_type`, `property_chain`, `property_brand`, `property_contact`, `property_executive` | +| Oda | `property_room`, `property_room_type`, `property_room_bed`, `property_room_view_type` | +| Fotoğraf | `property_photo`, `property_photo_category`, `property_room_photo_mapping` | +| İçerik | `property_content`, `property_content_category`, `property_fact`, `property_fact_mapping` | +| Fiyat & Oran | `property_room_rate`, `property_room_rate_mapping`, `property_room_rate_channel_mapping` | +| Kanal | `property_channel`, `property_channel_mapping`, `property_channel_category` | +| Rezervasyon | `booking`, `booking_contact`, `booking_room_pax`, `booking_addon`, `booking_payment` | +| Politika | `property_cancellation_policy`, `property_pricing_policy_adult`, `property_pricing_policy_child` | +| Web | `property_web`, `property_web_content`, `property_web_menu`, `property_web_meta_tag` | +| Diğer | `property_promotion`, `property_coupon`, `property_addon`, `property_award_certificate`, `site_config` | + +--- + +## Modeller & İlişkiler + +### Property (Ana Model) + +``` +Property + ├── hasMany → PropertyPhoto, PropertyRoom, PropertyExecutive, PropertyUser + ├── hasOne → PropertyContact, PropertyWeb, PropertyBrand, PropertyChain + └── belongsTo → PropertyType, Destination +``` + +### Booking + +``` +Booking + ├── hasMany → BookingRoomPax, BookingAddon, BookingPayment + └── hasOne → BookingContact +``` + +### Offer + +``` +Offer + ├── hasMany → OfferContactMapping, OfferFactMapping + └── hasOne → OfferPaymentType +``` + +--- + +## Controller Grupları + +### Auth & Kullanıcı + +- `AuthController` — login, refresh-token, logout +- `UserController` — CRUD, şifre sıfırlama, rol yönetimi + +### Property Yönetimi + +- `PropertyController` — CRUD, dashboard, raporlar +- `PropertyPhotoController` — yükleme, sıralama, yayınlama +- `PropertyContactController`, `PropertyExecutiveController`, `PropertyBrandController` +- `PropertyRoomController`, `PropertyRoomBedController`, `PropertyRoomTypeController` + +### Fiyat & Oran + +- `PropertyRoomRateController`, `PropertyRoomRateMappingController` +- `PropertyRoomRateChannelMappingController` +- `PropertyQuickPricingController`, `PropertyPersonPricingPolicyController` +- `PropertyOfferController`, `PropertyNonrefundableController` +- `PropertyCancellationPolicyController` + +### Kanal Yönetimi + +- `PropertyChannelController`, `PropertyChannelMappingController` +- `PropertyChannelGroupController`, `PropertyChannelCategoryController` +- `CompetitorPriceAnalysisController` + +### İçerik & Web + +- `PropertyContentController`, `PropertyFactController` +- `PropertyWebController`, `PropertyWebContentController`, `PropertyWebMenuController` +- `PropertyPlaceController`, `PropertyAdditionalInfoController` + +### Rezervasyon & Ödeme + +- `PropertyBookingController` +- `PaymentController`, `PaymentLinkController` +- `PropertyBookingTicketController` + +### Özel + +- `AIController` — OpenAI entegrasyonu +- `ReputationManagementController` — Review/yorum yönetimi +- `PropertyAwardCertificatesController` +- `ExportPdfController`, `DashboardPlusService` controllers + +--- + +## Middleware + +| Middleware | Görev | +| ------------------------------------------ | ------------------------ | +| `JwtMiddleware` | JWT token doğrulama | +| `CorsMiddleware` | CORS başlıkları | +| `LanguageSettingMiddleware` | Dil seçimi | +| `PropertyMiddleware` | Property context | +| `UserRoutePermissionAuthorize` | RBAC yetki kontrolü | +| `BookingEngineTokenMiddleware` | Booking engine auth | +| `MyWebTokenMiddleware` | MyWeb auth | +| `CheckPropertyChannelConnectionMiddleware` | Kanal bağlantı doğrulama | +| `ContentWizardMiddleware` | İçerik sihirbazı akışı | + +--- + +## Jobs (Queue) + +| Job | Görev | +| --------------------------------- | ---------------------- | +| `PropertyReviewServiceJob` | Review senkronizasyonu | +| `PropertyReviewAnalyzeServiceJob` | Review analizi | +| `PropertyCatalogServiceJob` | Katalog güncellemeleri | +| `SlackLogJob` | Slack bildirim logları | + +--- + +## Route Yapısı + +``` +POST /app/v1/auth/login +POST /app/v1/auth/refresh-token +POST /app/v1/user/register +POST /app/v1/logout + +GET /property-comparison/{weekKey} +POST /web/check-domain + +[Protected - /app/v1] + ├── /property/** → Property CRUD & yönetim + ├── /property-room/** → Oda yönetimi + ├── /property-rate/** → Fiyat & oran + ├── /property-channel/** → Kanal yönetimi + ├── /booking/** → Rezervasyon + ├── /payment/** → Ödeme + ├── /property-web/** → Web içerik + └── /user/** → Kullanıcı yönetimi +``` + +--- + +## Temel Paketler + +| Paket | Sürüm | Kullanım | +| ------------------------- | ------ | -------------- | +| `laravel/lumen-framework` | 5.8 | Framework | +| `firebase/php-jwt` | ^5.0 | JWT auth | +| `stripe/stripe-php` | ^7.66 | Ödeme | +| `google/cloud-vision` | ^0.24 | Görsel analiz | +| `maatwebsite/excel` | ^3.1 | Excel export | +| `barryvdh/laravel-dompdf` | ^0.8.7 | PDF üretimi | +| `intervention/image` | ^2.5 | Görsel işleme | +| `predis/predis` | ^1.1 | Redis | +| `ramsey/uuid` | ^4.1 | UUID üretimi | +| `symfony/translation` | 4.4.1 | Çeviri desteği | + +--- + +## Dil Desteği + +`config/` altında hazır dil paketi dosyaları: + +- `language-pack-en.php` — İngilizce +- `language-pack-de.php` — Almanca +- `language-pack-tr.php` — Türkçe + +--- + +## Entegrasyonlar + +- **Stripe** — Ödeme işlemleri +- **OpenAI** — AI özellikler (`AIController`) +- **Google Cloud Vision** — Görsel analiz +- **OneSignal** — Push bildirim (`OneSignalChannel`) +- **Slack** — Log bildirimleri (`SlackLogJob`) +- **Redis** — Cache & queue +- **Gmail SMTP** — Mail gönderimi diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee4410f --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# api.extranetwork.com + +Laravel 5.x tabanlı ExtraNetwork API backend. + +## Gereksinimler + +- PHP 7.3 +- MySQL 8.0 +- Docker & Docker Compose +- Composer 2.2 + +## Kurulum + +```bash +# Bağımlılıkları kur +composer install + +# .env dosyasını oluştur +cp .env.example .env +php artisan key:generate + +# Veritabanı migrate +php artisan migrate +``` + +## Docker ile Çalıştırma + +```bash +docker compose up -d +``` + +Uygulama `http://localhost:8073` adresinde çalışır. + +## CI/CD + +Drone CI pipeline otomatik olarak: + +1. `composer install` çalıştırır +2. PHPUnit testlerini çalıştırır +3. Docker image build edip Gitea registry'e push eder +4. SSH ile sunucuya deploy eder + +### Drone Secrets (Ayarlanması gerekenler) + +| Secret | Açıklama | +| ---------------- | --------------------------- | +| `GITEA_USER` | Gitea kullanıcı adı | +| `GITEA_TOKEN` | Gitea access token | +| `DEPLOY_HOST` | Deploy sunucusu IP/hostname | +| `DEPLOY_USER` | SSH kullanıcısı | +| `DEPLOY_SSH_KEY` | SSH private key | diff --git a/app/Channels/OneSignalChannel.php b/app/Channels/OneSignalChannel.php new file mode 100644 index 0000000..1135004 --- /dev/null +++ b/app/Channels/OneSignalChannel.php @@ -0,0 +1,22 @@ +toOneSignal($notifiable); + + // Send notification to the $notifiable instance... + } +} diff --git a/app/Console/Commands/.gitkeep b/app/Console/Commands/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Console/Commands/ApplicationLanguageFiles/ApplicationFillTableLanguageKey.php b/app/Console/Commands/ApplicationLanguageFiles/ApplicationFillTableLanguageKey.php new file mode 100644 index 0000000..4743459 --- /dev/null +++ b/app/Console/Commands/ApplicationLanguageFiles/ApplicationFillTableLanguageKey.php @@ -0,0 +1,48 @@ +languageBaseService = $languageBaseService; + parent::__construct(); + } + + public function handle() + { + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE START'); + $process = $this->languageBaseService->fillApplicationLanguageKeys(); + if($process['status'] != 'success'){ + throw new Exception($process['message']) ; + + } + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageBaseData.php b/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageBaseData.php new file mode 100644 index 0000000..9da00e8 --- /dev/null +++ b/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageBaseData.php @@ -0,0 +1,48 @@ +languageBaseService = $languageBaseService; + parent::__construct(); + } + + public function handle() + { + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE START'); + $process = $this->languageBaseService->createApplicationLanguageBaseData(); + if($process['status'] != 'success'){ + throw new Exception($process['message']) ; + + } + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageFiles.php b/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageFiles.php new file mode 100644 index 0000000..13a4022 --- /dev/null +++ b/app/Console/Commands/ApplicationLanguageFiles/ApplicationLanguageFiles.php @@ -0,0 +1,48 @@ +languageBaseService = $languageBaseService; + parent::__construct(); + } + + public function handle() + { + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE CREATE JSON START'); + $process = $this->languageBaseService->createApplicationLanguageFiles(); + if($process['status'] != 'success'){ + throw new Exception($process['message']) ; + + } + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE CREATE JSON FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/BestAvailableRateSyncService.php b/app/Console/Commands/ChannelManager/BestAvailableRateSyncService.php new file mode 100644 index 0000000..e383bbc --- /dev/null +++ b/app/Console/Commands/ChannelManager/BestAvailableRateSyncService.php @@ -0,0 +1,356 @@ +mailer = $mailer; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyBookingEngineService = $propertyBookingEngineService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => 2],//Channex + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['property'] + ]; + + $howManyDays = 90; + if (!is_null($this->option('property_id'))) { + $requestParam['criteria'][] = ['field' => 'property_id', 'condition' => '=', 'value' => $this->option('property_id')]; + $howManyDays = 6 * 30; + } + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + $channelManagerPropertyMapping = $channelManagerPropertyMapping['status'] == 'success' ? $channelManagerPropertyMapping['data'] : []; + + foreach ($channelManagerPropertyMapping as $propertyMapping) { + + if ($propertyMapping['property']['status'] != 1) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $propertyMapping['property']['name']); + continue; + } + + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyRoomRateChannelMappingParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//Kanal Yöentimi + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyMapping['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingParam); + $propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping['status'] == 'success' ? $propertyRoomRateChannelMapping['data'] : []; + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping); + + $propertyBookingEngineParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyMapping['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property.propertyBookingEngineToken'], + 'firstRow' => 1 + ]; + + $propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineParam, ['id', 'property_id', 'channel_id', 'token']); + $propertyBookingEngine = $propertyBookingEngine['status'] == 'success' ? $propertyBookingEngine['data'] : []; + + if (empty($propertyBookingEngine)) { + $this->info(date('Y-m-d H:i:s') . ' : None Booking Engine!'); + continue; + } + + + $searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController"); + + + $roomRateFormatted = []; + + + $today = Carbon::now()->startOfDay()->toDateTimeString(); + if (!is_null($this->option('property_id'))) { + $today = Carbon::now()->startOfDay()->toDateTimeString(); + } else { + + //00:00 04:00 08:00 12:00 16:00 20:00 + $processHour = (integer)Carbon::now()->format('H'); + + switch ($processHour) { + + case ($processHour >= 0 && $processHour <= 2) : + case ($processHour > 8 && $processHour <= 10): + case ($processHour > 16 && $processHour <= 18): + $today = Carbon::now()->startOfDay()->toDateTimeString(); + break; + case ($processHour > 2 && $processHour <= 4) : + case ($processHour > 10 && $processHour <= 12): + case ($processHour > 18 && $processHour <= 20) : + $today = Carbon::now()->startOfDay()->addDays($howManyDays)->toDateTimeString(); + break; + case ($processHour > 4 && $processHour <= 6) : + case ($processHour > 12 && $processHour <= 14): + case ($processHour > 20 && $processHour <= 22) : + $today = Carbon::now()->startOfDay()->addDays($howManyDays * 2)->toDateTimeString(); + break; + case ($processHour > 6 && $processHour <= 8) : + case ($processHour > 14 && $processHour <= 16): + case ($processHour > 22 && $processHour < 24) : + $today = Carbon::now()->startOfDay()->addDays($howManyDays * 3)->toDateTimeString(); + break; + + } + + } + + + for ($i = 0; $i < $howManyDays; $i++) { + + $checkIn = Carbon::parse($today)->addDays($i)->toDateString(); + $checkOut = Carbon::parse($checkIn)->addDay()->toDateString(); + + $searchRequestJson = [ + 'date' => [ + 'checkIn' => $checkIn, + 'checkOut' => $checkOut, + ], + 'rooms' => [ + [ + 'adults' => 2, + 'children' => 0, + 'age' => [], + ] + ], + 'property' => [], + 'ipAddress' => '185.137.215.118', + 'isMobile' => null, + 'noneCacheSearch' => true, + 'min_stay_disabled' => true + ]; + + + $requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson)); + $requestCreate->headers->set('channelId', '1'); + $requestCreate->headers->set('bookingEnginePropertyId', $propertyMapping['property_id']); + $requestCreate->headers->set('channelToken', $propertyBookingEngine['channel']['token']); + $requestCreate->headers->set('bookingEngineToken', $propertyBookingEngine['property']['property_booking_engine_token']['token']); + + $search = $searchController->search($requestCreate); + $search = json_decode(json_encode($search), 1); + + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn); + + if ($search['original']['status'] == 200) { + + + if (empty($search['original']['data']['properties'])) { + + //Rate Stop or Price 0 Case + foreach ($propertyRoomRateChannelMapping as $roomRateChannelMapping) { + + $referenceRoomRateMapping = $propertyRoomRateChannelMappingCollect + ->where('property_room_rate_mapping.room_id', $roomRateChannelMapping['property_room_rate_mapping']['room_id']) + ->where('property_room_rate_mapping.property_room_rate.name', 'Best Available Rate')->first(); + + if (!empty($referenceRoomRateMapping)) { + $roomRateKey = '1|' . $referenceRoomRateMapping['property_room_rate_mapping']['room_id'] . '|' . $referenceRoomRateMapping['property_room_rate_mapping']['id'] . '|' . $checkIn; + $roomRateFormatted[$roomRateKey] = [ + 'setup_type_id' => '1', + 'room_id' => $referenceRoomRateMapping['property_room_rate_mapping']['room_id'], + 'room_rate_mapping_id' => $referenceRoomRateMapping['property_room_rate_mapping']['id'], + 'date' => $checkIn, + 'amount' => 0 + ]; + } + } + //Rate Stop or Price 0 Case + + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + $property = reset($search['original']['data']['properties']); + if (empty($property)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + if (!isset($property['availabilities'])) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + $propertyAvailability = reset($property['availabilities']); + if (empty($propertyAvailability)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + /*dd($propertyAvailability['rooms']); + + $propertyAvailabilityRoom = reset($propertyAvailability['rooms']); + if (empty($propertyAvailability)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + $propertyAvailabilityRoom['rates'] = collect($propertyAvailabilityRoom['rates'])->sortBy('total')->toArray(); +*/ + + foreach ($propertyAvailability['rooms'] as $roomId => $room) { + foreach ($room['rates'] as $roomRateInnerKey => $roomRate) { + + /*$propertyAvailabilityRoomRate = reset($propertyAvailabilityRoom['rates']); + if (empty($propertyAvailabilityRoomRate)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + }*/ + + $propertyAvailabilityRoomRatePrices = reset($roomRate['requestedRoomPrice']); + if (empty($propertyAvailabilityRoomRatePrices)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + $propertyAvailabilityRoomRatePrice = reset($propertyAvailabilityRoomRatePrices['prices']); + if (empty($propertyAvailabilityRoomRatePrice)) { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + continue; + } + + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['id'] . ' - ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - ' . $propertyAvailabilityRoomRatePrice['total']); + + + $referenceRoomRateMapping = $propertyRoomRateChannelMappingCollect + ->where('property_room_rate_mapping.room_id', $roomId) + ->where('property_room_rate_mapping.property_room_rate.name', 'Best Available Rate')->first(); + + if (empty($referenceRoomRateMapping)) { + $this->info(date('Y-m-d H:i:s') . ' : None Best Available Rate! PropertyId: ' . $propertyMapping['property_id'] . ' Room: ' . $room['name']); + continue; + } + + /*if($referenceRoomRateMapping['property_room_rate_mapping']['id'] != 6003) { + continue; + }*/ + + + $roomRateKey = '1|' . $referenceRoomRateMapping['property_room_rate_mapping']['room_id'] . '|' . $referenceRoomRateMapping['property_room_rate_mapping']['id'] . '|' . $checkIn; + + if (!isset($roomRateFormatted[$roomRateKey])) { + $roomRateFormatted[$roomRateKey] = [ + 'setup_type_id' => '1', + 'room_id' => $referenceRoomRateMapping['property_room_rate_mapping']['room_id'], + 'room_rate_mapping_id' => $referenceRoomRateMapping['property_room_rate_mapping']['id'], + 'date' => $checkIn, + 'amount' => $propertyAvailabilityRoomRatePrice['total'] + ]; + + } + + if ($propertyAvailabilityRoomRatePrice['total'] < $roomRateFormatted[$roomRateKey]['amount']) { + $roomRateFormatted[$roomRateKey]['amount'] = $propertyAvailabilityRoomRatePrice['total']; + } + + } + + } + + } else { + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE'); + } + + } + + $requestParams = [ + 'property_id' => $propertyMapping['property_id'], + 'channel_id' => 5, + 'availability' => [], + 'user_id' => 1, + 'rates' => $roomRateFormatted + ]; + + $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams); + + if ($roomRateUpdate['status'] != 'success') { + throw new ApiErrorException($roomRateUpdate['message']); + } + + $response['status'] = true; + + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['id'] . ' : ' . $propertyBookingEngine['property']['name'] . ' - Today: ' . $today . ' - OK'); + + Log::debug($propertyBookingEngine['property']['id'] . ' : ' . $propertyBookingEngine['property']['name'] . ' - Today: ' . $today . ' - OK'); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $this->error(date('Y-m-d H:i:s') . ' : ' . $response['message']); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/MetaCancellationService.php b/app/Console/Commands/ChannelManager/MetaCancellationService.php new file mode 100644 index 0000000..5a8aedc --- /dev/null +++ b/app/Console/Commands/ChannelManager/MetaCancellationService.php @@ -0,0 +1,130 @@ +mailer = $mailer; + $this->channelManagerBookingService = $channelManagerBookingService; + + } + + public function handle() + { + + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $today = Carbon::now()->startOfDay()->toDateString(); + + + if(!Carbon::parse($today)->isLastOfMonth()) { + $this->alert(date('Y-m-d H:i:s') . ' : Not Today!'); + return false; + } + + $fistDayOfMonth = Carbon::parse($today)->startOfMonth()->toDateString(); + $lastDayOfMonth = Carbon::parse($today)->addMonth()->startOfMonth()->toDateString(); + + $cancellationBooking = Booking::where('channel_id', 1) + ->where('status', 0) + ->where('checkout_date', '>', $fistDayOfMonth) + ->where('checkout_date', '<', $lastDayOfMonth) + //->where('id', 68690) + ->with('channelManagerBooking') + ->with('bookingRoom') + ->get(); + + //11 - Trivago + + $cancellationBooking = $cancellationBooking ? $cancellationBooking->toArray() : []; + + + foreach ($cancellationBooking as $booking) { + + try { + + + if (empty($booking['channel_manager_booking'])) { + $this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']); + continue; + } + + $channelBookingCheck = collect($booking['channel_manager_booking']) + ->where('channel_manager_id', 11) + ->where('type', 'Booking') + ->where('is_pushed', 1) + ->isEmpty(); + + if ($channelBookingCheck) { + $this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']); + continue; + } + + $channelCancelCheck = collect($booking['channel_manager_booking']) + ->where('channel_manager_id', 11) + ->where('type', 'Cancel') + ->where('is_pushed', 1) + ->isEmpty(); + + if (!$channelCancelCheck) { + $this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']); + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $booking['property_id'], + 'booking_id' => $booking['id'], + 'channel_manager_id' => 11, + 'type' => 'Cancel', + ]; + + $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + $this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']); + + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } + +} diff --git a/app/Console/Commands/ChannelManager/PropertyBookingSyncService.php b/app/Console/Commands/ChannelManager/PropertyBookingSyncService.php new file mode 100644 index 0000000..d009a79 --- /dev/null +++ b/app/Console/Commands/ChannelManager/PropertyBookingSyncService.php @@ -0,0 +1,72 @@ +mailer = $mailer; + $this->propertyRoomService = $propertyRoomService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + } + + public function handle() + { + + $sourcePath = 'C:\www\api.extranetwork.com\app\Console\Commands\ChannelManager\akgun.xlsx'; + + + $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); + $spreadsheet = $reader->load($sourcePath); + $sheet = $spreadsheet->getSheet($spreadsheet->getFirstSheetIndex()); + $rows = $sheet->toArray(); + + $rowKey = 0; + foreach ($rows as $row) { + + $rowKey++; + + if($rowKey < 3) { + continue; + } + + dd($row); + } + + //dd(file_exists($sourcePath)); + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/PropertyChannelSyncService.php b/app/Console/Commands/ChannelManager/PropertyChannelSyncService.php new file mode 100644 index 0000000..2f309e8 --- /dev/null +++ b/app/Console/Commands/ChannelManager/PropertyChannelSyncService.php @@ -0,0 +1,222 @@ +mailer = $mailer; + $this->propertyRoomService = $propertyRoomService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + } + + public function handle() + { + + $sourceChannelId = 1; //Booking Engine + $targetChannelId = 5; //Channel Manager + + $propertyIdList = [1098]; + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + + foreach ($propertyIdList as $propertyId) { + + + $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + + $isPropertyRoomAvailabilityUpdate = false; + + DB::beginTransaction(); + + try { + + $propertyRoomAvailabilityUpdateQuery = <<= curdate() AND channel_id IS NULL AND status = 1; +BUR; + + $propertyRoomAvailabilityUpdate = DB::select(DB::raw($propertyRoomAvailabilityUpdateQuery)); + + $isPropertyRoomAvailabilityUpdate = true; + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (\Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + + if ($isPropertyRoomAvailabilityUpdate) { + DB::commit(); + $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + } else { + DB::rollBack(); + $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + } + + $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + + + $this->info(date('Y-m-d H:i:s') . ' - RATE START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + + $requestParams = [ + 'property_id' => $propertyId, + 'channel_id' => $sourceChannelId, + 'start_date' => Carbon::now()->toDateString(), + 'end_date' => Carbon::now()->addMonths(6)->subDay()->toDateString(), + //'start_date' => '2023-03-01', + //'end_date' => '2024-01-01', + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams); + + if ($propertyRoomType['status'] != 'success') { + throw new ApiErrorException($propertyRoomType['message']); + } + + $propertyRoomType = $propertyRoomType['data']; + $propertyRoomRateAvailability = collect($propertyRoomType); + + $roomRates = []; + foreach ($propertyRoomRateAvailability as $room) { + + foreach ($room['property_room_rate_mapping'] as $roomRateMapping) { + + + foreach ($room['room_availability'] as $date => $roomAvailability) { + $roomRates[$room['id']]['availability'][$date] = $roomAvailability['value']; + } + + $roomRates[$room['id']]['rate'][$roomRateMapping['id']] = [ + 'roomName' => $room['name'], + 'roomRateName' => $roomRateMapping['name'], + 'currencyCode' => $roomRateMapping['currency_code'], + ]; + + + $roomRatePrices = reset($roomRateMapping['prices']); + foreach ($roomRatePrices['price'] as $date => $roomRatePrice) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['price'][$date] = $roomRatePrice['value']; + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $roomRatePrice['stop_sell']; + } + + foreach ($roomRatePrices['stop_sell'] as $date => $stopSell) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $stopSell['value']; + } + + foreach ($roomRatePrices['min_stay'] as $date => $minStay) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['minStay'][$date] = $minStay['value']; + } + + } + } + + + $roomRateFormatted = []; + foreach ($roomRates as $roomId => $roomRateMapping) { + foreach ($roomRateMapping['rate'] as $roomRateMappingId => $roomRate) { + + foreach ($roomRate['price'] as $date => $price) { + + $roomRateKey = '1|' . $roomId . '|' . $roomRateMappingId . '|' . $date; + + $roomRateFormatted[$roomRateKey] = [ + 'setup_type_id' => '1', + 'room_id' => $roomId, + 'room_rate_mapping_id' => $roomRateMappingId, + 'date' => $date, + 'amount' => is_null($price) ? 0 : $price, + 'min_stay' => $roomRate['minStay'][$date], + 'stop_sell' => $roomRate['stopSell'][$date], + ]; + + } + + } + + } + + $isPropertyRoomRateUpdate = false; + + DB::beginTransaction(); + + try { + + $roomRateFormattedChunked = array_chunk($roomRateFormatted, 1000); + + foreach ($roomRateFormattedChunked as $roomRateFormattedParsed) { + + $requestParams = [ + 'property_id' => $propertyId, + 'channel_id' => $targetChannelId, + 'rates' => $roomRateFormattedParsed + ]; + + $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams); + + if ($roomRateUpdate['status'] != 'success') { + throw new ApiErrorException($roomRateUpdate['message']); + } + + } + + $isPropertyRoomRateUpdate = true; + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (\Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + + if ($isPropertyRoomRateUpdate) { + DB::commit(); + $this->info(date('Y-m-d H:i:s') . ' - RATE SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + } else { + DB::rollBack(); + $this->info(date('Y-m-d H:i:s') . ' - RATE ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + } + + $this->info(date('Y-m-d H:i:s') . ' - RATE FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId); + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePriceService.php b/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePriceService.php new file mode 100644 index 0000000..27cf166 --- /dev/null +++ b/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePriceService.php @@ -0,0 +1,344 @@ +mailer = $mailer; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + + if (!is_null($this->option('property_id'))) { + $propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'promotion', 'status'])->toArray(); + } else { + $propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'promotion', 'status'])->toArray(); + } + + foreach ($propertyMeta as $property) { + + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price Start: ' . $property['property']['name']); + + + $roomRateOccupancyPriceParam = []; + + $propertyId = $property['property_id']; + $startDate = Carbon::now()->toDateString(); + $finishDate = Carbon::parse($startDate)->addDays(360)->toDateString(); + + $propertyCancellationPolicy = json_decode($property['cancellation_policy'], 1); + $propertyAdultPolicy = json_decode($property['adult_policy'], 1); + $propertyChildPolicy = json_decode($property['child_policy'], 1); + $propertyPromotion = json_decode($property['promotion'], 1); + + $propertyRoomRatePrice = PropertyRoomRatePrice::where('property_id', $propertyId) + ->where('date', '>=', $startDate) + ->where('date', '<=', $finishDate) + ->where('channel_id', 1) + //->where('room_rate_mapping_id', 79)//TODO: Delete + //->where('date', '2024-09-01')//TODO: Delete + ->where('availability_type_id', 1) + ->where('status', 1) + ->get(['id', 'property_id', 'property_room_id', 'room_rate_mapping_id', 'date', 'amount', 'currency', 'min_stay', 'stop_sell']); + + $propertyRoomRatePrice = $propertyRoomRatePrice->toArray(); + + $roomRateOccupancy = PropertyMetaRoomRate::where('property_id', $propertyId)->get()->toArray(); + + //TODO: DEL + //$roomRateOccupancy = collect($roomRateOccupancy)->where('occupancy_code', 'A')->toArray(); + + $propertyAllPriceCounter = 0; + + $roomRateOccupancyPrice = []; + foreach ($propertyRoomRatePrice as $perPropertyRoomRatePrice) { + + $roomRateOccupancySelected = collect($roomRateOccupancy)->where('room_rate_mapping_id', $perPropertyRoomRatePrice['room_rate_mapping_id'])->toArray(); + + foreach ($roomRateOccupancySelected as $roomRateOccupancyKey => $perRoomRateOccupancy) { + + $baseAmount = $perPropertyRoomRatePrice['amount']; + + $roomRateOccupancyKey = $perRoomRateOccupancy['code']; + + $affectedAmountArray = []; + + $roomRateMappingId = $perPropertyRoomRatePrice['room_rate_mapping_id']; + $cancellationPolicy = isset($propertyCancellationPolicy[$roomRateMappingId]) ? $propertyCancellationPolicy[$roomRateMappingId] : []; + $adultPolicy = isset($propertyAdultPolicy[$roomRateMappingId]) ? $propertyAdultPolicy[$roomRateMappingId] : []; + $childPolicy = isset($propertyChildPolicy[$roomRateMappingId]) ? $propertyChildPolicy[$roomRateMappingId] : []; + $promotions = isset($propertyPromotion[$roomRateMappingId]) ? $propertyPromotion[$roomRateMappingId] : []; + + //dd($promotions,$perPropertyRoomRatePrice,$baseAmount); + + + $perPersonAmount = $baseAmount / $perRoomRateOccupancy['included_occupancy']; + + //Kişi bazlı fiyat hesaplamada baz fiyat dikkate alınır, daha sonra $perPersonAmount baz fiyat üzerinden alınıp çocuk hespaplanır. + + + //Adult Policy + $affectedAmount = 0; + if ($perRoomRateOccupancy['included_occupancy'] != strlen($perRoomRateOccupancy['occupancy_code'])) { + if (!empty($adultPolicy)) { + + if ($perRoomRateOccupancy['included_occupancy'] > strlen($perRoomRateOccupancy['occupancy_code'])) { + + $occupancyDifference = $perRoomRateOccupancy['included_occupancy'] - strlen($perRoomRateOccupancy['occupancy_code']); + $adultPolicySelected = collect($adultPolicy) + ->where('adult', $occupancyDifference) + ->where('adult_action_type', 'DEC') + ->first(); + + if (!empty($adultPolicySelected)) { + if ($adultPolicySelected['type'] == 'PER') { + $affectedAmount = ($baseAmount * $adultPolicySelected['value'] / 100); + } elseif ($adultPolicySelected['type'] == 'FIX') { + $affectedAmount = $adultPolicySelected['value']; + } + + $affectedAmountArray[] = $adultPolicySelected['action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount; + + } + + } + + if (strlen($perRoomRateOccupancy['occupancy_code']) > $perRoomRateOccupancy['included_occupancy']) { + + $occupancyDifference = strlen($perRoomRateOccupancy['occupancy_code']) - $perRoomRateOccupancy['included_occupancy']; + $adultPolicySelected = collect($adultPolicy) + ->where('adult', $occupancyDifference) + ->where('adult_action_type', 'INC') + ->first(); + + + if (!empty($adultPolicySelected)) { + if ($adultPolicySelected['type'] == 'PER') { + $affectedAmount = ($baseAmount * $adultPolicySelected['value'] / 100); + } elseif ($adultPolicySelected['type'] == 'FIX') { + $affectedAmount = $adultPolicySelected['value']; + } + + $affectedAmountArray[] = $adultPolicySelected['action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount; + + } + + + } + + } + + } + //Adult Policy + + //Önce Oda Fiyatı Hesaplanır, Yetişkine Göre + $roomAmount = $baseAmount + array_sum($affectedAmountArray); + + + //Oluşan fiyata göre de iptal politikası uygulanır + //$cancellationPolicy + $affectedAmount = 0; + $isCancellationPolicyActive = false; + if (isset($cancellationPolicy[$perRoomRateOccupancy['cancellation_policy_id']])) { + $cancellationPolicySelected = $cancellationPolicy[$perRoomRateOccupancy['cancellation_policy_id']]; + + //dd($cancellationPolicy,$perRoomRateOccupancy,$cancellationPolicySelected,$perPropertyRoomRatePrice['date']); + + + //if ($cancellationPolicySelected['is_affected_price'] == 1) { + + $isDateRange = $cancellationPolicySelected['is_date_range']; + $isDateRangeDate = Carbon::parse($perPropertyRoomRatePrice['date'])->between($cancellationPolicySelected['start_date'], $cancellationPolicySelected['finish_date']); + + if (($isDateRange && $isDateRangeDate) || empty($isDateRange)) { + + if ($cancellationPolicySelected['affect_price_type'] == 'PER') { + $affectedAmount = ($roomAmount * $cancellationPolicySelected['affect_price_value'] / 100); + } elseif ($cancellationPolicySelected['affect_price_type'] == 'FIX') { + $affectedAmount = $cancellationPolicySelected['affect_price_value']; + } + + $affectedAmountArray[] = $cancellationPolicySelected['affect_price_action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount; + + $isCancellationPolicyActive = true; + + } + + //} + + } + //$cancellationPolicy + + + //dd($perRoomRateOccupancy, $perPropertyRoomRatePrice, $cancellationPolicy); + + $isCancellationPolicyActive = true; + if ($isCancellationPolicyActive) { + + $calculatedAmount = $baseAmount + array_sum($affectedAmountArray); + + $promotionsGrouped = collect($promotions)->groupBy('type')->toArray(); + + /**** PROMOTION START ****/ + $totalPromotionDiscount = 0; + foreach ($promotionsGrouped as $promotionsGroupKey => $promotions) { + + $promotions = collect($promotions)->sortByDesc('amount')->toArray(); + + foreach ($promotions as $promotion) { + + if ($promotion['min_stay'] > 1) { + continue; + } + + if ($promotion['is_mobile']) { + continue; + } + + $daysArray = !empty($promotion['days']) ? json_decode($promotion['days'], 1) : []; + if (!in_array((Carbon::parse($perPropertyRoomRatePrice['date'])->dayOfWeek + 1), $daysArray)) { + continue; + } + + if ($promotion['type'] == 'PRD') { + + if (!Carbon::now()->startOfDay()->between(Carbon::parse($promotion['start_date'])->toDateString(), Carbon::parse($promotion['end_date'])->toDateString())) { + continue; + } + + if (!Carbon::parse($perPropertyRoomRatePrice['date'])->startOfDay()->between(Carbon::parse($promotion['reservation_start_date'])->toDateString(), Carbon::parse($promotion['reservation_end_date'])->toDateString())) { + continue; + } + + $totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100; + + break; + + } + + if ($promotion['type'] == 'BFD') { + + if (Carbon::parse($perPropertyRoomRatePrice['date'])->diffInDays(Carbon::now()->startOfDay()->toDateString()) < $promotion['day_before']) { + continue; + } + + $totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100; + + break; + } + + if ($promotion['type'] == 'DSC') { + $totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100; + + break; + } + + + } + } + + + $calculatedAmount = moneyDoubleFormatDecimal($calculatedAmount - $totalPromotionDiscount); + $calculatedAmount = $calculatedAmount > 0 ? $calculatedAmount : 0; + /**** PROMOTION FINISHED ****/ + + $roomRateOccupancyPriceParam[] = [ + 'property_id' => $property['property_id'], + 'room_id' => $perRoomRateOccupancy['room_id'], + 'room_rate_mapping_id' => $roomRateMappingId, + 'date' => $perPropertyRoomRatePrice['date'], + 'code' => $roomRateOccupancyKey, + //'title' => $perRoomRateOccupancy['title'], + //'baseAmount' => $perPropertyRoomRatePrice['amount'], + 'amount' => $calculatedAmount, + 'currency' => $perPropertyRoomRatePrice['currency'], + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => Carbon::now()->unix(), + 'updated_at' => Carbon::now()->unix(), + ]; + + $propertyAllPriceCounter++; + + } + + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price Finished: ' . $property['property']['name']); + + //dd(collect($roomRateOccupancyPriceParam)->sortBy('room_id')->sortBy('amount')->toArray()); + + + $insertRows = []; + $updateRows = []; + $rowChunk = 0; + foreach ($roomRateOccupancyPriceParam as $roomRateOccupancyPrice) { + + $insertRows[$rowChunk][] = $roomRateOccupancyPrice; + if (count($insertRows[$rowChunk]) > 1000) { + $rowChunk++; + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price to DB Start: ' . $property['property']['name']); + + DB::beginTransaction(); + + PropertyMetaRoomRatePrice::where('property_id', $propertyId)->delete(); + + if (!empty($insertRows)) { + foreach ($insertRows as $insertRow) { + PropertyMetaRoomRatePrice::insert($insertRow); + } + } + + DB::commit(); + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price to DB Finished: ' . $property['property']['name']); + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePushService.php b/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePushService.php new file mode 100644 index 0000000..f50a1cd --- /dev/null +++ b/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePushService.php @@ -0,0 +1,309 @@ +mailer = $mailer; + $this->miraiService = $miraiService; + } + + function getMonthlyPeriod($endDate) + { + $diffInMonths = Carbon::parse()->floorMonth()->diffInMonths(Carbon::parse($endDate)->floorMonth()); + $diffInMonths++; + + $monthlyPeriod = []; + $startDate = null; + $finishDate = null; + for ($i = 0; $i < $diffInMonths; $i++) { + + if (empty($startDate)) { + $startDate = Carbon::now()->toDateString(); + $finishDate = Carbon::parse($startDate)->endOfMonth()->toDateString(); + } else { + $startDate = Carbon::now()->addMonths($i)->startOfMonth()->toDateString(); + $finishDate = Carbon::parse($startDate)->endOfMonth()->toDateString(); + } + + if ($finishDate > $endDate) { + $finishDate = $endDate; + } + + $monthlyPeriod[] = [ + 'startDate' => $startDate, + 'finishDate' => $finishDate, + ]; + + } + + return $monthlyPeriod; + + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + + if (!is_null($this->option('property_id'))) { + $propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'param', 'status'])->toArray(); + } else { + $propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'param', 'status'])->toArray(); + } + + + foreach ($propertyMeta as $property) { + + + $propertyId = $property['property_id']; + + //Mirai User Setup + $this->miraiService->setupUser($property['paramsArray']['login'], $property['paramsArray']['password']); + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Push Start: ' . $property['property']['name']); + + //$propertyRoomRatePriceEndDate = PropertyRoomRatePrice::where('property_id', $propertyId)->orderBy('date', 'DESC')->first(); + //$propertyRoomRatePriceEndDate = $propertyRoomRatePriceEndDate->toArray() ? $propertyRoomRatePriceEndDate['date'] : null; + //$propertyRoomRatePriceEndDate = '2023-10-31'; + + //$getMonthlyPeriod = $this->getMonthlyPeriod($propertyRoomRatePriceEndDate); + $getMonthlyPeriod = []; + $getMonthlyPeriod[] = [ + 'startDate' => Carbon::now()->toDateString(), + //'finishDate' => Carbon::now()->addYear()->toDateString(), + 'finishDate' => Carbon::now()->addDays(360)->toDateString(), + ]; + + $propertyMetaRoomRateMapping = PropertyMetaRoomRateMapping::where('property_id', $propertyId)->with('propertyMetaRoomRate')->get()->toArray(); + $propertyMetaRoomRateMappingCollect = collect($propertyMetaRoomRateMapping); + + $channelManagerPropertyMapping = ChannelManagerPropertyMapping::where('property_id', $propertyId)->where('status', 1)->where('channel_manager_id', 7)->first()->toArray(); + + if (empty($channelManagerPropertyMapping)) { + continue; + } + + $metaRoomRateMapping = []; + $propertyMetaRoomRateMappingGroup = $propertyMetaRoomRateMappingCollect->groupBy('property_meta_room_rate.room_id')->toArray(); + foreach ($propertyMetaRoomRateMappingGroup as $roomGroup) { + $roomGroup = reset($roomGroup); + $metaRoomRateMapping[$roomGroup['property_meta_room_rate']['room_id']]['meta_code'] = $roomGroup['meta_code']; + } + + + foreach ($getMonthlyPeriod as $period) { + + $this->info(date('Y-m-d H:i:s') . ' : Meta Availability Start: ' . $property['property']['name'] . ' - ' . $period['startDate'] . ' / ' . $period['finishDate']); + + try { + + + $propertyRoomAvailability = PropertyRoomAvailability::where('property_id', $propertyId) + ->where('status', 1)->where('channel_id', null) + ->whereBetween('date', [$period['startDate'], $period['finishDate']]) + ->get(['property_room_id', 'date', 'stop_sell', 'availability']) + ->toArray(); + $propertyRoomAvailabilityCollect = collect($propertyRoomAvailability); + + + foreach ($metaRoomRateMapping as $roomId => $metaRoom) { + $metaRoomRateMapping[$roomId]['data'] = $propertyRoomAvailabilityCollect->where('property_room_id', $roomId)->sortBy('date')->toArray(); + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $channelManagerPropertyMapping['channel_manager_property_id']); + + foreach ($metaRoomRateMapping as $roomId => $metaRoom) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $metaRoom['meta_code']); + + $roomInventory = $room->addChild('inventory'); + + foreach ($metaRoom['data'] as $roomRate) { + $roomInventoryAvailability = $roomInventory->addChild('availability'); + + $roomRate['availability'] = $roomRate['stop_sell'] == 1 ? 0 : $roomRate['availability']; + + $roomInventoryAvailability->addAttribute('date', $roomRate['date']); + $roomInventoryAvailability->addAttribute('quantity', $roomRate['availability']); + + } + + } + + + $request = $this->miraiService->inventoryRoomRateUpdate('webservice_updater.apro', $xmlResponse->asXML()); + + if (!$request['status']) { + throw new ApiErrorException('webservice_updater AVAILABILITY Error: ' . $request['message']); + } + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + + $this->info(date('Y-m-d H:i:s') . ' : Meta Price Start: ' . $property['property']['name'] . ' - ' . $period['startDate'] . ' / ' . $period['finishDate']); + + try { + + + $propertyMetaRoomRatePrice = PropertyMetaRoomRatePrice::where('property_id', $propertyId) + ->whereBetween('date', [$period['startDate'], $period['finishDate']])->where('status', 1) + ->whereIn('code', pickItemFromArray('code', $propertyMetaRoomRateMapping)) + ->get(['date', 'code', 'amount', 'currency']) + ->toArray(); + + $propertyMetaRoomRatePriceCollect = collect($propertyMetaRoomRatePrice); + + if (empty($propertyMetaRoomRatePrice)) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $property['property']['name'] . ' : Price not found!'); + continue; + } + + + $metaRoomRatePrice = []; + $metaRoomPricesOrdered = []; + foreach ($propertyMetaRoomRateMapping as $metaRoom) { + + $metaRoomPrices = $propertyMetaRoomRatePriceCollect->where('code', $metaRoom['code'])->sortBy('date')->toArray(); + $metaRoomPricesCollect = collect($metaRoomPrices); + + $metaRoomPricesGroup = []; + foreach ($metaRoomPrices as $metaRoomPrice) { + $metaRoomPricesGroup[md5($metaRoomPrice['amount'])][$metaRoomPrice['date']] = $metaRoomPrice; + ksort($metaRoomPricesGroup[md5($metaRoomPrice['amount'])]); + } + + foreach ($metaRoomPricesGroup as $priceGroupKey => $priceGroup) { + + $priceDateGroup = 0; + foreach ($priceGroup as $priceGroupDate => $price) { + + if (!isset($metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'])) { + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'] = $price['date']; + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date']; + } else { + + if (Carbon::parse($metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'])->addDay()->toDateString() != $price['date']) { + + $priceDateGroup++; + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'] = $price['date']; + + } else { + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date']; + } + + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date']; + + } + + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['amount'] = $price['amount']; + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['currency'] = $price['currency']; + //$metaRoomPricesOrdered[$priceGroupKey][$priceDateGroup]['metaCode'] = $metaRoom['meta_code']; + + $metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['title'] = $metaRoom['property_meta_room_rate']['title']; + + } + } + + } + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $channelManagerPropertyMapping['channel_manager_property_id']); + + foreach ($metaRoomPricesOrdered as $roomRateMetaCode => $metaRoom) { + + foreach ($metaRoom as $priceGroupKey => $metaRoomPriceGroup) { + + $room = $xmlResponse->addChild('room'); + + $room->addAttribute('id', $roomRateMetaCode); + + $currency = !empty($metaRoomPriceGroup) ? reset($metaRoomPriceGroup)['currency'] : 'EUR'; + + $rate = $room->addChild('rate'); + $rate->addAttribute('currency', $currency); + + foreach ($metaRoomPriceGroup as $metaRoomPrice) { + $planning = $rate->addChild('planning'); + + $planning->addAttribute('from', $metaRoomPrice['startDate']); + $planning->addAttribute('to', $metaRoomPrice['finishDate']); + $planning->addAttribute('unitPrice', $metaRoomPrice['amount']); + + } + } + + } + + $request = $this->miraiService->inventoryRoomRateUpdate('webservice_updater.apro', $xmlResponse->asXML()); + + if (!$request['status']) { + throw new ApiErrorException('webservice_updater PRICE Error: ' . $request['message']); + } + + //Remove all prices then push to meta + PropertyMetaRoomRatePrice::where('property_id', $propertyId)->delete(); + + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/PropertyMetaRoomRateService.php b/app/Console/Commands/ChannelManager/PropertyMetaRoomRateService.php new file mode 100644 index 0000000..593dbcf --- /dev/null +++ b/app/Console/Commands/ChannelManager/PropertyMetaRoomRateService.php @@ -0,0 +1,288 @@ +mailer = $mailer; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + + if (!is_null($this->option('property_id'))) { + $propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'status'])->toArray(); + } else { + $propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'status'])->toArray(); + } + + foreach ($propertyMeta as $property) { + + $this->info(date('Y-m-d H:i:s') . ' : Property Policy Start: ' . $property['property']['name']); + + + //Property All Room Rate Price Policy + $propertyRoomRateChannelMapping = PropertyRoomRateChannelMapping::with('propertyRoomRateMapping') + ->with('propertyRoomRateMapping.propertyRoom') + ->with('propertyRoomRateMapping.propertyRoomRate') + ->with('propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy') + ->with('propertyRoomRateChannelPricingAdultPolicy.propertyPricingPolicyAdult') + ->with('propertyRoomRateChannelPricingChildPolicy.propertyPricingPolicyChild') + ->with('propertyRoomRateChannelPromotion.propertyPromotion.promotionType') + ->get() + ->where('property_id', $property['property_id'])->where('channel_id', 1) + ->where('status', 1); + + $propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping->where('propertyRoomRateMapping', '!=', null)->toArray(); + + //dd($propertyRoomRateChannelMapping); + + $roomRateMappingPolicy = []; + foreach ($propertyRoomRateChannelMapping as $propertyRoom) { + + + $roomRateMappingPolicy['promotion'][$propertyRoom['room_rate_mapping_id']] = []; + foreach ($propertyRoom['property_room_rate_channel_promotion'] as $propertyRoomRateChannelPromotion) { + + if($propertyRoomRateChannelPromotion['status'] != 1) { + continue; + } + + $roomRateMappingPolicy['promotion'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateChannelPromotion['property_promotion_id']] = [ + 'type' => $propertyRoomRateChannelPromotion['property_promotion']['promotion_type']['type_code'], + 'start_date' => $propertyRoomRateChannelPromotion['property_promotion']['start_date'], + 'end_date' => $propertyRoomRateChannelPromotion['property_promotion']['end_date'], + 'reservation_start_date' => $propertyRoomRateChannelPromotion['property_promotion']['reservation_start_date'], + 'reservation_end_date' => $propertyRoomRateChannelPromotion['property_promotion']['reservation_end_date'], + 'day_before' => $propertyRoomRateChannelPromotion['property_promotion']['day_before'], + 'amount' => $propertyRoomRateChannelPromotion['property_promotion']['amount'], + 'min_stay' => $propertyRoomRateChannelPromotion['property_promotion']['min_stay'], + 'is_mobile' => $propertyRoomRateChannelPromotion['property_promotion']['is_mobile'], + 'days' => $propertyRoomRateChannelPromotion['property_promotion']['days'], + ]; + + } + + $roomRateMappingPolicy['cancellation_policy'][$propertyRoom['room_rate_mapping_id']] = []; + foreach ($propertyRoom['property_room_rate_channel_cancellation_policy'] as $propertyRoomRateCancellationPolicy) { + + $roomRateMappingPolicy['cancellation_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateCancellationPolicy['cancellation_policy_id']] = [ + 'is_affected_price' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_affected_price'], + 'affect_price_action_type' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_action_type'], + 'affect_price_type' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_type'], + 'affect_price_value' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_value'], + 'is_date_range' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_date_range'], + 'start_date' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['start_date'], + 'finish_date' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['finish_date'], + ]; + + } + + $roomRateMappingPolicy['adult_policy'][$propertyRoom['room_rate_mapping_id']] = []; + foreach ($propertyRoom['property_room_rate_channel_pricing_adult_policy'] as $propertyRoomRateAdultPolicy) { + + $roomRateMappingPolicy['adult_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateAdultPolicy['pricing_policy_adult_id']] = [ + 'adult_action_type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['adult_action_type'], + 'adult' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['adult'], + 'action_type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['action_type'], + 'type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['type'], + 'value' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['value'], + ]; + + } + + $roomRateMappingPolicy['child_policy'][$propertyRoom['room_rate_mapping_id']] = []; + foreach ($propertyRoom['property_room_rate_channel_pricing_child_policy'] as $propertyRoomRateChildPolicy) { + + $roomRateMappingPolicy['child_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateChildPolicy['pricing_policy_child_id']] = [ + 'adult' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['adult'], + 'child_order' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_order'], + 'child_age_start' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_age_start'], + 'child_age_end' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_age_end'], + 'type' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['type'], + 'value' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['value'], + ]; + + } + + } + //Property All Room Rate Price Policy + + $propertyMetaPolicyUpdate = [ + 'cancellation_policy' => json_encode($roomRateMappingPolicy['cancellation_policy']), + 'adult_policy' => json_encode($roomRateMappingPolicy['adult_policy']), + 'child_policy' => json_encode($roomRateMappingPolicy['child_policy']), + 'promotion' => json_encode($roomRateMappingPolicy['promotion']), + ]; + + PropertyMeta::where('id', $property['id'])->update($propertyMetaPolicyUpdate); + + $this->info(date('Y-m-d H:i:s') . ' : Property Policy Finished: ' . $property['property']['name']); + + + //$propertyMetaTemp + /*$propertyMetaTemp = PropertyMeta::where('property_id', $property['property_id'])->with('property')->get()->first(); + $propertyMetaTemp = $propertyMetaTemp->toArray(); + $propertyMetaPolicyUpdate = [ + 'cancellation_policy' => json_decode($propertyMetaTemp['cancellation_policy'], 1), + 'adult_policy' => json_decode($propertyMetaTemp['adult_policy'], 1), + 'child_policy' => json_decode($propertyMetaTemp['child_policy'], 1), + ];*/ + //$propertyMetaTemp + + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy Start: ' . $property['property']['name']); + + + //Property All Price Combination + /*$propertyRoomRateChannelMapping = PropertyRoomRateChannelMapping::with('propertyRoomRateMapping') + ->with('propertyRoomRateMapping.propertyRoom') + ->with('propertyRoomRateMapping.propertyRoomRate') + ->with('propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy') + ->with('propertyRoomRateChannelPricingAdultPolicy') + ->with('propertyRoomRateChannelPricingChildPolicy') + ->get() + ->where('property_id', $property['property_id'])->where('channel_id', 1) + ->where('status', 1); + + $propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping->where('propertyRoomRateMapping', '!=', null)->toArray();*/ + + $roomRateOccupancy = []; + foreach ($propertyRoomRateChannelMapping as $propertyRoom) { + + $roomId = $propertyRoom['property_room_rate_mapping']['room_id']; + $propertyRoomRateMappingId = $propertyRoom['property_room_rate_mapping']['id']; + $occupancyGroup = occupancyGroup( + $propertyRoom['property_room_rate_mapping']['property_room']['max_adult'], + $propertyRoom['property_room_rate_mapping']['property_room']['max_child'], + $propertyRoom['property_room_rate_mapping']['property_room']['max_occupancy'] + ); + + //TODO: Burası incelenebilir, cancellation policy yok ise gelmiyor çünkü.... + /*if(empty($propertyRoom['property_room_rate_channel_cancellation_policy'])) { + $propertyRoom['property_room_rate_channel_cancellation_policy'][] = [ + 'cancellation_policy_id' => 0, + 'property_cancellation_policy' => [ + 'name' => 'Refundable', + 'is_nonrefundable' => 0, + ] + ]; + }*/ + + foreach ($propertyRoom['property_room_rate_channel_cancellation_policy'] as $propertyRoomRateCancellationPolicy) { + + + foreach ($occupancyGroup as $occupancyCode) { + + $roomRateOccupancyKey = $roomId . '-' . $propertyRoomRateMappingId . '-' . $propertyRoomRateCancellationPolicy['cancellation_policy_id'] . '-' . $occupancyCode; + $roomRateOccupancyKey = md5($roomRateOccupancyKey); + + $cancellationPolicyName = []; + $cancellationPolicyName[] = $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_nonrefundable'] ? 'NonRefundable' : 'Refundable'; + $cancellationPolicyName[] = !empty($propertyRoomRateCancellationPolicy['property_cancellation_policy']['name']) ? '(' . $propertyRoomRateCancellationPolicy['property_cancellation_policy']['name'] . ')' : null; + $cancellationPolicyName = implode(' ', $cancellationPolicyName); + + $roomRateOccupancyTitle = []; + $roomRateOccupancyTitle[] = $propertyRoom['property_room_rate_mapping']['property_room']['name']; + $roomRateOccupancyTitle[] = $propertyRoom['property_room_rate_mapping']['property_room_rate']['name']; + $roomRateOccupancyTitle[] = $cancellationPolicyName; + $roomRateOccupancyTitle[] = $occupancyCode; + + $roomRateOccupancyTitle = implode(' - ', $roomRateOccupancyTitle); + + $roomRateOccupancy[$roomRateOccupancyKey] = [ + 'propertyId' => $property['property_id'], + 'roomId' => $roomId, + 'roomName' => $propertyRoom['property_room_rate_mapping']['property_room']['name'], + 'roomRateMappingId' => $propertyRoomRateMappingId, + 'roomRateMappingName' => $propertyRoom['property_room_rate_mapping']['property_room_rate']['name'], + 'cancellationPolicyId' => $propertyRoomRateCancellationPolicy['cancellation_policy_id'], + 'cancellationPolicyName' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['name'], + 'occupancyCode' => $occupancyCode, + 'includedOccupancy' => $propertyRoom['property_room_rate_mapping']['included_occupancy'], + 'title' => $roomRateOccupancyTitle + ]; + + } + + } + + } + //Property All Price Combination + + + $propertyMetaRoomRateParam = []; + foreach ($roomRateOccupancy as $roomRateOccupancyKey => $roomRate) { + + //$propertyMetaRoomRateCheck = PropertyMetaRoomRate::where('code', $roomRateOccupancyKey)->count(); + + $propertyMetaRoomRateParam[] = [ + 'code' => $roomRateOccupancyKey, + 'title' => $roomRate['title'], + 'property_id' => $roomRate['propertyId'], + 'room_id' => $roomRate['roomId'], + 'room_rate_mapping_id' => $roomRate['roomRateMappingId'], + 'cancellation_policy_id' => $roomRate['cancellationPolicyId'], + 'included_occupancy' => $roomRate['includedOccupancy'], + 'occupancy_code' => $roomRate['occupancyCode'], + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => Carbon::now()->unix(), + 'updated_at' => Carbon::now()->unix(), + ]; + + /*if ($propertyMetaRoomRateCheck) { + $propertyMetaRoomRateUpdate = PropertyMetaRoomRate::where('code', $roomRateOccupancyKey)->update($propertyMetaRoomRateParam); + } else { + $propertyMetaRoomRateCreate = PropertyMetaRoomRate::create($propertyMetaRoomRateParam); + }*/ + + //$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy: ' . $roomRate['title']); + + } + + //Delete all codes + if (!empty($propertyMetaRoomRateParam)) { + PropertyMetaRoomRate::where('property_id', $property['property_id'])->delete(); + PropertyMetaRoomRate::insert($propertyMetaRoomRateParam); + } + + $this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy Finished: ' . $property['property']['name']); + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/RemovePaymentTokenService.php b/app/Console/Commands/ChannelManager/RemovePaymentTokenService.php new file mode 100644 index 0000000..cbee425 --- /dev/null +++ b/app/Console/Commands/ChannelManager/RemovePaymentTokenService.php @@ -0,0 +1,116 @@ +mailer = $mailer; + $this->bookingPaymentService = $bookingPaymentService; + } + + public function handle() + { + + try { + + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $bookingPaymentDataCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 2], + ['field' => 'type', 'condition' => '=', 'value' => 'ch'], + ], + 'with' => ['bookingDetail.channelManager'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $bookingPaymentData = $this->bookingPaymentService->selectPaymentData($bookingPaymentDataCriteria); + $bookingPaymentData = $bookingPaymentData['status'] == 'success' && !empty($bookingPaymentData['data']) ? $bookingPaymentData['data'] : []; + + if (!empty($bookingPaymentData)) { + $bookingPaymentDataCollect = collect($bookingPaymentData); + $bookingPaymentData = $bookingPaymentDataCollect->where('booking_detail.checkout_date', '<', Carbon::now()->subDays(7))->toArray(); + } + + //$bookingPaymentData + foreach ($bookingPaymentData as $bookingPaymentKey => $bookingPayment) { + + if (empty($bookingPayment['booking_detail']['channel_manager_id'])) { + continue; + } + + $channelManagerId = $bookingPayment['booking_detail']['channel_manager_id']; + + switch ($channelManagerId) { + case 2 : + + $channelService = App::make("App\Core\Service\ChannelManager\\{$bookingPayment['booking_detail']['channel_manager']['name']}"); + + $removeCreditCardToken = $channelService->removeCreditCardToken($bookingPayment['data']); + + if (!$removeCreditCardToken['status']) { + + //Hata maili atılsın + $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $bookingPayment['booking_detail']['channel_manager']['name'] . ' Token: ' . $bookingPayment['data']); + + } else { + + $this->bookingPaymentService->updatePaymentData($bookingPayment['id'], ['status' => 1]); + + $this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $bookingPayment['booking_detail']['channel_manager']['name'] . ' Token: ' . $bookingPayment['data']); + + } + + break; + + default; + break; + + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/ReservationPullService.php b/app/Console/Commands/ChannelManager/ReservationPullService.php new file mode 100644 index 0000000..b12be61 --- /dev/null +++ b/app/Console/Commands/ChannelManager/ReservationPullService.php @@ -0,0 +1,957 @@ +mailer = $mailer; + $this->channelManagerMappingService = $channelManagerMappingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->bookingService = $bookingService; + $this->bookingContactService = $bookingContactService; + $this->bookingRoomService = $bookingRoomService; + $this->bookingPaymentService = $bookingPaymentService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->newBookingMailService = $newBookingMailService; + $this->channelManagerService = $channelManagerService; + $this->channelManagerBookingService = $channelManagerBookingService; + } + + public function getDateByDay($dates = []) + { + + $dateByDay = []; + + $diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut'])); + + for ($i = 0; $i < $diffInDays; $i++) { + $dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d'); + } + + return $dateByDay; + + } + + public function createBooking($channelCode, $param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}"); + + $bookingCode = getCodeGenerate('BKG'); + + $param['booking']['booking_code'] = $bookingCode; + $param['booking']['extra_param'] = json_encode($param['channel_manager']); + $bookingCreate = $this->bookingService->create($param['booking']); + //$bookingCreate['status'] = 'success';//TODO: Delete + //$bookingCreate['data']['id'] = 1106; + + if ($bookingCreate['status'] != 'success') { + throw new ApiErrorException('Booking could not be made, Reservation: ' . $param['booking']['search_key']); + } + + $param['booking']['id'] = $bookingCreate['data']['id']; + + //INSERT CONTACT DATA + $bookingContactCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'name' => $param['contact']['name'], + 'surname' => $param['contact']['surname'], + 'phone_code' => $param['contact']['phone_code'], + 'phone_number' => $param['contact']['phone_number'], + 'email' => $param['contact']['email'], + 'country_code' => fillOnUndefined($param['contact'], 'country_code'), + 'note' => !empty($param['contact']['note']) ? $param['contact']['note'] : null, + 'language_code' => fillOnUndefined($param['contact'], 'language', 'en'), + 'extra_param' => fillOnUndefined($param['contact'], 'extra_param'), + 'status' => 1 + ]; + + $bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam); + //$bookingContactCreate['status'] = 'success'; + + if ($bookingContactCreate['status'] != 'success') { + throw new ApiErrorException('Booking Contact could not be made'); + } + + //INSERT ROOM DATA + foreach ($param['room'] as $roomOrder => $room) { + + $bookingRoomCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'room_order_number' => ($roomOrder + 1), + 'occupancy_code' => $room['occupancy_code'], + 'checkin_date' => $room['checkin_date'], //$room['checkin'], + 'checkout_date' => $room['checkout_date'],//$room['checkout'], + 'rate_key' => fillOnUndefined($room, 'rate_key'), + 'rate_key_code' => fillOnUndefined($room, 'rate_key_code'), + 'availability_id' => 1, + 'availability_code' => 'ROM', + 'room_id' => $room['room_id'], + 'room_name' => $room['room_name'], + 'room_rate_mapping_id' => $room['room_rate_mapping_id'], + 'room_rate_name' => $room['room_rate_name'], + 'cancellation_policy' => fillOnUndefined($room, 'cancellation_policy'), + 'payment_type_code' => fillOnUndefined($room, 'payment_type_code', 'CHN'), + 'daily_amount' => fillOnUndefined($room, 'daily_amount'), + 'extra_param' => fillOnUndefined($room, 'extra_param'), + 'rate_detail' => fillOnUndefined($room, 'rate_detail'), + 'total' => $room['total'], + 'currency_code' => $room['currency_code'], + 'status' => fillOnUndefined($room, 'status', 1), + ]; + + $bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam); + //$bookingRoomCreate['status'] = 'success'; + + if ($bookingRoomCreate['status'] != 'success') { + throw new ApiErrorException('Booking Room could not be made'); + } + + + /* ROOM AVAILABILITY */ + $dateByDay = []; + $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]); + foreach ($dateByDay as $day) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') { + throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty'); + } + + foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) { + $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 0 : ($roomAvailability['availability'] - 1); + $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]); + } + + } + + /* ROOM AVAILABILITY */ + + } + + + //INSERT PAYMENT DATA + $bookingPaymentCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'payment_code' => fillOnUndefined($param['payment'], 'payment_code'), + 'payment_type_code' => fillOnUndefined($param['payment'], 'payment_type_code'),//Type: CHN + 'payment_source_code' => fillOnUndefined($param['payment'], 'payment_source_code'), + 'extra_param' => fillOnUndefined($param['payment'], 'extra_param'), + 'total' => fillOnUndefined($param['payment'], 'total'), + 'currency_code' => fillOnUndefined($param['payment'], 'currency_code'), + 'status' => fillOnUndefined($param['payment'], 'status'),//Type: 2 + ]; + + $bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam); + //$bookingPaymentCreate['status'] = 'success'; + + if ($bookingPaymentCreate['status'] != 'success') { + throw new ApiErrorException('Booking Payment could not be made'); + } + //INSERT PAYMENT DATA + + + //INSERT CHANNEL PAYMENT DATA + if (isset($param['payment_channel']) && !empty($param['payment_channel'])) { + + $bookingPaymentDataCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'type' => fillOnUndefined($param['payment_channel'], 'type'), + 'data' => fillOnUndefined($param['payment_channel'], 'data'), + 'status' => fillOnUndefined($param['payment_channel'], 'status', 1), + ]; + + $bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam); + + if ($bookingPaymentDataCreate['status'] != 'success') { + throw new ApiErrorException('Booking Channel Payment could not be made'); + } + } + //INSERT CHANNEL PAYMENT DATA + + $reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param); + $reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + + //PUSH CHANNEL MANAGER QUEUE + /* + 538 Euphoria Hotel Batumi + 541 Intourist Palace Hotel & SPA + 545 Metro Sky Tower Hotel + 546 Legend Hotel Batumi Convention Center & Spa + 548 Legend Business Hotel Batumi + 549 Euphoria Apartments + 550 City Hotel Batumi + */ + /*if (in_array($bookingCreate['data']['property_id'], [546])) { + + $channelManagerBookingParam = [ + 'property_id' => $bookingCreate['data']['property_id'], + 'booking_id' => $bookingCreate['data']['id'], + 'channel_manager_id' => $bookingCreate['data']['channel_manager_id'], + 'type' => 'Booking', + ]; + + $this->channelManagerBookingService->create($channelManagerBookingParam); + + }*/ + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingCreate['data']['property_id']], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + if(in_array($channelPropertyData['channel_manager_id'],[11,13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $bookingCreate['data']['property_id'], + 'booking_id' => $bookingCreate['data']['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => 'Booking', + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + //PUSH CHANNEL MANAGER QUEUE + + DB::commit(); + + $mailParams = ['booking_id' => $bookingCreate['data']['id']]; + $this->newBookingMailService->process($mailParams); + + $response['status'] = true; + $response['data'] = $param; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + DB::rollBack(); + } + + return $response; + + } + + public function modifiedBooking($channelCode, $param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}"); + + $bookingCode = null; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']], + ['field' => 'search_key', 'condition' => '=', 'value' => $param['booking']['search_key']], + //['field' => 'channel_manager_id', 'condition' => '=', 'value' => $param['booking']['channel_manager_id']], + ], + 'with' => ['bookingRoom', 'bookingContact', 'bookingChannel', 'bookingPayment'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['booking']['search_key'])); + } + + if (!empty($bookingDetail['data'])) { + + $bookingCode = $bookingDetail['data']['booking_code']; + + $param['booking']['id'] = $bookingDetail['data']['id']; + $param['booking']['booking_code'] = $bookingDetail['data']['booking_code']; + + $bookingUpdateParam = [ + 'channel_booking_code' => fillOnUndefined($param['booking'], 'channel_booking_code'), + 'search_key' => $param['booking']['search_key'], + 'checkin_date' => $param['booking']['checkin_date'], + 'checkout_date' => $param['booking']['checkout_date'], + 'payment_type_code' => $param['booking']['payment_type_code'], + 'total' => $param['booking']['total'], + 'currency_code' => $param['booking']['currency_code'], + ]; + + $bookingUpdate = $this->bookingService->update($bookingDetail['data']['id'], $bookingUpdateParam); + + $bookingContactUpdateParam = [ + 'name' => $param['contact']['name'], + 'surname' => $param['contact']['surname'], + 'phone_code' => $param['contact']['phone_code'], + 'phone_number' => $param['contact']['phone_number'], + 'email' => $param['contact']['email'], + 'country_code' => !empty($param['contact']['country_code']) ? $param['contact']['country_code'] : null, + 'note' => !empty($param['contact']['note']) ? $param['contact']['note'] : null, + 'language_code' => fillOnUndefined($param['contact'], 'language_code', 'en') + ]; + + $bookingContactUpdate = $this->bookingContactService->update($bookingDetail['data']['booking_contact']['id'], $bookingContactUpdateParam); + + foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) { + + foreach ($param['room'] as $roomOrderChannel => $roomChannel) { + + if ($roomOrder == $roomOrderChannel) { + + $bookingRoomUpdateParam = [ + 'occupancy_code' => $roomChannel['occupancy_code'], + 'checkin_date' => $roomChannel['checkin_date'], + 'checkout_date' => $roomChannel['checkout_date'], + 'room_id' => $roomChannel['room_id'], + 'room_name' => $roomChannel['room_name'], + 'room_rate_mapping_id' => $roomChannel['room_rate_mapping_id'], + 'room_rate_name' => $roomChannel['room_rate_name'], + 'rate_detail' => json_encode($roomChannel), + 'total' => $roomChannel['total'], + 'currency_code' => $roomChannel['currency_code'], + 'daily_amount' => fillOnUndefined($roomChannel, 'daily_amount'), + ]; + + $bookingRoomUpdate = $this->bookingRoomService->update($room['id'], $bookingRoomUpdateParam); + + /* ROOM AVAILABILITY */ + //Eğer odaya ait tarihler farklı ise buraya gelecek. + if (($room['checkin_date'] != $roomChannel['checkin_date']) || ($room['checkout_date'] != $roomChannel['checkout_date'])) { + + $dateByDay = []; + $dateByDay['update'] = []; + $dateByDay['current'] = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]); + $dateByDay['modified'] = $this->getDateByDay(['checkIn' => $roomChannel['checkin_date'], 'checkOut' => $roomChannel['checkout_date']]); + + foreach ($dateByDay['current'] as $date) { + $dateByDay['update'][$date] = !isset($dateByDay['update'][$date]) ? 0 : $dateByDay['update'][$date]; + $dateByDay['update'][$date]++; + } + + foreach ($dateByDay['modified'] as $date) { + $dateByDay['update'][$date] = !isset($dateByDay['update'][$date]) ? 0 : $dateByDay['update'][$date]; + $dateByDay['update'][$date]--; + } + + ksort($dateByDay['update']); + foreach ($dateByDay['update'] as $day => $availabilityModified) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') { + throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty'); + } + + foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) { + + $roomAvailabilityUpdated = 0; + $roomAvailabilityUpdated = $roomAvailability['availability'] + $availabilityModified; + if($roomAvailabilityUpdated < 0) { + $roomAvailabilityUpdated = 0; + } + + $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]); + } + + } + } + /* ROOM AVAILABILITY */ + + } + } + + } + + //Added New Room Case + if (count($bookingDetail['data']['booking_room']) != count($param['room']) && count($param['room']) > count($bookingDetail['data']['booking_room']) ) { + + foreach ($param['room'] as $roomOrderChannel => $roomChannel) { + + foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) { + + if ($roomOrder != $roomOrderChannel) { + + $bookingRoomCreateParam = [ + 'booking_id' => $bookingDetail['data']['id'], + 'room_order_number' => ($roomOrderChannel + 1), + 'occupancy_code' => $roomChannel['occupancy_code'], + 'checkin_date' => $roomChannel['checkin_date'], //$room['checkin'], + 'checkout_date' => $roomChannel['checkout_date'],//$room['checkout'], + 'rate_key' => fillOnUndefined($roomChannel, 'rate_key'), + 'rate_key_code' => fillOnUndefined($roomChannel, 'rate_key_code'), + 'availability_id' => 1, + 'availability_code' => 'ROM', + 'room_id' => $roomChannel['room_id'], + 'room_name' => $roomChannel['room_name'], + 'room_rate_mapping_id' => $roomChannel['room_rate_mapping_id'], + 'room_rate_name' => $roomChannel['room_rate_name'], + 'cancellation_policy' => fillOnUndefined($roomChannel, 'cancellation_policy'), + 'payment_type_code' => fillOnUndefined($roomChannel, 'payment_type_code', 'CHN'), + 'daily_amount' => fillOnUndefined($roomChannel, 'daily_amount'), + 'extra_param' => fillOnUndefined($roomChannel, 'extra_param'), + 'rate_detail' => fillOnUndefined($roomChannel, 'rate_detail'), + 'total' => $roomChannel['total'], + 'currency_code' => $roomChannel['currency_code'], + 'status' => fillOnUndefined($roomChannel, 'status', 1), + ]; + + $bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam); + + } + } + + } + } + + //UPDATE PAYMENT DATA + $bookingPaymentUpdateParam = [ + 'payment_type_code' => fillOnUndefined($param['payment'], 'payment_type_code'), + 'payment_source_code' => fillOnUndefined($param['payment'], 'payment_source_code'), + 'extra_param' => fillOnUndefined($param['payment'], 'extra_param'), + 'total' => fillOnUndefined($param['payment'], 'total'), + 'currency_code' => fillOnUndefined($param['payment'], 'currency_code') + ]; + + $bookingPaymentUpdate = $this->bookingPaymentService->update($bookingDetail['data']['booking_payment']['id'], $bookingPaymentUpdateParam); + //UPDATE PAYMENT DATA + + + //INSERT CHANNEL PAYMENT DATA + if (isset($param['payment_channel']) && !empty($param['payment_channel'])) { + + $bookingPaymentDataCreateParam = [ + 'booking_id' => $bookingDetail['data']['id'], + 'type' => fillOnUndefined($param['payment_channel'], 'type'), + 'data' => fillOnUndefined($param['payment_channel'], 'data'), + 'status' => fillOnUndefined($param['payment_channel'], 'status', 1), + ]; + + $bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam); + + if ($bookingPaymentDataCreate['status'] != 'success') { + throw new ApiErrorException('Booking Channel Payment could not be made'); + } + } + //INSERT CHANNEL PAYMENT DATA + + + } else { + return $this->createBooking($channelCode, $param); + } + + $bookingCode = is_null($bookingCode) ? 'ENW' . $param['booking']['search_key'] : $bookingCode; + + $reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param); + $reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + + $notificationModifiedToPropertyUser = [ + 'booking_id' => $param['booking']['id'], + ]; + + $this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($notificationModifiedToPropertyUser)); + + $response['status'] = true; + $response['data'] = $param; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + + //PUSH CHANNEL MANAGER QUEUE + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['data']['property_id']], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + if(in_array($channelPropertyData['channel_manager_id'],[11,13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $bookingDetail['data']['property_id'], + 'booking_id' => $bookingDetail['data']['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => 'Modify', + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + //PUSH CHANNEL MANAGER QUEUE + + DB::commit(); + + } else { + DB::rollBack(); + } + + return $response; + + } + + public function cancelBooking($channelCode, $param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}"); + + $bookingCode = null; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']], + ['field' => 'search_key', 'condition' => '=', 'value' => $param['booking']['search_key']], + //['field' => 'channel_manager_id', 'condition' => '=', 'value' => $param['booking']['channel_manager_id']], + ], + 'with' => ['bookingRoom', 'bookingContact', 'bookingChannel'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['booking']['search_key'])); + } + + if (!empty($bookingDetail['data'])) { + + $bookingCode = $bookingDetail['data']['booking_code']; + + $param['booking']['id'] = $bookingDetail['data']['id']; + $param['booking']['booking_code'] = $bookingDetail['data']['booking_code']; + + $this->bookingService->update($bookingDetail['data']['id'], ['status' => 0]); + + foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) { + + $bookingRoomUpdate = $this->bookingRoomService->update($room['id'], ['status' => 0]); + + /* ROOM AVAILABILITY */ + $dateByDay = []; + $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]); + foreach ($dateByDay as $day) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') { + throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty'); + } + + foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) { + $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 1 : ($roomAvailability['availability'] + 1); + $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]); + } + + } + + /* ROOM AVAILABILITY */ + + } + + } + + $bookingCode = is_null($bookingCode) ? 'ENW' . $param['booking']['search_key'] : $bookingCode; + + $reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param); + $reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + $notificationCancelToPropertyUser = [ + 'booking_id' => $param['booking']['id'], + ]; + + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser)); + + $response['status'] = true; + $response['data'] = $param; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + + //PUSH CHANNEL MANAGER QUEUE + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['data']['property_id']], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + if(in_array($channelPropertyData['channel_manager_id'],[11,13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $bookingDetail['data']['property_id'], + 'booking_id' => $bookingDetail['data']['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => 'Cancel', + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + //PUSH CHANNEL MANAGER QUEUE + + DB::commit(); + + } else { + DB::rollBack(); + } + + return $response; + + } + + public function handle() + { + + try { + + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $channelManagerCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManager = $this->channelManagerService->select($channelManagerCriteria); + + $channelManagerList = []; + if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) { + $channelManagerList = $channelManager['data']; + } + + + //CHANNEL MANAGER + foreach ($channelManagerList as $channelKey => $channel) { + + $this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']); + + if (!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) { + $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' Class does not exist!'); + continue; + } + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}"); + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping', 'property'], + 'orderBy' => [ + ['field' => 'property_id', 'value' => 'ASC'] + ] + ]; + + //TODO: Channex limited hotels + if ($channel['id'] == 2) { + $channexPullReservationPropertyIds = [71,313, /*538, 541, 545, 546, 548, 549, 550,*/ 672, 712, 785, 808, 790, 755, 901, 952, 912, 848, 1098, 1103, 1035]; + $channelManagerPropertyMappingCriteria['whereIn'][] = ["field" => "property_id", "value" => $channexPullReservationPropertyIds]; + } + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + //Eğer kanala ait bir otel yok ise devam et + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + continue; + } + + if ($channelManagerPropertyMapping['status'] == 'success') { + + //CHANNEL MANAGER PROPERTY + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + //Property + if (!in_array($propertyMapping['property']['id'],[623])) { + //continue; + } + + $this->info(date('Y-m-d H:i:s') . ' : Property: ' . $propertyMapping['property']['id'] . ' - ' . $propertyMapping['property']['name']); + + $reservationListParam = $channelService->reservationListParam($propertyMapping['channel_manager_property_id']); + $reservationList = $channelService->reservationList($reservationListParam); + + //Eğer kanaldaki otele ait bir rezervasyon yok ise devam et + if (!$reservationList['status']) { + continue; + } + + //CHANNEL MANAGER PROPERTY Reservation + foreach ($reservationList['data'] as $reservationKey => $reservation) { + + + $reservationPullFormatted = $channelService->reservationPullFormattedData($propertyMapping['property_id'], $propertyMapping['channel_manager_property_id'], $reservation); + + if (!$reservationPullFormatted['status']) { + //Burada bi hata var demektir, mail atılsın ama sonraki işleme devam edilsin. + + //$logMessage + $mailParams = [ + 'title' => $channel['name'] . ' - ReservationPullService Error - reservationPullFormatted', + 'logMessage' => '
' . print_r($reservationPullFormatted, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Property: ' . $propertyMapping['property']['id'] . ' - ' . $propertyMapping['property']['name'].' Error: reservationPullFormattedData'); + + continue; + } + + //TODO: Eğer burada gelen kanal extranetwork ise alınmış gibi yapılıp diğer işleme geçilmeli + if (in_array($reservationPullFormatted['data']['channel_manager']['sub_channel'], ['ExtranetWork'])) { + + $reservationConfirmParam = $channelService->reservationConfirmParam($reservationPullFormatted['data']['channel_manager']['property_id'], $reservationPullFormatted['data']['channel_manager']['booking_id'], 'ENW' . $reservationPullFormatted['data']['channel_manager']['booking_id'], $reservationPullFormatted['data']); + $reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + continue; + } + + + $reservationPull = ['status' => false, 'message' => '']; + + + if ($reservationPullFormatted['type'] == 'createBooking') { + $reservationPull = $this->createBooking($channel['name'], $reservationPullFormatted['data']); + } elseif ($reservationPullFormatted['type'] == 'modifiedBooking') { + + //If the modified reservation is not found, first create a reservation. + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $reservationPullFormatted['data']['booking']['property_id']], + ['field' => 'search_key', 'condition' => '=', 'value' => $reservationPullFormatted['data']['booking']['search_key']], + ], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if (empty($bookingDetail['data'])) { + $reservationPull = $this->createBooking($channel['name'], $reservationPullFormatted['data']); + } else { + $reservationPull = $this->modifiedBooking($channel['name'], $reservationPullFormatted['data']); + } + + + } elseif ($reservationPullFormatted['type'] == 'cancelBooking') { + $reservationPull = $this->cancelBooking($channel['name'], $reservationPullFormatted['data']); + } + + if ($reservationPull['status']) { + $this->info(date('Y-m-d H:i:s') . ' : Success ' . $reservationPullFormatted['type'] . ': ' . $reservationPull['data']['booking']['booking_code']); + } else { + + //$logMessage + $mailParams = [ + 'title' => $channel['name'] . ' - ReservationPullService Error - Booking', + 'logMessage' => '
' . print_r(array_merge($reservationPullFormatted, $reservationPull), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $reservationPull['message']); + } + + + } + + } + + + } + + $this->info(PHP_EOL); + } + + + //dd($channelManagerList); + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/ReservationPushService.php b/app/Console/Commands/ChannelManager/ReservationPushService.php new file mode 100644 index 0000000..967768f --- /dev/null +++ b/app/Console/Commands/ChannelManager/ReservationPushService.php @@ -0,0 +1,150 @@ +mailer = $mailer; + $this->channelService = $channelService; + $this->channelManagerBookingService = $channelManagerBookingService; + + } + + public function handle() + { + + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $pendingBookingCriteria = [ + 'criteria' => + [ + //['field' => 'id', 'condition' => '=', 'value' => 22461],#21390 + ['field' => 'is_pushed', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'channelManager', + 'bookingDetail.bookingContact', 'bookingDetail.bookingChannel', + 'bookingDetail.bookingPayment', 'bookingDetail.bookingPaymentType', + 'bookingDetail.bookingStatus', 'bookingDetail.bookingRoom.roomPax.paxCountry' + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'take' => 100 + ]; + + $pendingBooking = $this->channelManagerBookingService->select($pendingBookingCriteria); + + + if ($pendingBooking['status'] == 'success') { + + $pendingBooking = $pendingBooking['data']; + + foreach ($pendingBooking as $booking) { + + try { + + $this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id']); + + $channelService = App::make("App\Core\Service\ChannelManager\\{$booking['channel_manager']['name']}"); + + $this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $booking['channel_manager']['name']); + + if ($booking['channel_manager_id'] == 10) { + //After 3 minutes, the faulty operation is set to status 2 for Hyperguest. + if (Carbon::createFromTimestamp($booking['created_at'])->diffInMinutes(Carbon::now()) > 3) { + $this->channelManagerBookingService->update($booking['id'], ['status' => 2]); + $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $booking['channel_manager']['name']); + continue; + } + } + + //After 30 minutes, the faulty operation is set to status 2. + if (Carbon::createFromTimestamp($booking['created_at'])->diffInMinutes(Carbon::now()) > 30) { + $this->channelManagerBookingService->update($booking['id'], ['status' => 2]); + } + + $requestPostReservationPushParam = $channelService->requestPostReservationPushParam($booking['property_id'], $booking['booking_id'], $booking['type'], $booking); + + if (empty($requestPostReservationPushParam)) { + throw new ApiErrorException('requestPostReservationPushParam Error'); + } + + $this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Push'); + + $this->channelManagerBookingService->update($booking['id'], ['request' => $requestPostReservationPushParam]); + + $requestPostReservationPush = $channelService->requestPostReservationPush($requestPostReservationPushParam); + + if ($requestPostReservationPush['status']) { + + $this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Success'); + $this->channelManagerBookingService->update($booking['id'], ['is_pushed' => 1, 'status' => 1, 'response' => $requestPostReservationPush['response']]); + + } else { + + //$logMessage + $mailParams = [ + 'title' => 'ReservationPushService Error - ChannelManagerName: ' . $booking['channel_manager']['name'], + 'logMessage' => '
' . print_r(array_merge($booking, $requestPostReservationPush), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Failed'); + + $this->channelManagerBookingService->update($booking['id'], ['response' => $requestPostReservationPush['message']]); + } + + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } + +} diff --git a/app/Console/Commands/ChannelManager/RoomAvailabilityPushService.php b/app/Console/Commands/ChannelManager/RoomAvailabilityPushService.php new file mode 100644 index 0000000..749a34c --- /dev/null +++ b/app/Console/Commands/ChannelManager/RoomAvailabilityPushService.php @@ -0,0 +1,262 @@ +mailer = $mailer; + $this->channelManagerService = $channelManagerService; + $this->propertyRoomAvailabilityQueueService = $propertyRoomAvailabilityQueueService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + } + + public function handle() + { + + try { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + //Queue Check + $this->info(date('Y-m-d H:i:s') . ' : Queue Check'); + $roomAvailabilityQueueCountCriteria = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]], 'count' => true]; + $roomAvailabilityQueueCount = $this->propertyRoomAvailabilityQueueService->select($roomAvailabilityQueueCountCriteria); + if ($roomAvailabilityQueueCount['status'] == 'success') { + $roomAvailabilityQueueCount = $roomAvailabilityQueueCount['data']; + + if ($roomAvailabilityQueueCount > 2000) { + + + $roomAvailabilityQueueCountGroupByProperty = PropertyRoomAvailabilityQueue::selectRaw('property_id, COUNT(*) as total') + ->groupBy('property_id') + ->orderByDesc('total') + ->first(); + + $roomAvailabilityQueueCountGroupByProperty = $roomAvailabilityQueueCountGroupByProperty ? $roomAvailabilityQueueCountGroupByProperty->toArray() : null; + if ($roomAvailabilityQueueCountGroupByProperty) { + if ($roomAvailabilityQueueCountGroupByProperty['total'] > 1000) { + PropertyRoomAvailabilityQueue::where('property_id', $roomAvailabilityQueueCountGroupByProperty['property_id'])->delete(); + } + } + + } + + if ($roomAvailabilityQueueCount > 1000) { + + $this->error(date('Y-m-d H:i:s') . ' : Queue Alarm: ' . $roomAvailabilityQueueCount); + + //Clear Test Property Data + PropertyRoomAvailabilityQueue::where('property_id', 1)->delete(); + + //$logMessage + $mailParams = [ + 'title' => 'RoomAvailabilityPushService Error - Queue Error', + 'logMessage' => 'Queue: ' . $roomAvailabilityQueueCount + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + } + } + //Queue Check + + + $channelManagerCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + /*'whereIn' => + [ + ['field' => 'id', "value" => [7]] + ],*/ + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManager = $this->channelManagerService->select($channelManagerCriteria); + + $channelManagerList = []; + if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) { + $channelManagerList = $channelManager['data']; + } + + + $roomAvailabilityQueueCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['property'/*, 'propertyChannelManager.channelManagerRoomRate.propertyRoomRateMapping'*/], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'take' => 500 + ]; + + $roomAvailabilityQueue = $this->propertyRoomAvailabilityQueueService->select($roomAvailabilityQueueCriteria); + + if ($roomAvailabilityQueue['status'] == 'success' && !empty($roomAvailabilityQueue['data'])) { + + + foreach ($roomAvailabilityQueue['data'] as $data) { + $roomAvailabilityQueueData[$data['property_id']][] = $data; + } + + + $channelManagerPushedIdsList = []; + $channelManagerNoneMappingIdsList = []; + + //PROPERTY + foreach ($roomAvailabilityQueueData as $roomAvailabilityQueuePropertyId => $roomAvailabilityQueueProperty) { + + + //CHANNEL MANAGER + $channelManagerCheckList = []; + foreach ($channelManagerList as $channelKey => $channel) { + + if (in_array($channel['id'], [7, 10, 13])) { + continue; + } + + $this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']); + + if (!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) { + $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' Class does not exist!'); + continue; + } + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}"); + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $roomAvailabilityQueuePropertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'firstRow' => true, + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + + if ($channelManagerPropertyMapping['status'] != 'success' || ($channelManagerPropertyMapping['status'] == 'success' && empty($channelManagerPropertyMapping['data']))) { + $this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' PropertyID: ' . $roomAvailabilityQueuePropertyId . ' : PASS'); + continue; + } + + $channelManagerCheckList[$channel['id']] = true; + + $roomAvailabilityPush = $channelService->roomAvailabilityPush($roomAvailabilityQueuePropertyId, $roomAvailabilityQueueProperty); + + if ($roomAvailabilityPush['status']) { + + $channelManagerPushedIdsList[$channel['id']] = $roomAvailabilityPush['data']['channelManagerPushedIds']; + $channelManagerNoneMappingIdsList[$channel['id']] = $roomAvailabilityPush['data']['channelManagerNoneMappingIds']; + + $this->info(date('Y-m-d H:i:s') . ' : Success: ' . $channel['name']); + + } else { + + $channelManagerCheckList[$channel['id']] = false; + + //$logMessage + $mailParams = [ + 'title' => $channel['name'] . ' - RoomAvailabilityPushService Error - inventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($roomAvailabilityPush, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $channel['name'] . ' - ' . $roomAvailabilityPush['message']); + + + } + + $this->info(date('Y-m-d H:i:s') . ' : Channel Finished: ' . $channel['name']); + + } + + if (in_array(false, $channelManagerCheckList)) { + $this->error(date('Y-m-d H:i:s') . ' : Error Break: ' . var_export($channelManagerCheckList)); + continue; + } + + if (count($channelManagerPushedIdsList) > 1) { + $channelManagerPushedIdIntersect = call_user_func_array('array_intersect', $channelManagerPushedIdsList); + if (!empty($channelManagerPushedIdIntersect)) { + $this->propertyRoomAvailabilityQueueService->delete($channelManagerPushedIdIntersect); + $this->info(date('Y-m-d H:i:s') . ' : channelManagerPushedIdsList Deleted: ' . var_dump($channelManagerPushedIdIntersect)); + } + } elseif (!empty($channelManagerPushedIdsList)) { + $this->propertyRoomAvailabilityQueueService->delete(reset($channelManagerPushedIdsList)); + $this->info(date('Y-m-d H:i:s') . ' : channelManagerPushedIdsList Deleted: ' . var_dump($channelManagerPushedIdsList)); + } + + if (empty($channelManagerNoneMappingIdsList)) { + $this->info(date('Y-m-d H:i:s') . ' : channelManagerNoneMappingIdsList Empty'); + continue; + } + + $channelManagerNoneMappingIdsListMerge = call_user_func_array('array_merge', $channelManagerNoneMappingIdsList); + if (!empty($channelManagerNoneMappingIdsListMerge)) { + $this->propertyRoomAvailabilityQueueService->delete($channelManagerNoneMappingIdsListMerge); + $this->info(date('Y-m-d H:i:s') . ' : channelManagerNoneMappingIdsListMerge Deleted: ' . var_dump($channelManagerNoneMappingIdsListMerge)); + } + + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/RoomRatePushService.php b/app/Console/Commands/ChannelManager/RoomRatePushService.php new file mode 100644 index 0000000..a48b1cd --- /dev/null +++ b/app/Console/Commands/ChannelManager/RoomRatePushService.php @@ -0,0 +1,255 @@ +mailer = $mailer; + $this->propertyRoomRatePriceQueueService = $propertyRoomRatePriceQueueService; + $this->channelManagerService = $channelManagerService; + $this->propertyRoomAvailabilityQueueService = $propertyRoomAvailabilityQueueService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + } + + public function handle() + { + //$request = $this->channelService->productList(14480); + + try { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + //Queue Check + $this->info(date('Y-m-d H:i:s') . ' : Queue Check'); + $roomRatePriceQueueCountCriteria = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]],'count' => true]; + $roomRatePriceQueueCount = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCountCriteria); + if($roomRatePriceQueueCount['status'] == 'success') { + $roomRatePriceQueueCount = $roomRatePriceQueueCount['data']; + + if($roomRatePriceQueueCount > 1000) { + + $this->error(date('Y-m-d H:i:s') . ' : Queue Alarm: '. $roomRatePriceQueueCount); + + //Clear Test Property Data + PropertyRoomRatePriceQueue::where('property_id',1)->delete(); + + //$logMessage + $mailParams = [ + 'title' => 'RoomRatePushService Error - Queue Error', + 'logMessage' => 'Queue: '.$roomRatePriceQueueCount + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + } + } + //Queue Check + + $channelManagerCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + /*'whereIn' => + [ + ['field' => 'id', "value" => [7]] + ],*/ + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManager = $this->channelManagerService->select($channelManagerCriteria); + + $channelManagerList = []; + if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) { + $channelManagerList = $channelManager['data']; + } + + $roomRatePriceQueueCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['property'/*, 'propertyChannelManager.channelManagerRoomRate'*/], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'take' => 500 + ]; + + $roomRatePriceQueue = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCriteria); + + if ($roomRatePriceQueue['status'] == 'success' && !empty($roomRatePriceQueue['data'])) { + + + foreach ($roomRatePriceQueue['data'] as $data) { + $roomRatePriceQueueData[$data['property_id']][] = $data; + } + + $channelManagerPushedIdsList = []; + $channelManagerNoneMappingIdsList = []; + + //PROPERTY + foreach ($roomRatePriceQueueData as $roomRatePriceQueuePropertyId => $roomRatePriceQueueProperty) { + + + //CHANNEL MANAGER + $channelManagerCheckList = []; + foreach ($channelManagerList as $channelKey => $channel) { + + if(in_array($channel['id'],[7,10, 13])) { + continue; + } + + $this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']); + + if(!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) { + $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'].' Class does not exist!'); + continue; + } + + $channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}"); + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $roomRatePriceQueuePropertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'firstRow' => true, + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + + if ($channelManagerPropertyMapping['status'] != 'success' || ($channelManagerPropertyMapping['status'] == 'success' && empty($channelManagerPropertyMapping['data']))) { + $this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' PropertyID: ' . $roomRatePriceQueuePropertyId . ' : PASS'); + continue; + } + + $channelManagerCheckList[$channel['id']] = true; + + + $roomRatePricePush = $channelService->roomRatePricePush($roomRatePriceQueuePropertyId, $roomRatePriceQueueProperty); + + + if ($roomRatePricePush['status']) { + + if (!empty($roomRatePricePush['data']['channelManagerPushedIds']) || !empty($roomRatePricePush['data']['channelManagerNoneMappingIds'])) { + $channelManagerPushedIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerPushedIds']; + $channelManagerNoneMappingIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerNoneMappingIds']; + } + + $this->info(date('Y-m-d H:i:s') . ' : Channel Success: ' . $channel['name']); + + } else { + + $channelManagerCheckList[$channel['id']] = false; + + //$logMessage + $mailParams = [ + 'title' => $channel['name'] . ' - RoomRatePushService Error - InventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($roomRatePricePush, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $channel['name'] . ' - ' . $roomRatePricePush['message']); + + + } + + $this->info(date('Y-m-d H:i:s') . ' : Channel Finished: ' . $channel['name']); + + } + + /*foreach ($channelManagerPushedIdsList as $key => $channelManagerPushedIds) { + if(empty($channelManagerPushedIds)) { + unset($channelManagerPushedIdsList[$key]); + } + }*/ + + if (in_array(false, $channelManagerCheckList)) { + $this->error(date('Y-m-d H:i:s') . ' : Error Break: ' . var_export($channelManagerCheckList)); + continue; + } + + if (count($channelManagerPushedIdsList) > 1) { + $channelManagerPushedIdIntersect = call_user_func_array('array_intersect', $channelManagerPushedIdsList); + if (!empty($channelManagerPushedIdIntersect)) { + $this->propertyRoomRatePriceQueueService->delete($channelManagerPushedIdIntersect); + $this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdIntersect)); + } + } elseif (!empty($channelManagerPushedIdsList)) { + $this->propertyRoomRatePriceQueueService->delete(reset($channelManagerPushedIdsList)); + $this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdsList)); + } + + if (!empty($channelManagerNoneMappingIdsList)) { + $channelManagerNoneMappingIdsListMerge = call_user_func_array('array_merge', $channelManagerNoneMappingIdsList); + if (!empty($channelManagerNoneMappingIdsListMerge)) { + $this->propertyRoomRatePriceQueueService->delete($channelManagerNoneMappingIdsListMerge); + $this->info(date('Y-m-d H:i:s') . ' : $channelManagerNoneMappingIdsListMerge Deleted: ' . var_dump($channelManagerNoneMappingIdsListMerge)); + } + } + + + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/_ReselivaAvailRateUpdateService.php b/app/Console/Commands/ChannelManager/_ReselivaAvailRateUpdateService.php new file mode 100644 index 0000000..95b93f0 --- /dev/null +++ b/app/Console/Commands/ChannelManager/_ReselivaAvailRateUpdateService.php @@ -0,0 +1,497 @@ +mailer = $mailer; + $this->propertyRoomService = $propertyRoomService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->channelManagerLogService = $channelManagerLogService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + } + + public function propertyChannelMapping($propertyId, $channelId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId, $channelId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId, $channelId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channelId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $channelId = 1; + $channelManagerId = 1; + + $channelManagerLogCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => 32670], + ['field' => 'service', 'condition' => '=', 'value' => 'AvailRateUpdate'], + ['field' => 'status', 'condition' => '=', 'value' => null], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerLog = $this->channelManagerLogService->select($channelManagerLogCriteria); + + if ($channelManagerLog['status'] && !empty($channelManagerLog['data'])) { + + foreach ($channelManagerLog['data'] as $logData) { + + $response = ['status' => false, 'message' => '']; + + $payloadXML = simplexml_load_string($logData['request']); + $payloadParam = json_decode(json_encode($payloadXML), 1); + + try { + + $propertyId = $payloadParam['Hotel']['@attributes']['id']; + + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId, $channelId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId, $channelId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId, $channelId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $availRateUpdates = singleElementXMLArray($payloadParam['AvailRateUpdate']); + + DB::beginTransaction(); + + foreach ($availRateUpdates as $availRateUpdate) { + + $dateRange = []; + $dateRange['startDate'] = $availRateUpdate['DateRange']['@attributes']['from']; + $dateRange['finishDate'] = $availRateUpdate['DateRange']['@attributes']['to']; + + if (Carbon::parse($dateRange['startDate'])->isBefore(Carbon::now()->toDateString()) || Carbon::parse($dateRange['finishDate'])->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + $roomTypes = singleElementXMLArray($availRateUpdate['RoomType']); + + $this->info(date('Y-m-d H:i:s') . ' : ' . $dateRange['startDate'] . ' - ' . $dateRange['finishDate']); + + foreach ($roomTypes as $roomType) { + + $roomId = $roomType['@attributes']['id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Tanımlı ya da aktif olmayan oda'); + } + + + $totalInventoryAvailable = null; + if (isset($roomType['Inventory']['@attributes']['totalInventoryAvailable'])) { + $totalInventoryAvailable = $roomType['Inventory']['@attributes']['totalInventoryAvailable']; + } + + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $dateRange['startDate'], + 'end_date' => $dateRange['finishDate'], + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']); + } + + + if (isset($roomType['RatePlan'])) { + + $ratePlans = singleElementXMLArray($roomType['RatePlan']); + + foreach ($ratePlans as $ratePlan) { + + $roomRateMappingId = $ratePlan['@attributes']['id']; + + $isCloseRoomRateMappingSale = null; + if (isset($ratePlan['@attributes']['closed'])) { + $isCloseRoomRateMappingSale = $ratePlan['@attributes']['closed'] == 'true' ? true : false; + } + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + throw new ApiErrorException('Tanımlı ya da aktif olmayan oda konaklama'); + } + + + $roomRates = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + + $paramsListChannel = []; + $paramsListChannel[] = 1; + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + + foreach ($paramsListChannel as $paramChannelId) { + + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($ratePlan['Rate'])) { + + $currency = $ratePlan['Rate']['@attributes']['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Kanal döviz kuru ile eşleşmeyen döviz kuru, kanal döviz kuru: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + $amountPerDay = $ratePlan['Rate']['PerDay']['@attributes']['rate']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $amountPerDay; + $requestParams['room_rates'] = [$roomRates]; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $this->info(date('Y-m-d H:i:s') . + ' : Update Type: ' .$requestParams['update_type']. + ' : Channel ID: '. $requestParams['channel_id']. + ' : Room ID: '. $roomRates['room_id'] + ); + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = [$roomRates]; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']); + } + + + //Kısıtlamalar var ise min los + if (isset($ratePlan['Restrictions'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($ratePlan['Restrictions']['@attributes']['minLOS'])) { + + $minStay = $ratePlan['Restrictions']['@attributes']['minLOS']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $minStay; + $requestParams['room_rates'] = [$roomRates]; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']); + + } + + } + + } + + + } + + } + + + } + + } + + $response['status'] = true; + + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + + + $channelManagerLog = $this->channelManagerLogService->update($logData['id'], $updateDataLog); + + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + //TODO: mail + if (!$response['status']) { + DB::rollBack(); + } + + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + + } +} diff --git a/app/Console/Commands/ChannelManager/_ReservationPullService.php b/app/Console/Commands/ChannelManager/_ReservationPullService.php new file mode 100644 index 0000000..099b6f5 --- /dev/null +++ b/app/Console/Commands/ChannelManager/_ReservationPullService.php @@ -0,0 +1,784 @@ +mailer = $mailer; + $this->channelService = $channelService; + $this->channelManagerMappingService = $channelManagerMappingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->bookingService = $bookingService; + $this->bookingContactService = $bookingContactService; + $this->bookingRoomService = $bookingRoomService; + $this->bookingPaymentService = $bookingPaymentService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->newBookingMailService = $newBookingMailService; + } + + public function reservationListParam($channelManagerPropertyId) + { + + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $channelManagerPropertyId); + + return $requestParam->asXML(); + } + + public function reservationConfirmParam($propertyId, $channelManagerBookingId, $bookingCode) + { + + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $propertyId); + + $reservations = $requestParam->addChild('reservations'); + $reservation = $reservations->addChild('reservation'); + $reservation->addAttribute('reseliva_id', $channelManagerBookingId); + $reservation->addAttribute('pms_id', $bookingCode); + + return $requestParam->asXML(); + } + + public function getDateByDay($dates = []) + { + + $dateByDay = []; + + $diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut'])); + + for ($i = 0; $i < $diffInDays; $i++) { + $dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d'); + } + + return $dateByDay; + + } + + public function createBooking($param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + $bookingCode = getCodeGenerate('BKG'); + $bookingStatus = 1; + + $roomRequest = []; + foreach ($param['room'] as $room) { + $roomRequest[] = [ + 'adults' => $room['totalpax'], + 'children' => $room['totalchd'], + 'age' => [] + ]; + } + + if (empty(fillOnUndefined($param, 'reservno_ota'))) { + $param['reservno_ota'] = null; + } + + + $bookingCreateParam = [ + 'property_id' => $param['property']['id'], + 'channel_id' => $param['property']['channel_id'], + 'booking_code' => $bookingCode, + 'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'), + 'search_key' => $param['reservno'], + 'checkin_date' => $param['checkinFormatted'], + 'checkout_date' => $param['checkoutFormatted'], + 'rooms' => json_encode($roomRequest), + 'payment_type_code' => 'CHN', + 'room_amount' => $param['paymenttotal'], + 'addon_amount' => 0, + 'discount_amount' => 0, + 'total' => $param['paymenttotal'], + 'currency_code' => $param['paymentcurr'], + 'channel_token' => null, + 'booking_engine_token' => null, + 'reservation_time' => $param['restimeUnixFormatted'], + 'status' => $param['status'] == 'A' ? 1 : 0 + ]; + + $bookingCreate = $this->bookingService->create($bookingCreateParam); + //$bookingCreate['status'] = 'success'; + //$bookingCreate['data']['id'] = 52; + + if ($bookingCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be made, Reservation: ' . $param['reservno'])); + } + + //INSERT CONTACT DATA + $bookingContactCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'name' => $param['firstname'], + 'surname' => !empty($param['lastname']) ? $param['lastname'] : null, + 'phone_code' => null, + 'phone_number' => $param['tel'], + 'email' => $param['email'], + 'note' => !empty($param['note']) ? $param['note'] : null, + 'language_code' => fillOnUndefined($param, 'language', 'en'), + 'status' => 1 + ]; + + $bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam); + //$bookingContactCreate['status'] = 'success'; + + if ($bookingContactCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Contact could not be made')); + } + + //INSERT ROOM DATA + foreach ($param['room'] as $roomOrder => $room) { + + $bookingRoomCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'room_order_number' => ($roomOrder + 1), + 'occupancy_code' => str_repeat('A', $room['totalpax']) . str_repeat('C', $room['totalchd']), + 'checkin_date' => $param['checkinFormatted'], //$room['checkin'], + 'checkout_date' => $param['checkoutFormatted'],//$room['checkout'], + 'rate_key' => null, + 'rate_key_code' => null, + 'availability_id' => 1, + 'availability_code' => 'ROM', + 'room_id' => $room['property']['room_id'], + 'room_name' => $room['roomtype'], + 'room_rate_mapping_id' => $room['property']['room_rate_mapping_id'], + 'room_rate_name' => $room['ratename'], + 'cancellation_policy' => null, + 'payment_type_code' => 'CHN', + 'rate_detail' => json_encode($room), + 'total' => $room['total_amount'], + 'currency_code' => $param['paymentcurr'], + 'status' => $param['status'] == 'A' ? 1 : 0 + ]; + + $bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam); + //$bookingRoomCreate['status'] = 'success'; + + if ($bookingRoomCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Room could not be made')); + } + + + /* ROOM AVAILABILITY */ + $dateByDay = []; + $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin'], 'checkOut' => $room['checkout']]); + foreach ($dateByDay as $day) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['property']['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') { + throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty'); + } + + foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) { + $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 0 : ($roomAvailability['availability'] - 1); + $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]); + } + + } + + /* ROOM AVAILABILITY */ + + } + + //INSERT PAYMENT DATA + $bookingPaymentCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'payment_code' => (isset($param['cc_token']) && !empty($param['cc_token'])) ? fillOnUndefined($param, 'cc_token') : null, + 'payment_type_code' => 'CHN', + 'total' => $param['paymenttotal'], + 'currency_code' => $param['paymentcurr'], + 'status' => 2 + ]; + + $bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam); + //$bookingContactCreate['status'] = 'success'; + + if ($bookingPaymentCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Payment could not be made')); + } + //INSERT PAYMENT DATA + + //INSERT CHANNEL PAYMENT DATA + if (isset($param['cc_token']) && !empty($param['cc_token'])) { + + $bookingPaymentDataCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'type' => 'ch', + 'data' => md5($param['reservno'].$param['channelManagerPropertyId'].$param['cc_token']) + ]; + + $bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam); + + if ($bookingPaymentDataCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Payment could not be made')); + } + } + //INSERT CHANNEL PAYMENT DATA + + + //$param['reservno'] = '27145472222'; + $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode); + $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + DB::commit(); + + $mailParams = ['booking_id' => $bookingCreate['data']['id']]; + $this->newBookingMailService->process($mailParams); + + $response['status'] = true; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + DB::rollBack(); + } + + return $response; + + } + + public function cancelBooking($param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + $bookingCode = null; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']], + ['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']] + ], + 'with' => ['bookingRoom'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno'])); + } + + if (!empty($bookingDetail['data'])) { + + $bookingCode = $bookingDetail['data']['booking_code']; + + $this->bookingService->update($bookingDetail['data']['id'], ['status' => 0]); + + foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) { + + $bookingRoomCreate = $this->bookingRoomService->update($room['id'], ['status' => 0]); + + + /* ROOM AVAILABILITY */ + $dateByDay = []; + $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]); + foreach ($dateByDay as $day) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') { + throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty'); + } + + foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) { + $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 1 : ($roomAvailability['availability'] + 1); + $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]); + } + + } + + /* ROOM AVAILABILITY */ + + } + + } + + $response['status'] = true; + + $bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode; + + $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode); + $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + $notificationCancelToPropertyUser = [ + 'channel' => $param['otaname'], + 'channelBookingCode' => $param['reservno_ota'], + 'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'], + 'nameSurname' => $param['firstname'] . ' ' . $param['lastname'], + 'propertyId' => $param['property']['id'], + ]; + + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser)); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + + DB::commit(); + + } else { + DB::rollBack(); + } + + return $response; + + } + + public function modifiedBooking($param) + { + + $response = ['status' => false, 'message' => '']; + + DB::beginTransaction(); + + try { + + $bookingCode = null; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']], + ['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']] + ], + 'with' => ['bookingRoom', 'bookingContact'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno'])); + } + + if (!empty($bookingDetail['data'])) { + + $bookingCode = $bookingDetail['data']['booking_code']; + + $bookingUpdateParam = [ + 'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'), + 'search_key' => $param['reservno'], + 'checkin_date' => $param['checkinFormatted'], + 'checkout_date' => $param['checkoutFormatted'], + 'payment_type_code' => 'CHN', + 'total' => $param['paymenttotal'], + 'currency_code' => $param['paymentcurr'], + ]; + + $bookingUpdate = $this->bookingService->update($bookingDetail['data']['id'], $bookingUpdateParam); + + $bookingContactUpdateParam = [ + 'name' => $param['firstname'], + 'surname' => $param['lastname'], + 'phone_code' => null, + 'phone_number' => $param['tel'], + 'email' => $param['email'], + 'note' => !empty($param['note']) ? $param['note'] : null, + 'language_code' => fillOnUndefined($param, 'language', 'en') + ]; + + $bookingContactUpdate = $this->bookingContactService->update($bookingDetail['data']['booking_contact']['id'], $bookingContactUpdateParam); + + foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) { + + foreach ($param['room'] as $roomOrderChannel => $roomChannel) { + + if ($roomOrder == $roomOrderChannel) { + + + $bookingRoomUpdateParam = [ + 'occupancy_code' => str_repeat('A', $roomChannel['totalpax']) . str_repeat('C', $roomChannel['totalchd']), + 'checkin_date' => $roomChannel['checkin'], + 'checkout_date' => $roomChannel['checkout'], + 'room_id' => $roomChannel['property']['room_id'], + 'room_name' => $roomChannel['roomtype'], + 'room_rate_mapping_id' => $roomChannel['property']['room_rate_mapping_id'], + 'room_rate_name' => $roomChannel['ratename'], + 'rate_detail' => json_encode($roomChannel), + 'total' => $roomChannel['total_amount'], + 'currency_code' => $param['paymentcurr'], + ]; + + $bookingRoomUpdate = $this->bookingRoomService->update($room['id'], $bookingRoomUpdateParam); + + } + } + + } + + } + + $response['status'] = true; + + $bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode; + + $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode); + $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + $notificationModifiedToPropertyUser = [ + 'channel' => $param['otaname'], + 'channelBookingCode' => $param['reservno_ota'], + 'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'], + 'nameSurname' => $param['firstname'] . ' ' . $param['lastname'], + 'propertyId' => $param['property']['id'], + ]; + + $this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($notificationModifiedToPropertyUser)); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + + DB::commit(); + + } else { + DB::rollBack(); + } + + return $response; + + } + + public function handle() + { + //$request = $this->channelService->productList(14480); + + try { + + /* + 1. Reseliva mapping olan oteller çekilecek + 2. Her otel için foreach ile reservaion servisi çağrılacak + 3. Gelen bilgiler enw ye işlenecek, sonra da confirmcheck yapılacak + * */ + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $channelManagerMappingCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyChannelManager'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerMappingData = $this->channelManagerMappingService->select($channelManagerMappingCriteria); + $channelManagerMappingCollect = collect($channelManagerMappingData['data']); + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + //['field' => 'property_id', 'condition' => '=', 'value' => 326],//TODO: Delete + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success') { + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + $channelManagerRoomRateCollect = collect($propertyMapping['channel_manager_room_rate']); + + $reservationListParam = $this->reservationListParam($propertyMapping['channel_manager_property_id']); + $reservationList = $this->channelService->reservationList($reservationListParam); + + if (!$reservationList['status']) { + + //$logMessage + $mailParams = [ + 'title' => 'ReservationPullService Error - ReservationList Error', + 'logMessage' => '
' . $reservationListParam . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException('ReservationList Error: ' . $reservationList['message']); + } + + foreach ($reservationList['data'] as $reservationKey => $reservation) { + + //Check Channel Manager Mapping + $channelManagerMapping = $channelManagerMappingCollect->where('channel_manager_channel_id', $reservation['otaname'])->first(); + + //Eğer ExtranetWork ise içeri almadan onayla + if ($reservation['otaname'] == 'ExtranetWork') { + + $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']); + //$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + $reservationConfirm['status'] = true; + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + continue; + } + + if (empty($channelManagerMapping)) { + //Eğer mapping yapılmış kanal bulunamamış ise rezervasyonu içeri alamazsın + //$logMessage + $mailParams = [ + 'title' => 'ReservationPullService Error - Channel Manager Mapping', + 'logMessage' => '
' . print_r(array_merge($propertyMapping, $reservation), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + unset($reservationList['data'][$reservationKey]); + continue; + } + + $reservationList['data'][$reservationKey]['property']['id'] = $propertyMapping['property_id']; + $reservationList['data'][$reservationKey]['property']['channel_id'] = $channelManagerMapping['property_channel_id']; + + foreach ($reservation['room'] as $roomKey => $room) { + + //Check Room Rate Mapping + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->where('channel_manager_room_rate_id', $room['rateid'])->first(); + if (empty($channelManagerRoomRate)) { + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->first(); + } + + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = null; + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = null; + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = null; + $reservationList['data'][$reservationKey]['channelManagerPropertyId'] = $propertyMapping['channel_manager_property_id']; + + if (empty($channelManagerRoomRate)) { + //Eğer mapping yapılmış oda bulunamamış ise rezervasyonu içeri alamazsın + //$logMessage + $mailParams = [ + 'title' => 'ReservationPullService Error - Channel Manager Room Rate Mapping', + 'logMessage' => '
' . print_r(array_merge($propertyMapping, $reservation), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + unset($reservationList['data'][$reservationKey]); + $this->error(date('Y-m-d H:i:s') . ' : Error: RoomRate Mapping Reservation: ' . $reservation['reservno']); + + + //Eşleşmeyen ve iptal edilen işlemin otele bildirilmesi. + if ($reservation['status'] == 'C') { + + $notificationCancelToPropertyUser = [ + 'channel' => $reservation['otaname'], + 'channelBookingCode' => $reservation['reservno_ota'], + 'propertyChannelManager' => $channelManagerMapping['property_channel_manager']['name'], + 'nameSurname' => $reservation['firstname'] . ' ' . $reservation['lastname'], + 'propertyId' => $propertyMapping['property_id'], + ]; + + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser)); + + $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']); + $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + } + + } else { + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_id']; + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_rate_id']; + $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = $channelManagerRoomRate['property_room_rate_mapping']['id']; + } + + } + + } + + foreach ($reservationList['data'] as $reservationKey => $reservation) { + + //Eğer ExtranetWork ise içeri almadan onayla + if ($reservation['otaname'] == 'ExtranetWork') { + + $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']); + $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam); + + if (!$reservationConfirm['status']) { + throw new ApiErrorException($reservationConfirm['message']); + } + + continue; + } + + $booking = ['status' => false, 'message' => '']; + + if ($reservation['status'] == 'A') { + $booking = $this->createBooking($reservation); + } elseif ($reservation['status'] == 'C') { + $booking = $this->cancelBooking($reservation); + } elseif ($reservation['status'] == 'M') { + $booking = $this->modifiedBooking($reservation); + } + + //M Modified kayıt bul güncelle ve sonra mail atılacak cancel ile aynı mail yapısı kullanılacak + + if ($booking['status']) { + $this->info(date('Y-m-d H:i:s') . ' : Success: ' . $reservation['reservno']); + } else { + + //$logMessage + $mailParams = [ + 'title' => 'ReservationPullService Error - Booking', + 'logMessage' => '
' . print_r(array_merge($booking, $reservation), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $booking['message']); + } + + + } + + } + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch + (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/_ReservationPushService.php b/app/Console/Commands/ChannelManager/_ReservationPushService.php new file mode 100644 index 0000000..edfdc80 --- /dev/null +++ b/app/Console/Commands/ChannelManager/_ReservationPushService.php @@ -0,0 +1,281 @@ +mailer = $mailer; + $this->channelService = $channelService; + $this->channelManagerBookingService = $channelManagerBookingService; + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + } + + public function handle() + { + + try { + + $this->info(date('Y-m-d H:i:s') . ' : Start'); + + $pendingBookingCriteria = [ + 'criteria' => + [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => 1], + ['field' => 'is_pushed', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['bookingDetail.bookingContact', 'bookingDetail.bookingChannel', 'bookingDetail.bookingPayment', 'bookingDetail.bookingPaymentType', 'bookingDetail.bookingStatus', 'bookingDetail.bookingRoom.roomPax.paxCountry'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'take' => 100 + ]; + + $pendingBooking = $this->channelManagerBookingService->select($pendingBookingCriteria); + + if ($pendingBooking['status'] == 'success') { + + $pendingBooking = $pendingBooking['data']; + + foreach ($pendingBooking as $booking) { + + + $bookingDetail = $booking['booking_detail']; + + $type = $this->typeMapping[$booking['type']]; + + $serviceRequestName = 'BookingRetrieval'; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + if (in_array($bookingDetail['status'], [0, 3])) { + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + if(Carbon::createFromTimestamp($booking['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) { + $Booking->addAttribute('id', $bookingDetail['id']); + } else { + $Booking->addAttribute('id', $bookingDetail['booking_code']); + } + + $Booking->addAttribute('type', 'Cancel'); + $Booking->addAttribute('cancelDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + } + + } else { + + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + if(Carbon::createFromTimestamp($booking['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) { + $Booking->addAttribute('id', $bookingDetail['id']); + } else { + $Booking->addAttribute('id', $bookingDetail['booking_code']); + } + + //Book ve Modify Aynı olacak, Cancel + if ($type == 'Book') { + $Booking->addAttribute('type', 'Book'); + $Booking->addAttribute('createDateTime', Carbon::createFromTimestamp($bookingDetail['created_at'])->toISOString()); + } + + if ($type == 'Modify') { + $Booking->addAttribute('type', 'Modify'); + $Booking->addAttribute('modifyDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + } + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + + $roomPaxCollect = collect($room['room_pax']); + + $GuestCount = $RoomStay->addChild('GuestCount'); + $GuestCount->addAttribute('adult', $roomPaxCollect->where('type', 'ADT')->count()); + + $diffInDays = Carbon::parse($room['checkin_date'])->diffInDays(Carbon::parse($room['checkout_date'])); + + //dd($room['total'], $diffInDays, $room); + + $PerDayRates = $RoomStay->addChild('PerDayRates'); + $PerDayRates->addAttribute('currency', $room['currency_code']); + + $baseRateDaily = moneyDoubleFormatDecimal($room['total'] / $diffInDays); + + $currentDate = $room['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $PerDayRate = $PerDayRates->addChild('PerDayRate'); + $PerDayRate->addAttribute('stayDate', $currentDate); + $PerDayRate->addAttribute('baseRate', $baseRateDaily); + $PerDayRate->addAttribute('hotelServiceFees', 0); + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + $Total = $RoomStay->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $room['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $room['currency_code']); + + $roomNotes['cancellationPolicy'] = 'Cancellation Policy: Refundable'; + $cancellationPolicy = json_decode($room['cancellation_policy'],1); + if(!empty($cancellationPolicy) && is_array($cancellationPolicy)) { + if(isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) { + $roomNotes['cancellationPolicy'] = 'Cancellation Policy: NonRefundable'; + } + } + + $roomNotes['payment'] = 'Payment: '.$bookingDetail['booking_payment_type']['name']; + + $RoomStay->addChild('RoomNotes', implode('. ',$roomNotes)); + + } + + + $PrimaryGuest = $Booking->addChild('PrimaryGuest'); + + $Name = $PrimaryGuest->addChild('Name'); + $Name->addAttribute('givenName', $bookingDetail['booking_contact']['name']); + $Name->addAttribute('surname', $bookingDetail['booking_contact']['surname']); + + $Phone = $PrimaryGuest->addChild('Phone'); + $Phone->addAttribute('countryCode', $bookingDetail['booking_contact']['phone_code']); + //$Phone->addAttribute('cityAreaCode'); + $Phone->addAttribute('number', $bookingDetail['booking_contact']['phone_number']); + + $PrimaryGuest->addChild('Email', $bookingDetail['booking_contact']['email']); + + + $Total = $Booking->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $bookingDetail['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $bookingDetail['currency_code']); + + + $Booking->addChild('SpecialRequest'); + $Booking->addChild('BookingNotes', $bookingDetail['booking_contact']['note']); + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Push'); + + + $xmlPayload = $xmlResponse->asXML(); + + $this->channelManagerBookingService->update($booking['id'], ['request' => $xmlPayload]); + + $requestPostReservationPush = $this->channelService->requestPostReservationPush($xmlPayload); + + $this->channelManagerBookingService->update($booking['id'], ['response' => $requestPostReservationPush['data']['xmlBase']]); + + + if ($requestPostReservationPush['status']) { + + if($requestPostReservationPush['data']['Status'] == 'success') { + $this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Success'); + $this->channelManagerBookingService->update($booking['id'], ['is_pushed' => 1]); + } else { + + //$logMessage + $mailParams = [ + 'title' => 'ReservationPushService Error - requestPostReservationPush Error', + 'logMessage' => '
' . print_r(array_merge($booking, $requestPostReservationPush), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + } + + + } else { + + //$logMessage + $mailParams = [ + 'title' => 'ReservationPushService Error - requestPostReservationPush Error', + 'logMessage' => '
' . print_r(array_merge($booking, $requestPostReservationPush), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Failed'); + } + + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : Finished'); + + } catch (ApiErrorException $e) { + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/ChannelManager/akgun.xlsx b/app/Console/Commands/ChannelManager/akgun.xlsx new file mode 100644 index 0000000..97e5cf6 Binary files /dev/null and b/app/Console/Commands/ChannelManager/akgun.xlsx differ diff --git a/app/Console/Commands/CurrencyRates/CurrencyRatesService.php b/app/Console/Commands/CurrencyRates/CurrencyRatesService.php new file mode 100644 index 0000000..07a5ed9 --- /dev/null +++ b/app/Console/Commands/CurrencyRates/CurrencyRatesService.php @@ -0,0 +1,188 @@ +currencyRatesRepository = $currencyRatesRepository; + $this->serviceUrl = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; + $this->currencyService = $currencyService; + } + + public function handle() + { + + $currencyList = $this->currencyService->getCurrencyList(); + + if (!$currencyList['status']) { + $this->error(date('Y-m-d H:i:s') . ' : CurrencyList alınamadı.'); + } + + $availableCurrencies = []; + foreach ($currencyList['data'] as $currency) { + $availableCurrencies[] = $currency['code']; + } + $availableCurrency = $availableCurrencies; + + $this->restClient = new Client(['allow_redirects' => false]); + $request = $this->restClient->GET($this->serviceUrl); + $requestResponse = $request->getBody(); + + $currencyRatesData = json_decode(json_encode(simplexml_load_string($requestResponse)), 1); + + if (empty($currencyRatesData)) { + $this->error(date('Y-m-d H:i:s') . ' : CurrencyRatesData alınamadı.'); + + return false; + } + + //Georgia GEL + $tbcBankApiUrl = 'https://nbg.gov.ge/gw/api/ct/monetarypolicy/currencies/en/json/'; + $requestTbcBank = $this->restClient->GET($tbcBankApiUrl); + + $requestResponseTbcBank = $requestTbcBank->getBody()->getContents(); + $currencyRatesDataTbcBank = json_decode($requestResponseTbcBank, 1); + + if (empty($currencyRatesDataTbcBank)) { + $this->error(date('Y-m-d H:i:s') . ' : GEL CurrencyRatesData alınamadı.'); + } + + $currencyRatesDataTbcBank = reset($currencyRatesDataTbcBank); + $currencyRatesDataTbcBank = collect($currencyRatesDataTbcBank['currencies'])->where('code','EUR')->first(); + + $currencyRatesData['Cube']['Cube']['Cube'][] = [ + '@attributes' => [ + 'currency' => 'GEL', + 'rate' => $currencyRatesDataTbcBank['rate'] + ] + ]; + //Georgia GEL + + //Morocco MAD + $euroApiUrl = 'https://www.floatrates.com/daily/eur.xml'; + $requestEuroApiUrl = $this->restClient->GET($euroApiUrl); + $responseEuroApi = $requestEuroApiUrl->getBody(); + + $currencyRatesDataEuroApi = json_decode(json_encode(simplexml_load_string($responseEuroApi)), 1); + + if (empty($currencyRatesDataEuroApi)) { + $this->error(date('Y-m-d H:i:s') . ' : EUR CurrencyRatesData alınamadı.'); + } + + $currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','MAD')->first(); + + $currencyRatesData['Cube']['Cube']['Cube'][] = [ + '@attributes' => [ + 'currency' => 'MAD', + 'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4) + ] + ]; + //Morocco MAD + + $currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','AZN')->first(); + + $currencyRatesData['Cube']['Cube']['Cube'][] = [ + '@attributes' => [ + 'currency' => 'AZN', + 'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4) + ] + ]; + //Azerbaijani AZN + + $date = $currencyRatesData['Cube']['Cube']['@attributes']['time']; + + $currencyRatesCriteria = [ + 'criteria' => [ + ['field' => 'date', 'condition' => '=', 'value' => $date], + ], + 'count' => true, + ]; + + $currencyRateCount = $this->currencyRatesRepository->findByCriteria($currencyRatesCriteria); + + + if ($currencyRateCount > 0) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için döviz bilgisi güncel.'); + + return false; + } + + $euroParity[] = [ + 'currency_code' => 'EUR', + 'exc_currency_code' => 'EUR', + 'rate' => 1 + ]; + foreach ($currencyRatesData['Cube']['Cube']['Cube'] as $perEuroParity) { + if (in_array($perEuroParity['@attributes']['currency'], $availableCurrency)) { + $euroParity[] = [ + 'currency_code' => 'EUR', + 'exc_currency_code' => $perEuroParity['@attributes']['currency'], + 'rate' => floatval($perEuroParity['@attributes']['rate']), + ]; + } + } + + $exchangeParity = []; + foreach ($euroParity as $perParity) { + foreach ($euroParity as $perParityExchange) { + $exchangeParity[$perParity['exc_currency_code'] . $perParityExchange['exc_currency_code']] = [ + 'currency_code' => $perParity['exc_currency_code'], + 'exc_currency_code' => $perParityExchange['exc_currency_code'], + 'rate' => $perParityExchange['rate'] / $perParity['rate'] + ]; + + + $exchangeParity[$perParityExchange['exc_currency_code'] . $perParity['exc_currency_code']] = [ + 'currency_code' => $perParityExchange['exc_currency_code'], + 'exc_currency_code' => $perParity['exc_currency_code'], + 'rate' => $perParity['rate'] / $perParityExchange['rate'] + ]; + } + } + + ksort($exchangeParity); + + foreach ($exchangeParity as $perExchangeParity) { + + + $data[] = [ + 'date' => $date, + 'currency_code' => $perExchangeParity['currency_code'], + 'exc_currency_code' => $perExchangeParity['exc_currency_code'], + 'rate' => $perExchangeParity['rate'], + 'created_at' => Carbon::now()->timestamp + ]; + } + + $currencyRateUpdate = $this->currencyRatesRepository->insert($data); + + if ($currencyRateUpdate['status'] == 'success') { + $this->info(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için ' . count($exchangeParity) . ' adet döviz bilgisi güncellendi.'); + } + + + } +} diff --git a/app/Console/Commands/Data/DashboardCacheService.php b/app/Console/Commands/Data/DashboardCacheService.php new file mode 100644 index 0000000..03e5933 --- /dev/null +++ b/app/Console/Commands/Data/DashboardCacheService.php @@ -0,0 +1,149 @@ +restClient = $restClient; + } + + + public function handle() + { + try { + + + $this->info(date('Y-m-d H:i:s') . ' : START'); + + $bookingService = App::make("App\Core\Service\BookingService"); + $propertyWebController = App::make("App\Http\Controllers\V1\PropertyWebController"); + + $vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->orderBy('id')->get()->toArray(); + + + //$dashboardCountablePlaceCacheKey + $this->info(date('Y-m-d H:i:s') . ' : $dashboardCountablePlaceCacheKey'); + foreach ($vwActiveProperty as $property) { + + + //$dashboardCountablePlaceCacheKey + $dashboardCountablePlaceCacheKey = md5('dashboardCountablePlace-' . $property['id']); + + try { + + $this->line(date('Y-m-d H:i:s') . ' : ' . $property['id'] . ' - ' . $property['name']); + + $propertyWeb = PropertyWeb::where('property_id', $property['id'])->where('status', 1)->orderByDesc('id')->first(); + $propertyWeb = $propertyWeb ? $propertyWeb->toArray() : null; + if (empty($propertyWeb)) { + throw new Exception('Empty Web ID'); + } + + $dashboardCountablePlaceParam = ['property_id' => $property['id']]; + $dashboardCountablePlace = $propertyWebController->dashboardCountablePlace($dashboardCountablePlaceParam, $propertyWeb['id']); + + if ($dashboardCountablePlace['status']) { + Cache::put($dashboardCountablePlaceCacheKey, $dashboardCountablePlace, 24 * 60 * 60);//1 Day + } + + + } catch (Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $e->getMessage()); + } + + } + + + //$getBookingDetailedListCacheKey + $this->info(date('Y-m-d H:i:s') . ' : GetBookingDetailedListCacheKey'); + foreach ($vwActiveProperty as $property) { + $getBookingDetailedListCacheKey = md5('getBookingDetailedList-' . $property['id']); + + try { + + $this->line(date('Y-m-d H:i:s') . ' : ' . $property['id'] . ' - ' . $property['name']); + + $getBookingDetailedListParam = ['property_id' => $property['id'], 'channel_id' => 1]; + $getBookingDetailedList = $bookingService->getBookingDetailedList($getBookingDetailedListParam); + + if ($getBookingDetailedList['status'] == 'success') { + + + $bookings = collect($getBookingDetailedList['data']); + $channelBookings = $bookings->where('channel_id', '=', 1); + $getBookingEngineBookings = $channelBookings->all(); + $paxCountArray = $channelBookings->where('status', '=', 1)->map(function ($booking) { + $roomPaxCount = collect($booking['booking_room'])->map(function ($room) { + return collect($room['room_pax'])->count(); + })->values()->first(); + return [ + 'booking_id' => $booking['id'], + 'room_pax_count' => $roomPaxCount, + ]; + + })->values()->all(); + + $totalPaxCount = collect($paxCountArray)->sum('room_pax_count'); + + $allBookingCount = $channelBookings->count(); + $preBookingCount = $channelBookings->where('status', '=', 2)->count(); + $successBookingCount = $channelBookings->where('status', '=', 1)->count(); + + $conversionRate = $allBookingCount > 0 ? ($successBookingCount * 100) / $allBookingCount : 0; + + $responseData['all_booking_count'] = $allBookingCount; + $responseData['success_booking_count'] = $successBookingCount; + $responseData['pre_booking_count'] = $preBookingCount; + $responseData['conversion_rate'] = number_format($conversionRate, 2); + $responseData['total_pax_count'] = $totalPaxCount; + + Cache::put($getBookingDetailedListCacheKey, $responseData, 24 * 60 * 60);//1 Day + + + } + + + } catch (Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $e->getMessage()); + } + //$getBookingDetailedListCacheKey + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Data/HotelBedsList.php b/app/Console/Commands/Data/HotelBedsList.php new file mode 100644 index 0000000..ea0dd18 --- /dev/null +++ b/app/Console/Commands/Data/HotelBedsList.php @@ -0,0 +1,128 @@ +info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START'); + + $baseUrl = 'https://api.hotelbeds.com'; + $apiKey = 'ddaa6y6zpf6sy8fne4n2zj7q'; + $secret = 'wc87VEfTSD'; + + $countryCode = 'TR'; + $language = 'TUR'; + $destinationCode = 'AYT'; + + $fields = ['code', 'name', 'email', 'countryCode', 'destinationCode', 'city','phones']; + + + $chunk = 500; + + $from = 1; + $to = $chunk; + + $isContinue = true; + while ($isContinue) { + + $xSignature = hash("sha256", $apiKey . $secret . time()); + $urlGenerate = $baseUrl . '/hotel-content-api/1.0/hotels?fields=' . implode(',', $fields) . '&countryCode=' . $countryCode . '&language=' . $language . '&from=' . $from . '&to=' . $to.'&destinationCode='.$destinationCode; + + $this->restClient = new Client(['allow_redirects' => false]); + + $request = $this->restClient->GET($urlGenerate, [ + 'headers' => [ + 'content-type' => 'application/json', + 'Api-key' => $apiKey, + 'X-Signature' => $xSignature, + ], + 'body' => null, + ]); + Log::debug($xSignature); + $requestResponse = $request->getBody(); + $requestResponse = json_decode($requestResponse, 1); + + $this->info(date('Y-m-d H:i:s') . ' : ' . $urlGenerate); + + $from += $chunk; + $to = $from + $chunk - 1; + + if (empty($requestResponse['hotels'])) { + $isContinue = false; + } + + foreach ($requestResponse['hotels'] as $hotel) { + + if(!isset($hotel['email'])) { + continue; + } + + $email = mb_strtolower($hotel['email']); + + $hotelList[$email] = [ + 'code' => $hotel['code'], + 'content' => (string)uCase($hotel['name']['content']), + 'countryCode' => $hotel['countryCode'], + 'email' => $email + ]; + + foreach ($hotel['phones'] as $phone) { + if(in_array($phone['phoneType'], ['PHONEHOTEL','PHONEMANAGEMENT'])) { + $hotelList[$email]['phone'] = $phone['phoneNumber']; + break; + } + } + } + } + + + + // Open a file in write mode ('w') + $fileName = $countryCode.(!empty($destinationCode) ? '-'.$destinationCode : ''); + $fp = fopen(resource_path().'/data/'.$fileName.'.csv', 'w'); + + // Loop through file pointer and a line + foreach ($hotelList as $hotel) { + fputcsv($fp, $hotel); + } + + fclose($fp); + + $this->info(date('Y-m-d H:i:s') . ' : Total: ' . count($hotelList).' / '. $requestResponse['total']); + + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Data/WeatherService.php b/app/Console/Commands/Data/WeatherService.php new file mode 100644 index 0000000..bbc26bd --- /dev/null +++ b/app/Console/Commands/Data/WeatherService.php @@ -0,0 +1,130 @@ +restClient = $restClient; + } + + + public function handle() + { + try { + + + $date = date('Y-m-d'); + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START'); + + $baseUrl = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline'; + $apiKey = 'GQG8FVH2C7ZZYZXS6PECE2QFX'; + + $this->restClient = new Client(['http_errors' => false]); + + $propertyWeb = PropertyWeb::where('status', 1) + ->where('weather_active', 1)->with('property.propertyContact') + //->where('property_id',1231)//TODO:Del + ->get()->toArray(); + + foreach ($propertyWeb as $property) { + + + $propertyWebWeatherId = null; + $propertyWebWeather = PropertyWebWeather::where('property_id', $property['property']['id'])->first(); + if ($propertyWebWeather) { + $propertyWebWeatherId = $propertyWebWeather['id']; + } + + + $latitude = $property['property']['property_contact']['latitude']; + $longitude = $property['property']['property_contact']['longitude']; + if (!empty($latitude) && !empty($longitude)) { + + $requestUrl = $baseUrl . '/' . $latitude . ',' . $longitude . '/' . $date . '?key=' . $apiKey . '&include=days&unitGroup=metric&elements=tempmax,tempmin,temp,conditions,icon'; + + $requestWeather = $this->restClient->request('GET', $requestUrl); + + $getResponseBody = $requestWeather->getBody(); + $getResponse = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + $propertyWebWeatherParam = [ + 'property_id' => $property['property']['id'], + 'date' => $date, + 'temp' => $getResponse['days'][0]['tempmax'], + 'conditions' => $getResponse['days'][0]['conditions'], + 'icon' => $getResponse['days'][0]['icon'], + 'response' => json_encode($getResponse), + 'created_by' => 1, + 'updated_by' => 1, + ]; + + if (empty($propertyWebWeatherId)) { + + $locationUrl = 'https://geocode.maps.co/reverse?lat=' . $latitude . '&lon=' . $longitude . '&api_key=6683d9ee52e5d111344805khdf0451c'; + $requestLocation = $this->restClient->request('GET', $locationUrl); + + $getResponseBodyLocation = $requestLocation->getBody(); + $getResponseLocation = $getResponseBodyLocation ? json_decode($getResponseBodyLocation, 1) : []; + + + if ($getResponseLocation) { + + $location = null; + if(isset($getResponseLocation['address']['province'])) { + $location = $getResponseLocation['address']['province']; + }elseif(isset($getResponseLocation['address']['town'])) { + $location = $getResponseLocation['address']['town']; + }elseif(isset($getResponseLocation['address']['city'])) { + $location = $getResponseLocation['address']['city']; + } + + $propertyWebWeatherParam['location'] = $location; + $propertyWebWeatherParam['address'] = json_encode($getResponseLocation); + } + + PropertyWebWeather::create($propertyWebWeatherParam); + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyWebWeatherParam['property_id'] . ' - ' . $propertyWebWeatherParam['date'] . ' : ' . $propertyWebWeatherParam['conditions']. ' : ' . $propertyWebWeatherParam['temp']); + + } else { + + PropertyWebWeather::where('id', $propertyWebWeatherId)->update($propertyWebWeatherParam); + $this->line(date('Y-m-d H:i:s') . ' : ' . $propertyWebWeatherParam['property_id'] . ' - ' . $propertyWebWeatherParam['date'] . ' : ' . $propertyWebWeatherParam['conditions']. ' : ' . $propertyWebWeatherParam['temp']); + } + + + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Google/GoogleReview.php b/app/Console/Commands/Google/GoogleReview.php new file mode 100644 index 0000000..28768f6 --- /dev/null +++ b/app/Console/Commands/Google/GoogleReview.php @@ -0,0 +1,140 @@ +restClient = $restClient; + } + + public function handle() + { + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START'); + + $baseUrl = 'https://maps.googleapis.com/maps/api/place/details/json'; + $apiKey = 'AIzaSyAPsKZ_XasAieKEhbmpOLUpArY2u2UcXuk'; + $availableRating = [4,5]; + + $this->restClient = new Client(['http_errors' => false]); + + + if (!is_null($this->option('property_id'))) { + $propertyWebComponentMapping = PropertyWebComponentMapping::where('status', 1)->where('component_id', 3)->where('property_id', $this->option('property_id'))->get()->toArray(); + } else { + $propertyWebComponentMapping = PropertyWebComponentMapping::where('status', 1)->where('component_id', 3)->get()->toArray(); + } + + foreach ($propertyWebComponentMapping as $propertyWebComponent) { + + if (!isset($propertyWebComponent['parameterArray']['placeId'])) { + continue; + } + + $googlePlaceId = trim($propertyWebComponent['parameterArray']['placeId']); + + Log::debug('google-review: '.$googlePlaceId); + + + $params = [ + 'query' => [ + 'place_id' => $googlePlaceId, + 'key' => $apiKey, + 'fields' => 'name,rating,reviews', + 'reviews_sort' => 'newest', + 'reviews_no_translations' => true, + //'language' => 'tr' + ] + ]; + + $requestReview = $this->restClient->request('GET', $baseUrl, $params); + + $getResponseBody = $requestReview->getBody(); + $getResponse = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + $reviews = []; + if(isset($getResponse['result']['reviews'])) { + $reviews = collect($getResponse['result']['reviews'])->sortBy('time')->toArray(); + } + + foreach ($reviews as $review) { + + if(!in_array(fillOnUndefined($review, 'rating'),$availableRating)) { + continue; + } + + try { + + $code = md5($propertyWebComponent['property_id'].'-'.$review['author_name'] . '-' . $review['time']); + + $propertyWebReviewCheck = PropertyWebReview::where('code', $code)->first(); + if ($propertyWebReviewCheck) { + $this->error(date('Y-m-d H:i:s') . ' : ' . $propertyWebComponent['property_id'] . ' - ' . $review['author_name'] . ' : ' . $review['rating']); + continue; + } + + $propertyWebWeatherParam = [ + 'property_id' => $propertyWebComponent['property_id'], + 'channel' => 'google', + 'code' => $code, + 'language_code' => fillOnUndefined($review, 'language') ? substr($review['language'],0,2) : null, + 'author' => $review['author_name'], + 'profile_photo' => fillOnUndefined($review, 'profile_photo_url'), + 'rating' => fillOnUndefined($review, 'rating'), + 'review' => fillOnUndefined($review, 'text'), + 'time' => fillOnUndefined($review, 'time'), + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + ]; + + $propertyWebReviewCreate = PropertyWebReview::create($propertyWebWeatherParam); + + $this->info(date('Y-m-d H:i:s') . ' : ' . $propertyWebComponent['property_id'] . ' - ' . $review['author_name'] . ' : ' . $review['rating']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + + } + + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED'); + + } + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Google/GoogleStaticMap.php b/app/Console/Commands/Google/GoogleStaticMap.php new file mode 100644 index 0000000..6e8d0ae --- /dev/null +++ b/app/Console/Commands/Google/GoogleStaticMap.php @@ -0,0 +1,107 @@ +restClient = $restClient; + } + + public function handle() + { + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START'); + + $baseUrl = 'https://maps.googleapis.com/maps/api/staticmap'; + $apiKey = 'AIzaSyAPsKZ_XasAieKEhbmpOLUpArY2u2UcXuk'; + + $imageSizes = []; + $imageSizes[] = ['name' => 'square','size' => '250x250']; + $imageSizes[] = ['name' => 'rectangle','size' => '1000x200']; + + $this->restClient = new Client(['http_errors' => false]); + + if (!is_null($this->option('property_id'))) { + $propertyList = Property::where('status', 1)->where('id', $this->option('property_id'))->with('propertyContact')->get()->toArray(); + } else { + $propertyList = Property::where('status', 1)->where('commission','>=', 1)->with('propertyContact')->get()->toArray(); + } + + foreach ($propertyList as $property) { + + if (!isset($property['property_contact'])) { + continue; + } + + $folderPath = Config::get('app.fileSystemDriver') . '/property-map/' . $property['id']; + if(!is_dir($folderPath)) { + mkdir($folderPath); + } + + foreach ($imageSizes as $imageSize) { + + $imageName = 'map-'.$property['id'].'-'.$imageSize['name'].'.png'; + + $imagePath = Config::get('app.fileSystemDriver') . '/property-map/' . $property['id'] . '/'.$imageName; + + if(is_file($imagePath)) { + $this->line(date('Y-m-d H:i:s') . ' : ' . $imageName); + continue; + } + + $params = [ + 'center' => $property['property_contact']['latitude'] . ',' . $property['property_contact']['longitude'], + 'size' => $imageSize['size'], //300x300 1000x200 + 'zoom' => 18, + 'format' => 'png', + 'scale' => 2, + 'markers' => 'color:red|' . $property['property_contact']['latitude'] . ',' . $property['property_contact']['longitude'], + 'key' => $apiKey, + 'language' => 'en' + ]; + + $imageUrl = $baseUrl . '?' . http_build_query($params, '', '&'); + $imageSave = file_put_contents($imagePath, file_get_contents($imageUrl)); + + + $this->info(date('Y-m-d H:i:s') . ' : ' . $imageName); + + } + + } + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Google/GoogleVisioLabel.php b/app/Console/Commands/Google/GoogleVisioLabel.php new file mode 100644 index 0000000..e70053d --- /dev/null +++ b/app/Console/Commands/Google/GoogleVisioLabel.php @@ -0,0 +1,72 @@ +info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START'); + + $googleVisionAuthentication = base_path().'/resources/data/google-vision-authentication.json'; + + putenv('GOOGLE_APPLICATION_CREDENTIALS='.$googleVisionAuthentication); + $imageAnnotator = new ImageAnnotatorClient(); + + $fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566879.jpg'; + $fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566886.jpg'; + $fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566881.jpg'; + $fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566878.jpg'; + $image = file_get_contents($fileName); + $response = $imageAnnotator->labelDetection($image); + $labels = $response->getLabelAnnotations(); + + $labelList = []; + + if ($labels) { + foreach ($labels as $label) { + $labelList[] = [ + 'description' => $label->getDescription(), + 'score' => $label->getScore(), + 'topicality' => $label->getTopicality(), + ]; + } + } else { + echo('No label found' . PHP_EOL); + } + + $imageAnnotator->close(); + + print_r($labelList); + + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Commands/Jobs/BookingCommissionService.php b/app/Console/Commands/Jobs/BookingCommissionService.php new file mode 100644 index 0000000..8495352 --- /dev/null +++ b/app/Console/Commands/Jobs/BookingCommissionService.php @@ -0,0 +1,122 @@ +bookingService = $bookingService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + try { + + + $bookingListParam = [ + 'criteria' => [ + //['field' => 'id', 'condition' => '=', 'value' => 600], + //['field' => 'property_id', 'condition' => '=', 'value' => 313], + ['field' => 'commission', 'condition' => '=', 'value' => null], + ['field' => 'commission_rate', 'condition' => '=', 'value' => null] + ], + 'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty'], + "take" => 10000, + "orderBy" => [ + ["field" => "id", "value" => "ASC"] + ], + ]; + + $bookingList = $this->bookingService->select($bookingListParam); + + if ($bookingList['status'] != 'success' || ($bookingList['status'] == 'success' && empty($bookingList['data']))) { + throw new ApiErrorException('Property list not found!'); + } + + foreach ($bookingList['data'] as $booking) { + + + $commission = null; + $commissionRate = null; + //$booking['booking_property']['commission'] = 15;//TOOD: DEL + switch ($booking['booking_channel']['channel_category_id']) { + case "3" : + + if (fillOnUndefined($booking['booking_property'], 'commission') && $booking['booking_property']['commission'] > 0) { + $commissionRate = $booking['booking_property']['commission']; + $commission = moneyDoubleFormatDecimal($booking['booking_property']['commission'] * $booking['total'] / 100); + } + + break; + case "2" : + + if (fillOnUndefined($booking['booking_property'], 'commission_offline') && $booking['booking_property']['commission_offline'] > 0) { + $commissionRate = $booking['booking_property']['commission_offline']; + $commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_offline'] * $booking['total'] / 100); + } + + break; + case "4" : + + if (fillOnUndefined($booking['booking_property'], 'commission_channel') && $booking['booking_property']['commission_channel'] > 0) { + $commissionRate = $booking['booking_property']['commission_channel']; + $commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_channel'] * $booking['total'] / 100); + } + + break; + case "7" : + + if (fillOnUndefined($booking['booking_property'], 'commission_wholesaler') && $booking['booking_property']['commission_wholesaler'] > 0) { + $commissionRate = $booking['booking_property']['commission_wholesaler']; + $commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_wholesaler'] * $booking['total'] / 100); + } + + break; + } + + if (!empty($commission) && !empty($commissionRate)) { + $this->bookingService->update($booking['id'], ['commission' => $commission, 'commission_rate' => $commissionRate]); + $this->info(date('Y-m-d H:i:s') . ' Property: ' . $booking['booking_property']['name'] . ' Code: ' . $booking['booking_code'] . ' Commission: ' . $commission . ' Commission Rate: ' . $commissionRate); + } else { + + $this->bookingService->update($booking['id'], ['commission' => 0, 'commission_rate' => 0]); + $this->error(date('Y-m-d H:i:s') . ' Property: ' . $booking['booking_property']['name'] . ' Code: ' . $booking['booking_code'] . ' Commission: ' . $commission . ' Commission Rate: ' . $commissionRate); + } + + //sleep(1); + + } + + + } catch (ApiErrorException | Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' ERROR:' . $e->getMessage()); + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/BookingEngineSearchReportService.php b/app/Console/Commands/Jobs/BookingEngineSearchReportService.php new file mode 100644 index 0000000..b173a3c --- /dev/null +++ b/app/Console/Commands/Jobs/BookingEngineSearchReportService.php @@ -0,0 +1,194 @@ +mailer = $mailer; + $this->propertyService = $propertyService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $reportPropertyList = [506, 529, 1606]; + //506 Green Nature Diamond Hotel + //529 Green Nature Resort & Spa Otel + //1606 Green Nature Sarıgerme + + $propertyListCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyUser.user'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'whereIn' => + [ + ['field' => 'id', 'value' => $reportPropertyList] + ] + ]; + + $propertyListData = $this->propertyService->select($propertyListCriteria); + + $propertyList = []; + if ($propertyListData['status'] == 'success' && !empty($propertyListData['data'])) { + $propertyList = $propertyListData['data']; + } + + + $reportData = []; + $reportDate = Carbon::now()->subDay()->toDateString(); + //$reportDate = '2023-02-28'; + $reportDateFormatted = Carbon::parse($reportDate)->format('d.m.Y'); + + $countryList = Country::all()->toArray(); + $languageList = Language::all()->toArray(); + + + $this->info(date('Y-m-d H:i:s') . ' Date: ' . $reportDate); + + foreach ($propertyList as $property) { + + $reportData = []; + + $reportData['propertyId'] = $property['id']; + $reportData['propertyName'] = $property['name']; + $reportData['propertyCountry'] = $property['country']; + $reportData['logo'] = $property['property_brand']['logoUrl']; + $reportData['date'] = $reportDateFormatted; + $reportData['propertyUserEmail'] = collect($property['property_user'])->where('user.email','<>', null)->pluck('user.email')->toArray(); + + $searchData = vwBookingEngineSearch::where('property_id', $property['id']) + ->where('date', $reportDate) + ->get()->toArray(); + + $this->info(date('Y-m-d H:i:s') . ' Property: ' . $reportData['propertyName']); + + if (!empty($searchData)) { + + $reportData['transaction']['search'] = collect($searchData)->count(); + $reportData['transaction']['roomFound'] = collect($searchData)->where('status', 1)->count(); + $reportData['transaction']['roomNotFound'] = collect($searchData)->where('status', 0)->count(); + $reportData['transaction']['preBooking'] = collect($searchData)->where('status', 2)->count(); + $reportData['transaction']['booking'] = collect($searchData)->where('status', 3)->count(); + + + $countryCodes = collect($searchData)->groupBy('country_code')->keys()->toArray(); + foreach ($countryCodes as $countryCode) { + $countryText = $countryCode; + $countryTextCheck = collect($countryList)->where('country_code', mb_strtoupper($countryCode))->first(); + if (!empty($countryTextCheck)) { + $countryText = $countryTextCheck['name']; + } + $reportData['country'][$countryCode]['text'] = $countryText; + $reportData['country'][$countryCode]['search'] = collect($searchData)->where('country_code', $countryCode)->count(); + $reportData['country'][$countryCode]['roomFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 1)->count(); + $reportData['country'][$countryCode]['roomNotFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 0)->count(); + $reportData['country'][$countryCode]['preBooking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 2)->count(); + $reportData['country'][$countryCode]['booking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 3)->count(); + } + + $reportData['country'] = collect($reportData['country'])->sortByDesc('search')->toArray(); + + $languageCodes = collect($searchData)->groupBy('language_code')->keys()->toArray(); + foreach ($languageCodes as $languageCode) { + $languageText = $languageCode; + $languageTextCheck = collect($languageList)->where('code', $languageCode)->first(); + if (!empty($languageTextCheck)) { + $languageText = $languageTextCheck['name']; + } + $reportData['language'][$languageCode]['text'] = $languageText; + $reportData['language'][$languageCode]['search'] = collect($searchData)->where('language_code', $languageCode)->count(); + $reportData['language'][$languageCode]['roomFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 1)->count(); + $reportData['language'][$languageCode]['roomNotFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 0)->count(); + $reportData['language'][$languageCode]['preBooking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 2)->count(); + $reportData['language'][$languageCode]['booking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 3)->count(); + } + + $reportData['language'] = collect($reportData['language'])->sortByDesc('search')->toArray(); + + + $occupancyCodes = collect($searchData)->groupBy('pax')->keys()->toArray(); + foreach ($occupancyCodes as $occupancyCode) { + $reportData['occupancy'][$occupancyCode]['text'] = occupancyCodeFormatted($occupancyCode); + $reportData['occupancy'][$occupancyCode]['count'] = collect($searchData)->where('pax', $occupancyCode)->count(); + } + + $reportData['occupancy'] = collect($reportData['occupancy'])->sortByDesc('count')->toArray(); + + //Daily Intensity + $dailyIntensity = []; + foreach ($searchData as $data) { + $checkInDate = $data['checkin_date']; + $checkOutDate = $data['checkout_date']; + $dateDiff = Carbon::parse($data['checkout_date'])->diffInDays(Carbon::parse($data['checkin_date'])); + + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($checkInDate)->addDays($i)->toDateString(); + + if (!isset($dailyIntensity[$date])) { + $dailyIntensity[$date]['text'] = Carbon::parse($date)->format('d.m.Y'); + $dailyIntensity[$date]['search'] = 0; + $dailyIntensity[$date]['roomFound'] = 0; + $dailyIntensity[$date]['roomNotFound'] = 0; + $dailyIntensity[$date]['preBooking'] = 0; + $dailyIntensity[$date]['booking'] = 0; + } + + $dailyIntensity[$date]['search']++; + $dailyIntensity[$date]['roomFound'] += $data['status'] == 1 ? 1 : 0; + $dailyIntensity[$date]['roomNotFound'] += $data['status'] == 0 ? 1 : 0; + $dailyIntensity[$date]['preBooking'] += $data['status'] == 2 ? 1 : 0; + $dailyIntensity[$date]['booking'] += $data['status'] == 3 ? 1 : 0; + + } + } + ksort($dailyIntensity); + $reportData['dailyIntensity'] = $dailyIntensity; + //Daily Intensity + + } + + if (!empty($searchData)) { + $this->mailer->onQueue('bookingEngineSearchReportMail', new BookingEngineSearchReportMail($reportData)); + $this->info(date('Y-m-d H:i:s') . ' Property: ' . $reportData['propertyName'] . ' - SENT MAIL'); + } + + } + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/DataFetch.php b/app/Console/Commands/Jobs/DataFetch.php new file mode 100644 index 0000000..0392e3a --- /dev/null +++ b/app/Console/Commands/Jobs/DataFetch.php @@ -0,0 +1,92 @@ +where('commission', '>', 1) + //->where('id', 1456) + ->with('propertyContractUser') + ->with('propertyExecutive.executiveType') + ->with('propertyContact') + ->with('propertyAdditionalInfos.propertyAdditionalInfoKey') + ->with('propertyType') + ->with('propertyStatus') + ->get(); + + $propertyList = $propertyList ? $propertyList->toArray() : null; + + + $propertyListToExcel = []; + foreach ($propertyList as $property) { + + $numberOfRooms = collect($property['property_additional_infos'])->where('additional_info_key_id',3)->first(); + $numberOfRooms = $numberOfRooms['value']; + + $propertyListToExcel[] = [ + 'contract_user' => $property['property_contract_user']['nameSurname'], + 'executive_name_surname' => reset($property['property_executive'])['name_surname'], + 'name' => $property['name'], + 'phone' => $property['property_contact']['view_full_phone'], + 'email' => $property['property_contact']['email'], + 'executive_position' => reset($property['property_executive'])['executive_type']['name'], + 'executive_phone' => reset($property['property_executive'])['view_full_phone'], + 'executive_email' => reset($property['property_executive'])['email'], + 'web' => $property['property_contact']['web'], + 'address' => $property['property_contact']['address'], + 'location' => null, //Bölge + 'number_of_rooms' => $numberOfRooms, + 'category' => $property['property_type']['name'], + 'property_pms' => null, + 'property_cm' => null, + 'commission' => $property['commission'], + 'commission_period' => $property['invoice_type'], + 'contract_start' => Carbon::createFromTimestamp($property['created_at'])->format('d.m.Y'), + 'contract_finish' => null, + 'content' => null, + 'dns' => null, + 'ssl' => null, + 'cm' => null, + 'third_party' => null, + 'golive' => Carbon::createFromTimestamp($property['created_at'])->format('d.m.Y'), + 'training' => null, + 'panel' => null, + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'tax_address' => $property['property_contact']['address'], + 'status' => $property['property_status']['name'], + 'id' => $property['id'], + ]; + + } + + $f = fopen("C:\www\api.extranetwork.com\storage/tmp.csv", "w"); + foreach ($propertyListToExcel as $property) { + fputcsv($f, $property); + } + + + } + +} diff --git a/app/Console/Commands/Jobs/MailJobs.php b/app/Console/Commands/Jobs/MailJobs.php new file mode 100644 index 0000000..2d0f0cb --- /dev/null +++ b/app/Console/Commands/Jobs/MailJobs.php @@ -0,0 +1,97 @@ +jobsService = $jobsService; + } + + public function handle() + { + + $mailJobsCriteria = + [ + "whereIn" => + [ + ["field" => "queue", "value" => $this->mailJobs] + ], + "orderBy" => + [ + ["field" => "id", "value" => "ASC"] + ], + "take" => 20 + ]; + + $mailJobs = $this->jobsService->getJobsList($mailJobsCriteria, ["queue"]); + + foreach ($mailJobs as $perJob) { + + try { + Artisan::call("queue:work --queue=" . $perJob["queue"]." --tries=5"); + } catch (Exception $e) { + $message = "Mail Job Fail --- Failed Mail : " . $perJob . " ErrorDetail : " . $e->getLine() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + continue; + } + sleep(1); + } + } + +} diff --git a/app/Console/Commands/Jobs/PriceComparisonService.php b/app/Console/Commands/Jobs/PriceComparisonService.php new file mode 100644 index 0000000..6a8cbaa --- /dev/null +++ b/app/Console/Commands/Jobs/PriceComparisonService.php @@ -0,0 +1,252 @@ +toDateString(); + + $today = Carbon::parse($today)->startOfWeek(Carbon::MONDAY); + + $year = Carbon::parse($today)->format('Y'); + $week = Carbon::parse($today)->isoWeek(); + + $daysCount = [1, 15, 45, 90]; + $exchangeCurrency = 'EUR'; + //'BookingEngine' + $comparisonChannels = ['Agoda.com', 'etstur.com', 'Booking.com']; + + $exchangeRateUSD = CurrencyRates::where('currency_code', 'USD')->where('exc_currency_code', $exchangeCurrency)->orderBy('date', 'DESC')->first()->toArray(); + $exchangeRateUSD = $exchangeRateUSD['rate']; + + $competitorPriceAnalysisController = App::make('App\Http\Controllers\V1\CompetitorPriceAnalysisController'); + + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $queryWeekPrices = []; + $queryWeekPricesDaily = []; + $queryKeyHash = md5($year . '-' . $week); + + + $propertyList = vwActiveProperty::where('commission', '>', 1) + //->whereIn('id', [1433,1441,1551,1574]) + ->get()->toArray(); + + foreach ($propertyList as $property) { + + try { + + $channelManagerProperty = ChannelManagerPropertyMapping::where('channel_manager_id', 12) + ->where('property_id', $property['id'])->first(); + $channelManagerProperty = $channelManagerProperty ? $channelManagerProperty->toArray() : null; + $channelManagerPropertyId = $channelManagerProperty ? $channelManagerProperty['channel_manager_property_id'] : null; + + $this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $property['name']); + + if (empty($channelManagerPropertyId)) { + $this->error(date('Y-m-d H:i:s') . ' ' . $property['name'] . ': channelManagerPropertyId!'); + continue; + } + + + foreach ($daysCount as $day) { + + + //Booking Engine + $queryDate = Carbon::parse($today)->addDays($day)->toDateString(); + + //FIRST Trigger + $paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency,]; + $getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice); + + $this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $queryDate); + + sleep(1); + + + $bestPriceOfDay = 0; + $queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [ + 'channel' => 'BookingEngine', + 'date' => $queryDate, + 'amount' => null, + 'currency' => null + ]; + + $propertyPrices = PropertyRoomRatePrice::where('property_id', $property['id']) + ->where('channel_id', 5) + ->where('stop_sell', 0) + ->where('status', 1) + ->where('amount', '<>', 0) + ->where('amount', '<>', null) + ->where('date', $queryDate) + ->with('roomRateMapping.propertyRoomRate') + ->get(); + + $propertyPrices = $propertyPrices ? $propertyPrices->toArray() : null; + + if (empty($propertyPrices)) { + //continue; + } + + $bestPrice = collect($propertyPrices) + ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate') + ->sortBy('amount')->first(); + + + + if (empty($bestPrice)) { + //continue; + } else { + + + if ($bestPrice['currency'] != $exchangeCurrency) { + $exchangeRate = CurrencyRates::where('currency_code', $bestPrice['currency']) + ->where('exc_currency_code', $exchangeCurrency) + ->orderBy('date', 'DESC')->first()->toArray(); + $exchangeRate = $exchangeRate['rate']; + + $bestPrice['amount'] = $bestPrice['amount'] * $exchangeRate; + } + + $bestPrice['amount'] = moneyDoubleFormatDecimal($bestPrice['amount']); + $queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [ + 'channel' => 'BookingEngine', + 'date' => $queryDate, + 'amount' => $bestPrice['amount'], + 'currency' => $exchangeCurrency, + ]; + + $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $bestPrice['amount']; + } + //Booking Engine + + + //OTHER Channels + + $paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency]; + $getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice); + + foreach ($comparisonChannels as $comparisonChannel) { + + $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day] = [ + 'channel' => $comparisonChannel, + 'date' => $queryDate, + 'amount' => null, + 'currency' => null + ]; + + if(!isset($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) { + $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount']; + } + + if ($getPropertyCompetitorPrice['status'] && !empty($getPropertyCompetitorPrice['data']['all'])) { + + $getPropertyCompetitorPriceChannel = $getPropertyCompetitorPrice['data']['all']; + $getPropertyCompetitorPriceChannelCheck = collect($getPropertyCompetitorPriceChannel)->where('provider', $comparisonChannel)->first(); + + if ($getPropertyCompetitorPriceChannelCheck) { + $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] = moneyDoubleFormatDecimal($getPropertyCompetitorPriceChannelCheck['amount'] * $exchangeRateUSD); + $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['currency'] = 'EUR'; + + //BestPriceCheck + + + if(empty($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) { + $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount']; + }elseif ($queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] < $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day]) { + $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount']; + } + + } + + } + + } + } + + //dd($queryWeekPrices[$queryKeyHash][$property['id']],$queryWeekPricesDaily[$queryKeyHash][$property['id']]); + + foreach ($queryWeekPrices[$queryKeyHash][$property['id']] as $channelKey => $channelDays) { + foreach ($channelDays as $channelDayKey => $channelDay) { + + //dd($channelDay,$queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey]); + + + if ($queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey] == $channelDay['amount'] && !is_null($channelDay['amount'])) { + $queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = true; + } else { + $queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = false; + } + + } + } + + $this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $property['name'] . ' OK!'); + + + $propertyComparisonPrice = [ + 'property_id' => $property['id'], + 'week_key' => $queryKeyHash, + 'year' => $year, + 'week' => $week, + 'date' => $today, + 'data' => json_encode($queryWeekPrices[$queryKeyHash][$property['id']]), + 'status' => 1, + 'created_at' => Carbon::now()->unix(), + 'updated_at' => Carbon::now()->unix(), + + ]; + + $propertyPriceComparisonCheck = PropertyPriceComparison::where('week_key', $queryKeyHash)->where('property_id', $property['id'])->first(); + + if ($propertyPriceComparisonCheck) { + $propertyPriceComparisonCheck = $propertyPriceComparisonCheck->toArray(); + $propertyPriceComparison = PropertyPriceComparison::where('id', $propertyPriceComparisonCheck['id'])->update($propertyComparisonPrice); + } else { + $propertyPriceComparison = PropertyPriceComparison::insert($propertyComparisonPrice); + } + + unset($queryWeekPrices[$queryKeyHash]); + + } catch (ApiErrorException|Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage()); + } + + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/PropertyCatalogService.php b/app/Console/Commands/Jobs/PropertyCatalogService.php new file mode 100644 index 0000000..c9b24c3 --- /dev/null +++ b/app/Console/Commands/Jobs/PropertyCatalogService.php @@ -0,0 +1,113 @@ +pdf = $pdf; + $this->mailer = $mailer; + $this->propertyService = $propertyService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $pdfDataRequest = [ + 'property_id' => $this->argument('property_id'), + 'locale' => $this->argument('language') + ]; + + $pdfContentService = App::make('App\Core\Service\PdfContentService'); + + $factSheetDataResponse = $pdfContentService->factSheetData($pdfDataRequest); + if ($factSheetDataResponse['status'] != 'success') { + throw new Exception($factSheetDataResponse['message']); + } + + $pageContent = $factSheetDataResponse['data']; + $pdfLanguage = $pdfDataRequest['locale']; + + $this->info(date('Y-m-d H:i:s') . ' PDF'); + + app('translator')->setLocale($pdfLanguage); + $pdfService = $this->pdf->loadView('pdf.propertyCatalog', compact('pageContent'), [], 'UTF8'); + $pdfService->setOptions([ + 'dpi' => 100, + 'isHtml5ParserEnabled' => true, + 'isRemoteEnabled' => true, + 'chroot', base_path(), + 'enable_html5_parser' => true, + 'enable_css_float' => true + ]); + + + $hotelName = Str::slug($pageContent['name'], '_', 'en') . '_' . $pdfLanguage; + $pathStorage = Config::get('app.fileSystemDriver') . '/property-catalog/' . $hotelName . '.pdf'; + + file_put_contents($pathStorage, $pdfService->output()); + + if ($this->option('email')) { + + $this->info(date('Y-m-d H:i:s') . ' E-Mail'); + + $languageDetail = Language::where('code', $pdfLanguage)->first(); + $languageDetail = $languageDetail ? $languageDetail->toArray() : null; + + $mailParams = [ + 'email' => $this->option('email'), + 'catalogUrl' => Config::get('app.imageUrl') . '/property-catalog/' . $hotelName . '.pdf', + 'propertyName' => $pageContent['name'], + 'language' => $pdfLanguage, + 'languageText' => __($languageDetail['language_key'],[],'tr'), + 'pathStorage' => $pathStorage + ]; + + + $this->mailer->send('emails.propertyCatalogMail', ['mailParams' => $mailParams], function ($message) use ($mailParams) { + $message->to($mailParams['email'], 'Extranetwork Property Katalog') + ->bcc(Config::get('app.logMailAddress')) + ->subject($mailParams['propertyName'] . ' Catalog - ' . $mailParams['languageText']) + //->attach($mailParams['pathStorage']) + ->from(Config::get('app.mailSenderAddress'), 'Extranetwork'); + }); + + } + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/PropertyInvoiceService.php b/app/Console/Commands/Jobs/PropertyInvoiceService.php new file mode 100644 index 0000000..bcf73fd --- /dev/null +++ b/app/Console/Commands/Jobs/PropertyInvoiceService.php @@ -0,0 +1,117 @@ +firstOfMonth()->toDateString(); + $lastDayOfYear = Carbon::parse($lastAllOfYear)->firstOfMonth()->toDateString(); + + $diffInPeriod = Carbon::parse($startDayOfYear)->diffInMonths(Carbon::parse($lastDayOfYear)); + + $periodList = []; + for ($i = 0; $i < $diffInPeriod; $i++) { + $periodList[] = Carbon::parse($firstAllOfYear)->addMonths($i)->format('Y-m'); + }*/ + //$periodList[] = '2025-09'; + //BULK + + //$invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod(623, '2025-10'); + //dd($invoiceWithPeriod); + //$periodList = ['2025-09']; + + //$lastOfMonth = '2025-10-30'; + //$dayOfMonth = '2025-10-30'; + + //$lastOfMonth = Carbon::now()->lastOfMonth()->format('Y-m-d'); + //$dayOfMonth = Carbon::now()->format('Y-m-d'); + + //if ($lastOfMonth != $dayOfMonth) { + //$this->alert(date('Y-m-d H:i:s') . ' : ' . $lastOfMonth . ' - ' . $dayOfMonth); + //return false; + //} + + + //$period = Carbon::parse($dayOfMonth)->lastOfMonth()->format('Y-m'); + //$periodList = [$period]; + + $year = Carbon::now()->year; + $currentMonth = Carbon::now()->month; + $periodList = []; + for ($month = $currentMonth; $month <= 12; $month++) { + $periodList[] = Carbon::create($year, $month, 1)->format('Y-m'); + } + + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $propertyList = Property::where('commission', '>', 1) + ->whereIn('status', [1,3]) + //->whereIn('id', [1810]) + ->get()->toArray(); + + foreach ($periodList as $period) { + + $this->alert('PERIOD: ' . $period); + + foreach ($propertyList as $property) { + + try { + + $invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod($property['id'], $period); + + if ($invoiceWithPeriod['status'] == 'success') { + $this->info(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $property['name'] . ' : ' . $period . ' - ' . $invoiceWithPeriod['data']['total'] . ' ' . $invoiceWithPeriod['data']['currency']); + } else { + $this->error(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $invoiceWithPeriod['message']); + } + + + } catch (ApiErrorException | Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage() . ' - ' . $property['id'] . ' - ' . $property['name']); + } + + } + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/PropertySummaryService.php b/app/Console/Commands/Jobs/PropertySummaryService.php new file mode 100644 index 0000000..95c6eda --- /dev/null +++ b/app/Console/Commands/Jobs/PropertySummaryService.php @@ -0,0 +1,124 @@ +firstOfMonth()->toDateString(); + $lastDayOfYear = Carbon::parse($lastAllOfYear)->firstOfMonth()->toDateString(); + + $diffInPeriod = Carbon::parse($startDayOfYear)->diffInMonths(Carbon::parse($lastDayOfYear)); + + $periodList = []; + for ($i = 0; $i < $diffInPeriod; $i++) { + $periodList[] = Carbon::parse($firstAllOfYear)->addMonths($i)->format('Y-m'); + }*/ + //$periodList[] = '2025-09'; + //BULK + + //$invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod(623, '2025-10'); + //dd($invoiceWithPeriod); + //$periodList = ['2025-09']; + + //$lastOfMonth = '2025-10-30'; + //$dayOfMonth = '2025-10-30'; + + //$lastOfMonth = Carbon::now()->lastOfMonth()->format('Y-m-d'); + //$dayOfMonth = Carbon::now()->format('Y-m-d'); + + //if ($lastOfMonth != $dayOfMonth) { + //$this->alert(date('Y-m-d H:i:s') . ' : ' . $lastOfMonth . ' - ' . $dayOfMonth); + //return false; + //} + + + //$period = Carbon::parse($dayOfMonth)->lastOfMonth()->format('Y-m'); + //$periodList = [$period]; + + $year = Carbon::now()->year; + $currentMonth = Carbon::now()->month; + $periodList = []; + for ($month = $currentMonth; $month <= 12; $month++) { + $periodList[] = Carbon::create($year, $month, 1)->format('Y-m'); + } + + //$periodList = ['2025-03']; + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $propertyList = Property::where('commission', '>', 1) + ->where('status', 1) + //->whereIn('id', [71]) + ->get()->toArray(); + + $types[1] = 'Checkout'; + $types[2] = 'Transaction'; + foreach ($periodList as $period) { + + $this->alert('PERIOD: ' . $period); + + foreach ($propertyList as $property) { + + try { + + foreach ($types as $typeCode => $type) { + + $invoiceWithPeriod = $propertySummaryService->summaryWithPeriod($property['id'], $period, $typeCode); + + if ($invoiceWithPeriod['status'] == 'success') { + $this->info(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $property['name'] . ' : ' . $type . ' : ' . $period . ' - ' . $invoiceWithPeriod['data']['total'] . ' ' . $invoiceWithPeriod['data']['currency']); + } else { + $this->error(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $invoiceWithPeriod['message']); + } + + } + + + } catch (ApiErrorException | Exception $e) { + $this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage() . ' - ' . $property['id'] . ' - ' . $property['name']); + } + + } + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/SummaryReportMail.php b/app/Console/Commands/Jobs/SummaryReportMail.php new file mode 100644 index 0000000..151e199 --- /dev/null +++ b/app/Console/Commands/Jobs/SummaryReportMail.php @@ -0,0 +1,386 @@ +mailer = $mailer; + $this->propertyService = $propertyService; + $this->currencyService = $currencyService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $today = Carbon::now()->subDay()->toDateString(); + + $report['daily']['data'] = []; + $report['daily']['title'] = 'Daily Report'; + $report['daily']['period'] = Carbon::parse($today)->format('d.m.Y'); + $daily = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->toDateString()) + ->where('time', '<', Carbon::parse($today)->addDay()->toDateString()) + ->where('commission', '>', 0) + ->get()->toArray(); + + if ($daily) { + $dataCollect = collect($daily); + $dataCollect = $dataCollect->filter(function ($item) { + if ($item['property_id'] == 362) { + //Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet + if (!in_array($item['channel_id'], [34, 103])) { + return $item; + } + } else if ($item['property_id'] == 712) { + //Exclude Commission - G Hotels Skopje + if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) { + return $item; + } + } else { + return $item; + } + }); + + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['daily']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['daily']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + $report['daily']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup)); + } + + $report['daily']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0]; + foreach ($report['daily']['data'] as $currentCurrency => $dailyData) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR'); + $report['daily']['summary']['count'] += $dailyData['count']; + $report['daily']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data']; + $report['daily']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data']; + } + } + + + $report['monthly']['data'] = []; + $report['monthly']['title'] = 'Monthly Report'; + $report['monthly']['period'] = Carbon::parse($today)->firstOfMonth()->format('m.Y'); + $monthly = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfMonth()->toDateString()) + ->where('time', '<', Carbon::parse($today)->addMonth()->firstOfMonth()->toDateString()) + ->where('commission', '>', 0) + ->get()->toArray(); + + if ($monthly) { + $dataCollect = collect($monthly); + $dataCollect = $dataCollect->filter(function ($item) { + if ($item['property_id'] == 362) { + //Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet + if (!in_array($item['channel_id'], [34, 103])) { + return $item; + } + } else if ($item['property_id'] == 712) { + //Exclude Commission - G Hotels Skopje + if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) { + return $item; + } + } else { + return $item; + } + }); + + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['monthly']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['monthly']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + $report['monthly']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup)); + } + + $report['monthly']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0]; + foreach ($report['monthly']['data'] as $currentCurrency => $dailyData) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR'); + $report['monthly']['summary']['count'] += $dailyData['count']; + $report['monthly']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data']; + $report['monthly']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data']; + } + + + //summaryCheckout + $monthlyCheckout = vwBookingSummaryAll::where('checkout_period', Carbon::parse($today)->firstOfMonth()->format('Y-m')) + ->where('commission', '>', 0) + ->get()->toArray(); + + $dataCollect = collect($monthlyCheckout); + $dataCollect = $dataCollect->filter(function ($item) { + if ($item['property_id'] == 362) { + //Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet + if (!in_array($item['channel_id'], [34, 103])) { + return $item; + } + } else if ($item['property_id'] == 712) { + //Exclude Commission - G Hotels Skopje + if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) { + return $item; + } + } else { + return $item; + } + }); + + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['monthly']['summaryCheckoutData'][$currencyCode]['count'] = count($currencyGroup); + $report['monthly']['summaryCheckoutData'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + $report['monthly']['summaryCheckoutData'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup)); + } + + $report['monthly']['summaryCheckout'] = ['count' => 0, 'total' => 0, 'commission' => 0]; + foreach ($report['monthly']['summaryCheckoutData'] as $currentCurrency => $dailyData) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR'); + $report['monthly']['summaryCheckout']['count'] += $dailyData['count']; + $report['monthly']['summaryCheckout']['total'] += $dailyData['total'] * $lastExchangeRate['data']; + $report['monthly']['summaryCheckout']['commission'] += $dailyData['commission'] * $lastExchangeRate['data']; + } + + $monthlySummary = []; + $annuallyMonths = []; + for ($i = 0; $i < 12; $i++) { + $annuallyMonths[] = Carbon::parse($today)->firstOfYear()->addMonths($i)->format('Y-m'); + } + + $vwBookingSummaryTransaction = vwBookingSummaryAll::whereIn('transaction_period',$annuallyMonths) + ->where('commission', '>', 0) + ->get()->toArray(); + + $vwBookingSummaryCheckout = vwBookingSummaryAll::whereIn('checkout_period',$annuallyMonths) + ->where('commission', '>', 0) + ->get()->toArray(); + + + $vwBookingSummaryTransactionGrouped = collect($vwBookingSummaryTransaction)->groupBy('transaction_period')->toArray(); + $vwBookingSummaryCheckoutGrouped = collect($vwBookingSummaryCheckout)->groupBy('checkout_period')->toArray(); + + + $monthlySummary['month'] = []; + foreach ($annuallyMonths as $annuallyMonth) { + //$annuallyMonth = Carbon::parse($annuallyMonth)->format('Y-m'); + + $monthlySummary['month'][$annuallyMonth] = $annuallyMonth; + + $monthlySummary['transaction'][$annuallyMonth]['count'] = 0; + $monthlySummary['transaction'][$annuallyMonth]['total'] = 0; + $monthlySummary['transaction'][$annuallyMonth]['commission'] = 0; + if(isset($vwBookingSummaryTransactionGrouped[$annuallyMonth])) { + $dataCollectGroupCurrency = collect($vwBookingSummaryTransactionGrouped[$annuallyMonth])->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR'); + $monthlySummary['transaction'][$annuallyMonth]['count'] += collect($currencyGroup)->count(); + $monthlySummary['transaction'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data']; + $monthlySummary['transaction'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data']; + + } + } + + $monthlySummary['checkout'][$annuallyMonth]['count'] = 0; + $monthlySummary['checkout'][$annuallyMonth]['total'] = 0; + $monthlySummary['checkout'][$annuallyMonth]['commission'] = 0; + if(isset($vwBookingSummaryCheckoutGrouped[$annuallyMonth])) { + $dataCollectGroupCurrency = collect($vwBookingSummaryCheckoutGrouped[$annuallyMonth])->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR'); + $monthlySummary['checkout'][$annuallyMonth]['count'] += collect($currencyGroup)->count(); + $monthlySummary['checkout'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data']; + $monthlySummary['checkout'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data']; + + } + } + + } + + $report['monthlySummary'] = $monthlySummary; + + } + + $report['annually']['data'] = []; + $report['annually']['title'] = 'Annually Report'; + $report['annually']['period'] = Carbon::parse($today)->firstOfYear()->format('Y'); + $annually = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfYear()->toDateString()) + ->where('time', '<', Carbon::parse($today)->addYear()->firstOfYear()->toDateString()) + ->where('commission', '>', 0) + ->get()->toArray(); + + if ($annually) { + $dataCollect = collect($annually); + $dataCollect = $dataCollect->filter(function ($item) { + if ($item['property_id'] == 362) { + //Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet + if (!in_array($item['channel_id'], [34, 103])) { + return $item; + } + } else if ($item['property_id'] == 712) { + //Exclude Commission - G Hotels Skopje + if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) { + return $item; + } + } else { + return $item; + } + }); + + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['annually']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['annually']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + $report['annually']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup)); + } + + $report['annually']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0]; + foreach ($report['annually']['data'] as $currentCurrency => $dailyData) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR'); + $report['annually']['summary']['count'] += $dailyData['count']; + $report['annually']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data']; + $report['annually']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data']; + } + + + //summaryCheckout Annually + + $annuallyCheckout = vwBookingSummaryAll::where('checkout_date', '>=', Carbon::parse($today)->firstOfYear()->format('Y-m-d')) + ->where('checkout_date', '<=', Carbon::parse($today)->endOfYear()->format('Y-m-d')) + ->where('commission', '>', 0) + ->get()->toArray(); + + $dataCollect = collect($annuallyCheckout); + $dataCollect = $dataCollect->filter(function ($item) { + if ($item['property_id'] == 362) { + //Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet + if (!in_array($item['channel_id'], [34, 103])) { + return $item; + } + } else if ($item['property_id'] == 712) { + //Exclude Commission - G Hotels Skopje + if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) { + return $item; + } + } else { + return $item; + } + }); + + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['annually']['summaryCheckoutData'][$currencyCode]['count'] = count($currencyGroup); + $report['annually']['summaryCheckoutData'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + $report['annually']['summaryCheckoutData'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup)); + } + + $report['annually']['summaryCheckout'] = ['count' => 0, 'total' => 0, 'commission' => 0]; + foreach ($report['annually']['summaryCheckoutData'] as $currentCurrency => $dailyData) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR'); + $report['annually']['summaryCheckout']['count'] += $dailyData['count']; + $report['annually']['summaryCheckout']['total'] += $dailyData['total'] * $lastExchangeRate['data']; + $report['annually']['summaryCheckout']['commission'] += $dailyData['commission'] * $lastExchangeRate['data']; + } + + } + + //Hotel LIST + $vwActivePropertySummary = []; + $vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->orderByDesc('id')->get()->toArray(); + $vwActivePropertySummary['count'] = count($vwActiveProperty); + $vwActivePropertySummary['groupByMonth'] = collect($vwActiveProperty)->sortByDesc('month')->groupBy('month')->toArray(); + $vwActivePropertySummary['lastMonth'] = collect($vwActivePropertySummary['groupByMonth'])->take(12)->toArray(); + + if ($vwActivePropertySummary['lastMonth']) { + foreach ($vwActivePropertySummary['lastMonth'] as $lastMonthKey => $lastMonth) { + $vwActivePropertySummary['lastMonth'][$lastMonthKey] = collect($vwActivePropertySummary['lastMonth'][$lastMonthKey])->sortByDesc('id')->toArray(); + if ($vwActivePropertySummary['lastMonth'][$lastMonthKey]) { + $vwActivePropertySummary['lastMonth'][$lastMonthKey] = array_values($vwActivePropertySummary['lastMonth'][$lastMonthKey]); + } + } + } + + //Hotel LIST + + $report['activeProperty'] = $vwActivePropertySummary; + + //Comparative Summary Data + //Carbon::setLocale('tr'); + for ($month = 1; $month <= 12; $month++) { + $months[$month] = Carbon::create(null, $month, 1)->translatedFormat('F'); + } + $report['comparative']['monthList'] = $months; + + $currentYear = Carbon::parse($today)->firstOfYear()->format('Y'); + $lastYear = Carbon::parse($today)->subYear()->firstOfYear()->format('Y'); + + $report['comparative']['yearList'][] = $lastYear; + $report['comparative']['yearList'][] = $currentYear; + + $periodList = []; + foreach ([$currentYear,$lastYear] as $periodYear) { + for ($month = 1; $month <= 12; $month++) { + $periodList[] = $periodYear . '-' . str_pad((integer)$month, 2, '0', STR_PAD_LEFT); + } + } + + $propertyInvoice = PropertyInvoice::where('status',1)->whereIn('period', $periodList); + $propertyInvoice = $propertyInvoice ? $propertyInvoice->get()->toArray() : []; + + foreach ($propertyInvoice as $invoice) { + $periodYear = Carbon::parse($invoice['period'])->format('Y'); + $periodMonth = (int)Carbon::parse($invoice['period'])->format('m'); + if(!isset($report['comparative']['data'][$periodYear][$periodMonth])) { + $report['comparative']['data'][$periodYear][$periodMonth] = 0; + } + $report['comparative']['data'][$periodYear][$periodMonth]+=$invoice['total']; + } + + $comparativeDiff = []; + foreach ($months as $monthKey => $month) { + $comparativeDiff[$monthKey]['amount'] = $report['comparative']['data'][$currentYear][$monthKey] - $report['comparative']['data'][$lastYear][$monthKey]; + } + $report['comparative']['diff'] = $comparativeDiff; + //Comparative Summary Data + + + //$json = json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + //file_put_contents(resource_path('data/data.json'), $json); + //die(); + + $this->mailer->onQueue('dailyReportMail', new DailyReportMail($report)); + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/Jobs/SummaryReportMailSales.php b/app/Console/Commands/Jobs/SummaryReportMailSales.php new file mode 100644 index 0000000..0129ff7 --- /dev/null +++ b/app/Console/Commands/Jobs/SummaryReportMailSales.php @@ -0,0 +1,310 @@ +mailer = $mailer; + $this->propertyService = $propertyService; + $this->currencyService = $currencyService; + $this->userService = $userService; + } + + public function reportCalculate($userId, $contractUserProperty, $type) + { + + $today = Carbon::now()->subDay()->toDateString(); + + $report = ['data' => null, 'summary' => null]; + + + switch ($type) { + + case 'daily': + $vwBookingSummaryAll = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->toDateString()) + ->where('time', '<', Carbon::parse($today)->addDay()->toDateString()) + ->where('commission', '>', 0) + ->where('contract_user_id', $userId) + ->whereIn('property_id', $contractUserProperty) + ->get()->toArray(); + break; + + case 'monthly': + + $monthlySummary = []; + $annuallyMonths = []; + for ($i = 0; $i < 12; $i++) { + $annuallyMonths[] = Carbon::parse($today)->firstOfYear()->addMonths($i)->format('Y-m'); + } + + $vwBookingSummaryAll = vwBookingSummaryAll::whereIn('transaction_period', [Carbon::parse($today)->firstOfMonth()->format('Y-m')]) + ->where('commission', '>', 0) + ->where('contract_user_id', $userId) + ->whereIn('property_id', $contractUserProperty) + ->get()->toArray(); + + $vwBookingSummaryTransaction = vwBookingSummaryAll::whereIn('transaction_period', $annuallyMonths) + ->where('commission', '>', 0) + ->where('contract_user_id', $userId) + ->whereIn('property_id', $contractUserProperty) + ->get()->toArray(); + + $vwBookingSummaryCheckout = vwBookingSummaryAll::whereIn('checkout_period', $annuallyMonths) + ->where('commission', '>', 0) + ->where('contract_user_id', $userId) + ->whereIn('property_id', $contractUserProperty) + ->get()->toArray(); + + + $vwBookingSummaryTransactionGrouped = collect($vwBookingSummaryTransaction)->groupBy('transaction_period')->toArray(); + $vwBookingSummaryCheckoutGrouped = collect($vwBookingSummaryCheckout)->groupBy('checkout_period')->toArray(); + + $monthlySummary['month'] = []; + foreach ($annuallyMonths as $annuallyMonth) { + $annuallyMonth = Carbon::parse($annuallyMonth)->format('Y-m'); + + $monthlySummary['month'][$annuallyMonth] = $annuallyMonth; + + $monthlySummary['transaction'][$annuallyMonth]['count'] = 0; + $monthlySummary['transaction'][$annuallyMonth]['total'] = 0; + $monthlySummary['transaction'][$annuallyMonth]['commission'] = 0; + if(isset($vwBookingSummaryTransactionGrouped[$annuallyMonth])) { + $dataCollectGroupCurrency = collect($vwBookingSummaryTransactionGrouped[$annuallyMonth])->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR'); + $monthlySummary['transaction'][$annuallyMonth]['count'] += collect($currencyGroup)->count(); + $monthlySummary['transaction'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data']; + $monthlySummary['transaction'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data']; + + } + } + + $monthlySummary['checkout'][$annuallyMonth]['count'] = 0; + $monthlySummary['checkout'][$annuallyMonth]['total'] = 0; + $monthlySummary['checkout'][$annuallyMonth]['commission'] = 0; + if(isset($vwBookingSummaryCheckoutGrouped[$annuallyMonth])) { + $dataCollectGroupCurrency = collect($vwBookingSummaryCheckoutGrouped[$annuallyMonth])->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR'); + $monthlySummary['checkout'][$annuallyMonth]['count'] += collect($currencyGroup)->count(); + $monthlySummary['checkout'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data']; + $monthlySummary['checkout'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data']; + + } + } + + } + + $report['monthlySummary'] = $monthlySummary; + + break; + + case 'annually': + $vwBookingSummaryAll = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfYear()->toDateString()) + ->where('time', '<', Carbon::parse($today)->addYear()->firstOfYear()->toDateString()) + ->where('commission', '>', 0) + ->where('contract_user_id', $userId) + ->whereIn('property_id', $contractUserProperty) + ->get()->toArray(); + break; + } + + + if ($vwBookingSummaryAll) { + $dataCollect = collect($vwBookingSummaryAll); + + $dataCollectGroup = $dataCollect->groupBy('property_id')->toArray(); + foreach ($dataCollectGroup as $propertyId => $propertyList) { + + $property = reset($propertyList); + $report['data'][$propertyId]['id'] = $property['property_id']; + $report['data'][$propertyId]['name'] = $property['property_name']; + + $report['data'][$propertyId]['count'] = 0; + $report['data'][$propertyId]['total'] = 0; + $report['data'][$propertyId]['commission'] = 0; + + $dataCollectGroupCurrency = collect($propertyList)->groupBy('currency_code')->toArray(); + + foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR'); + + $count = collect($currencyGroup)->count(); + $total = collect($currencyGroup)->sum('total'); + $commission = collect($currencyGroup)->sum('commission'); + + $report['data'][$propertyId]['count'] += $count; + $report['data'][$propertyId]['total'] += $total * $lastExchangeRate['data']; + $report['data'][$propertyId]['commission'] += $commission * $lastExchangeRate['data']; + + } + } + + $report['data'] = collect($report['data'])->sortByDesc('commission')->toArray(); + + $report['summary']['count'] = collect($report['data'])->sum('count'); + $report['summary']['total'] = collect($report['data'])->sum('total'); + $report['summary']['commission'] = collect($report['data'])->sum('commission'); + + } + + + return $report; + + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $today = Carbon::now()->subDay()->toDateString(); + + $userListIds = [904, 941, 1485];//41, 22, 883 + + $userListCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'id', 'value' => $userListIds] + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + $userList = $this->userService->select($userListCriteria); + + foreach ($userList['data'] as $user) { + + $contractUserProperty = vwActiveProperty::where('contract_user_id', $user['id']) + //->where('month', '>', '2024-10') + ->get()->toArray(); + + $contractUserProperty = $contractUserProperty ? pickItemFromArray('id',$contractUserProperty) : []; + + $this->info(date('Y-m-d H:i:s') . ' : '.$user['nameSurname']); + + $report['name'] = $user['nameSurname']; + $report['email'] = $user['email']; + + + //DAILY + $report['daily']['data'] = []; + $report['daily']['title'] = 'Daily Report'; + $report['daily']['type'] = 'daily'; + $report['daily']['period'] = Carbon::parse($today)->format('d.m.Y'); + + $reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['daily']['type']); + + $report['daily']['data'] = $reportCalculate['data']; + $report['daily']['summary'] = $reportCalculate['summary']; + + + + + //MONTHLY + $report['monthly']['data'] = []; + $report['monthly']['title'] = 'Monthly Report'; + $report['monthly']['type'] = 'monthly'; + $report['monthly']['period'] = Carbon::parse($today)->firstOfMonth()->format('m.Y'); + + $reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['monthly']['type']); + + $report['monthly']['data'] = $reportCalculate['data']; + $report['monthly']['summary'] = $reportCalculate['summary']; + $report['monthlySummary'] = $reportCalculate['monthlySummary']; + + + //ANNUALLY + $report['annually']['data'] = []; + $report['annually']['title'] = 'Annually Report'; + $report['annually']['type'] = 'annually'; + $report['annually']['period'] = Carbon::parse($today)->firstOfYear()->format('Y'); + + $reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['annually']['type']); + + $report['annually']['data'] = $reportCalculate['data']; + $report['annually']['summary'] = $reportCalculate['summary']; + + $report['activeProperty'] = vwActiveProperty::where('commission', '>', 1) + ->where('contract_user_id', $user['id']) + ->whereIn('id', $contractUserProperty) + ->orderByDesc('id') + ->get()->toArray(); + + + //Property Price Comparison + $priceComparisonLink = null; + $todayComparison = Carbon::now()->toDateString(); + $firstDayOfWeek = Carbon::parse($todayComparison)->startOfWeek(Carbon::MONDAY); + //$firstDayOfWeek = Carbon::parse($today)->startOfWeek(Carbon::MONDAY)->toDateString(); + + //if(Carbon::now()->toDateString() == $firstDayOfWeek) { + $year = Carbon::parse($firstDayOfWeek)->format('Y'); + $week = Carbon::parse($firstDayOfWeek)->isoWeek(); + $queryKeyHash = md5($year . '-' . $week); + $priceComparisonLink = config('app.url').'/property-comparison/'.$queryKeyHash.'/'.$user['id']; + //} + $report['priceComparisonLink'] = $priceComparisonLink; + //Property Price Comparison + + + $this->mailer->onQueue('dailyReportSalesMail', new DailyReportMailSales($report)); + + + } + + //Hotel LIST + /*$vwActivePropertySummary = []; + $vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->get()->toArray(); + $vwActivePropertySummary['count'] = count($vwActiveProperty); + $vwActivePropertySummary['groupByMonth'] = collect($vwActiveProperty)->sortByDesc('month')->groupBy('month')->toArray(); + $vwActivePropertySummary['lastMonth'] = collect($vwActivePropertySummary['groupByMonth'])->take(3)->toArray(); + //Hotel LIST + + $report['activeProperty'] = $vwActivePropertySummary;*/ + + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/PropertyReviewService/PropertyReviewAnalyzeService.php b/app/Console/Commands/PropertyReviewService/PropertyReviewAnalyzeService.php new file mode 100644 index 0000000..df250f7 --- /dev/null +++ b/app/Console/Commands/PropertyReviewService/PropertyReviewAnalyzeService.php @@ -0,0 +1,239 @@ +restClient = new Client(['http_errors' => false]); + + } + + protected function requestService($params = []) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $client = new \GuzzleHttp\Client([ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['https'], + 'timeout' => 30, + 'headers' => [ + 'Authorization' => 'Bearer ' . config('app.openAISecretKey'), + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache', + 'Connection' => 'keep-alive', + 'Accept-Encoding' => 'gzip' + ] + ] + ); + + + $result = $client->post('https://api.openai.com/v1/chat/completions', [ + 'body' => json_encode($params['query']) + ]); + + $result = $result->getBody()->getContents(); + $result = json_decode($result, 1); + + $choiceMessage = reset($result['choices']); + + if (isset($choiceMessage['message']['content'])) { + $choiceMessage = json_decode($choiceMessage['message']['content'], 1); + $data = $choiceMessage; + } + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return $response; + + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + + //420 + + $propertyReview = PropertyReview::where('id', $this->argument('review_id')) + ->with('channel') + ->with('property') + ->first(); + + $propertyReview = $propertyReview ? $propertyReview->toArray() : null; + + if (!$propertyReview) { + Log::error('Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']); + return false; + } + + + $propertyReviewCategory = PropertyReviewCategory::where('status', 1)->select(['id', 'name'])->get()->toArray(); + $propertyReviewCategoryText = implode(', ', collect($propertyReviewCategory)->pluck('name')->toArray()); + + + $params['query'] = [ + 'model' => 'gpt-4o', + 'response_format' => [ + 'type' => 'json_object' + ], + 'messages' => [ + [ + 'role' => 'system', + 'content' => 'Sen bir otel gelir yönetimi uzmanısın ve otellere yapılan yorumları değerlendiriyosun. Cevaplar SADECE JSON formatında. Yorumu genel olarak değerlendirip, misafir gibi düşünüp 0: olumsuz,1: olumlu olacak şekilde sentiment alanında işaretleyelim. Gelen yorumları \"' . $propertyReviewCategoryText . '\" kategorilerine göre categories alanında işaretleyip gruplayalım. Her bir gruplanan kategori için de 0: olumsuz,1: olumlu olacak şekilde işaretleyelim, ilgisiz kategorileri eklemeyelim. keywords alanında bu yorum ile ilgili kilit kelimeleri, ileride kelime bulutu yapmak için ingilizce çıkaralım,kelimeler otel ve otelcilik ile ilgili olsun, kelimeler normal metin şeklinde, aralıkları boşluklu ve sadece ilk harfleri büyük olsun, bu kelimeler için de 0: olumsuz,1: olumlu olacak şekilde işaretleyelim. Yorumu da language parametresi altında 2 haneli ISO koduna göre verelim.' + ], + [ + 'role' => 'user', + 'content' => $propertyReview['review'] + ] + ] + + ]; + + $propertyReviewAnalyze = $this->requestService($params); + //$propertyReviewAnalyze = json_decode('{"status":true,"data":{"sentiment":0,"categories":{"Location":0,"Breakfast":0,"Service":1,"Cleanliness":1,"Room Facilities":0},"keywords":{"Location":0,"Breakfast":0,"Service Quality":1,"Cleaning":1,"Room Amenities":0}}}', 1); + + if ($propertyReviewAnalyze['status']) { + + + DB::beginTransaction(); + + $transactionSave = false; + + try { + + + $this->info(date('Y-m-d H:i:s') . ': Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']); + + PropertyReview::where('id', $propertyReview['id'])->update(['sentiment' => $propertyReviewAnalyze['data']['sentiment'], 'language' => $propertyReviewAnalyze['data']['language']]); + + //PropertyReviewCategoryMapping + $this->info(date('Y-m-d H:i:s') . ': Property Review Category Mapping: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']); + $bulkReviewCategoryMapping = []; + PropertyReviewCategoryMapping::where('review_id', $propertyReview['id'])->delete(); + foreach ($propertyReviewAnalyze['data']['categories'] as $category => $categorySentiment) { + + $categorySelected = collect($propertyReviewCategory)->where('name', $category)->first(); + + if (isset($categorySelected['id'])) { + + $bulkReviewCategoryMapping[] = [ + 'review_id' => $propertyReview['id'], + 'property_id' => $propertyReview['property_id'], + 'channel_id' => $propertyReview['channel_id'], + 'category_id' => $categorySelected['id'], + 'sentiment' => $categorySentiment, + 'review_date' => $propertyReview['review_date'], + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + } + } + + if (!empty($bulkReviewCategoryMapping)) { + PropertyReviewCategoryMapping::insert($bulkReviewCategoryMapping); + } + //PropertyReviewCategoryMapping + + + //PropertyReviewKeywordMapping + if (is_array($propertyReviewAnalyze['data']['keywords'])) { + $this->info(date('Y-m-d H:i:s') . ': Property Review Keyword Mapping: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']); + $bulkReviewKeywordMapping = []; + PropertyReviewKeywordMapping::where('review_id', $propertyReview['id'])->delete(); + foreach ($propertyReviewAnalyze['data']['keywords'] as $keyword => $keywordSentiment) { + + $bulkReviewKeywordMapping[] = [ + 'review_id' => $propertyReview['id'], + 'property_id' => $propertyReview['property_id'], + 'channel_id' => $propertyReview['channel_id'], + 'keyword' => $keyword, + 'sentiment' => $keywordSentiment, + 'review_date' => $propertyReview['review_date'], + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + } + + if (!empty($bulkReviewKeywordMapping)) { + PropertyReviewKeywordMapping::insert($bulkReviewKeywordMapping); + } + } + //PropertyReviewKeywordMapping + + + //throw new Exception('Booking Room could not be made'); + + $transactionSave = true; + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $transactionSave = false; + } + + if ($transactionSave) { + DB::commit(); + } else { + DB::rollBack(); + } + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/PropertyReviewService/PropertyReviewScheduleService.php b/app/Console/Commands/PropertyReviewService/PropertyReviewScheduleService.php new file mode 100644 index 0000000..eb88d54 --- /dev/null +++ b/app/Console/Commands/PropertyReviewService/PropertyReviewScheduleService.php @@ -0,0 +1,62 @@ +info(date('Y-m-d H:i:s') . ' START'); + + + $propertyReviewChannelMapping = PropertyReviewChannelMapping::where('status', 1) + ->with('channel') + ->with('property') + ->get(); + + $propertyReviewChannelMapping = $propertyReviewChannelMapping ? $propertyReviewChannelMapping->toArray() : null; + + foreach ($propertyReviewChannelMapping as $propertyReview) { + + if (Carbon::createFromTimestamp($propertyReview['created_at'])->dayName != Carbon::now()->dayName) { + continue; + } + + $this->info(date('Y-m-d H:i:s') . ' Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']); + + dispatch(new PropertyReviewServiceJob($propertyReview['property_id'], $propertyReview['channel_id'])); + + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/PropertyReviewService/PropertyReviewService.php b/app/Console/Commands/PropertyReviewService/PropertyReviewService.php new file mode 100644 index 0000000..06e2b31 --- /dev/null +++ b/app/Console/Commands/PropertyReviewService/PropertyReviewService.php @@ -0,0 +1,738 @@ +restClient = new Client(['http_errors' => false]); + + } + + protected function requestService($params) + { + + try { + + $requestUrl = $params['requestUrl']; + $requestParams['headers']['x-api-key'] = $this->xApiKey; + $requestParams['headers']['Content-Type'] = 'application/json'; + + unset($params['requestUrl']); + $requestParams['query'] = $params; + + $result = $this->restClient->request('GET', $requestUrl, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + //$getResponseData = json_decode(file_get_contents(storage_path() . '/response.json'), 1); + //$getResponseData = json_decode(file_get_contents(storage_path() . '/google.json'), 1); + //$getResponseData = json_decode(file_get_contents(storage_path() . '/Tripadvisor.json'), 1); + //$getResponseData = json_decode(file_get_contents(storage_path() . '/Tripadvisor.json'), 1); + + if (isset($getResponseData['error'])) { + throw new ApiErrorException($getResponseData['detail']); + } + + $response['status'] = true; + $response['data'] = $getResponseData; + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + dd($response); + + } + + return $response; + + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $propertyReviewChannelMapping = PropertyReviewChannelMapping::where('property_id', $this->argument('property_id')) + ->where('channel_id', $this->argument('channel_id')) + ->with('channel') + ->with('property') + ->first(); + + $propertyReviewChannelMapping = $propertyReviewChannelMapping ? $propertyReviewChannelMapping->toArray() : null; + + Log::debug('Property Review: ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + switch ($propertyReviewChannelMapping['channel_id']) { + + //BookingCom + case '1': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/booking/hotel/reviews', + 'hotel_id' => $propertyReviewChannelMapping['parameterArray']['hotelId'], + 'sort' => 'newest', + 'per_page' => 20, + 'page' => ($i + 1) + ]; + + $requestReview = $this->requestService($requestParams); + + //$bulkReview = []; + if ($requestReview['status']) { + + foreach ($requestReview['data']['data']['reviews'] as $review) { + + try { + + if (empty($review['review']['positive']) && empty($review['review']['negative'])) { + continue; + } + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['id'], + 'author' => $review['guest']['name'], + 'title' => fillOnUndefined($review['review'], 'title'), + 'review' => $review['review']['positive'] . ' ' . $review['review']['negative'], + 'review_date' => Carbon::parse($review['reviewed_date'])->toDateTimeString(), + 'rating' => $review['score'], + 'top_rating' => 10, + 'score' => number_format($review['score'] / 10 * 100, 2), + 'language' => $review['review']['language'], + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //Google + case '2': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/google_reviews/reviews-paginated', + 'data_id' => $propertyReviewChannelMapping['parameterArray']['dataId'], + 'sort_by' => 'newest', + 'pages' => 10 + ]; + + $requestReview = $this->requestService($requestParams); + + + if ($requestReview['status']) { + + foreach ($requestReview['data']['reviews'] as $review) { + + if (empty($review['text'])) { + continue; + } + + try { + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['review_id'], + 'author' => $review['reviewer']['name'], + 'title' => null, + 'review' => $review['text'], + 'review_date' => Carbon::parse($review['iso_date'])->toDateTimeString(), + 'rating' => $review['rating'], + 'top_rating' => 5, + 'score' => number_format($review['rating'] / 5 * 100, 2), + 'language' => null, + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //Tripadvisor + case '3': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/tripadvisor/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'], + 'per_page' => 20, + 'page' => ($i + 1) + ]; + + $requestReview = $this->requestService($requestParams); + + if ($requestReview['status']) { + + foreach ($requestReview['data']['reviews'] as $review) { + + if (!fillOnUndefined($review, 'text')) { + continue; + } + + try { + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['id'], + 'author' => $review['user']['display_name'], + 'title' => fillOnUndefined($review, 'title'), + 'review' => fillOnUndefined($review, 'text'), + 'review_date' => Carbon::parse($review['created_date'])->toDateTimeString(), + 'rating' => $review['rating'], + 'top_rating' => 5, + 'score' => number_format($review['rating'] / 5 * 100, 2), + 'language' => fillOnUndefined($review, 'language'), + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //Agoda + case '4': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/agoda/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'], + 'page' => ($i + 1) + ]; + + $requestReview = $this->requestService($requestParams); + + + if ($requestReview['status']) { + + foreach ($requestReview['data']['reviews'] as $review) { + + if (!fillOnUndefined($review, 'comment')) { + continue; + } + + try { + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['review_id'], + 'author' => null, + 'title' => fillOnUndefined($review, 'title'), + 'review' => fillOnUndefined($review, 'comment'), + 'review_date' => Carbon::parse($review['date'])->toDateTimeString(), + 'rating' => $review['rating'], + 'top_rating' => 10, + 'score' => number_format($review['rating'] / 10 * 100, 2), + 'language' => fillOnUndefined($review, 'language'), + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //Trip.com + case '5': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/tripcom/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'], + 'page' => ($i + 1), + 'page_size' => 50 + ]; + + $requestReview = $this->requestService($requestParams); + + if ($requestReview['status']) { + + foreach ($requestReview['data']['data']['reviews'] as $review) { + + if (!fillOnUndefined($review, 'text')) { + continue; + } + + /* if ($review['source'] != 1) { + continue; + }*/ + + try { + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['id'], + 'author' => isset($review['reviewer_name']) ? $review['reviewer_name'] : null, + 'title' => fillOnUndefined($review, 'title'), + 'review' => fillOnUndefined($review, 'text'), + 'review_date' => Carbon::parse($review['date'])->toDateTimeString(), + 'rating' => $review['rating'], + 'top_rating' => 10, + 'score' => number_format($review['rating'] / 10 * 100, 2), + 'language' => fillOnUndefined($review, 'language'), + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //Expedia.com + case '6': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $requestParams = [ + 'requestUrl' => 'https://api.stayapi.com/v1/expedia/hotel/reviews', + 'property_id' => $propertyReviewChannelMapping['parameterArray']['hotelId'], + 'page' => $i, + 'page_size' => 5 + ]; + + $requestReview = $this->requestService($requestParams); + + if ($requestReview['status']) { + + foreach ($requestReview['data']['reviews'] as $review) { + + if (!fillOnUndefined($review, 'text')) { + continue; + } + + try { + + preg_match('/(\d+)\s*\/\s*(\d+)/', $review['rating'], $matches); + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => $review['id'], + 'author' => isset($review['reviewer_name']) ? $review['reviewer_name'] : null, + 'title' => fillOnUndefined($review, 'title'), + 'review' => fillOnUndefined($review, 'text'), + 'review_date' => Carbon::parse($review['review_date'])->toDateTimeString(), + 'rating' => (int)$matches[1], + 'top_rating' => 10, + 'score' => number_format((int)$matches[1] / 10 * 100, 2), + 'language' => fillOnUndefined($review, 'language'), + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + + //HolidayCheck + case '7': + + $this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']); + + $maxPageSize = 1; + + if ($propertyReviewChannelMapping['fetch_status'] == 3) { + $maxPageSize = $this->maxPageSize; + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]); + } + + + for ($i = 0; $i < $maxPageSize; $i++) { + + $hotelId = $propertyReviewChannelMapping['parameterArray']['hotelId']; + $limit = 10; + $offset = $i * $limit; + + $requestParams = [ + 'requestUrl' => "https://www.holidaycheck.de/api/hotel-reviews;filter=hotel.id:{$hotelId};limit={$limit};offset={$offset};select=id,user,title,texts,textAdvice,hotel,travelDate,recommendation,ratings,ranking,proofedReservation,ownerComment,additional,entryDate;sort=entryDate:desc", + ]; + + $requestReview = $this->requestService($requestParams); + + if ($requestReview['status']) { + + $reviews = isset($requestReview['data']['data']['items']) ? $requestReview['data']['data']['items'] : []; + + foreach ($reviews as $review) { + + $reviewText = fillOnUndefined($review, 'textAdvice'); + if (empty($reviewText)) { + $reviewText = fillOnUndefined($review, 'texts.GENERAL'); + } + + if (empty($reviewText)) { + continue; + } + + try { + + $rating = fillOnUndefined($review, 'ratings.GENERAL.GENERAL'); + + $author = fillOnUndefined($review, 'user.firstName'); + if (empty($author)) { + $author = fillOnUndefined($review, 'user.name'); + } + + $bulkReview = [ + 'property_id' => $propertyReviewChannelMapping['property_id'], + 'channel_id' => $propertyReviewChannelMapping['channel_id'], + 'channel_review_id' => fillOnUndefined($review, 'id'), + 'author' => $author, + 'title' => fillOnUndefined($review, 'title'), + 'review' => $reviewText, + 'review_date' => Carbon::createFromTimestampMs(fillOnUndefined($review, 'entryDate'))->toDateTimeString(), + 'rating' => $rating, + 'top_rating' => 6, + 'score' => number_format($rating / 6 * 100, 2), + 'language' => fillOnUndefined($review, 'originalLocale'), + 'detail' => json_encode($review), + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id']) + ->where('channel_id', $bulkReview['channel_id']) + ->where('channel_review_id', $bulkReview['channel_review_id']) + ->first(); + + if (!$propertyReviewCheck) { + $propertyReviewCreate = PropertyReview::create($bulkReview); + + dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id'])); + + $this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } else { + $this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']); + } + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + //dd($message); + } + + } + + } + + + } + + + PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]); + + break; + } + + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/PropertyTrialCheck/PropertyTrialCheck.php b/app/Console/Commands/PropertyTrialCheck/PropertyTrialCheck.php new file mode 100644 index 0000000..c2f9b56 --- /dev/null +++ b/app/Console/Commands/PropertyTrialCheck/PropertyTrialCheck.php @@ -0,0 +1,125 @@ +propertyService = $propertyService; + $this->productMappingService = $productMappingService; + } + + public function handle() + { + + $response = ['status' => false, 'message' => '']; + + $propertySelectCriteria = [ + 'criteria' => [ + //['field' => 'id', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'commission', 'condition' => '=', 'value' => null], + ['field' => 'created_at', 'condition' => '>', 'value' => Carbon::parse('2021-10-01')->timestamp], + + ], + 'with' => ['propertyProductMapping'], + 'orderBy' => [ + ["field" => "id", "value" => "ASC"] + ], + 'take' => 100 + ]; + + $propertyData = $this->propertyService->select($propertySelectCriteria); + + if ($propertyData['status'] == 'success') { + + foreach ($propertyData['data'] as $property) { + + + if (empty($property['property_product_mapping'])) { + continue; + } + + $expireDay = Carbon::now()->diff(Carbon::createFromTimestamp($property['created_at']))->days; + + $this->info(date('Y-m-d H:i:s') . ' Property: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $expireDay. ' Day'); + + if (in_array($expireDay, [30])) { + + DB::beginTransaction(); + + try { + + $this->info(date('Y-m-d H:i:s') . ' : Property: ' . $property['id'] . ' - ' . $property['name']); + + //Product remove from property + foreach ($property['property_product_mapping'] as $productMapping) { + $this->productMappingService->update($productMapping['id'], ['status' => 0]); + } + + //Trial period status + $propertyData = $this->propertyService->update($property['id'], ['status' => 2]); + + //Burada otel user larına mail atılabilir, trial süresi biti diye + + $response['status'] = true; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + } + + + //Expiration Check + //Product remove from property via expiration date + foreach ($property['property_product_mapping'] as $productMapping) { + + if($productMapping['status'] == 1 && !is_null($productMapping['expiration_date'])) { + if(Carbon::now()->greaterThanOrEqualTo(Carbon::parse($productMapping['expiration_date']))) { + $this->productMappingService->update($productMapping['id'], ['status' => 3]);} + + } + + } + + + + } + + + } + + } +} diff --git a/app/Console/Commands/PropertyTrialCheck/PropertyTrialMail.php b/app/Console/Commands/PropertyTrialCheck/PropertyTrialMail.php new file mode 100644 index 0000000..3c67bb8 --- /dev/null +++ b/app/Console/Commands/PropertyTrialCheck/PropertyTrialMail.php @@ -0,0 +1,83 @@ +mailer = $mailer; + $this->propertyService = $propertyService; + } + + public function handle() + { + + $this->info(date('Y-m-d H:i:s') . ' START'); + + $propertySelectCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'commission', 'condition' => '=', 'value' => null], + + ], + 'orderBy' => [ + ["field" => "id", "value" => "ASC"] + ], + ]; + + $propertyData = $this->propertyService->select($propertySelectCriteria); + + if ($propertyData['status'] == 'success') { + + foreach ($propertyData['data'] as $property) { + + $createDate = Carbon::createFromTimestamp($property['created_at'])->toDateTimeString(); + $expireDay = Carbon::now()->diff(Carbon::createFromTimestamp($property['created_at']))->days; + + if (in_array($expireDay, [4, 10])) { + + if ($expireDay == 4) { + $this->mailer->onQueue('trialFirstMail', new TrialFirstMail(['propertyId' => $property['id']])); + $this->info(date('Y-m-d H:i:s') . ' SENT Day 4: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $createDate); + } + + if ($expireDay == 10) { + $this->mailer->onQueue('trialSecondMail', new TrialSecondMail(['propertyId' => $property['id']])); + $this->info(date('Y-m-d H:i:s') . ' SENT Day 10: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $createDate); + } + + + } + + } + + } + + $this->info(date('Y-m-d H:i:s') . ' FINISHED'); + + + } +} diff --git a/app/Console/Commands/PropertyWebCheckDns/PropertyWebCheckDns.php b/app/Console/Commands/PropertyWebCheckDns/PropertyWebCheckDns.php new file mode 100644 index 0000000..7ce49c8 --- /dev/null +++ b/app/Console/Commands/PropertyWebCheckDns/PropertyWebCheckDns.php @@ -0,0 +1,57 @@ +propertyWebService = $propertyWebService; + parent::__construct(); + } + + public function handle() + { + + + try { + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Check DNS Status start'); + $process = $this->propertyWebService->checkDnsStatus(); + if($process['status'] != 'success'){ + throw new Exception($process['message']) ; + + } + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Check DNS Status finished'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + + + + + + + } + +} diff --git a/app/Console/Commands/PropertyWebMenuMapping/PropertyWebMenuMappingConsole.php b/app/Console/Commands/PropertyWebMenuMapping/PropertyWebMenuMappingConsole.php new file mode 100644 index 0000000..909d84a --- /dev/null +++ b/app/Console/Commands/PropertyWebMenuMapping/PropertyWebMenuMappingConsole.php @@ -0,0 +1,64 @@ +info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Start'); + + $webMenus = PropertyWebMenu::all(); + $webs = PropertyWeb::all(); + + $datas = []; + foreach ($webs as $key => $web){ + foreach ($webMenus as $key1 => $menu){ + $datas[$key][$key1]['property_id'] = $web->property_id; + $datas[$key][$key1]['property_web_id'] = $web->id; + $datas[$key][$key1]['property_web_menu_id'] = $menu->id; + $datas[$key][$key1]['order_number'] = $menu->order_number; + $datas[$key][$key1]['status'] = 1; + $datas[$key][$key1]['created_by'] = 1; + $datas[$key][$key1]['updated_by'] = 1; + $datas[$key][$key1]['created_at'] = 1; + $datas[$key][$key1]['updated_at'] = 1; + } + } + + PropertyWebMenuMapping::insert(collect($datas)->flatten(1)->toArray()); + + $this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Finished'); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message); + } + + } + +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php new file mode 100644 index 0000000..a2cf7e0 --- /dev/null +++ b/app/Console/Kernel.php @@ -0,0 +1,161 @@ +command('cron:mail-jobs') + ->withoutOverlapping() + ->everyMinute() + ->sendOutputTo(storage_path() . '/logs/cron-mail-jobs.log');*/ + + $schedule->command('cron:mail-jobs')->everyMinute(); + + $schedule->command('cron:currency-rates') + ->withoutOverlapping() + ->twiceDaily(2, 14) + //->everyMinute() + //->emailOutputTo('byumak@rezervasyon.com') + ->sendOutputTo(storage_path() . '/logs/cron-currency-rates.log'); + + $schedule->command('cron:roomrate-push-service')->everyMinute(); + $schedule->command('cron:roomavailability-push-service')->everyMinute(); + $schedule->command('cron:reservation-pull-service')->everyMinute(); + $schedule->command('cron:reservation-push-service')->everyMinute(); + + $schedule->command('cron:property-trial-check')->withoutOverlapping()->twiceDaily(9, 15); + $schedule->command('cron:property-trial-mail')->withoutOverlapping()->dailyAt('10:00'); + + //$schedule->command('queue:work')->everyMinute()->withoutOverlapping(); + $schedule->command('queue:restart')->hourly()->withoutOverlapping(); + + $schedule->command('cron:summary-report-mail')->dailyAt('00:05'); + $schedule->command('cron:summary-report-mail-sales')->dailyAt('09:00'); + $schedule->command('cron:remove-payment-token-service')->withoutOverlapping()->dailyAt('02:00'); + $schedule->command('cron:bookingengine-search-report-mail')->withoutOverlapping()->dailyAt('09:00'); + + $schedule->command('cron:propertymeta-roomrate-service')->withoutOverlapping()->dailyAt('03:00'); + $schedule->command('cron:propertymeta-roomrateprice-service')->withoutOverlapping()->dailyAt('05:00'); + $schedule->command('cron:propertymeta-roomratepush-service')->withoutOverlapping()->dailyAt('07:00'); + + //$schedule->command('cron:bar-sync-service')->withoutOverlapping()->cron('0 */2 * * *'); + $schedule->command('cron:bar-sync-service')->cron('0 */2 * * *'); + + $schedule->command('cron:price-comparison-service')->withoutOverlapping()->weekly()->mondays()->at('02:00'); + + $schedule->command('cron:commission-service')->everyTenMinutes(); + + $schedule->command('cron:weather')->withoutOverlapping()->twiceDaily(2, 14); + $schedule->command('cron:dashboard-cache')->withoutOverlapping()->dailyAt('03:00'); + $schedule->command('cron:google-static-map')->withoutOverlapping()->dailyAt('04:00'); + + $schedule->command('cron:google-review')->withoutOverlapping()->weekly()->mondays()->at('14:00'); + + $schedule->command('cron:property-invoice-service')->withoutOverlapping()->dailyAt('04:00'); + $schedule->command('cron:property-summary-service')->withoutOverlapping()->dailyAt('04:30'); + + $schedule->command('cron:property-review-schedule-service')->withoutOverlapping()->dailyAt('05:00'); + + $schedule->command('cron:meta-cancellation-service')->withoutOverlapping()->dailyAt('05:30'); + } +} diff --git a/app/Core/Contracts/MailInterface.php b/app/Core/Contracts/MailInterface.php new file mode 100644 index 0000000..533392b --- /dev/null +++ b/app/Core/Contracts/MailInterface.php @@ -0,0 +1,8 @@ +flip()->except($except)->flip()->toArray(); + } + + public static function getAllLangPackages() + { + $langPackages = []; + $validSystemLanguages = self::getValidLanguages(); + foreach ($validSystemLanguages as $perLanguage) + { + $langPackages[$perLanguage] = self::getCurrentLangPack($perLanguage); + } + return $langPackages; + } + + public static function convertAllLanguageSettingsAndCache() + { + $cacheParam = []; + $wordIndexCounter = 0; + $allLangPackages = self::getAllLangPackages(); + $systemDefaultLang = self::getDefaultLang(); + + foreach ($allLangPackages[$systemDefaultLang] as $perLangKey => $perLangWord) + { + $cacheParam[$wordIndexCounter]["md5"] = self::convertToMd5ForMultiLanguage($perLangWord); + + foreach ($allLangPackages as $perLangPackKey => $perLangPack) + { + $cacheParam[$wordIndexCounter][$perLangPackKey] = $perLangPack[$wordIndexCounter]; + } + $wordIndexCounter++; + } + + $cacheParam = collect($cacheParam)->keyBy("md5")->toArray(); + Cache::put(self::$languageSupportCacheName,$cacheParam,120); + return $cacheParam; + } + + public static function getLanguageSupportList() + { + $cachedData = self::$languageSupportList; + if ( !$cachedData) + { + $cachedData = Cache::get(self::$languageSupportCacheName); + self::$languageSupportList = $cachedData; + } + $cachedData = $cachedData ? $cachedData : self::convertAllLanguageSettingsAndCache(); + return $cachedData; + } + + + private static function makeSlugForMultiLanguage( $word ) + { + $word = lowerCase($word); + preg_match_all("#[\pL\d+]+#iu",$word,$results); + $results = $results[0]; + $converted = implode("",$results); + return $converted; + } + + public static function convertToMd5ForMultiLanguage($word) + { + /*Clear The Parameters*/ + $word = preg_replace('/\{\#\d+\}/',"",$word); + /**/ + /*Clear From Html*/ + $word = strip_tags($word); + /**/ + $word = self::makeSlugForMultiLanguage($word); + return md5($word); + } + + + public static function findWordForLanguage($word,$lang,array $parameters = []) + { + $md5Key = self::convertToMd5ForMultiLanguage($word); + $langSupportList = self::getLanguageSupportList(); + $converted = fillOnUndefined($langSupportList,$md5Key.".".$lang); + $converted = $converted ? $converted : fillOnUndefined($langSupportList,$md5Key.".".self::getDefaultLang()); + $converted = $converted ? $converted : $word; + + /*Inject Parameters*/ + $parameters = reIndexArrayKeys($parameters,1); + foreach ($parameters as $perParameterKey => $perParameter) + { + $converted = preg_replace('/\{\#'.$perParameterKey.'\}/',$perParameter,$converted); + } + /**/ + + return $converted; + } + + public static function lang ( $word,array $parameters = [],$lang = null ) + { + $lang = $lang ? : self::$currentLanguage; + return self::findWordForLanguage($word,$lang,$parameters); + } + + public static function langArrayStack ( array $langParamStack ) + { + $result = []; + $validCases = ["lower","title","upper"]; + + foreach ($langParamStack as $perLangParam) + { + $word = castToString(fillOnUndefined($perLangParam,"word")); + $parameters = fillOnUndefined($perLangParam,"parameters",[]); + $lang = castToString(fillOnUndefined($perLangParam,"lang")); + $case = lowerCase(castToString(fillOnUndefined($perLangParam,"case"))); + $case = in_array($case,$validCases) ? $case : null; + $caseFunction = $case ? camel_case("lang".$case."case") : "lang"; + $result[] = self::$caseFunction($word,$parameters,$lang); + } + + return $result; + } + + public static function langArray ( array $words, $lang = null ) + { + $result = []; + foreach ($words as $perWord) + { + $result[] = self::lang($perWord, [], $lang); + } + return $result; + } + + public static function langLowerCase($word,array $parameters = [],$lang = null) + { + $lang = $lang ? : self::getCurrentLang(); + $translated = self::lang($word, $parameters,$lang); + return $lang == "tr" ? lowerCase($translated) : mb_strtolower($translated); + } + + public static function langTitleCase($word,array $parameters = [],$lang = null) + { + $lang = $lang ? : self::getCurrentLang(); + $translated = self::lang($word, $parameters,$lang); + return $lang == "tr" ? uCase($translated) : mb_convert_case($translated,MB_CASE_TITLE); + } + + public static function langUpperCase($word,array $parameters = [],$lang = null) + { + $lang = $lang ? : self::getCurrentLang(); + $translated = self::lang($word, $parameters,$lang); + return $lang == "tr" ? upperCase($translated) : mb_strtoupper($translated); + } + + +} diff --git a/app/Core/Helper/PhpHelper.php b/app/Core/Helper/PhpHelper.php new file mode 100644 index 0000000..073b528 --- /dev/null +++ b/app/Core/Helper/PhpHelper.php @@ -0,0 +1,570 @@ +'; + print_r($input); + echo ''; + } + + /** + * Display the difference between two dates + * (30 years, 9 months, 25 days, 21 hours, 33 minutes, 3 seconds). + * + * @param string $start starting date + * @param string $end=false ending date + * + * @return string formatted date difference + */ + public static function dateDiff($start, $end = false) {$return = []; + + try { + $start = new DateTime($start); + $end = new DateTime($end); + $form = $start->diff($end); + } catch (Exception $e) { + return $e->getMessage(); + } + + $display = ['y' => 'Yıl', 'm' => 'Ay', 'd' => 'Gün', 'h' => 'Saat', 'i' => 'Dakika', 's' => 'Saniye']; + + foreach ($display as $key => $value) { + if ($form->$key > 0) { + $return[] = $form->$key . ' ' . $value; + } + } + + return implode($return, ', '); + } + + /** + * Display the day count between two dates + * (3 days). + * + * @param string $start starting date + * @param string $end=false ending date + * + * @return string day count + */ + public static function dayCount($end, $start) { + $return = []; + + try { + $start = new DateTime($start); + $end = new DateTime($end); + $form = $start->diff($end); + } catch (Exception $e) { + return $e->getMessage(); + } + + return $form->days; + } + + /** + * Display the day and month name + * (16 July). + * + * @param string $date date + * + * @return string formatted date + */ + public static function dayNumberAndMonthWord($date) { + return date('d', strtotime($date)) . ' ' . self::$months[date('m', strtotime($date)) - 1]; + } + + /** + * Display the month name + * (July). + * + * @param string $date date + * + * @return string formatted date + */ + public static function monthName($date) { + return self::$months[date('m', strtotime($date)) - 1]; + } + + /** + * Display the day name + * (Sunday). + * + * @param string $date date + * + * @return string formatted date + */ + public static function dayName($date) { + return self::$days[date('N', strtotime($date)) - 1]; + } + + /** + * Display the day number + * 01. + * + * @param string $date date + * + * @return string formatted date + */ + public static function dayNumber($date) { + return date('d', strtotime($date)); + } + + /** + * Display the human readable day + * 01. + * + * @param string $date date + * + * @return string formatted date + */ + public static function humanReadableDateWithDay($date) { + return date('d', strtotime($date)) . ' ' . self::$months[date('m', strtotime($date)) - 1] . ' ' . date('Y', strtotime($date)) . ', ' . self::dayName($date); + } + + /** + * Display the human readable day + * 01. + * + * @param string $date date + * + * @return string formatted date + */ + public static function humanReadableDate($date) { + return date('d-m-Y H:i:s', strtotime($date)); + } + + public static function humanReadableDateWithoutClock($date) { + return date('d-m-Y', strtotime($date)); + } + + /** + * @param string $date date + * + * @return string formatted date + */ + public static function sqlDate($date) { + $date = date('Y-m-d', strtotime($date)); + + return $date; + } + + public static function getMonth() { + return self::$months; + } + + public static function isValidDate($date) { + if (!is_string($date)) { + return false; + } + $day = substr($date, 0, 2); + $mont = substr($date, 3, 2); + $year = substr($date, 6, 4); + return checkdate($mont, $day, $year); + } + + public static function fillNullIfEmpty(&$variable) { + if (!isset($variable)) { + $variable = null; + } + return $variable; + } + + public static function getWeekDays() { + $days = self::$days; + $result = array(); + $counter = 1; + foreach ($days as $x) { + $result[$counter] = $x; + $counter++; + } + return $result; + } + + public static function parseXmlToArray($xmlSource) { + try { + $xmlOut = simplexml_load_string($xmlSource, 'SimpleXMLElement', LIBXML_NOCDATA); + + $arrayOut = json_decode(json_encode($xmlOut), true); + } catch (\Exception $e) { + $arrayOut = false; + } + return $arrayOut; + } + + public static function encryptCodeNumber($string, $key) { + $key = is_null($key) ? self::$encryptionKey : $key; + + $result = ''; + for ($i = 0; $i < mb_strlen($string, "UTF-8"); $i++) { + $char = mb_substr($string, $i, 1, "UTF-8"); + $keychar = mb_substr($key, ($i % mb_strlen($key, "UTF-8")) - 1, 1, "UTF-8"); + $char = chr(ord($char) + ord($keychar)); + $result.=$char; + } + $result = base64_encode($result); + $result = str_replace("=", "", $result); + return urlencode($result); + } + + public static function decryptCodeNumber($string, $key) { + $key = is_null($key) ? self::$encryptionKey : $key; + + $string = urldecode($string); + $eqcount = strlen($string) % 4; + if ($eqcount == 2) + $string . "=="; + else if ($eqcount == 3) + $string . "="; + $result = ''; + $string = base64_decode($string); + for ($i = 0; $i < mb_strlen($string); $i++) { + $char = mb_substr($string, $i, 1); + $keychar = mb_substr($key, ($i % mb_strlen($key)) - 1, 1); + $char = chr(ord($char) - ord($keychar)); + $result.=$char; + } + return $result; + } + + public static function generateRandomString($length = 5) { + $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; + } + + + public static function convertArrayToCsv (array $valueArray ) + { + if ( !$valueArray ) + { + return false; + } + $csvResult = ""; + + $valueArray = singleElementArray($valueArray); + + /*Get The Column Names*/ + $firstArray = reset($valueArray); + + $csvResult.=implode(",",array_keys($firstArray))."\r\n"; + + foreach ($valueArray as $perArray) + { + $csvResult.=implode(",",$perArray)."\r\n"; + } + return $csvResult; + } + + private static function nextExcelColName ( $colName = null ) + { + $primary = range("A","Z"); + if ( !$colName) + { + return reset($primary); + } + + if(last($primary) == $colName) + { + return reset($primary); + } + + return $primary[array_search($colName,$primary)+1]; + + } + + /* If $params[keyNames] is Empty Function Gonna Take All The Keys Of The Array */ + public static function convertArrayToXls (array $valueArray,array $params = [] ) + { + try + { + $excel = App::make('excel'); + $params[ "fileName" ] = isset( $params[ "fileName" ] ) ? $params[ "fileName" ] : "xls_file"; + $params[ "pagePrefix" ] = isset( $params[ "pagePrefix" ] ) ? $params[ "pagePrefix" ] : "Page"; + $params[ "onlyTheseKeys" ] = isset( $params[ "onlyTheseKeys" ] ) ? $params[ "onlyTheseKeys" ] : []; + $params[ "keyNames" ] = isset( $params[ "keyNames" ] ) ? $params[ "keyNames" ] : []; + $result = $excel->create ( $params[ "fileName" ], function ( $excel ) use ( $valueArray, $params ) + { + $excel->sheet ( $params[ "pagePrefix" ], function ( $sheet ) use ( $valueArray, $params) + { + $rowCounter = 1; + $sheet->setOrientation ( 'landscape' ); + if ($params["keyNames"]) + { + $colCounter = 0; + + foreach ($params["keyNames"] as $perKey) + { + if ($params["onlyTheseKeys"] && !in_array($perKey,$params["onlyTheseKeys"])) + { + continue; + } + $sheet->setCellValueByColumnAndRow ( $colCounter, $rowCounter, $perKey ); + $style = array( + 'alignment' => array( + 'horizontal' => "center", + ) + ); + + $sheet->getDefaultStyle()->applyFromArray($style); + $colCounter++; + } + $rowCounter++; + } + + foreach ($valueArray as $perValue) + { + $colCounter = 0; + foreach ($perValue as $perCol) + { + if ($params["onlyTheseKeys"] && !in_array($perKey,$params["onlyTheseKeys"])) + { + continue; + } + if (is_array($perCol)) + { + $perCol = json_encode($perCol); + } + $sheet->setCellValueByColumnAndRow ( $colCounter, $rowCounter, $perCol ); + $colCounter++; + } + $rowCounter++; + } + + } ); + + }); + return $result; + } catch ( Exception $e ) + { + return null; + } + + } + + public static function singleElementArray ( $arrayElement,array $extraParams = null) + { + $isMultiArray = true; + + if ( !is_array($arrayElement)) + { + return []; + } + + foreach ($arrayElement as $perItem) + { + if (gettype($perItem)!="array") + { + $isMultiArray = false; + break; + } + } + + if(!$isMultiArray) + { + $isMultiArray = true; + foreach (array_keys ( $arrayElement ) as $perKey) + { + if (!is_numeric($perKey)) + { + $isMultiArray = false; + break; + } + } + } + + + return $isMultiArray?$arrayElement:array($arrayElement); + + } + + public static function checkWizardMenu($wizardArray, $menuCode) + { + return array_filter($wizardArray, function ($key) use ($menuCode) { + return $key['menu_code'] == $menuCode ? true : false; + }, ARRAY_FILTER_USE_BOTH); + } + + + /*If its an array enter the index of the array to $index variable*/ + public static function fillOnUndefined($variable,$index = null,$fillWith = null,$arrayDelimiter = ".") + { + if ( !$arrayDelimiter) + { + return null; + } + + $index = trim($index,$arrayDelimiter); + + if ( !$index && $index !== '0') + { + return false; + } + + $indexes = explode($arrayDelimiter,$index); + + $arrayDeep = $variable; + + foreach ($indexes as $perIndex) + { + if ( !isset($arrayDeep[$perIndex])) + { + return $fillWith; + } + + $arrayDeep = $arrayDeep[$perIndex]; + } + + return $arrayDeep; + } + public static function hexToBinary ( $hex ) + { + if ( strlen($hex)<=0) + { + return null; + } + $str = ""; + for($i=0;$i $perValue) + { + if (isset($perValue[$index])) + { + $result[] = $perValue[$index]; + } + + } + return $result; + } catch ( Exception $e ) + { + return []; + } + } + + public static function pickNodeFromArray($index, $value, array $targetArray) + { + try { + $result = []; + foreach ($targetArray as $perIndex => $perValue) { + if (isset($perValue[$index]) && $perValue[$index] == $value) { + $result = $perValue; + break; + } + } + return $result; + } catch (Exception $e) { + return []; + } + } + + public static function numberSortTurkish($number) + { + $returnString = ''; + $numberValue = [ + 'inci' => [1,5,8,20,70,80], + 'üncü' => [3,4,100], + 'nci' => [2,7,50], + 'ıncı' => [0,40,60,90], + 'ncı' => [6], + 'uncu' => [9,10,30] + ]; + + if(strlen($number) < 4) { + if ($number % 10 == 0) { + $numberKey = $number; + } else $numberKey = substr($number, -1,1); + } + + foreach ($numberValue as $orderKey => $numbers) { + if (array_search($numberKey, $numbers) !== false) { + $returnString = $orderKey; + } + } + + return $returnString; + + } + + public static function now ( array $param = [] ) + { + return date("Y-m-d H:i:s"); + } + + public static function todayDate ( array $param = [] ) + { + return date("Y-m-d"); + } + + public static function moneyFormatWithTwoDecimals($money) + { + $money = str_replace(",","",$money); + return number_format($money,2,'.',''); + } + + public static function getXmlResponse ($view,$data) + { + $responseObj = App::make("Response"); + return $responseObj::view($view,$data)->header('Content-Type', 'text/xml'); + } + + public static function preDie($args) + { + + echo '
';
+            print_r($args);
+            echo '
'; + + die; + } +} diff --git a/app/Core/Helper/compat_l5.php b/app/Core/Helper/compat_l5.php new file mode 100644 index 0000000..207d1f6 --- /dev/null +++ b/app/Core/Helper/compat_l5.php @@ -0,0 +1,264 @@ +getConfigurationPath(rtrim($path, ".php")); + } +} + +if(!function_exists('public_path')) +{ + + /** + * Return the path to public dir + * @param null $path + * @return string + */ + function public_path($path=null) + { + return rtrim(app()->basePath('public/'.$path), '/'); + } +} + +if(!function_exists('storage_path')) +{ + + /** + * Return the path to storage dir + * @param null $path + * @return string + */ + function storage_path($path=null) + { + return app()->storagePath($path); + } +} + +if(!function_exists('database_path')) +{ + + /** + * Return the path to database dir + * @param null $path + * @return string + */ + function database_path($path=null) + { + return app()->databasePath($path); + } +} + +if(!function_exists('resource_path')) +{ + + /** + * Return the path to resource dir + * @param null $path + * @return string + */ + function resource_path($path=null) + { + return app()->resourcePath($path); + } +} + +if(!function_exists('lang_path')) +{ + + /** + * Return the path to lang dir + * @param null $str + * @return string + */ + function lang_path($path=null) + { + return app()->getLanguagePath($path); + } +} + +if ( ! function_exists('asset')) +{ + /** + * Generate an asset path for the application. + * + * @param string $path + * @param bool $secure + * @return string + */ + function asset($path, $secure = null) + { + return app('url')->asset($path, $secure); + } +} + +if ( ! function_exists('elixir')) +{ + /** + * Get the path to a versioned Elixir file. + * + * @param string $file + * @return string + */ + function elixir($file) + { + static $manifest = null; + if (is_null($manifest)) + { + $manifest = json_decode(file_get_contents(public_path().'/build/rev-manifest.json'), true); + } + if (isset($manifest[$file])) + { + return '/build/'.$manifest[$file]; + } + throw new InvalidArgumentException("File {$file} not defined in asset manifest."); + } +} + +if ( ! function_exists('auth')) +{ + /** + * Get the available auth instance. + * + * @return \Illuminate\Contracts\Auth\Guard + */ + function auth() + { + return app('Illuminate\Contracts\Auth\Guard'); + } +} + +if ( ! function_exists('bcrypt')) +{ + /** + * Hash the given value. + * + * @param string $value + * @param array $options + * @return string + */ + function bcrypt($value, $options = array()) + { + return app('hash')->make($value, $options); + } +} + +if ( ! function_exists('redirect')) +{ + /** + * Get an instance of the redirector. + * + * @param string|null $to + * @param int $status + * @param array $headers + * @param bool $secure + * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse + */ + function redirect($to = null, $status = 302, $headers = array(), $secure = null) + { + if (is_null($to)) return app('redirect'); + return app('redirect')->to($to, $status, $headers, $secure); + } +} + +if ( ! function_exists('response')) +{ + /** + * Return a new response from the application. + * + * @param string $content + * @param int $status + * @param array $headers + * @return \Symfony\Component\HttpFoundation\Response|\Illuminate\Contracts\Routing\ResponseFactory + */ + function response($content = '', $status = 200, array $headers = array()) + { + $factory = app('Illuminate\Contracts\Routing\ResponseFactory'); + if (func_num_args() === 0) + { + return $factory; + } + return $factory->make($content, $status, $headers); + } +} + +if ( ! function_exists('secure_asset')) +{ + /** + * Generate an asset path for the application. + * + * @param string $path + * @return string + */ + function secure_asset($path) + { + return asset($path, true); + } +} + +if ( ! function_exists('secure_url')) +{ + /** + * Generate a HTTPS url for the application. + * + * @param string $path + * @param mixed $parameters + * @return string + */ + function secure_url($path, $parameters = array()) + { + return url($path, $parameters, true); + } +} + + +if ( ! function_exists('session')) +{ + /** + * Get / set the specified session value. + * + * If an array is passed as the key, we will assume you want to set an array of values. + * + * @param array|string $key + * @param mixed $default + * @return mixed + */ + function session($key = null, $default = null) + { + if (is_null($key)) return app('session'); + if (is_array($key)) return app('session')->put($key); + return app('session')->get($key, $default); + } +} + + +if ( ! function_exists('cookie')) +{ + /** + * Create a new cookie instance. + * + * @param string $name + * @param string $value + * @param int $minutes + * @param string $path + * @param string $domain + * @param bool $secure + * @param bool $httpOnly + * @return \Symfony\Component\HttpFoundation\Cookie + */ + function cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true) + { + $cookie = app('Illuminate\Contracts\Cookie\Factory'); + if (is_null($name)) + { + return $cookie; + } + return $cookie->make($name, $value, $minutes, $path, $domain, $secure, $httpOnly); + } +} diff --git a/app/Core/Helper/helpers.php b/app/Core/Helper/helpers.php new file mode 100644 index 0000000..bb867b8 --- /dev/null +++ b/app/Core/Helper/helpers.php @@ -0,0 +1,463 @@ + "success", -1 => "exception", 0 => "error"]; + $exceptionClassArr = ["exception" => "\Exception", "error" => "App\Exceptions\ApiErrorException"]; + $statusCodeArr = [1 => 200, -1 => 500, 0 => 400]; + $param["status"] = isset($param["status"]) ? $param["status"] : 1; + $status = isset($statusArr[$param["status"]]) ? $statusArr[$param["status"]] : "success"; + $statusCode = isset($statusCodeArr[$param["status"]]) ? $statusCodeArr[$param["status"]] : 200; + $message = (isset($param['message']) ? $param['message'] : ''); + $data = (isset($param['data']) ? $param['data'] : ''); + $exceptionClass = isset($exceptionClassArr[$status]) ? new $exceptionClassArr[$status]($message) : null; + + return ['status' => $status, 'message' => $message, 'data' => $data, 'statusCode' => $statusCode, "exceptionClass" => $exceptionClass]; +} + +function apiResponse($status = -1, $message = "", $data = [], $statusCode = null, $errorCode = null) +{ + $genericMessage = "Bilinmeyen Bir Hata Oluştu"; + $error = $status <= 0 ? true : false; + $statusCode = $statusCode ? $statusCode : 200; + $errorCode = $errorCode ? $errorCode : null; + //$statusCode = $error ? 500 : $statusCode; + $message = $status != -1 ? $message : $genericMessage; + $message = $message ? $message : null; + $data = $data && is_array($data) ? $data : []; + + $responseData = [ + "status" => $statusCode, + "error" => $error, + "errorCode" => $errorCode, + "message" => $message, + "data" => $data + ]; + + /** ServiceLog **/ + $serviceLogId = app('request')->serviceLogId; + $serviceLogRequestTime = app('request')->serviceLogRequestTime; + if (!empty($serviceLogId)) { + $updateServiceLog = [ + 'response' => json_encode($responseData), + 'response_time' => microtime(true) - $serviceLogRequestTime, + 'status' => 1 + ]; + $serviceLog = App::make("App\Core\Service\ServiceLogService"); + $serviceLog->update($serviceLogId, $updateServiceLog); + } + /** ServiceLog **/ + + return response()->json($responseData, $statusCode); +} + +function fillOnUndefined($variable, $index = null, $fillWith = null, $arrayDelimiter = ".") +{ + if (!$arrayDelimiter) { + return null; + } + + + if (!$index && $index !== '0' && $index !== 0) { + return false; + } + + $indexes = explode($arrayDelimiter, $index); + + $arrayDeep = $variable; + + foreach ($indexes as $perIndex) { + if (!isset($arrayDeep[$perIndex])) { + return $fillWith; + } + + $arrayDeep = $arrayDeep[$perIndex]; + } + + + return $arrayDeep; + +} + +function fillOnUndefinedAndEmpty($variable, $index = null, $fillWith = null, $arrayDelimiter = ".") +{ + if (!$arrayDelimiter) { + return null; + } + + + if (!$index && $index !== '' && $index !== '0' && $index !== 0) { + return false; + } + + $indexes = explode($arrayDelimiter, $index); + + $arrayDeep = $variable; + + foreach ($indexes as $perIndex) { + if (!isset($arrayDeep[$perIndex]) || empty($arrayDeep[$perIndex])) { + return $fillWith; + } + + $arrayDeep = $arrayDeep[$perIndex]; + } + + + return $arrayDeep; + +} + +function createFolderAndSubFolder($structure, $path = __DIR__, &$createdPaths, $mode = 0777) +{ + + foreach ($structure as $folder => $subFolder) { + if (is_array($subFolder)) { + $newPath = "{$path}/{$folder}"; + //$createdPaths[$newPath] = $newPath; + $createdPaths[] = $newPath; + + if (!is_dir($newPath)) mkdir($newPath, $mode); + + createFolderAndSubFolder($subFolder, $newPath, $createdPaths); + } else { + $newPath = "{$path}/{$subFolder}"; + //$createdPaths[$newPath] = $newPath; + $createdPaths[] = $newPath; + if (!is_dir($newPath)) mkdir($newPath, $mode); + } + } + + return $createdPaths; +} + +function smartyModifierFileSize($size) +{ + $size = max(0, (int)$size); + $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); + $power = $size > 0 ? floor(log($size, 1024)) : 0; + $convertSize = number_format($size / pow(1024, $power), 2, '.', ','); + $convertType = $units[$power]; + return [$convertSize, $convertType]; +} + +function pickItemFromArray($index, array $targetArray) +{ + try { + $result = []; + foreach ($targetArray as $perIndex => $perValue) { + if (isset($perValue[$index])) { + $result[] = $perValue[$index]; + } + + } + return $result; + } catch (Exception $e) { + return []; + } +} + +function lang($word, array $parameters = [], $lang = null) +{ + return LanguageService::lang($word, $parameters, $lang); +} + +function getSystemLang() +{ + return LanguageService::getCurrentLang(); +} + +function getSystemLangSession() +{ + return session("sysLang"); +} + +function setSystemLangSession($language) +{ + $validLanguages = LanguageService::getValidLanguages(); + if (!in_array($language, $validLanguages)) { + throw new Exception("Invalid Language Selected language parameter : " . json_encode($language)); + } + session()->set("sysLang", $language); + return $language; +} + +function getSystemDefaultLang() +{ + return LanguageService::getDefaultLang(); +} + +function getLanguageSupportList() +{ + return LanguageService::getLanguageSupportList(); +} + +function upperCase($word, $charset = "UTF-8") +{ + $word = str_replace("i", "İ", $word); + return mb_strtoupper($word, $charset); +} + +function lowerCase($word, $charset = "UTF-8") +{ + $word = str_replace("I", "ı", $word); + return mb_strtolower($word, $charset); +} + +function uCase($word, $charset = "UTF-8") +{ + $word = preg_replace("#(^\i)#", "İ", $word); + $word = preg_replace("#(^\ı)#", "I", $word); + return mb_convert_case($word, MB_CASE_TITLE, $charset); +} + +function reIndexArrayKeys(array $targetArray, $startNo = 0) +{ + if (!$targetArray) { + return []; + } + return array_combine(range($startNo, ($startNo - 1) + count($targetArray)), $targetArray); +} + +function singleElementXMLArray($array = []) +{ + + return fillOnUndefined($array, 0) && is_array($array) ? $array : [$array]; +} + +function toArray($value): array +{ + return is_array($value) ? $value : ($value !== null ? [$value] : []); +} + + +function singleElementArray($arrayElement, array $extraParams = null) +{ + + $isMultiArray = true; + + if (!is_array($arrayElement)) { + return []; + } + + foreach ($arrayElement as $perItem) { + if (gettype($perItem) != "array") { + $isMultiArray = false; + break; + } + } + + if (!$isMultiArray) { + $isMultiArray = true; + foreach (array_keys($arrayElement) as $perKey) { + if (!is_numeric($perKey)) { + $isMultiArray = false; + break; + } + } + } + + + return $isMultiArray ? $arrayElement : array($arrayElement); + +} + +function generateRandomString($length = 5) +{ + return \App\Core\Helper\PhpHelper::generateRandomString($length); +} + +function humanReadableDate($date) +{ + return date('d/m/Y', strtotime($date)); +} + +function language_key($title) +{ + return Str::slug($title, $separator = '_', $language = 'en'); +} + +function getGuid() +{ + $hash = md5(uniqid()); + $guid = substr($hash, 0, 8) . + '-' . + substr($hash, 8, 4) . + '-' . + substr($hash, 12, 4) . + '-' . + substr($hash, 16, 4) . + '-' . + substr($hash, 20, 12); + + return $guid; +} + +function moneyDoubleFormat($money) +{ + return number_format($money, 2, ',', ''); +} + + +function moneyDoubleFormatDecimal($money) +{ + return floatval(number_format($money, 2, '.', '')); +} + +function moneyFourFormatDecimal($money) +{ + return floatval(number_format($money, 4, '.', '')); +} + + +function getCodeGenerate($prefix = 'ENW') +{ + return $prefix . date('ymd') . '-' . upperCase(generateRandomString(8)); +} + +function getPaymentGenerate($prefix = 'PYM') +{ + $prefix = is_null($prefix) ? 'PYM' : $prefix; + return 'ENW' . $prefix . date('ymd') . '_' . upperCase(generateRandomString(8)); +} + +function getTicketCodeGenerate($prefix = 'TCK') +{ + return $prefix . upperCase(generateRandomString(8)); +} + +function creditCardMask($cardNumber) +{ + return substr($cardNumber, 0, 6) . '******' . substr($cardNumber, -4); +} + +function occupancyCodeFormatted($occupancyCode) +{ + + $occupancyFormatted = []; + + $adultCount = substr_count($occupancyCode, 'A'); + if ($adultCount > 0) { + $occupancyFormatted[] = $adultCount . ' Adult'; + } + + $childCount = substr_count($occupancyCode, 'C'); + if ($childCount > 0) { + + $childAges = []; + $roomsChildArray = explode('C', $occupancyCode); + for ($i = 1; $i < count($roomsChildArray); $i++) { + if (!empty($roomsChildArray[$i]) || $roomsChildArray[$i] == 0) { + $childAges[] = $roomsChildArray[$i]; + } + } + + if (!empty($childAges)) { + $childAges = implode(', ', $childAges); + } + + $occupancyFormatted[] = $childCount . ' Child' . (!empty($childAges) ? ' (' . $childAges . ')' : null); + } + + if (!empty($occupancyFormatted)) { + $occupancyFormatted = implode(', ', $occupancyFormatted); + } + + return $occupancyFormatted; +} + +function occupancyCodeParser($occupancyCode) +{ + + $occupancy = []; + $occupancy['ADT'] = 0; + $occupancy['CHD'] = 0; + $occupancy['AGE'] = []; + + $adultCount = substr_count($occupancyCode, 'A'); + if ($adultCount > 0) { + $occupancy['ADT'] = $adultCount; + } + + $childCount = substr_count($occupancyCode, 'C'); + if ($childCount > 0) { + + $childAges = []; + $roomsChildArray = explode('C', $occupancyCode); + for ($i = 1; $i < count($roomsChildArray); $i++) { + if (!empty($roomsChildArray[$i])) { + $childAges[] = $roomsChildArray[$i]; + } + } + + $occupancy['CHD'] = $childCount; + $occupancy['AGE'] = $childAges; + + //$occupancyFormatted[] = $childCount . ' Child' . (!empty($childAges) ? ' (' . $childAges . ')' : null); + } + + return $occupancy; +} + + +function occupancyGroup($maxAdult, $maxChild, $maxOccupancy, $excludeOccupancy = []) +{ + + $occupancyGroup = []; + //TODO: $excludeOccupancy + for ($i = 0; $i < $maxAdult; $i++) { + $occupancyCodeAdult = str_repeat('A', ($i + 1)); + if (strlen($occupancyCodeAdult) > $maxOccupancy) { + break; + } + $occupancyGroup[] = $occupancyCodeAdult; + + for ($j = 0; $j < $maxChild; $j++) { + $occupancyCodeChild = str_repeat('C', ($j + 1)); + + if (strlen($occupancyCodeChild) > $maxOccupancy) { + continue; + } + + if (strlen($occupancyCodeAdult . $occupancyCodeChild) > $maxOccupancy) { + break; + } + + $occupancyGroup[] = $occupancyCodeAdult . $occupancyCodeChild; + } + } + + return $occupancyGroup; +} + + +function cancellationPolicyTextFormatted($isNonRefundable, $isFreeCancellation, $beforeArrivalDay, $type, $value, $currency, $languageCode = 'en') +{ + + $formattedText = null; + if (!$isFreeCancellation) { + if ($isNonRefundable) { + $formattedText = __('btn-irrevocable', [], $languageCode); + } else { + + $formattedText = __('be-if_canceled_up_to_days', ['day' => $beforeArrivalDay], $languageCode) . ', ' . $value . ($type == 'PER' ? '%' : $currency) . ' ' . __('be-search-impose_penalty', [], $languageCode); + } + } else { + $formattedText = ($beforeArrivalDay > 0 ? __('be-up_to_days', ['day' => $beforeArrivalDay], $languageCode) : '') . ' ' . __('btn-free_cancellation', [], $languageCode); + } + + return $formattedText; + +} diff --git a/app/Core/Mail/AffiliateRequestMail.php b/app/Core/Mail/AffiliateRequestMail.php new file mode 100644 index 0000000..9a0fb5a --- /dev/null +++ b/app/Core/Mail/AffiliateRequestMail.php @@ -0,0 +1,60 @@ +param = $param; + } + + public function build () + { + try + { + $params = $this->param; + $mailParams = $params['mailViewParams'] ; + $mailData = $params['mailData'] ; + $mailSenderAddress = Config::get('app.mailSenderAddress') ; + $mailTitle = $mailData['to']["name"]. ' | Affiliate Request Mail'; + + app('translator')->setLocale(fillOnUndefined($params['mailViewParams'],'language', 'en')); + + + /*echo view('emails.affiliateRequestMail', compact('mailParams', 'mailTitle')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.affiliateRequestMail', compact('mailParams', 'mailTitle')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject($mailTitle) + ->with(['message' => $this]); + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Mail/BaseMail.php b/app/Core/Mail/BaseMail.php new file mode 100644 index 0000000..f402bf5 --- /dev/null +++ b/app/Core/Mail/BaseMail.php @@ -0,0 +1,13 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + $bookingService = App::make('App\Core\Service\BookingService'); + $userService = App::make('App\Core\Service\UserService'); + + $requestData = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['bookingCode']] + ], + 'with' => ['bookingProperty.propertyBrand', 'bookingContact'], + 'firstRow' => true + ]; + + $bookingDetail = $bookingService->select($requestData); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException('Booking not found.'); + } + + $bookingDetail = $bookingDetail['data']; + + $mailParams = [ + 'to' => $bookingDetail['booking_contact']['email'], + 'toNameSurname' => $bookingDetail['booking_contact']['nameSurname'], + 'bcc' => [], + 'confirmCode' => $params['confirmCode'], + 'bookingId' => fillOnUndefined($bookingDetail, 'id'), + 'propertyId' => fillOnUndefined($bookingDetail, 'property_id'), + 'bookingCode' => fillOnUndefined($bookingDetail, 'booking_code'), + 'locale' => fillOnUndefined($bookingDetail['booking_contact'], 'language_code', 'en'), + ]; + + /*echo view('emails.bookingCancellationConfirmCode', compact('mailParams')); + die();*/ + + $mailParams['bcc'][] = 'channel@extranetwork.com'; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.bookingCancellationConfirmCode', compact('mailParams')) + ->to($mailParams['to'], $mailParams['toNameSurname']) + ->bcc($mailParams['bcc']) + ->subject(__('api-mailing-cancellation_confirm_code-subject', ['bookingCode' => $mailParams['bookingCode']], $mailParams['locale'])); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingCancellationRequestMail.php b/app/Core/Mail/BookingCancellationRequestMail.php new file mode 100644 index 0000000..648fda1 --- /dev/null +++ b/app/Core/Mail/BookingCancellationRequestMail.php @@ -0,0 +1,123 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + $bookingService = App::make('App\Core\Service\BookingService'); + $userService = App::make('App\Core\Service\UserService'); + + $requestData = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['bookingCode']] + ], + 'with' => [ + 'bookingPayment', 'bookingRoom.roomRateMapping.propertyRoom', 'bookingRoom.roomRateMapping.propertyRoomRate', + 'bookingContact', 'bookingProperty.propertyBrand', 'bookingProperty.propertyExecutive', 'bookingProperty.propertyUser.user', + 'bookingPropertyWeb', 'propertyBookingEngine', 'propertyBookingChannel' + ], + 'firstRow' => true + ]; + + $bookingDetail = $bookingService->select($requestData); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException('Booking not found.'); + } + + $bookingDetail = $bookingDetail['data']; + + + //Language + $userData = $bookingDetail['booking_property']['property_user']; + $firstUserData = reset($userData); + $bookingLanguageCode = fillOnUndefined($firstUserData['user'], 'language', 'en'); + + + //Mail Contact Data + $bcc = []; + foreach ($userData as $user) { + if ($user['user']['email'] != $firstUserData['user']['email']) { + $bcc[] = $user['user']['email']; + } + } + + $reservationExecutives = []; + if (isset($bookingDetail['booking_property']['property_executive'])) { + $reservationExecutives = collect($bookingDetail['booking_property']['property_executive']) + ->where('executive_type_id', '=', '7') + ->values()->all(); + } + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + + $mailData = [ + 'to' => [ + 'name' => $bookingDetail['booking_property']['name'], + 'email' => $firstUserData['user']['email'] + ] + ]; + + + $mailParams = [ + 'to' => $firstUserData['user']['email'], + 'bcc' => $bcc, + 'toNameSurname' => $bookingDetail['booking_property']['name'], + 'bookingContactNameSurname' => $bookingDetail['booking_contact']['nameSurname'], + 'bookingCode' => fillOnUndefined($bookingDetail, 'booking_code'), + 'locale' => $bookingLanguageCode, + ]; + + $mailParams['detailUrl'] = config('app.client_server').'/app/network/reservation/'.$bookingDetail['id'].'?propertyid='.$bookingDetail['property_id']; + + /*echo view('emails.bookingCancellationRequest', compact('mailParams')); + die();*/ + + $mailParams['bcc'][] = 'channel@extranetwork.com'; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.bookingCancellationRequest', compact('mailParams')) + ->to($mailParams['to'], $mailParams['toNameSurname']) + ->bcc($mailParams['bcc']) + ->subject(__('api-mailing-cancellation_request-subject', ['bookingCode' => $mailParams['bookingCode']], $mailParams['locale'])); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingEngineSearchReportMail.php b/app/Core/Mail/BookingEngineSearchReportMail.php new file mode 100644 index 0000000..4896888 --- /dev/null +++ b/app/Core/Mail/BookingEngineSearchReportMail.php @@ -0,0 +1,54 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + /*echo view('emails.bookingEngineSearchReportMail', compact('params')); + die();*/ + + $bcc = $params['propertyUserEmail']; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.bookingEngineSearchReportMail', compact('params')) + ->to($mailSenderAddress, 'Extranetwork') + ->bcc($bcc) + ->subject($params['propertyName'].' - Günlük İşlem Raporu : '. $params['date']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingInvoiceUpdateMail.php b/app/Core/Mail/BookingInvoiceUpdateMail.php new file mode 100644 index 0000000..28a6aa1 --- /dev/null +++ b/app/Core/Mail/BookingInvoiceUpdateMail.php @@ -0,0 +1,120 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + + + $bookingService = App::make("App\Core\Service\BookingService"); + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['bookingCode']], + ], + 'with' => ['property.propertyBrand', 'property.propertyExecutive', 'property.propertyUser.user','property.propertyBookingEngineToken'], + 'firstRow' => true + ]; + + $bookingDetail = $bookingService->select($bookingDetailParam); + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException($bookingDetail['message']); + } + + $bookingDetail = $bookingDetail['status'] == 'success' && !empty($bookingDetail['data']) ? $bookingDetail['data'] : null; + + + $property = $bookingDetail['property']; + + + //Mail Contact Data + $reservationExecutives = []; + if (isset($property['property_executive'])) { + $reservationExecutives = collect($property['property_executive']) + ->where('executive_type_id', '=', '7') + ->values()->all(); + } + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + $bcc[] = "channel@extranetwork.com"; + + + $userData = $property['property_user']; + $firstUserData = reset($userData); + + foreach ($userData as $user) { + if ($user['user']['email'] != $firstUserData['user']['email']) { + $bcc[] = $user['user']['email']; + } + } + + $mailData = [ + 'to' => [ + 'name' => $firstUserData['user']['nameSurname'], + 'email' => $firstUserData['user']['email'], + ], + 'bcc' => $bcc + + ]; + + $locale = fillOnUndefined($firstUserData['user'], 'language', 'tr'); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + app('translator')->setLocale($locale); + + + $mailParams = [ + 'propertyName' => $property['name'], + 'bookingCode' => $params['bookingCode'], + 'logo' => $property['property_brand']['logoUrl'], + 'btnUrl' => config('app.bookingEngineUrl') . '/' . $property['property_booking_engine_token']['token'] . '/' . $locale . '/booking-detail/' . $params['bookingCode'], + ]; + + /*echo view('emails.bookingInvoiceUpdateMail', compact('mailParams')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['propertyName']) + ->view('emails.bookingInvoiceUpdateMail', compact('mailParams')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject(__('api-mailing-booking-invoice_update-title', ['bookingCode' => $mailParams['bookingCode']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingPaymentDataCodeMail.php b/app/Core/Mail/BookingPaymentDataCodeMail.php new file mode 100644 index 0000000..d7a84ac --- /dev/null +++ b/app/Core/Mail/BookingPaymentDataCodeMail.php @@ -0,0 +1,101 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + $bookingService = App::make('App\Core\Service\BookingService'); + $userService = App::make('App\Core\Service\UserService'); + + $requestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + //'with' => ['bookingProperty.propertyExecutive', 'bookingProperty.propertyBookingEngineToken', 'bookingProperty.propertyBrand', 'bookingContact', 'bookingChannel', 'bookingPayment', 'bookingPaymentType', 'bookingStatus'], + 'firstRow' => true + ]; + + $booking = $bookingService->select($requestData); + + if ($booking['status'] != 'success' || empty($booking['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $booking = $booking['data']; + + $requestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['user_id']] + ], + 'firstRow' => true + ]; + + $user = $userService->select($requestData); + + if ($user['status'] != 'success' || empty($user['data'])) { + throw new ApiErrorException(lang('User not found')); + } + + $user = $user['data']; + + $mailParams = [ + 'to' => $user['email'], + 'toNameSurname' => $user['nameSurname'], + 'bcc' => [], + 'unlockCode' => $params['unlock_code'], + 'bookingId' => fillOnUndefined($booking, 'id'), + 'propertyId' => fillOnUndefined($booking, 'property_id'), + 'bookingCode' => fillOnUndefined($booking, 'booking_code'), + 'locale' => fillOnUndefined($user, 'language', 'en'), + ]; + + + /*echo view('emails.bookingPaymentDataCode', compact('mailParams')); + die();*/ + + $mailParams['bcc'][] = 'burhan@extranetwork.com'; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.bookingPaymentDataCode', compact('mailParams')) + ->to($mailParams['to'], $mailParams['toNameSurname']) + ->bcc($mailParams['bcc']) + ->subject(__('api-mailing-payment_data_code-subject',['bookingCode' => $mailParams['bookingCode']],$mailParams['locale'])); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingPropertyAddonUpdateMail.php b/app/Core/Mail/BookingPropertyAddonUpdateMail.php new file mode 100644 index 0000000..52e6c0f --- /dev/null +++ b/app/Core/Mail/BookingPropertyAddonUpdateMail.php @@ -0,0 +1,113 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + + $propertyService = App::make("App\Core\Service\PropertyService"); + + $propertyParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['propertyId']], + ], + 'with' => ['propertyBrand', 'propertyExecutive', 'propertyUser.user','propertyBookingEngineToken'], + 'firstRow' => true + ]; + + $property = $propertyService->select($propertyParam); + if ($property['status'] != 'success') { + throw new ApiErrorException($property['message']); + } + + $property = $property['data']; + + //Mail Contact Data + $reservationExecutives = []; + if (isset($property['property_executive'])) { + $reservationExecutives = collect($property['property_executive']) + ->where('executive_type_id', '=', '7') + ->values()->all(); + } + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + $bcc[] = "channel@extranetwork.com"; + + + $userData = $property['property_user']; + $firstUserData = reset($userData); + + foreach ($userData as $user) { + if ($user['user']['email'] != $firstUserData['user']['email']) { + $bcc[] = $user['user']['email']; + } + } + + $mailData = [ + 'to' => [ + 'name' => $firstUserData['user']['nameSurname'], + 'email' => $firstUserData['user']['email'], + ], + 'bcc' => $bcc + + ]; + + $locale = fillOnUndefined($firstUserData['user'], 'language', 'tr'); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + app('translator')->setLocale($locale); + + + $mailParams = [ + 'propertyName' => $property['name'], + 'bookingCode' => $params['bookingCode'], + 'addonLanguageKey' => $params['addonLanguageKey'], + 'logo' => $property['property_brand']['logoUrl'], + 'btnUrl' => config('app.bookingEngineUrl') . '/' . $property['property_booking_engine_token']['token'] . '/' . $locale . '/booking-detail/' . $params['bookingCode'], + ]; + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['propertyName']) + ->view('emails.bookingPropertyAddonUpdateMail', compact('mailParams')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject(__('api-mailing-booking-addon_update-title', ['bookingCode' => $mailParams['bookingCode'], 'addonLanguageKey' => __($mailParams['addonLanguageKey'])])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/BookingTicketMail.php b/app/Core/Mail/BookingTicketMail.php new file mode 100644 index 0000000..5e6766e --- /dev/null +++ b/app/Core/Mail/BookingTicketMail.php @@ -0,0 +1,140 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $bookingService = App::make('App\Core\Service\BookingService'); + + $requestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => ['bookingProperty.propertyExecutive', 'bookingProperty.propertyBookingEngineToken', 'bookingProperty.propertyBrand', 'bookingContact', 'bookingChannel', 'bookingPayment', 'bookingPaymentType', 'bookingStatus'], + 'firstRow' => true + ]; + + $booking = $bookingService->select($requestData); + + if ($booking['status'] != 'success' || empty($booking['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $booking = $booking['data']; + + $locale = fillOnUndefined($params, 'locale', 'en'); + if (!is_null($params['user'])) { + $locale = $booking['booking_contact']['language_code']; + } + app('translator')->setLocale($locale); + + $propertyLogo = 'https://www.extranetwork.com/assets/img/logo/mini-logo.png'; + if (isset($booking['booking_property']['property_brand']['logo_name'])) { + $propertyLogo = Config::get('app.imageUrl') . '/property-photos/' . $booking['booking_property']['id'] . "/logo/" . $booking['booking_property']['property_brand']['logo_name'] . '_250x250.' . $booking['booking_property']['property_brand']['logo_file_ext']; + } + + $bookingContact = [ + 'mail' => $booking['booking_contact']['email'], + 'nameSurname' => $booking['booking_contact']['nameSurname'], + ]; + + if (!isset($booking['booking_property']['property_executive'])) { + throw new ApiErrorException(lang('Property Executive not found')); + } + + $propertyExecutives = collect($booking['booking_property']['property_executive'])->where('status', 1)->where('executive_type_id', 7)->pluck('email')->toArray(); + + $params['subject'] = __('api-mailing-booking_ticket-subject', ['booking_code' => $booking['booking_code']]);//'Booking Ticket Message: ' . $booking['booking_code']; + $params['mailSenderName'] = 'Extranetwork - ' . $booking['booking_property']['name']; + + if (!is_null($params['user'])) { + + $mailParams = [ + 'to' => $bookingContact['mail'], + 'toNameSurname' => $bookingContact['mail'], + 'bcc' => [], + 'title' => __('general-hi') . ', ' . $bookingContact['nameSurname'], + 'logo' => $propertyLogo, + 'message' => __('api-mailing-booking_ticket-message-user', ['booking_code' => $booking['booking_code']]), + 'btnTitle' => __('api-mailing-booking_ticket-btn-message'), + 'btnUrl' => config('app.bookingEngineUrl') . '/' . $booking['booking_property']['property_booking_engine_token']['token'] . '/' . $locale . '/booking-detail/' . $booking['booking_code'], + ]; + + } else { + + if (empty($propertyExecutives)) { + throw new ApiErrorException(lang('Property Executive not found')); + } + + $mailParams = [ + 'to' => $propertyExecutives[0], + 'toNameSurname' => null, + 'bcc' => $propertyExecutives, + 'title' => __('general-hi') . ',', + 'logo' => $propertyLogo, + 'message' => __('api-mailing-booking_ticket-message-enw-user', ['booking_code' => $booking['booking_code'], 'property_name' => $booking['booking_property']['name']]), + 'btnTitle' => __('api-mailing-booking_ticket-btn-message'), + 'btnUrl' => config('app.client_server') . '/app/network/reservation/' . $booking['id'].'?propertyid='.$booking['property_id'], + ]; + + } + + //$bcc[] = "sales@extranetwork.com"; + $bcc = $mailParams['bcc']; + $bcc[] = "channel@extranetwork.com"; + + /*echo view('emails.bookingTicketMail', compact('mailParams')); + die();*/ + + return $this->from($mailSenderAddress, $params['mailSenderName']) + ->view('emails.bookingTicketMail', compact('mailParams')) + ->to($mailParams['to'], $mailParams['toNameSurname']) + ->bcc($bcc) + ->subject($params['subject']); + + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + die(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + die(); + } + + } + +} diff --git a/app/Core/Mail/CancelBookingMail.php b/app/Core/Mail/CancelBookingMail.php new file mode 100644 index 0000000..f40e959 --- /dev/null +++ b/app/Core/Mail/CancelBookingMail.php @@ -0,0 +1,277 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + + $propertyService = App::make("App\Core\Service\PropertyService"); + $bookingService = App::make("App\Core\Service\BookingService"); + $propertyBrandService = App::make("App\Core\Service\PropertyBrandService"); + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => [ + 'bookingPayment', 'bookingRoom.roomRateMapping.propertyRoom','bookingRoom.roomRateMapping.propertyRoomRate', + 'bookingContact','bookingProperty.propertyBrand', 'bookingProperty.propertyExecutive', 'bookingProperty.propertyUser.user', + 'bookingPropertyWeb', 'propertyBookingEngine', 'propertyBookingChannel' + ], + 'firstRow' => true + ]; + + $bookingData = $bookingService->select($bookingDetailParam); + $bookingData = $bookingData['data']; + + + $hostAddress = Config::get('app.bookingEngineUrl') . '/' . $bookingData['property_booking_engine']['token'] . '/' . $bookingData['booking_contact']['language_code'] . '/booking-detail/' . $bookingData['booking_code']; + + $brandRequestData = ['property_id' => $bookingData['property_id']]; + $getPropertyBrand = $propertyBrandService->getPropertyBrand($brandRequestData); + if ($getPropertyBrand['status'] != "success") { + throw new Exception($getPropertyBrand['message']); + } + + $propertyBrand = $getPropertyBrand['data']; + $propertyBrandLogo = isset($propertyBrand['name']) + ? Config::get('app.fileSystemDriver') . '/property-photos/' . $propertyBrand['property_id'] . "/logo/" . $propertyBrand['name'] . '_250x250.' . $propertyBrand['logo_file_ext'] + : null; + + $roomOrder = 1; + $bookingChannelRoom = []; + foreach ($bookingData['booking_room'] as $bookingRoom) { + + if (!empty($bookingRoom['room_rate_mapping']['property_room'])) { + $bookingRoom['room_name'] = $bookingRoom['room_rate_mapping']['property_room']['name']; + } + if (!empty($bookingRoom['room_rate_mapping']['property_room_rate'])) { + $bookingRoom['room_rate_name'] = $bookingRoom['room_rate_mapping']['property_room_rate']['name']; + } + + $extraParam = null; + if (!empty($bookingRoom['extra_param'])) { + $extraParamDecode = json_decode($bookingRoom['extra_param'], 1); + + foreach ($extraParamDecode as $extraParamKey => $extraParamValue) { + + $extraParamTitle = explode('_', $extraParamKey); + foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) { + $extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue); + } + $extraParamTitle = implode(' ', $extraParamTitle); + + $extraParam[$extraParamKey] = [ + 'title' => $extraParamTitle, + 'value' => $extraParamValue, + ]; + } + + } + + $additionalFee = null; + if (!empty($bookingRoom['rate_detail'])) { + $rateDetail = json_decode($bookingRoom['rate_detail'], 1); + if(isset($rateDetail['taxes']) && $bookingData['channel_manager_id'] == 2) { + $additionalFee = $rateDetail['taxes']; + } + } + + $bookingChannelRoom[] = [ + 'roomOrder' => $roomOrder, + 'roomName' => $bookingRoom['room_name'], + 'roomRateName' => $bookingRoom['room_rate_name'], + 'occupancyCode' => $bookingRoom['occupancy_code'], + 'occupancyText' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'amount' => $bookingRoom['amount'], + 'discount_amount' => $bookingRoom['discount_amount'], + 'total' => $bookingRoom['total'], + 'currencyCode' => $bookingRoom['currency_code'], + 'dailyAmount' => !empty($bookingRoom['daily_amount']) ? json_decode($bookingRoom['daily_amount'],1) : null, + 'extraParam' => $extraParam, + 'occupancyFormatted' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'additionalFee' => $additionalFee + ]; + + //$bookingChannelRoom[] = $roomOrder . '. ' . $bookingRoom['room_name'] . ' - ' . $bookingRoom['room_rate_name'] . ' - ' . occupancyCodeFormatted($bookingRoom['occupancy_code']); + $roomOrder++; + } + + $userData = $bookingData['booking_property']['property_user']; + $firstUserData = reset($userData); + + if (in_array($bookingData['property_booking_channel']['channel_category_id'], [2,3])) { + $bookingLanguageCode = fillOnUndefined($bookingData['booking_contact'], 'language_code', 'en'); + }else { + $bookingLanguageCode = fillOnUndefined($firstUserData['user'], 'language', 'en'); + } + + $bookingChannelPaymentType = __('property_booking_payment_type-pay_at_hotel',[],$bookingLanguageCode); + $bookingChannelPaymentSource = null; + if ($bookingData['booking_payment']['payment_type_code'] == 'CRD') { + $bookingChannelPaymentType = __('property_booking_payment_type-credit_card',[],$bookingLanguageCode); + if ($bookingData['booking_payment']['payment_source_code'] == 'OTA') { + $bookingChannelPaymentSource = __('enw-ota-credit_card',[],$bookingLanguageCode); + } + if ($bookingData['booking_payment']['payment_source_code'] == 'GST') { + $bookingChannelPaymentSource = __('enw-guest-credit_card',[],$bookingLanguageCode); + } + } + + $creditCardInformation = null; + if (!is_null($bookingData['booking_payment']['extra_param'])) { + $paymentData = json_decode($bookingData['booking_payment']['extra_param'], 1); + + if (isset($paymentData['attributes']['guarantee'])) { + $creditCardInformation['cardNumber'] = isset($paymentData['attributes']['guarantee']['card_number']) ? $paymentData['attributes']['guarantee']['card_number'] : null; + $creditCardInformation['cardHolderName'] = isset($paymentData['attributes']['guarantee']['cardholder_name']) ? $paymentData['attributes']['guarantee']['cardholder_name'] : null; + $creditCardInformation['expirationDate'] = isset($paymentData['attributes']['guarantee']['expiration_date']) ? $paymentData['attributes']['guarantee']['expiration_date'] : null; + $creditCardInformation['cvv'] = isset($paymentData['attributes']['guarantee']['cvv']) ? $paymentData['attributes']['guarantee']['cvv'] : null; + } + } + + //Genius Member + $bookingContactExtraParam = null; + if(!empty($bookingData['booking_contact']['extra_param'])) { + $bookingContactExtraParam = json_decode($bookingData['booking_contact']['extra_param'],1); + } + $isBookingGenius = false; + if(isset($bookingContactExtraParam['is_genius']) && $bookingContactExtraParam['is_genius']) { + $isBookingGenius = true; + } + + $mailParams = [ + 'bookingId' => $bookingData['id'], + 'bookingCode' => $bookingData['booking_code'], + 'propertyId' => $bookingData['booking_property']['id'], + 'booking_code' => $bookingData['booking_code'], + 'search_key' => $bookingData['search_key'], + 'channel_token' => $bookingData['channel_token'], + 'booking_engine_token' => $bookingData['booking_engine_token'], + 'checkin_date' => Carbon::parse($bookingData['checkin_date'])->format('d.m.Y'), + 'checkout_date' => Carbon::parse($bookingData['checkout_date'])->format('d.m.Y'), + 'payment_type_code' => $bookingData['booking_payment']['payment_type_code'], + 'payment_source_code' => $bookingData['booking_payment']['payment_source_code'], + 'room_amount' => $bookingData['room_amount'], + 'addon_amount' => $bookingData['addon_amount'], + 'discount_amount' => $bookingData['discount_amount'], + 'total' => $bookingData['total'], + 'currency_code' => $bookingData['currency_code'], + 'name_surname' => $bookingData['booking_contact']['nameSurname'], + 'countryCode' => upperCase($bookingData['booking_contact']['country_code']), + 'email' => $bookingData['booking_contact']['email'], + 'property_name' => $bookingData['booking_property']['name'], + 'url' => $hostAddress, + 'logo' => $bookingData['booking_property']['property_brand']['logoUrl'], + 'language_code' => $bookingData['booking_contact']['language_code'], + 'bookingChannelId' => $bookingData['channel_id'], + 'bookingChannelName' => fillOnUndefined($bookingData['property_booking_channel'], 'name'), + 'bookingChannelCategoryId' => $bookingData['property_booking_channel']['channel_category_id'], + 'bookingChannelCode' => $bookingData['channel_booking_code'], + 'bookingChannelContactNameSurname' => $bookingData['booking_contact']['nameSurname'], + 'bookingChannelContactEmail' => $bookingData['booking_contact']['email'], + 'bookingChannelContactPhone' => $bookingData['booking_contact']['phone_number'], + 'bookingChannelNote' => $bookingData['booking_contact']['note'], + 'bookingChannelRoom' => $bookingChannelRoom, + 'bookingChannelPaymentType' => $bookingChannelPaymentType, + 'bookingChannelPaymentSource' => $bookingChannelPaymentSource, + 'creditCardInformation' => $creditCardInformation, + 'isBookingGenius' => $isBookingGenius + ]; + + //Mail Contact Data + $reservationExecutives = []; + if (isset($bookingData['booking_property']['property_executive'])) { + $reservationExecutives = collect($bookingData['booking_property']['property_executive']) + ->where('executive_type_id', '=', '7') // sadece rezervasyon yetkisi olanlar ... + ->values()->all(); + } + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + $bcc[] = "channel@extranetwork.com"; + + foreach ($userData as $user) { + if ($user['user']['email'] != $firstUserData['user']['email']) { + $bcc[] = $user['user']['email']; + } + } + + //Booking Engine ve Offline Channel to Customer Info's + if (in_array($bookingData['property_booking_channel']['channel_category_id'], [2,3])) { + $mailData = [ + 'to' => [ + 'name' => $bookingData['booking_contact']['nameSurname'], + 'email' => $bookingData['booking_contact']['email'] + ] + ]; + } else { + $mailData = [ + 'to' => [ + 'name' => $bookingData['booking_property']['name'], + 'email' => $firstUserData['user']['email'] + ] + ]; + } + + $mailData['bcc'] = $bcc; + + + $mailSenderAddress = Config::get('app.mailSenderAddress'); + //app('translator')->setLocale(fillOnUndefined($firstUserData['user'], 'language', 'tr')); + app('translator')->setLocale($bookingLanguageCode); + + $mailParams['showCreditCardUrl'] = null; + if(!empty($mailParams['creditCardInformation'])) { + $mailParams['showCreditCardUrl'] = Config::get('app.client_server').'/app/network/reservation/'.$mailParams['bookingId'].'?propertyid='.$mailParams['propertyId']; + } + + /*echo view('emails.cancelBookingMail', compact('mailParams')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.cancelBookingMail', compact('mailParams')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject(__('api-malling-booking-cancel_booking-title', ['channel' => $mailParams['bookingChannelName']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/ChannelManagerNotificationMail.php b/app/Core/Mail/ChannelManagerNotificationMail.php new file mode 100644 index 0000000..ff90f71 --- /dev/null +++ b/app/Core/Mail/ChannelManagerNotificationMail.php @@ -0,0 +1,70 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $propertyService = App::make('App\Core\Service\PropertyService'); + + $requestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['propertyId']] + ], + 'with' => ['propertyUser.user'], + 'firstRow' => true + ]; + + $propertyDetail = $propertyService->select($requestData); + + $propertyUser = []; + if($propertyDetail['status'] == 'success' && !empty($propertyDetail['data'])) { + $propertyUser = collect($propertyDetail['data']['property_user'])->where('status',1)->pluck('user.email')->toArray(); + } + + /*echo view('emails.channelManagerNotificationMail', compact('params')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.channelManagerNotificationMail', compact('params')) + ->to('channel@extranetwork.com', 'Extranetwork Channel') + ->bcc($propertyUser) + ->subject('Channel Update Error: ' . $params['propertyName']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/ContactFormMail.php b/app/Core/Mail/ContactFormMail.php new file mode 100644 index 0000000..1caa777 --- /dev/null +++ b/app/Core/Mail/ContactFormMail.php @@ -0,0 +1,58 @@ +param = $param; + } + + public function build () + { + try + { + $params = $this->param; + $mailParams = $params['mailViewParams'] ; + $mailData = $params['mailData'] ; + $mailSenderAddress = Config::get('app.mailSenderAddress') ; + $mailTitle = $mailData['to']["name"]. ' Contact Form (' . $mailParams['name']. ' '.$mailParams['surname']. ')' ; + + + app('translator')->setLocale('en'); + + return $this->from($mailSenderAddress, $mailParams['name']. ' '.$mailParams['surname']) + ->view('emails.contactFormMail', compact('mailParams', 'mailTitle')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject($mailTitle) + ->with(['message' => $this]); + + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Mail/DailyReportMail.php b/app/Core/Mail/DailyReportMail.php new file mode 100644 index 0000000..b8ba479 --- /dev/null +++ b/app/Core/Mail/DailyReportMail.php @@ -0,0 +1,55 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + /*echo view('emails.dailyReportMail', compact('params')); + die();*/ + + $to = 'yoy@extranetwork.com'; + $bcc[] = 'burhan@extranetwork.com'; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.dailyReportMail', compact('params')) + ->to($to, 'Extranetwork') + ->bcc($bcc) + ->subject('Extranetwork Summary Report - '. $params['daily']['period']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/DailyReportMailSales.php b/app/Core/Mail/DailyReportMailSales.php new file mode 100644 index 0000000..ccdb9e6 --- /dev/null +++ b/app/Core/Mail/DailyReportMailSales.php @@ -0,0 +1,58 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + + /*echo view('emails.dailyReportMailSales', compact('params')); + die();*/ + + $to = $params['email']; + $bcc[] = 'yoy@extranetwork.com'; + $bcc[] = 'burhan@extranetwork.com'; + $bcc[] = 'cemile@extranetwork.com'; + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.dailyReportMailSales', compact('params')) + ->to($to, 'Extranetwork') + ->bcc($bcc) + ->subject('Extranetwork Summary Report - '. $params['daily']['period'].' - '. $params['name']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/EnwContactFormMail.php b/app/Core/Mail/EnwContactFormMail.php new file mode 100644 index 0000000..fbbbc00 --- /dev/null +++ b/app/Core/Mail/EnwContactFormMail.php @@ -0,0 +1,54 @@ +param = $param; + } + + public function build () + { + try + { + $params = $this->param; + $mailParams = $params['mailViewParams'] ; + $mailData = $params['mailData'] ; + $mailTitle = __('myweb-contact-contact_form-title'); + + app('translator')->setLocale($mailParams['language']); + + return $this->view('emails.enwContactFormMail', compact('mailParams', 'mailTitle')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject($mailTitle); + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Mail/InventoryActionMail.php b/app/Core/Mail/InventoryActionMail.php new file mode 100644 index 0000000..3c08820 --- /dev/null +++ b/app/Core/Mail/InventoryActionMail.php @@ -0,0 +1,60 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + app('translator')->setLocale(fillOnUndefined($params, 'locale', 'en')); + + $params['title'] = $params['propertyName'] . ' - ' . __('enw-action-mail-title'); + $params['channelContact'] = $params['channelContact']; + + if(empty($params['channelContact'])) { + return false; + } + + /*echo view('emails.inventoryActionMail', compact('params')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - '.$params['propertyName']) + ->view('emails.inventoryActionMail', compact('params')) + //->to($logMailAddress, 'Development Team') + ->bcc($params['channelContact']) + ->subject($params['title']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/InventoryPdfLinkMail.php b/app/Core/Mail/InventoryPdfLinkMail.php new file mode 100644 index 0000000..f60480c --- /dev/null +++ b/app/Core/Mail/InventoryPdfLinkMail.php @@ -0,0 +1,60 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + app('translator')->setLocale(fillOnUndefined($params, 'locale', 'en')); + + $params['title'] = $params['propertyName'] . ' - ' . __('enw-inventory-mail-pdf-link'); + $params['channelContact'] = $params['channelContact']; + + if(empty($params['channelContact'])) { + return false; + } + + /*echo view('emails.inventoryActionMail', compact('params')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - '.$params['propertyName']) + ->view('emails.inventoryPdfLinkMail', compact('params')) + //->to($logMailAddress, 'Development Team') + ->bcc($params['channelContact']) + ->subject($params['title']); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/LogMail.php b/app/Core/Mail/LogMail.php new file mode 100644 index 0000000..217cbb6 --- /dev/null +++ b/app/Core/Mail/LogMail.php @@ -0,0 +1,52 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + $logMailAddress = Config::get('app.logMailAddress'); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $params['title'] = 'ENW LOG - ' . $params['title']; + + app('translator')->setLocale('tr'); + + return $this->from($mailSenderAddress, 'Development Team') + ->view('emails.logMail', compact('params')) + ->to($logMailAddress, 'Development Team') + //->bcc(['bd@extranetwork.com']) + ->subject($params['title']); + + } catch (\Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/ManualPaymentMail.php b/app/Core/Mail/ManualPaymentMail.php new file mode 100644 index 0000000..42966d2 --- /dev/null +++ b/app/Core/Mail/ManualPaymentMail.php @@ -0,0 +1,64 @@ +param = $param; + } + + public function build () + { + try + { + $params = $this->param; + $mailParams = $params['mailViewParams'] ; + + $mailData = $params['mailData'] ; + $mailSenderAddress = Config::get('app.mailSenderAddress') ; + app('translator')->setLocale($mailParams["language_code"]); + + $description = __('api-manual_payment_mail-desc',[ + 'title' => $mailParams['process_title'] , + 'date' => $mailParams['date_time'], + 'amount' => $mailParams['amount'], + 'currency' => $mailParams['currency'] + ]); + + return $this->from($mailSenderAddress, 'Extranetwork - '.$mailParams['property_name']) + ->view('emails.manualPaymentMail', compact('mailParams', 'description')) + ->to($mailData['to']["email"]) + ->bcc($mailData['bcc']) + ->subject(__('api-manual_payment_mail-subject')) + ->with(['message' => $this]); + + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Mail/ModifiedBookingMail.php b/app/Core/Mail/ModifiedBookingMail.php new file mode 100644 index 0000000..ce45eb6 --- /dev/null +++ b/app/Core/Mail/ModifiedBookingMail.php @@ -0,0 +1,264 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + + $propertyService = App::make("App\Core\Service\PropertyService"); + $bookingService = App::make("App\Core\Service\BookingService"); + $propertyBrandService = App::make("App\Core\Service\PropertyBrandService"); + + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => [ + 'bookingPayment', 'bookingRoom.roomRateMapping.propertyRoom','bookingRoom.roomRateMapping.propertyRoomRate', + 'bookingContact','bookingProperty.propertyBrand', 'bookingProperty.propertyExecutive', 'bookingProperty.propertyUser.user', + 'bookingPropertyWeb', 'propertyBookingEngine', 'propertyBookingChannel' + ], + 'firstRow' => true + ]; + + $bookingData = $bookingService->select($bookingDetailParam); + $bookingData = $bookingData['data']; + + + $hostAddress = Config::get('app.bookingEngineUrl') . '/' . $bookingData['property_booking_engine']['token'] . '/' . $bookingData['booking_contact']['language_code'] . '/booking-detail/' . $bookingData['booking_code']; + + $brandRequestData = ['property_id' => $bookingData['property_id']]; + $getPropertyBrand = $propertyBrandService->getPropertyBrand($brandRequestData); + if ($getPropertyBrand['status'] != "success") { + throw new Exception($getPropertyBrand['message']); + } + + $propertyBrand = $getPropertyBrand['data']; + $propertyBrandLogo = isset($propertyBrand['name']) + ? Config::get('app.fileSystemDriver') . '/property-photos/' . $propertyBrand['property_id'] . "/logo/" . $propertyBrand['name'] . '_250x250.' . $propertyBrand['logo_file_ext'] + : null; + + $roomOrder = 1; + $bookingChannelRoom = []; + foreach ($bookingData['booking_room'] as $bookingRoom) { + + if (!empty($bookingRoom['room_rate_mapping']['property_room'])) { + $bookingRoom['room_name'] = $bookingRoom['room_rate_mapping']['property_room']['name']; + } + if (!empty($bookingRoom['room_rate_mapping']['property_room_rate'])) { + $bookingRoom['room_rate_name'] = $bookingRoom['room_rate_mapping']['property_room_rate']['name']; + } + + $extraParam = null; + if (!empty($bookingRoom['extra_param'])) { + $extraParamDecode = json_decode($bookingRoom['extra_param'], 1); + + foreach ($extraParamDecode as $extraParamKey => $extraParamValue) { + + $extraParamTitle = explode('_', $extraParamKey); + foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) { + $extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue); + } + $extraParamTitle = implode(' ', $extraParamTitle); + + $extraParam[$extraParamKey] = [ + 'title' => $extraParamTitle, + 'value' => $extraParamValue, + ]; + } + + } + + $additionalFee = null; + if (!empty($bookingRoom['rate_detail'])) { + $rateDetail = json_decode($bookingRoom['rate_detail'], 1); + if(isset($rateDetail['taxes']) && $bookingData['channel_manager_id'] == 2) { + $additionalFee = $rateDetail['taxes']; + } + } + + $bookingChannelRoom[] = [ + 'roomOrder' => $roomOrder, + 'roomName' => $bookingRoom['room_name'], + 'roomRateName' => $bookingRoom['room_rate_name'], + 'occupancyCode' => $bookingRoom['occupancy_code'], + 'occupancyText' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'amount' => $bookingRoom['amount'], + 'discount_amount' => $bookingRoom['discount_amount'], + 'total' => $bookingRoom['total'], + 'currencyCode' => $bookingRoom['currency_code'], + 'dailyAmount' => !empty($bookingRoom['daily_amount']) ? json_decode($bookingRoom['daily_amount'],1) : null, + 'extraParam' => $extraParam, + 'occupancyFormatted' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'additionalFee' => $additionalFee + ]; + + //$bookingChannelRoom[] = $roomOrder . '. ' . $bookingRoom['room_name'] . ' - ' . $bookingRoom['room_rate_name'] . ' - ' . occupancyCodeFormatted($bookingRoom['occupancy_code']); + $roomOrder++; + } + + $userData = $bookingData['booking_property']['property_user']; + $firstUserData = reset($userData); + + $bookingLanguageCode = fillOnUndefined($firstUserData['user'], 'language', 'en'); + $bookingChannelPaymentType = __('property_booking_payment_type-pay_at_hotel',[],$bookingLanguageCode); + $bookingChannelPaymentSource = null; + if ($bookingData['booking_payment']['payment_type_code'] == 'CRD') { + $bookingChannelPaymentType = __('property_booking_payment_type-credit_card',[],$bookingLanguageCode); + if ($bookingData['booking_payment']['payment_source_code'] == 'OTA') { + $bookingChannelPaymentSource = __('enw-ota-credit_card',[],$bookingLanguageCode); + } + if ($bookingData['booking_payment']['payment_source_code'] == 'GST') { + $bookingChannelPaymentSource = __('enw-guest-credit_card',[],$bookingLanguageCode); + } + } + + $creditCardInformation = null; + if (!is_null($bookingData['booking_payment']['extra_param'])) { + $paymentData = json_decode($bookingData['booking_payment']['extra_param'], 1); + + if (isset($paymentData['attributes']['guarantee'])) { + $creditCardInformation['cardNumber'] = isset($paymentData['attributes']['guarantee']['card_number']) ? $paymentData['attributes']['guarantee']['card_number'] : null; + $creditCardInformation['cardHolderName'] = isset($paymentData['attributes']['guarantee']['cardholder_name']) ? $paymentData['attributes']['guarantee']['cardholder_name'] : null; + $creditCardInformation['expirationDate'] = isset($paymentData['attributes']['guarantee']['expiration_date']) ? $paymentData['attributes']['guarantee']['expiration_date'] : null; + $creditCardInformation['cvv'] = isset($paymentData['attributes']['guarantee']['cvv']) ? $paymentData['attributes']['guarantee']['cvv'] : null; + } + } + + //Genius Member + $bookingContactExtraParam = null; + if(!empty($bookingData['booking_contact']['extra_param'])) { + $bookingContactExtraParam = json_decode($bookingData['booking_contact']['extra_param'],1); + } + $isBookingGenius = false; + if(isset($bookingContactExtraParam['is_genius']) && $bookingContactExtraParam['is_genius']) { + $isBookingGenius = true; + } + + $mailParams = [ + 'bookingId' => $bookingData['id'], + 'bookingCode' => $bookingData['booking_code'], + 'propertyId' => $bookingData['booking_property']['id'], + 'booking_code' => $bookingData['booking_code'], + 'search_key' => $bookingData['search_key'], + 'channel_token' => $bookingData['channel_token'], + 'booking_engine_token' => $bookingData['booking_engine_token'], + 'checkin_date' => Carbon::parse($bookingData['checkin_date'])->format('d.m.Y'), + 'checkout_date' => Carbon::parse($bookingData['checkout_date'])->format('d.m.Y'), + 'payment_type_code' => $bookingData['booking_payment']['payment_type_code'], + 'payment_source_code' => $bookingData['booking_payment']['payment_source_code'], + 'room_amount' => $bookingData['room_amount'], + 'addon_amount' => $bookingData['addon_amount'], + 'discount_amount' => $bookingData['discount_amount'], + 'total' => $bookingData['total'], + 'currency_code' => $bookingData['currency_code'], + 'name_surname' => $bookingData['booking_contact']['nameSurname'], + 'countryCode' => upperCase($bookingData['booking_contact']['country_code']), + 'email' => $bookingData['booking_contact']['email'], + 'property_name' => $bookingData['booking_property']['name'], + 'url' => $hostAddress, + 'logo' => $bookingData['booking_property']['property_brand']['logoUrl'], + 'language_code' => $bookingData['booking_contact']['language_code'], + 'bookingChannelId' => $bookingData['channel_id'], + 'bookingChannelName' => fillOnUndefined($bookingData['property_booking_channel'], 'name'), + 'bookingChannelCategoryId' => $bookingData['property_booking_channel']['channel_category_id'], + 'bookingChannelCode' => $bookingData['channel_booking_code'], + 'bookingChannelContactNameSurname' => $bookingData['booking_contact']['nameSurname'], + 'bookingChannelContactEmail' => $bookingData['booking_contact']['email'], + 'bookingChannelContactPhone' => $bookingData['booking_contact']['phone_number'], + 'bookingChannelNote' => $bookingData['booking_contact']['note'], + 'bookingChannelRoom' => $bookingChannelRoom, + 'bookingChannelPaymentType' => $bookingChannelPaymentType, + 'bookingChannelPaymentSource' => $bookingChannelPaymentSource, + 'creditCardInformation' => $creditCardInformation, + 'isBookingGenius' => $isBookingGenius + ]; + + //Mail Contact Data + $reservationExecutives = []; + if (isset($bookingData['booking_property']['property_executive'])) { + $reservationExecutives = collect($bookingData['booking_property']['property_executive']) + ->where('executive_type_id', '=', '7') // sadece rezervasyon yetkisi olanlar ... + ->values()->all(); + } + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + $bcc[] = "channel@extranetwork.com"; + + + + foreach ($userData as $user) { + if ($user['user']['email'] != $firstUserData['user']['email']) { + $bcc[] = $user['user']['email']; + } + } + + $mailData = [ + 'to' => [ + 'name' => $firstUserData['user']['nameSurname'], + 'email' => $firstUserData['user']['email'], + ], + 'bcc' => $bcc + ]; + + $mailSenderAddress = Config::get('app.mailSenderAddress'); + //app('translator')->setLocale(fillOnUndefined($firstUserData['user'], 'language', 'tr')); + app('translator')->setLocale($bookingLanguageCode); + + $mailParams['showCreditCardUrl'] = null; + if(!empty($mailParams['creditCardInformation'])) { + $mailParams['showCreditCardUrl'] = Config::get('app.client_server').'/app/network/reservation/'.$mailParams['bookingId'].'?propertyid='.$mailParams['propertyId']; + } + + /*echo view('emails.modifiedBookingMail', compact('mailParams')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.modifiedBookingMail', compact('mailParams')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject(__('api-mailing-booking-modified_booking-title', ['channel' => $mailParams['bookingChannelName']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/NewBookingMail.php b/app/Core/Mail/NewBookingMail.php new file mode 100644 index 0000000..4cbb0bb --- /dev/null +++ b/app/Core/Mail/NewBookingMail.php @@ -0,0 +1,68 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + $mailParams = $params['mailViewParams']; + + $mailData = $params['mailData']; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + app('translator')->setLocale($mailParams["language_code"]); + + $bookingData = __('api-mailling-booking-desc', [ + 'booking_code' => $mailParams['booking_code'], + 'property_name' => $mailParams['property_name'], + 'checkin_date' => $mailParams['checkin_date'], + 'checkout_date' => $mailParams['checkout_date'] + ]); + + $mailSubject = __('api-malling-booking-new_booking_info-title'); + if (isset($mailParams['bookingChannelCategoryId']) && $mailParams['bookingChannelCategoryId'] != 3) { + $mailSubject = $mailParams['bookingChannelName'] . ' - ' . $mailSubject; + } + + /*echo view('emails.newBookingMail', compact('mailParams', 'bookingData')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.newBookingMail', compact('mailParams', 'bookingData')) + ->to($mailData['to']["email"], $mailData['to']["name"]) + ->bcc($mailData['bcc']) + ->subject('🛎️ '.$mailSubject) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/OfferAcceptMail.php b/app/Core/Mail/OfferAcceptMail.php new file mode 100644 index 0000000..a6c48c4 --- /dev/null +++ b/app/Core/Mail/OfferAcceptMail.php @@ -0,0 +1,106 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + + $propertyService = App::make("App\Core\Service\OfferService"); + + $requestParams = [ + 'offer_id' => fillOnUndefined($params, 'offer_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + + $offerDetail = $propertyService->findOffer($requestParams); + $offerDetail = fillOnUndefined($offerDetail, 'data'); + + app('translator')->setLocale($offerDetail["language"]); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $mailParams['to'] = []; + $mailParams['to'] = $offerDetail['email']; + + $mailParams['cc'] = []; + if (!empty($offerDetail['create_user'])) { + $mailParams['cc'][] = $offerDetail['create_user']['email']; + } + + $mailParams['bcc'] = []; + $mailParams['bcc'][] = Config::get('app.logMailAddress'); + + + $mailParams['property_name'] = $offerDetail['property']['name']; + $mailParams['url'] = Config::get('app.client_server').'/offer/'.$offerDetail['offer_code']; + + + $mailParams['paymentUrl'] = null; + if(isset($params['paymentUrl']) && !is_null($params['paymentUrl'])) { + $mailParams['paymentUrl'] = $params['paymentUrl']; + } + + $description = []; + //$description[] = ''.$offerDetail['property']['name'].' tarafından oluşturulan '.$offerDetail['ticket_code'].' kodlu teklif onaylanmıştır.'; + $description[] = __('api-mailing-offer_accept_mail-description', ['propertyName' => $offerDetail['property']['name'], 'code' => $offerDetail['ticket_code']]); + + if(!is_null($offerDetail['payment_type_mapping_id']) && !empty($mailParams['paymentUrl'])) { + //$description[] = 'Teklife ait ödemenizi aşağıdaki Ödeme Linki üzerinden güvenle gerçekleştirebilirsiniz.'; + $description[] = __('api-mailing-offer_accept_mail-payment'); + } + + $description = implode('

', $description); + + $mailParams['logo'] = Config::get('app.webUrl').'/assets/img/logo/mini-logo.png'; + if(isset($offerDetail['property_brand']['logoUrl'])) { + $mailParams['logo'] = $offerDetail['property_brand']['logoUrl']; + } + + + /*echo view('emails.offerAcceptMail', compact('mailParams', 'description')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.offerAcceptMail', compact('mailParams', 'description')) + ->to($mailParams['to']) + ->cc($mailParams['cc']) + ->bcc($mailParams['bcc']) + ->subject(__('api-mailing-offer_accept_mail-title', ['code' => $offerDetail['ticket_code']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/OfferPreConfirmCustomerMail.php b/app/Core/Mail/OfferPreConfirmCustomerMail.php new file mode 100644 index 0000000..bfb3036 --- /dev/null +++ b/app/Core/Mail/OfferPreConfirmCustomerMail.php @@ -0,0 +1,91 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + + $propertyService = App::make("App\Core\Service\OfferService"); + + $requestParams = [ + 'offer_id' => fillOnUndefined($params, 'offer_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $offerDetail = $propertyService->findOffer($requestParams); + $offerDetail = fillOnUndefined($offerDetail, 'data'); + + app('translator')->setLocale($offerDetail["language"]); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $mailParams['to'] = []; + $mailParams['to'] = $offerDetail['email']; + + $mailParams['bcc'] = []; + $mailParams['bcc'][] = Config::get('app.logMailAddress'); + + + $mailParams['property_name'] = $offerDetail['property']['name']; + $mailParams['url'] = Config::get('app.client_server').'/offer/'.$offerDetail['offer_code']; + + $mailParams['logo'] = Config::get('app.webUrl').'/assets/img/logo/mini-logo.png'; + if(isset($offerDetail['property_brand']['logoUrl'])) { + $mailParams['logo'] = $offerDetail['property_brand']['logoUrl']; + } + + $description = []; + //$description[] = ''.$offerDetail['property']['name'].' tarafından oluşturulan '.$offerDetail['ticket_code'].' kodlu teklifi onayladınız.'; + $description[] = __('api-mailing-offer_preconfirm_customer_mail-description-one', ['propertyName' => $offerDetail['property']['name'], 'code' => $offerDetail['ticket_code']]); + //$description[] = 'Onayınız tesisimize bildirilmiştir. Tesisin teklifi onaylaması beklenmektedir, onaya istinaden size dönüş yapılacaktır.'; + $description[] = __('api-mailing-offer_preconfirm_customer_mail-description-two'); + + $description = implode('

', $description); + + + /*echo view('emails.offerPreConfirmCustomerMail', compact('mailParams', 'description')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.offerPreConfirmCustomerMail', compact('mailParams', 'description')) + ->to($mailParams['to']) + ->bcc($mailParams['bcc']) + //->subject($offerDetail['ticket_code'].' Kodlu Teklifiniz Tesis Onayı Bekliyor') + ->subject(__('api-mailing-offer_preconfirm_customer_mail-title', ['code' => $offerDetail['ticket_code']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/OfferPreConfirmPropertyMail.php b/app/Core/Mail/OfferPreConfirmPropertyMail.php new file mode 100644 index 0000000..232fb37 --- /dev/null +++ b/app/Core/Mail/OfferPreConfirmPropertyMail.php @@ -0,0 +1,91 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + + $propertyService = App::make("App\Core\Service\OfferService"); + + $requestParams = [ + 'offer_id' => fillOnUndefined($params, 'offer_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $offerDetail = $propertyService->findOffer($requestParams); + $offerDetail = fillOnUndefined($offerDetail, 'data'); + + app('translator')->setLocale($offerDetail["language"]); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $mailParams['to'] = []; + $mailParams['to'] = $offerDetail['create_user']['email']; + + $mailParams['bcc'] = []; + $mailParams['bcc'][] = Config::get('app.logMailAddress'); + + + $mailParams['property_name'] = $offerDetail['property']['name']; + $mailParams['url'] = Config::get('app.client_server').'/offer/'.$offerDetail['offer_code']; + + $mailParams['logo'] = Config::get('app.webUrl').'/assets/img/logo/mini-logo.png'; + if(isset($offerDetail['property_brand']['logoUrl'])) { + $mailParams['logo'] = $offerDetail['property_brand']['logoUrl']; + } + + $description = []; + //$description[] = 'Misafir, '.$offerDetail['ticket_code'].' kodlu teklifi onaylamıştır.'; + $description[] = __('api-mailing-offer_preconfirm_property_mail-description-one', ['code' => $offerDetail['ticket_code']]); + //$description[] = 'Teklif türü otel onaylı olduğu için, tesis onayı beklenmektedir. Tesis onayını Extranetwork üzerinden verebilirsiniz.'; + $description[] = __('api-mailing-offer_preconfirm_property_mail-description-two'); + + $description = implode('

', $description); + + + /*echo view('emails.offerPreConfirmPropertyMail', compact('mailParams', 'description')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.offerPreConfirmPropertyMail', compact('mailParams', 'description')) + ->to($mailParams['to']) + ->bcc($mailParams['bcc']) + //->subject($offerDetail['ticket_code'].' Kodlu Teklif Misafir Onayı') + ->subject(__('api-mailing-offer_preconfirm_property_mail-title', ['code' => $offerDetail['ticket_code']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/OfferSendMail.php b/app/Core/Mail/OfferSendMail.php new file mode 100644 index 0000000..7cc8b5f --- /dev/null +++ b/app/Core/Mail/OfferSendMail.php @@ -0,0 +1,86 @@ +param = $param; + } + + public function build() + { + try { + $params = $this->param; + + $propertyService = App::make("App\Core\Service\OfferService"); + + $requestParams = [ + 'offer_id' => fillOnUndefined($params, 'offer_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $offerDetail = $propertyService->findOffer($requestParams); + $offerDetail = fillOnUndefined($offerDetail, 'data'); + + app('translator')->setLocale($offerDetail["language"]); + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $mailParams['to'] = []; + $mailParams['to'] = $offerDetail['email']; + + $mailParams['bcc'] = []; + $mailParams['bcc'][] = Config::get('app.logMailAddress'); + + + $mailParams['property_name'] = $offerDetail['property']['name']; + $mailParams['url'] = Config::get('app.client_server').'/offer/'.$offerDetail['offer_code']; + + $mailParams['logo'] = Config::get('app.webUrl').'/assets/img/logo/mini-logo.png'; + if(isset($offerDetail['property_brand']['logoUrl'])) { + $mailParams['logo'] = $offerDetail['property_brand']['logoUrl']; + } + + $description = []; + $description[] = __('api-mailing-offer_mail-description', ['propertyName' => $offerDetail['property']['name'], 'code' => $offerDetail['ticket_code']]); + + $description = implode('

', $description); + + /*echo view('emails.offerMail', compact('mailParams', 'description')); + die();*/ + + return $this->from($mailSenderAddress, 'Extranetwork - ' . $mailParams['property_name']) + ->view('emails.offerMail', compact('mailParams', 'description')) + ->to($mailParams['to']) + ->bcc($mailParams['bcc']) + ->subject(__('api-mailing-offer_mail-title', ['propertyName' => $offerDetail['property']['name'], 'code' => $offerDetail['ticket_code']])) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/PropertyProductOfferMail.php b/app/Core/Mail/PropertyProductOfferMail.php new file mode 100644 index 0000000..dbb2b31 --- /dev/null +++ b/app/Core/Mail/PropertyProductOfferMail.php @@ -0,0 +1,100 @@ +param = $param; + } + + public function build() + { + try { + + $params = $this->param; + + + $propertyProductOffer = PropertyProductOffer::where('offer_key', $params['offerKey'])->first(); + $propertyProductOffer = $propertyProductOffer ? $propertyProductOffer->toArray() : null; + + if (!$propertyProductOffer) { + throw new ApiErrorException('The offer was not found'); + } + + + $mailData = [ + 'to' => [ + 'name' => $propertyProductOffer['executive_name'], + 'email' => $propertyProductOffer['executive_email'], + ], + 'bcc' => ['sales@extranetwork.com'] + + ]; + + $mailData['cc'] = []; + if (isset($propertyProductOffer['account_manager_email'])) { + $mailData['cc'][] = $propertyProductOffer['account_manager_email']; + } + + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $mailParams = [ + 'property_name' => $propertyProductOffer['property_name'], + 'executive_name' => $propertyProductOffer['executive_name'], + 'executive_email' => $propertyProductOffer['executive_email'], + 'executive_phone' => $propertyProductOffer['executive_phone'], + 'offer_expire_date' => $propertyProductOffer['offerExpireTimeFormatted'], + 'logo' => 'https://www.extranetwork.com/assets/img/logo/mini-logo.png', + 'btnUrl' => config('app.url') . '/property-product-offer/' . $propertyProductOffer['offer_key'] + ]; + + if ($propertyProductOffer['version'] == 'v2') { + $mailParams['btnUrl'] = config('app.webUrl') . '/property-product-offer/' . $propertyProductOffer['offer_key']; + } + + /*echo view('emails.propertyProductOfferMail', compact('mailParams')); + die();*/ + + $subjectMail = 'Extranetwork ' . $mailParams['property_name'] . ' Fiyat Teklifi'; + if (isset($propertyProductOffer['detailArray']['paket'])) { + $subjectMail = 'Extranetwork ' . $mailParams['property_name'] . ' - ' . $propertyProductOffer['detailArray']['paket'] . ' Fiyat Teklifi'; + } + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.propertyProductOfferMail', compact('mailParams')) + ->to($mailData['to']['email'], $mailData['to']['name']) + ->cc($mailData['cc']) + ->bcc($mailData['bcc']) + ->subject($subjectMail) + ->with(['message' => $this]); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/TrialFirstMail.php b/app/Core/Mail/TrialFirstMail.php new file mode 100644 index 0000000..5448c0a --- /dev/null +++ b/app/Core/Mail/TrialFirstMail.php @@ -0,0 +1,104 @@ +param = $param; + } + + public function build() + { + try { + + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $propertyService = App::make('App\Core\Service\PropertyService'); + + $propertySelectCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['propertyId']], + + ], + 'with' => ['userPropertyMapping.user'], + 'firstRow' => true + ]; + + $propertyData = $propertyService->select($propertySelectCriteria); + + if($propertyData['status'] == 'success') { + + + $userPropertyMappingCollect = collect($propertyData['data']['user_property_mapping']); + $userPropertyMapping = $userPropertyMappingCollect->where('status',1)->where('user.status',1)->sortBy('id'); + $userPropertyMapping = $userPropertyMapping ? $userPropertyMapping->toArray() : []; + + + $defaultUser = reset($userPropertyMapping); + + $mailData['to'] = [ + 'email' => $defaultUser['user']['email'], + 'nameSurname' => $defaultUser['user']['nameSurname'], + ]; + + $mailData['bcc'] = []; + foreach ($userPropertyMapping as $user) { + //$mailData['bcc'][] = $user['user']['email']; + } + $mailData['bcc'] = 'channel@extranetwork.com';//TODO: Delete + + $mailParams= [ + 'email' => $mailData['to']['email'], + 'nameSurname' => $mailData['to']['nameSurname'], + 'propertyName' => $propertyData['data']['name'], + ]; + + + $mailTitle = 'Rezervasyonlarını ikiye katlamaya hazır mısın? 🚀'; + //app('translator')->setLocale('en'); + + //echo view('emails.reminder.trialFirstMail', compact('mailParams')); die(); + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.reminder.trialFirstMail', compact('mailParams')) + ->to($mailData['to']['email'], $mailData['to']['nameSurname']) + ->bcc($mailData['bcc']) + ->subject($mailTitle) + ->with(['message' => $this]); + + } + + + } catch (ApiErrorException $e) { + return output(['status' => -1, 'message' => $e->getMessage()]); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + + } + +} diff --git a/app/Core/Mail/TrialSecondMail.php b/app/Core/Mail/TrialSecondMail.php new file mode 100644 index 0000000..9802a09 --- /dev/null +++ b/app/Core/Mail/TrialSecondMail.php @@ -0,0 +1,104 @@ +param = $param; + } + + public function build() + { + try { + + + $params = $this->param; + $mailSenderAddress = Config::get('app.mailSenderAddress'); + + $propertyService = App::make('App\Core\Service\PropertyService'); + + $propertySelectCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['propertyId']], + + ], + 'with' => ['userPropertyMapping.user'], + 'firstRow' => true + ]; + + $propertyData = $propertyService->select($propertySelectCriteria); + + if($propertyData['status'] == 'success') { + + + $userPropertyMappingCollect = collect($propertyData['data']['user_property_mapping']); + $userPropertyMapping = $userPropertyMappingCollect->where('status',1)->where('user.status',1)->sortBy('id'); + $userPropertyMapping = $userPropertyMapping ? $userPropertyMapping->toArray() : []; + + + $defaultUser = reset($userPropertyMapping); + + $mailData['to'] = [ + 'email' => $defaultUser['user']['email'], + 'nameSurname' => $defaultUser['user']['nameSurname'], + ]; + + $mailData['bcc'] = []; + foreach ($userPropertyMapping as $user) { + //$mailData['bcc'][] = $user['user']['email']; + } + $mailData['bcc'] = 'channel@extranetwork.com';//TODO: Delete + + $mailParams= [ + 'email' => $mailData['to']['email'], + 'nameSurname' => $mailData['to']['nameSurname'], + 'propertyName' => $propertyData['data']['name'], + ]; + + + $mailTitle = 'Çok görünürlük, daha çok satış.😎'; + //app('translator')->setLocale('en'); + + //echo view('emails.reminder.trialSecondMail', compact('mailParams')); die(); + + return $this->from($mailSenderAddress, 'Extranetwork') + ->view('emails.reminder.trialSecondMail', compact('mailParams')) + ->to($mailData['to']['email'], $mailData['to']['nameSurname']) + ->bcc($mailData['bcc']) + ->subject($mailTitle) + ->with(['message' => $this]); + + } + + + } catch (ApiErrorException $e) { + return output(['status' => -1, 'message' => $e->getMessage()]); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + + } + +} diff --git a/app/Core/Mail/UserCreateMail.php b/app/Core/Mail/UserCreateMail.php new file mode 100644 index 0000000..5d6c45c --- /dev/null +++ b/app/Core/Mail/UserCreateMail.php @@ -0,0 +1,46 @@ +param = $param; + } + + + public function build() + { + try { + + $params = $this->param; + app('translator')->setLocale($params["language"]); + return $this->view('emails.createUserMail', compact('params')) + ->to($params["email"], $params["name_surname"]) + ->subject(__('api-mailing-new_user_subject')); + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Mail/UserForgotPassword.php b/app/Core/Mail/UserForgotPassword.php new file mode 100644 index 0000000..597e9ef --- /dev/null +++ b/app/Core/Mail/UserForgotPassword.php @@ -0,0 +1,48 @@ +param = $param; + } + + public function build () + { + try + { + $params = $this->param; + app('translator')->setLocale($params["language"]); + return $this->view('emails.userForgotPassword', compact('params')) + ->to($params["email"], $params["name_surname"]) + ->subject(__('api-mailing-user_forgot_password_subject')) + ->with(['message' => $this]); + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Mail/WellcomeMail.php b/app/Core/Mail/WellcomeMail.php new file mode 100644 index 0000000..2365bf6 --- /dev/null +++ b/app/Core/Mail/WellcomeMail.php @@ -0,0 +1,47 @@ +param = $param; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + + $val = $this->param; + Log::debug($val); + return $this->view('emails.wellCome', compact('val')) + ->to('ygundogdu@rezervasyon.com', 'yadican') + ->bcc('ygundogdu@rezervasyon.com', 'Burhan YUMAK') + ->bcc('ygundogdu@rezervasyon.com', 'Operasyon') + ->subject("WellCome Mail"); + } +} \ No newline at end of file diff --git a/app/Core/Payment/BankOfGeorgia/BankOfGeorgia.php b/app/Core/Payment/BankOfGeorgia/BankOfGeorgia.php new file mode 100644 index 0000000..3a86022 --- /dev/null +++ b/app/Core/Payment/BankOfGeorgia/BankOfGeorgia.php @@ -0,0 +1,224 @@ +restClient = new Client(); + + $this->requestUrl = 'https://ipay.ge/opay/api/v1'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://dev.ipay.ge/opay/api/v1/'; + } + + + $this->clientId = $paymentInitializeParam['clientId']; + $this->secretKey = $paymentInitializeParam['secretKey']; + + $getAccessToken = $this->getAccessToken(); + $this->accessToken = $getAccessToken['status'] ? $getAccessToken['token'] : null; + + } + + private function makeRequest($method, $payloadData, $methodType = 'POST') + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + $requestParams['headers']['Authorization'] = 'Bearer ' . $this->accessToken; + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->request($methodType, $this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if (isset($getResponseData['error_code'])) { + $response['message'] = $getResponseData['status_description']; + $response['serviceResponse'] = $getResponseData; + } else { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } + + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + private function getAccessToken() + { + + $getTokenData = null; + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Authorization'] = 'Basic ' . base64_encode($this->clientId . ':' . $this->secretKey); + $requestParams['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; + $requestParams['form_params']['grant_type'] = 'client_credentials'; + + $result = $this->restClient->request('POST', $this->requestUrl . '/oauth2/token', $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if (isset($getResponseData['error_code'])) { + throw new ApiErrorException($getResponseData['error_message']); + } + + $response['status'] = true; + $response['token'] = $getResponseData['access_token']; + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function paymentInitialize($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $paymentInitializeParam = [ + 'intent' => 'CAPTURE', + 'items' => [ + [ + 'amount' => $param['amount'], + 'description' => $param['orderCode'], + 'quantity' => 1, + 'product_id' => $param['orderCode'], + ] + ], + 'locale' => 'en-US', + 'shop_order_id' => $param['orderId'], + 'redirect_url' => $param['paymentCheckUrl'], + 'capture_method' => 'AUTOMATIC', + 'purchase_units' => [ + [ + 'amount' => [ + 'currency_code' => $param['currencyCode'], + 'value' => $param['amount'], + ] + ] + ] + ]; + + $paymentInitialize = $this->makeRequest('checkout/orders', $paymentInitializeParam); + + if (!$paymentInitialize['status']) { + throw new ApiErrorException($paymentInitialize['message']); + } + + $response = [ + 'status' => true, + 'data' => $paymentInitialize['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkoutOrderInfo($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'checkout/orders/' . $orderId; + $payloadData = []; + + $checkoutOrderInfoRequest = $this->makeRequest($method, $payloadData, 'GET'); + + if (!$checkoutOrderInfoRequest['status']) { + throw new ApiErrorException($checkoutOrderInfoRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkoutOrderInfoRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkoutOrderInfoRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkoutOrderInfoRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/Esnekpos/Esnekpos.php b/app/Core/Payment/Esnekpos/Esnekpos.php new file mode 100644 index 0000000..85e8b3d --- /dev/null +++ b/app/Core/Payment/Esnekpos/Esnekpos.php @@ -0,0 +1,239 @@ +restClient = new Client(); + + $this->requestUrl = 'https://posservice.esnekpos.com'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://posservicetest.esnekpos.com'; + } + + + $this->merchant = $paymentInitializeParam['merchant']; + $this->merchantKey = $paymentInitializeParam['merchantKey']; + $this->contactMail = $paymentInitializeParam['contactMail']; + $this->ipAddress = isset($paymentInitializeParam['ipAddress']) ? $paymentInitializeParam['ipAddress'] : '185.137.215.118'; + + $this->currencyMapping = [ + 'TRY' => 'TRY', + 'USD' => 'USD', + 'EUR' => 'EUR', + 'GBP' => 'GBP', + ]; + + } + + private function makeRequest($method, $payloadData) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->post($this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData['STATUS'] == 'SUCCESS') { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } else { + throw new Exception($getResponseData['RETURN_MESSAGE']); + } + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + $response['message'] = $message; + Log::debug($message); + + } catch (ServerException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + if (isset($getResponseData)) { + $response['serviceResponse'] = $getResponseData; + } + + return $response; + + } + + + public function generateHashKey($total, $installment, $currency_code, $invoice_id) + { + + $data = $total . '|' . $installment . '|' . $currency_code . '|' . $this->merchantKey . '|' . $invoice_id; + + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($this->appSecret); + + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + + $encrypted = openssl_encrypt("$data", 'aes-256-cbc', "$saltWithPassword", null, $iv); + + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $msg_encrypted_bundle = str_replace('/', '__', $msg_encrypted_bundle); + + return $msg_encrypted_bundle; + } + + public function EYV3DPay($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $items = []; + $items[] = [ + 'PRODUCT_ID' => $param['orderCode'], + 'PRODUCT_NAME' => 'Booking', + 'PRODUCT_CATEGORY' => 'Booking', + 'PRODUCT_DESCRIPTION' => 'Booking', + 'PRODUCT_AMOUNT' => $param['amount'] + ]; + + $method = 'api/pay/EYV3DPay'; + $payloadData = [ + 'Config' => [ + 'MERCHANT' => $this->merchant, + 'MERCHANT_KEY' => $this->merchantKey, + 'BACK_URL' => $param['paymentCheckUrl'], + 'PRICES_CURRENCY' => isset($this->currencyMapping[$param['currencyCode']]) ? $this->currencyMapping[$param['currencyCode']] : $param['currencyCode'], + 'ORDER_REF_NUMBER' => $param['orderId'], + 'ORDER_AMOUNT' => $param['amount'], + ], + 'CreditCard' => [ + 'CC_NUMBER' => $param['creditCard']['number'], + 'EXP_MONTH' => $param['creditCard']['expiryMonth'], + 'EXP_YEAR' => $param['creditCard']['expiryYear'], + 'CC_CVV' => $param['creditCard']['cvv'], + 'CC_OWNER' => $param['creditCard']['holderName'], + 'INSTALLMENT_NUMBER' => $param['creditCard']['installment'], + ], + 'Customer' => [ + 'FIRST_NAME' => $param['orderId'], + 'LAST_NAME' => $param['orderId'], + 'MAIL' => $this->contactMail, + 'PHONE' => '5555555555', + 'CITY' => $param['orderId'], + 'STATE' => $param['orderId'], + 'ADDRESS' => $param['orderId'], + 'CLIENT_IP' => $this->ipAddress, + ], + 'Product' => $items + ]; + + $checkRequest = $this->makeRequest($method, $payloadData); + + if (!$checkRequest['status']) { + throw new ApiErrorException($checkRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkRequest['serviceResponse'] + ]; + + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'api/services/ProcessQuery'; + $payloadData = [ + 'MERCHANT' => $this->merchant, + 'MERCHANT_KEY' => $this->merchantKey, + 'ORDER_REF_NUMBER' => $orderId, + ]; + + $checkStatusRequest = $this->makeRequest($method, $payloadData); + + if (!$checkStatusRequest['status']) { + throw new ApiErrorException($checkStatusRequest['message']); + } + + if ($checkStatusRequest['serviceResponse']['STATUS'] != 'SUCCESS') { + throw new ApiErrorException($checkStatusRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkStatusRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkStatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkStatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/HalkOde/HalkOde.php b/app/Core/Payment/HalkOde/HalkOde.php new file mode 100644 index 0000000..84cade1 --- /dev/null +++ b/app/Core/Payment/HalkOde/HalkOde.php @@ -0,0 +1,254 @@ +restClient = new Client(); + + $this->requestUrl = 'https://app.halkode.com.tr/ccpayment'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://test.halkode.com.tr/ccpayment'; + } + + + $this->merchantId = $paymentInitializeParam['merchantId']; + $this->merchantKey = $paymentInitializeParam['merchantKey']; + $this->appKey = $paymentInitializeParam['appKey']; + $this->appSecret = $paymentInitializeParam['appSecret']; + + $this->getAccessToken = $this->getAccessToken(); + + } + + private function makeRequest($method, $payloadData) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + if ($method != 'api/token') { + $requestParams['headers']['Authorization'] = 'Bearer ' . $this->getAccessToken; + } + + + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->post($this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData['status_code'] == 100) { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } else { + $response['message'] = $getResponseData['status_description']; + $response['serviceResponse'] = $getResponseData; + } + + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + + private function getAccessToken() + { + + $method = 'api/token'; + $payloadData = [ + 'app_id' => $this->appKey, + 'app_secret' => $this->appSecret, + ]; + + $getTokenDataRequest = $this->makeRequest($method, $payloadData); + + if ($getTokenDataRequest['status']) { + $getTokenData = $getTokenDataRequest['serviceResponse']['data']['token']; + } + + return $getTokenData; + } + + public function generateHashKey($total, $installment, $currency_code, $invoice_id) + { + + $data = $total . '|' . $installment . '|' . $currency_code . '|' . $this->merchantKey . '|' . $invoice_id; + + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($this->appSecret); + + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + + $encrypted = openssl_encrypt("$data", 'aes-256-cbc', "$saltWithPassword", null, $iv); + + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $msg_encrypted_bundle = str_replace('/', '__', $msg_encrypted_bundle); + + return $msg_encrypted_bundle; + } + + public function generateRefundHashKey($invoice_id, $merchant_key, $app_secret) + { + $data = $invoice_id . '|' . $merchant_key; + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($app_secret); + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + $encrypted = openssl_encrypt( + $data, 'aes-256-cbc', "$saltWithPassword", null, $iv + ); + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $hash_key = str_replace('/', '__', $msg_encrypted_bundle); + return $hash_key; + } + + public function paySmart3D($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $generateHashKey = $this->generateHashKey($param['amount'], $param['creditCard']['installment'], $param['currencyCode'], $param['orderId']); + + $items = []; + $items[] = [ + 'name' => 'Booking', + 'price' => $param['amount'], + 'quantity' => 1, + 'description' => $param['orderCode'], + ]; + + $payment3dFormData['gateway'] = $this->requestUrl . '/api/paySmart3D'; + + $payment3dFormData['inputs'] = [ + 'currency_code' => $param['currencyCode'], + 'installments_number' => $param['creditCard']['installment'], + 'invoice_id' => $param['orderId'], + 'invoice_description' => $param['orderCode'], + 'total' => $param['amount'], + 'merchant_key' => $this->merchantKey, + 'items' => json_encode($items), + //'name' => $param['name'], + //'surname' => $param['surname'], + 'hash_key' => $generateHashKey, + 'return_url' => $param['paymentCheckUrl'], + 'cancel_url' => $param['paymentCheckUrl'], + 'cc_holder_name' => $param['creditCard']['holderName'], + 'cc_no' => $param['creditCard']['number'], + 'expiry_month' => $param['creditCard']['expiryMonth'], + 'expiry_year' => $param['creditCard']['expiryYear'], + 'cvv' => $param['creditCard']['cvv'], + 'transaction_type' => 'Auth', + 'is_comission_from_user' => '2', + 'response_method' => 'GET', + ]; + + $response = [ + 'status' => true, + 'data' => $payment3dFormData + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $generateHashKey = $this->generateRefundHashKey($orderId, $this->merchantKey, $this->appSecret); + + $method = 'api/checkstatus'; + $payloadData = [ + 'invoice_id' => $orderId, + 'merchant_key' => $this->merchantKey, + 'include_pending_status' => true, + 'hash_key' => $generateHashKey + ]; + + $checkstatusRequest = $this->makeRequest($method, $payloadData); + + if (!$checkstatusRequest['status']) { + throw new ApiErrorException($checkstatusRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkstatusRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkstatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkstatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/KuveytTurk/KuveytTurk.php b/app/Core/Payment/KuveytTurk/KuveytTurk.php new file mode 100644 index 0000000..918e87c --- /dev/null +++ b/app/Core/Payment/KuveytTurk/KuveytTurk.php @@ -0,0 +1,241 @@ +restClient = new Client(); + + $this->requestUrl = 'https://boa.kuveytturk.com.tr/sanalposservice/Home'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://boatest.kuveytturk.com.tr/boa.virtualpos.services/Home'; + } + + $this->customerId = $paymentInitializeParam['customerId']; + $this->merchantId = $paymentInitializeParam['merchantId']; + $this->userName = $paymentInitializeParam['userName']; + $this->password = $paymentInitializeParam['password']; + + $this->currencyCodeMapping = [ + 'TRY' => '0949', + 'USD' => '0840', + 'EUR' => '0978', + ]; + + } + + protected function post($param) + { + $getResponse = []; + $param['logDebug'] = fillOnUndefined($param, 'logDebug', false); + try { + + $paymentRequest = $this->restClient->post($this->requestUrl . '/' . $param['method'], [ + 'headers' => [ + 'Content-Type' => 'application/xml; charset=UTF8', + ], + 'body' => $param['payload'] + ]); + + $getResponseBody = $paymentRequest->getBody(); + $getResponseXmlBase = $getResponseBody->getContents(); + + if (!$getResponseXmlBase) { + throw new ApiErrorException('Payment Initialize not processing.'); + } else { + + $response = [ + 'status' => true, + 'data' => $getResponseXmlBase + ]; + } + + if ($param['logDebug']) { + Log::debug(json_encode($param['param'])); + Log::debug($param['param']); + Log::debug($getResponse); + } + + } catch (ApiErrorException | Exception | ClientException | ServerException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function threeDModelPayGate($param = []) + { + + try { + + $hashData = null; + $param['amount'] = (int)(floatval($param['amount']) * 100); + $hashedPassword = base64_encode(sha1($this->password, "ISO-8859-9")); + $hashData = base64_encode(sha1($this->merchantId . $param['orderId'] . $param['amount'] . $param['paymentCheckUrl'] . $param['paymentCheckUrl'] . $this->userName . $hashedPassword, "ISO-8859-9")); + + $requestParam['method'] = 'ThreeDModelPayGate'; + $requestPayload = new \SimpleXMLElement(''); + + $currencyCodeBank = isset($this->currencyCodeMapping[$param['currencyCode']]) ? $this->currencyCodeMapping[$param['currencyCode']] : '0949'; + + $requestPayload->addChild('APIVersion', '1.0.0'); + $requestPayload->addChild('OkUrl', $param['paymentCheckUrl']); + $requestPayload->addChild('FailUrl', $param['paymentCheckUrl']); + $requestPayload->addChild('HashData', $hashData); + $requestPayload->addChild('MerchantId', $this->merchantId); + $requestPayload->addChild('CustomerId', $this->customerId); + $requestPayload->addChild('UserName', $this->userName); + $requestPayload->addChild('CardNumber', $param['creditCard']['number']); + $requestPayload->addChild('CardExpireDateYear', mb_substr($param['creditCard']['expiryYear'], 2, 2)); + $requestPayload->addChild('CardExpireDateMonth', $param['creditCard']['expiryMonth']); + $requestPayload->addChild('CardCVV2', $param['creditCard']['cvv']); + $requestPayload->addChild('CardHolderName', $param['creditCard']['holderName']); + //$requestPayload->addChild('CardType', null); + $requestPayload->addChild('BatchID', 0); + $requestPayload->addChild('TransactionType', 'Sale'); + $requestPayload->addChild('InstallmentCount', $param['creditCard']['installment']); + $requestPayload->addChild('Amount', $param['amount']); + $requestPayload->addChild('DisplayAmount', $param['amount']); + $requestPayload->addChild('CurrencyCode', $currencyCodeBank); + $requestPayload->addChild('MerchantOrderId', $param['orderId']); + $requestPayload->addChild('TransactionSecurity', 3); + + $requestParam['payload'] = $requestPayload->asXML(); + + $paymentRequest = $this->post($requestParam); + + if (!$paymentRequest['status']) { + throw new ApiErrorException($paymentRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $paymentRequest['data'] + ]; + + } catch (ApiErrorException | Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } + + if (isset($getResponseData)) { + $response['serviceResponse'] = $paymentRequest; + } + + + return $response; + } + + public function checkPaymentStatus($paymentCode, $param = []) + { + $response = ['status' => false, 'message' => '']; + + $requestContent = null; + $paymentRequest = []; + + try { + + $requestContent = urldecode($param["AuthenticationResponse"]); + $requestContent = json_decode(json_encode(simplexml_load_string($requestContent)), 1); + + + if ($requestContent['ResponseCode'] != "00") { + $errorMessage = $requestContent['ResponseCode'] . ': ' . $requestContent['ResponseMessage']; + $paymentRequest['serviceResponse'] = $requestContent; + throw new ApiErrorException($errorMessage); + } + + $paymentCheckParam = [ + 'merchantOrderId' => isset($requestContent['VPosMessage']['MerchantOrderId']) ? $requestContent['VPosMessage']['MerchantOrderId'] : null, + 'amount' => isset($requestContent['VPosMessage']['Amount']) ? $requestContent['VPosMessage']['Amount'] : null, + 'md' => isset($requestContent['MD']) ? $requestContent['MD'] : null, + ]; + + $hashData = null; + //$param['amount'] = (int)(floatval($param['amount']) * 100); + $hashedPassword = base64_encode(sha1($this->password, "ISO-8859-9")); + $hashData = base64_encode(sha1($this->merchantId . $paymentCheckParam['merchantOrderId'] . $paymentCheckParam['amount'] . $this->userName . $hashedPassword, "ISO-8859-9")); + + + $requestParam['method'] = 'ThreeDModelProvisionGate'; + $requestPayload = new \SimpleXMLElement(''); + + $requestPayload->addChild('APIVersion', '1.0.0'); + $requestPayload->addChild('HashData', $hashData); + $requestPayload->addChild('MerchantId', $this->merchantId); + $requestPayload->addChild('CustomerId', $this->customerId); + $requestPayload->addChild('UserName', $this->userName); + $requestPayload->addChild('TransactionType', 'Sale'); + $requestPayload->addChild('InstallmentCount', 1); + $requestPayload->addChild('CurrencyCode', '0949'); + $requestPayload->addChild('Amount', $paymentCheckParam['amount']); + $requestPayload->addChild('MerchantOrderId', $paymentCheckParam['merchantOrderId']); + $requestPayload->addChild('TransactionSecurity', 3); + + $kuveytTurkVPosAdditionalData = $requestPayload->addChild('KuveytTurkVPosAdditionalData'); + $additionalData = $kuveytTurkVPosAdditionalData->addChild('AdditionalData'); + $additionalData->addChild('Key', 'MD'); + $additionalData->addChild('Data', $paymentCheckParam['md']); + + $requestParam['payload'] = $requestPayload->asXML(); + + $paymentRequest = $this->post($requestParam); + + if (!$paymentRequest['status']) { + throw new ApiErrorException($paymentRequest['message']); + } + + $requestContent = simplexml_load_string($paymentRequest['data']); + $requestContent = json_decode(json_encode($requestContent), 1); + + $paymentRequest['serviceResponse'] = $requestContent; + + if ($requestContent['ResponseCode'] != "00") { + $errorMessage = $requestContent['ResponseCode'] . ': ' . $requestContent['ResponseMessage']; + throw new ApiErrorException($errorMessage); + } + + $response = [ + 'status' => true, + 'data' => $requestContent + ]; + + } catch (ApiErrorException | Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } + + if (isset($paymentRequest['serviceResponse'])) { + $response['serviceResponse'] = $paymentRequest['serviceResponse']; + } + + + return $response; + } + +} diff --git a/app/Core/Payment/Moka/Moka.php b/app/Core/Payment/Moka/Moka.php new file mode 100644 index 0000000..9924a2c --- /dev/null +++ b/app/Core/Payment/Moka/Moka.php @@ -0,0 +1,176 @@ +restClient = new Client(); + + $this->requestUrl = 'https://service.moka.com'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://service.refmoka.com'; + } + + $this->userName = $paymentInitializeParam['userName']; + $this->password = $paymentInitializeParam['password']; + $this->dealerCode = $paymentInitializeParam['dealerCode']; + + } + + private function errorCodes($code) + { + $codes = [ + md5('PaymentDealer.CheckPaymentDealerAuthentication.InvalidRequest') => 'Hatalı hash bilgisi', + md5('PaymentDealer.CheckPaymentDealerAuthentication.InvalidAccount') => 'Böyle bir bayi bulunamadı', + md5('PaymentDealer.CheckPaymentDealerAuthentication.VirtualPosNotFound') => 'Bu bayi için sanal pos tanımı yapılmamış', + md5('PaymentDealer.RequiredFields.AmountRequired') => 'Tutar girilmemiş', + md5('PaymentDealer.DoCapture.DealerNotAuthorized') => 'Ön provizyonu provizyona çevirmek için yetkiniz yok', + md5('PaymentDealer.DoDirectPayment3dRequest.CardTokenNotFound') => 'Tanımlı CardToken bulunamadı', + md5('PaymentDealer.CheckCardInfo.InvalidCardInfo') => 'Geçersiz Kart Bilgisi', + md5('PaymentDealer.DoDirectPayment3dRequest.VirtualPosNotAvailable') => 'Bu kredi kartı için ödeme desteklenmemektedir, lütfen farklı bir kart deneyiniz', + md5('PaymentDealer.CheckDealerPaymentLimits.DailyDealerLimitExceeded') => 'Bu kredi kartı için günlük kullanım limiti dolmuştur, lütfen farklı bir kart deneyiniz', + md5('PaymentDealer.DoDirectPayment3dRequest.ThisInstallmentNumberNotAvailableForDealer') => 'Bu taksit sayısı kullanılamaz', + md5('EX') => 'Beklenmeyen bir hata oluştu' + ]; + + return fillOnUndefined($codes, md5($code), 'Bilinmeyen bir hata oluştu'); + } + + private function mokaServiceResponse($getResponse, $param) + { + $response = ['status' => false, 'message' => '', 'error' => '', 'data' => []]; + + if ($getResponse['ResultCode'] != 'Success') { + $response['message'] = $this->errorCodes($getResponse['ResultCode']); + //Log::error($getResponse); + } else { + $response = [ + 'status' => true, + 'data' => $getResponse['Data'] + ]; + } + + return $response; + + } + + protected function post($param) + { + $getResponse = []; + $param['logDebug'] = fillOnUndefined($param, 'logDebug', false); + try { + + $res = $this->restClient->post($this->requestUrl. $param['method'], [ + 'verify' => false, + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'body' => json_encode($param['param']) + ]); + + $getResponseBody = $res->getBody(); + $getResponse = json_decode($getResponseBody, true); + + if ($param['logDebug']) { + Log::debug(json_encode($param['param'])); + Log::debug($param['param']); + Log::debug($getResponse); + } + + $getResponse = $this->mokaServiceResponse($getResponse, $param); + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + return $getResponse; + + } + + public function paymentDealerAuthentication() + { + return [ + 'DealerCode' => $this->dealerCode, + 'Username' => $this->userName, + 'Password' => $this->password, + 'CheckKey' => hash('sha256', $this->dealerCode . 'MK' . $this->userName . 'PD' . $this->password) + ]; + } + + public function DoDirectPaymentThreeD($param = []) + { + + try { + + $doDirectPaymentThreeD['method'] = '/PaymentDealer/DoDirectPaymentThreeD'; + $doDirectPaymentThreeD['param']['PaymentDealerAuthentication'] = $this->paymentDealerAuthentication(); + $doDirectPaymentThreeD['param']['PaymentDealerRequest'] = [ + 'CardHolderFullName' => fillOnUndefined($param, 'CardHolderFullName'), + 'CardNumber' => fillOnUndefined($param, 'CardNumber', ''), + 'ExpMonth' => fillOnUndefined($param, 'ExpMonth'),//12 + 'ExpYear' => fillOnUndefined($param, 'ExpYear'),//2022 + 'CvcNumber' => fillOnUndefined($param, 'CvcNumber'), + 'CardToken' => fillOnUndefined($param, 'CardToken'), + 'Amount' => fillOnUndefined($param, 'Amount'),//10.50 + 'Currency' => fillOnUndefined($param, 'Currency', 'TL'), + 'InstallmentNumber' => fillOnUndefined($param, 'InstallmentNumber', 1), + 'ClientIP' => fillOnUndefined($param, 'ClientIP', Request::ip()), + 'OtherTrxCode' => fillOnUndefined($param, 'OtherTrxCode', ''), + 'IsPreAuth' => fillOnUndefined($param, 'IsPreAuth', 1), + 'Software' => fillOnUndefined($param, 'Software', ''), + 'Description' => fillOnUndefined($param, 'Description', ''), + 'RedirectUrl' => fillOnUndefined($param, 'RedirectUrl'), + ]; + + $response = $this->post($doDirectPaymentThreeD); + + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } + + return $response; + } + + public function getPaymentDetail($param = []) + { + try { + + $getPaymentList['method'] = '/PaymentDealer/GetDealerPaymentTrxDetailList'; + $getPaymentList['param']['PaymentDealerAuthentication'] = $this->paymentDealerAuthentication(); + $getPaymentList['param']['PaymentDealerRequest'] = [ + 'PaymentId' => fillOnUndefined($param, 'PaymentId', ''), + 'OtherTrxCode' => fillOnUndefined($param, 'OtherTrxCode', ''), + ]; + + $response = $this->post($getPaymentList); + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } + + return $response; + } + +} diff --git a/app/Core/Payment/Payriff/Payriff.php b/app/Core/Payment/Payriff/Payriff.php new file mode 100644 index 0000000..2d26368 --- /dev/null +++ b/app/Core/Payment/Payriff/Payriff.php @@ -0,0 +1,170 @@ +restClient = new Client(); + + $this->requestUrl = 'https://api.payriff.com/api/v3'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://api.payriff.com/api/v3'; + } + + + $this->secretKey = $paymentInitializeParam['secretKey']; + + + } + + private function makeRequest($method, $payloadData, $methodType = 'POST') + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + $requestParams['headers']['Authorization'] = $this->secretKey; + $requestParams['body'] = json_encode($payloadData); + + + $result = $this->restClient->request($methodType, $this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + + if ($getResponseData['code'] == '00000') { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } else { + $response['message'] = 'Redirect url not found.'; + $response['serviceResponse'] = $getResponseData; + } + + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + public function paymentInitialize($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $paymentInitializeParam = [ + 'amount' => $param['amount'], + 'language' => 'EN', + 'currency' => $param['currencyCode'], + 'description' => $param['orderId'], + 'callbackUrl' => $param['paymentCheckUrl'], + 'cardSave' => false, + 'operation' => 'PURCHASE', + 'metadata' => [ + 'orderId' => $param['orderId'], + ] + ]; + + $paymentInitialize = $this->makeRequest('orders', $paymentInitializeParam); + + if (!$paymentInitialize['status']) { + throw new ApiErrorException($paymentInitialize['message']); + } + + $response = [ + 'status' => true, + 'data' => $paymentInitialize['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function orderInformation($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'orders/' . $orderId; + $payloadData = []; + + $orderInformationRequest = $this->makeRequest($method, $payloadData, 'GET'); + + if (!$orderInformationRequest['status']) { + throw new ApiErrorException($orderInformationRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $orderInformationRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($orderInformationRequest['serviceResponse'])) { + $response['serviceResponse'] = $orderInformationRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/Pos/AkPos.php b/app/Core/Payment/Pos/AkPos.php new file mode 100644 index 0000000..68b961b --- /dev/null +++ b/app/Core/Payment/Pos/AkPos.php @@ -0,0 +1,701 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * Response Raw Data + * + * @var object + */ + protected $mbrId = 5; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + + return $this; + } + + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getRandomNumberBase16() + { + $n = 128; + + $characters = '0123456789ABCDEF'; + $randomString = ''; + + for ($i = 0; $i < $n; $i++) { + $index = rand(0, strlen($characters) - 1); + $randomString .= $characters[$index]; + } + + return strtoupper($randomString); + + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hashItems = []; + + $hashItems[] = mb_strtoupper($this->account->model); + $hashItems[] = $this->txnCode; + $hashItems[] = $this->account->merchant_safe_id; + $hashItems[] = $this->account->terminal_safe_id; + $hashItems[] = $this->order->id; + $hashItems[] = mb_strtoupper($this->order->lang); + $hashItems[] = $this->order->amount; + //$hashItems[] = $this->order->ccbRewardAmount; + //$hashItems[] = $this->order->pcbRewardAmount; + //$hashItems[] = $this->order->xcbRewardAmount; + $hashItems[] = $this->order->currency; + $hashItems[] = $this->order->installment; + $hashItems[] = $this->order->success_url; + $hashItems[] = $this->order->fail_url; + //$hashItems[] = $this->order->emailAddress; + //$hashItems[] = $this->order->subMerchantId; + $hashItems[] = $this->card->number; + $hashItems[] = $this->getCardExpDate(); + $hashItems[] = $this->card->cvv; + $hashItems[] = $this->order->rand; + $hashItems[] = $this->order->requestDateTime; + //$hashItems[] = $this->order->b2bIdentityNumber; + + $hashItemsString = implode('', $hashItems); + + $hashItemsStringHashed = hash_hmac('sha512', $hashItemsString, $this->account->secret_key, true); + + return base64_encode($hashItemsStringHashed); + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + $return = false; + + $params = explode('+', $data['hashParams']); + + $builder = ''; + foreach ($params as $param) { + $builder .= $data[$param]; + } + + $hashItemsStringHashed = hash_hmac('sha512', $builder, $this->account->secret_key, true); + $hashItemsStringHashed = base64_encode($hashItemsStringHashed); + + if ($data['hash'] == $hashItemsStringHashed) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + return false; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + return false; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + + if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('responseCode') == 'VPS-0000') { + $status = 'approved'; + } + + $transaction_security = 'MPI fallback'; + if ($status == 'approved') { + //if ($this->request->get('3DStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + // } elseif (in_array($this->request->get('3DStatus'), [2, 3, 4])) { + //$transaction_security = 'Half 3D Secure'; + //} + } + + + $this->response = (object)[ + 'id' => (string)$this->request->get('authCode'), + 'order_id' => (string)$this->request->get('orderId'), + 'trans_id' => (string)$this->request->get('rrn'), + 'response' => (string)$this->request->get('responseCode'), + 'merchantSafeId' => (string)$this->request->get('merchantSafeId'), + 'terminalSafeId' => (string)$this->request->get('terminalSafeId'), + 'transaction_type' => $this->type, + 'transaction' => (string)$this->request->get('rrn'), + 'transaction_security' => $transaction_security, + 'auth_code' => (string)$this->request->get('authCode'), + 'host_ref_num' => (string)$this->request->get('rrn'), + 'proc_return_code' => (string)$this->request->get('hostResponseCode'), + 'code' => (string)$this->request->get('responseCode'), + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => (string)$this->request->get('responseCode') != 'VPS-0000' ? (string)$this->request->get('responseCode') : null, + 'error_message' => (string)$this->request->get('responseCode') != 'VPS-0000' ? (string)$this->request->get('responseMessage') : null, + 'md_status' => (string)$this->request->get('md_status'), + 'hash' => (string)$this->request->get('hash'), + 'rand' => null, + 'hash_params' => (string)$this->request->get('hashParams'), + 'hash_params_val' => (string)$this->request->get('hash'), + 'amount' => (string)$this->request->get('amount'), + 'md_error_message' => (string)$this->request->get('responseCode') != 'VPS-0000' ? (string)$this->request->get('responseMessage') : null, + 'all' => $this->request->request->all() + ]; + + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $data = []; + + if ($this->order) { + + $this->order->amount = number_format($this->order->amount, 2, '.', ''); + $this->order->rand = $this->getRandomNumberBase16(); + $this->order->requestDateTime = mb_substr(Carbon::now()->toISOString(), 0, 23); + $this->order->installment = $this->order->installment == 0 ? 1 : $this->order->installment; + + $this->order->hash = $this->create3DHash(); + + $inputs = [ + 'paymentModel' => mb_strtoupper($this->account->model), + 'txnCode' => $this->txnCode, + 'merchantSafeId' => $this->account->merchant_safe_id, + 'terminalSafeId' => $this->account->terminal_safe_id, + 'orderId' => $this->order->id, + 'lang' => mb_strtoupper($this->order->lang), + 'amount' => $this->order->amount, + 'currencyCode' => $this->order->currency, + 'installCount' => $this->order->installment, + 'okUrl' => $this->order->success_url, + 'failUrl' => $this->order->fail_url, + 'creditCard' => $this->card->number, + 'expiredDate' => $this->getCardExpDate(), + 'cvv' => $this->card->cvv, + 'randomNumber' => $this->order->rand, + 'requestDateTime' => $this->order->requestDateTime, + 'hash' => $this->order->hash, + ]; + + $data = [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $this->order->hash, + 'inputs' => $inputs, + ]; + + //$formData = $data; + //echo view('threeDSecureForm', compact('formData'));die(); + + } + + return $data; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + $this->txnCode = 3000; + + $this->order->installment = $this->order->installment == 0 ? 0 : $this->order->installment; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + return false; + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + return false; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + return false; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + return false; + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } + + /** + * @return string|null + */ + public function getCardCode() + { + $card_type = null; + if (isset($this->card->type)) { + if ($this->card->type == 'visa') { + $card_type = '0'; + } elseif ($this->card->type == 'master') { + $card_type = '1'; + } elseif ($this->card->type == '1' || $this->card->type == '2') { + $card_type = $this->card->type; + } + } + return $card_type; + } + + protected function getCardExpDate() + { + $year = (string)substr($this->card->year, 2, 2); + $month = (string)substr($this->card->month, 0, 2); + + return (string)$month . $year; + } + + +} diff --git a/app/Core/Payment/Pos/EstPos.php b/app/Core/Payment/Pos/EstPos.php new file mode 100644 index 0000000..1f4465e --- /dev/null +++ b/app/Core/Payment/Pos/EstPos.php @@ -0,0 +1,881 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + return $this; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + + if ($this->account->model == '3d') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->order->rand . $this->account->store_key; + } elseif ($this->account->model == '3d_pay') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->store_key; + } + + return base64_encode(sha1($hash_str, true)); + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + $hash_params = $data['HASHPARAMS']; + $hash_params_val = $data['HASHPARAMSVAL']; + $hash_param = $data['HASH']; + $params_val = ''; + + $hashparams_arr = explode(':', $hash_params); + foreach ($hashparams_arr as $value) { + if(!empty($value) && isset($data[$value])){ + $params_val = $params_val . $data[$value]; + } + } + + $hash_val = $params_val . $this->account->store_key; + $hash = base64_encode(sha1($hash_val, true)); + + $return = false; + if ($hash_params && !($params_val != $hash_params_val || $hash_param != $hash)) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + $contents = ''; + if (in_array($this->order->transaction, ['pay', 'pre'])) { + $contents = $this->createRegularPaymentXML(); + } elseif ($this->order->transaction == 'post') { + $contents = $this->createRegularPostXML(); + } + + $this->send($contents); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'group_id' => isset($this->data->GroupId) ? $this->printData($this->data->GroupId) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'auth_code' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->printData($this->data->HostRefNum) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->Extra->ERRORCODE) : null, + 'error_message' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->ErrMsg) : null, + 'campaign_url' => null, + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + return $this; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + if ($this->check3DHash($this->request->request->all())) { + $contents = $this->create3DPaymentXML(); + $this->send($contents); + } + + $transaction_security = 'MPI fallback'; + if ($this->getProcReturnCode() == '00') { + if ($this->request->get('mdStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'group_id' => isset($this->data->GroupId) ? $this->printData($this->data->GroupId) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'auth_code' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->printData($this->data->HostRefNum) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->Extra->ERRORCODE) : null, + 'error_message' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->ErrMsg) : null, + 'md_status' => $this->request->get('mdStatus'), + 'hash' => (string)$this->request->get('HASH'), + 'rand' => (string)$this->request->get('rnd'), + 'hash_params' => (string)$this->request->get('HASHPARAMS'), + 'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), + 'masked_number' => (string)$this->request->get('maskedCreditCard'), + 'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + 'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'name' => (string)$this->request->get('firmaadi'), + 'campaign_url' => null, + 'email' => (string)$this->request->get('Email'), + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + '3d_all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + + if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') { + if (in_array($this->request->get('mdStatus'), [1, 2, 3, 4])) { + $status = 'approved'; + } + } + + $transaction_security = 'MPI fallback'; + if ($status == 'approved') { + if ($this->request->get('mdStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + } + + $this->response = (object)[ + 'id' => (string)$this->request->get('AuthCode'), + 'trans_id' => (string)$this->request->get('TransId'), + 'auth_code' => (string)$this->request->get('AuthCode'), + 'host_ref_num' => (string)$this->request->get('HostRefNum'), + 'response' => (string)$this->request->get('Response'), + 'order_id' => (string)$this->request->get('oid'), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'code' => (string)$this->request->get('ProcReturnCode'), + 'md_status' => $this->request->get('mdStatus'), + 'status' => $status, + 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, + 'hash' => (string)$this->request->get('HASH'), + 'rand' => (string)$this->request->get('rnd'), + 'hash_params' => (string)$this->request->get('HASHPARAMS'), + 'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), + 'masked_number' => (string)$this->request->get('maskedCreditCard'), + 'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + 'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'error_code' => (string)$this->request->get('ErrCode'), + 'error_message' => (string)$this->request->get('ErrMsg'), + 'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'name' => (string)$this->request->get('firmaadi'), + 'email' => (string)$this->request->get('Email'), + 'campaign_url' => null, + 'extra' => $this->request->get('Extra'), + 'all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $data = []; + + if ($this->order) { + $this->order->hash = $this->create3DHash(); + + $inputs = [ + 'clientid' => $this->account->client_id, + 'storetype' => $this->account->model, + 'hash' => $this->order->hash, + 'cardType' => $this->getCardCode(), + 'pan' => $this->card->number, + 'Ecom_Payment_Card_ExpDate_Month' => $this->card->month, + 'Ecom_Payment_Card_ExpDate_Year' => $this->card->year, + 'cv2' => $this->card->cvv, + 'firmaadi' => $this->order->name, + 'Email' => $this->order->email, + 'amount' => $this->order->amount, + 'oid' => $this->order->id, + 'okUrl' => $this->order->success_url, + 'failUrl' => $this->order->fail_url, + 'rnd' => $this->order->rand, + 'lang' => $this->order->lang, + 'currency' => $this->order->currency, + ]; + + if ($this->account->model == '3d_pay') { + $inputs = array_merge($inputs, [ + 'islemtipi' => $this->type, + 'taksit' => $this->order->installment, + ]); + } + + $data = [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $this->order->hash, + 'inputs' => $inputs, + ]; + } + + return $data; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Type' => 'Credit', + ] + ]; + + if ($meta['amount']) $nodes['Total'] = $meta['amount']; + + $xml = $this->createXML($nodes, 'ISO-8859-9'); + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->data->OrderId : null, + 'group_id' => isset($this->data->GroupId) ? $this->data->GroupId : null, + 'response' => isset($this->data->Response) ? $this->data->Response : null, + 'auth_code' => isset($this->data->AuthCode) ? $this->data->AuthCode : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->data->HostRefNum : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->data->ProcReturnCode : null, + 'trans_id' => isset($this->data->TransId) ? $this->data->TransId : null, + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->data->Extra->ERRORCODE : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->data->ErrMsg : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + ]; + + return $this; + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Type' => 'Void', + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->data->OrderId : null, + 'group_id' => isset($this->data->GroupId) ? $this->data->GroupId : null, + 'response' => isset($this->data->Response) ? $this->data->Response : null, + 'auth_code' => isset($this->data->AuthCode) ? $this->data->AuthCode : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->data->HostRefNum : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->data->ProcReturnCode : null, + 'trans_id' => isset($this->data->TransId) ? $this->data->TransId : null, + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->data->Extra->ERRORCODE : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->data->ErrMsg : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + ]; + + return $this; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Extra' => [ + 'ORDERSTATUS' => 'QUERY', + ], + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $first_amount = isset($this->data->Extra->ORIG_TRANS_AMT) ? $this->printData($this->data->Extra->ORIG_TRANS_AMT) : null; + $capture_amount = isset($this->data->Extra->CAPTURE_AMT) ? $this->printData($this->data->Extra->CAPTURE_AMT) : null; + $capture = $first_amount == $capture_amount ? true : false; + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->printData($this->data->ErrMsg) : null, + 'host_ref_num' => isset($this->data->Extra->HOST_REF_NUM) ? $this->printData($this->data->Extra->HOST_REF_NUM) : null, + 'order_status' => isset($this->data->Extra->ORDERSTATUS) ? $this->printData($this->data->Extra->ORDERSTATUS) : null, + 'process_type' => isset($this->data->Extra->CHARGE_TYPE_CD) ? $this->printData($this->data->Extra->CHARGE_TYPE_CD) : null, + 'pan' => isset($this->data->Extra->PAN) ? $this->printData($this->data->Extra->PAN) : null, + 'num_code' => isset($this->data->Extra->NUMCODE) ? $this->printData($this->data->Extra->NUMCODE) : null, + 'first_amount' => $first_amount, + 'capture_amount' => $capture_amount, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'capture' => $capture, + 'all' => $this->data, + 'xml' => $xml, + ]; + + return $this; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Extra' => [ + 'ORDERHISTORY' => 'QUERY', + ], + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->printData($this->data->ErrMsg) : null, + 'num_code' => isset($this->data->Extra->NUMCODE) ? $this->printData($this->data->Extra->NUMCODE) : null, + 'trans_count' => isset($this->data->Extra->TRXCOUNT) ? $this->printData($this->data->Extra->TRXCOUNT) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + 'xml' => $xml, + ]; + + return $this; + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } + + /** + * @return string|null + */ + public function getCardCode() + { + $card_type = null; + if (isset($this->card->type)) { + if ($this->card->type == 'visa') { + $card_type = '1'; + } elseif ($this->card->type == 'master') { + $card_type = '2'; + }elseif($this->card->type == '1' || $this->card->type == '2'){ + $card_type = $this->card->type; + } + } + return $card_type; + } +} diff --git a/app/Core/Payment/Pos/EstPosV3.php b/app/Core/Payment/Pos/EstPosV3.php new file mode 100644 index 0000000..65bcf36 --- /dev/null +++ b/app/Core/Payment/Pos/EstPosV3.php @@ -0,0 +1,913 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + return $this; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash($inputs) + { + + $hash3D = null; + $postParams = []; + foreach ($inputs as $key => $value){ + array_push($postParams, $key); + } + + natcasesort($postParams); + + $hashval = ""; + foreach ($postParams as $param){ + $paramValue = $inputs[$param]; + $escapedParamValue = str_replace("|", "\\|", str_replace("\\", "\\\\", $paramValue)); + + $lowerParam = strtolower($param); + if($lowerParam != "hash" && $lowerParam != "encoding" ) { + $hashval = $hashval . $escapedParamValue . "|"; + } + } + + $storeKey = $this->account->store_key; + $escapedStoreKey = str_replace("|", "\\|", str_replace("\\", "\\\\", $storeKey)); + $hashval = $hashval . $escapedStoreKey; + + $calculatedHashValue = hash('sha512', $hashval); + $hash3D = base64_encode (pack('H*',$calculatedHashValue)); + + return $hash3D; + + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + + $return = false; + + Log::debug('LOG - 1'); + Log::debug($data); + + $postParams = []; + foreach ($data as $key => $value) { + array_push($postParams, $key); + } + + natcasesort($postParams); + + $hashval = ""; + foreach ($postParams as $param) { + $paramValue = $data[$param]; + $escapedParamValue = str_replace("|", "\\|", str_replace("\\", "\\\\", $paramValue)); + + $lowerParam = strtolower($param); + if ($lowerParam != "hash" && $lowerParam != "encoding") { + $hashval = $hashval . $escapedParamValue . "|"; + } + } + + $storeKey = $this->account->store_key; + $escapedStoreKey = str_replace("|", "\\|", str_replace("\\", "\\\\", $storeKey)); + $hashval = $hashval . $escapedStoreKey; + + $calculatedHashValue = hash('sha512', $hashval); + $actualHash = base64_encode(pack('H*', $calculatedHashValue)); + + $retrievedHash = fillOnUndefined($data,'HASH'); + + Log::debug('LOG - 2'); + Log::debug($data); + + if ($retrievedHash == $actualHash) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + $contents = ''; + if (in_array($this->order->transaction, ['pay', 'pre'])) { + $contents = $this->createRegularPaymentXML(); + } elseif ($this->order->transaction == 'post') { + $contents = $this->createRegularPostXML(); + } + + $this->send($contents); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'group_id' => isset($this->data->GroupId) ? $this->printData($this->data->GroupId) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'auth_code' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->printData($this->data->HostRefNum) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->Extra->ERRORCODE) : null, + 'error_message' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->ErrMsg) : null, + 'campaign_url' => null, + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + return $this; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + if ($this->check3DHash($this->request->request->all())) { + $contents = $this->create3DPaymentXML(); + $this->send($contents); + } + + $transaction_security = 'MPI fallback'; + if ($this->getProcReturnCode() == '00') { + if ($this->request->get('mdStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'group_id' => isset($this->data->GroupId) ? $this->printData($this->data->GroupId) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'auth_code' => isset($this->data->AuthCode) ? $this->printData($this->data->AuthCode) : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->printData($this->data->HostRefNum) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->Extra->ERRORCODE) : null, + 'error_message' => isset($this->data->Extra->ERRORCODE) ? $this->printData($this->data->ErrMsg) : null, + 'md_status' => $this->request->get('mdStatus'), + 'hash' => (string)$this->request->get('HASH'), + 'rand' => (string)$this->request->get('rnd'), + 'hash_params' => (string)$this->request->get('HASHPARAMS'), + 'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), + 'masked_number' => (string)$this->request->get('maskedCreditCard'), + 'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + 'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'name' => (string)$this->request->get('firmaadi'), + 'campaign_url' => null, + 'email' => (string)$this->request->get('Email'), + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + '3d_all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + + if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') { + if (in_array($this->request->get('mdStatus'), [1, 2, 3, 4])) { + $status = 'approved'; + } + } + + $transaction_security = 'MPI fallback'; + if ($status == 'approved') { + if ($this->request->get('mdStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + } + + $this->response = (object)[ + 'id' => (string)$this->request->get('AuthCode'), + 'trans_id' => (string)$this->request->get('TransId'), + 'auth_code' => (string)$this->request->get('AuthCode'), + 'host_ref_num' => (string)$this->request->get('HostRefNum'), + 'response' => (string)$this->request->get('Response'), + 'order_id' => (string)$this->request->get('oid'), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'code' => (string)$this->request->get('ProcReturnCode'), + 'md_status' => $this->request->get('mdStatus'), + 'status' => $status, + 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, + 'hash' => (string)$this->request->get('HASH'), + 'rand' => (string)$this->request->get('rnd'), + 'masked_number' => (string)$this->request->get('maskedCreditCard'), + 'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + 'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'hashAlgorithm' => (string)$this->request->get('hashAlgorithm'), + 'xid' => (string)$this->request->get('xid'), + 'error_code' => (string)$this->request->get('ErrCode'), + 'error_message' => ($status != 'approved' && empty((string)$this->request->get('ErrMsg'))) ? (string)$this->request->get('mdErrorMsg') : (string)$this->request->get('ErrMsg'), + 'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'merchantName' => (string)$this->request->get('merchantName'), + 'all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $data = []; + + + if ($this->order) { + + $inputs = [ + 'clientid' => $this->account->client_id, + 'storetype' => $this->account->model, + 'hashAlgorithm' => 'ver3', + 'cardType' => $this->getCardCode(), + 'pan' => $this->card->number, + 'Ecom_Payment_Card_ExpDate_Month' => $this->card->month, + 'Ecom_Payment_Card_ExpDate_Year' => $this->card->year, + 'cv2' => $this->card->cvv, + //'firmaadi' => $this->order->name, + //'Email' => $this->order->email, + 'amount' => $this->order->amount, + 'oid' => $this->order->id, + 'okUrl' => $this->order->success_url, + 'failUrl' => $this->order->fail_url, + 'callbackUrl' => null, + 'rnd' => $this->order->rand, + 'lang' => $this->order->lang, + 'currency' => $this->order->currency, + 'TranType' => 'Auth', + 'Instalment' => $this->order->installment, + ]; + + $inputs['HASH'] = $this->create3DHash($inputs); + + $data = [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + //'hash' => $this->order->hash, + 'inputs' => $inputs, + ]; + } + + return $data; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Type' => 'Credit', + ] + ]; + + if ($meta['amount']) $nodes['Total'] = $meta['amount']; + + $xml = $this->createXML($nodes, 'ISO-8859-9'); + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->data->OrderId : null, + 'group_id' => isset($this->data->GroupId) ? $this->data->GroupId : null, + 'response' => isset($this->data->Response) ? $this->data->Response : null, + 'auth_code' => isset($this->data->AuthCode) ? $this->data->AuthCode : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->data->HostRefNum : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->data->ProcReturnCode : null, + 'trans_id' => isset($this->data->TransId) ? $this->data->TransId : null, + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->data->Extra->ERRORCODE : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->data->ErrMsg : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + ]; + + return $this; + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Type' => 'Void', + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->data->OrderId : null, + 'group_id' => isset($this->data->GroupId) ? $this->data->GroupId : null, + 'response' => isset($this->data->Response) ? $this->data->Response : null, + 'auth_code' => isset($this->data->AuthCode) ? $this->data->AuthCode : null, + 'host_ref_num' => isset($this->data->HostRefNum) ? $this->data->HostRefNum : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->data->ProcReturnCode : null, + 'trans_id' => isset($this->data->TransId) ? $this->data->TransId : null, + 'error_code' => isset($this->data->Extra->ERRORCODE) ? $this->data->Extra->ERRORCODE : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->data->ErrMsg : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + ]; + + return $this; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Extra' => [ + 'ORDERSTATUS' => 'QUERY', + ], + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $first_amount = isset($this->data->Extra->ORIG_TRANS_AMT) ? $this->printData($this->data->Extra->ORIG_TRANS_AMT) : null; + $capture_amount = isset($this->data->Extra->CAPTURE_AMT) ? $this->printData($this->data->Extra->CAPTURE_AMT) : null; + $capture = $first_amount == $capture_amount ? true : false; + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'trans_id' => isset($this->data->TransId) ? $this->printData($this->data->TransId) : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->printData($this->data->ErrMsg) : null, + 'host_ref_num' => isset($this->data->Extra->HOST_REF_NUM) ? $this->printData($this->data->Extra->HOST_REF_NUM) : null, + 'order_status' => isset($this->data->Extra->ORDERSTATUS) ? $this->printData($this->data->Extra->ORDERSTATUS) : null, + 'process_type' => isset($this->data->Extra->CHARGE_TYPE_CD) ? $this->printData($this->data->Extra->CHARGE_TYPE_CD) : null, + 'pan' => isset($this->data->Extra->PAN) ? $this->printData($this->data->Extra->PAN) : null, + 'num_code' => isset($this->data->Extra->NUMCODE) ? $this->printData($this->data->Extra->NUMCODE) : null, + 'first_amount' => $first_amount, + 'capture_amount' => $capture_amount, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'capture' => $capture, + 'all' => $this->data, + 'xml' => $xml, + ]; + + return $this; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + $xml = $this->createXML([ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'OrderId' => $meta['order_id'], + 'Extra' => [ + 'ORDERHISTORY' => 'QUERY', + ], + ] + ], 'ISO-8859-9'); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'order_id' => isset($this->data->OrderId) ? $this->printData($this->data->OrderId) : null, + 'response' => isset($this->data->Response) ? $this->printData($this->data->Response) : null, + 'proc_return_code' => isset($this->data->ProcReturnCode) ? $this->printData($this->data->ProcReturnCode) : null, + 'error_message' => isset($this->data->ErrMsg) ? $this->printData($this->data->ErrMsg) : null, + 'num_code' => isset($this->data->Extra->NUMCODE) ? $this->printData($this->data->Extra->NUMCODE) : null, + 'trans_count' => isset($this->data->Extra->TRXCOUNT) ? $this->printData($this->data->Extra->TRXCOUNT) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + 'xml' => $xml, + ]; + + return $this; + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } + + /** + * @return string|null + */ + public function getCardCode() + { + $card_type = null; + if (isset($this->card->type)) { + if ($this->card->type == 'visa') { + $card_type = '1'; + } elseif ($this->card->type == 'master') { + $card_type = '2'; + } elseif ($this->card->type == '1' || $this->card->type == '2') { + $card_type = $this->card->type; + } + } + return $card_type; + } +} diff --git a/app/Core/Payment/Pos/Exceptions/BankClassNullException.php b/app/Core/Payment/Pos/Exceptions/BankClassNullException.php new file mode 100644 index 0000000..c3d0eee --- /dev/null +++ b/app/Core/Payment/Pos/Exceptions/BankClassNullException.php @@ -0,0 +1,25 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'sales', + 'pre' => 'preauth', + 'post' => 'postauth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * Mode + * + * @var string + */ + protected $mode = 'PROD'; + + /** + * API version + * @var string + */ + //protected $version = 'v0.01'; + protected $version = '512'; + + /** + * GarantiPost constructor. + * + * @param array $config + * @param array $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $request = Request::createFromGlobals(); + $this->request = $request->request; + + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + if ($this->account->env == 'test') { + $this->mode = 'TEST'; + } + + return $this; + } + + /** + * Make Security Data + * + * @param bool $refund + * @return string + */ + protected function makeSecurityData($refund = false) + { + $map = [ + $this->account->{($refund ? 'refund_' : null) . 'password'}, + str_pad((int)$this->account->terminal_id, 9, 0, STR_PAD_LEFT), + ]; + + return strtoupper(sha1(implode('', $map))); + } + + /** + * Make Hash Data + * + * @param $security_data + * @return string + */ + protected function makeHashData($security_data) + { + $map = [ + $this->order->id, + $this->account->terminal_id, + isset($this->card->number) ? $this->card->number : null, + $this->amountFormat($this->order->amount), + $this->order->currency, + $security_data, + ]; + + + //return strtoupper(sha1(implode('', $map))); + return strtoupper(hash('sha512', implode('', $map))); + } + + /** + * Make 3d Hash Data + * + * @param $security_data + * @return string + */ + protected function make3dHashData($security_data) + { + $map = [ + $this->account->terminal_id, + $this->order->id, + $this->amountFormat($this->order->amount), + $this->order->currency, + $this->order->success_url, + $this->order->fail_url, + $this->type, + $this->order->installment ? $this->order->installment : '', + $this->account->store_key, + $security_data, + ]; + + //return strtoupper(sha1(implode('', $map))); + return strtoupper(hash('sha512', implode('', $map))); + } + + /** + * Make 3d Hash Data + * + * @param $security_data + * @return string + */ + protected function make3dRequestHashData($security_data) + { + $map = [ + $this->order->id, + $this->account->terminal_id, + $this->amountFormat($this->order->amount), + $security_data, + ]; + + return strtoupper(sha1(implode('', $map))); + } + + /** + * Amount Formatter + * + * @param double $amount + * @return int + */ + public function amountFormat($amount) + { + return (int)str_replace('.', '', number_format($amount, 2, '.', '')); + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $security_data = $this->makeSecurityData(); + $hash_data = $this->makeHashData($security_data); + + $nodes = [ + 'GVPSRequest' => [ + 'Mode' => $this->mode, + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT',//$this->account->username, + 'UserID' => $this->account->username, + 'HashData' => $hash_data, + 'ID' => $this->account->terminal_id, + 'MerchantID' => $this->account->client_id, + ], + 'Customer' => [ + 'IPAddress' => $this->order->ip, + 'EmailAddress' => $this->order->email, + ], + 'Card' => [ + 'Number' => $this->card->number, + 'ExpireDate' => $this->card->month . substr($this->card->year, -2), + 'CVV2' => $this->card->cvv, + ], + 'Order' => [ + 'OrderID' => $this->order->id, + 'GroupID' => '', + 'AddressList' => [ + 'Address' => [ + 'Type' => 'S', + 'Name' => $this->order->name, + 'LastName' => '', + 'Company' => '', + 'Text' => '', + 'District' => '', + 'City' => '', + 'PostalCode' => '', + 'Country' => '', + 'PhoneNumber' => '', + ], + ], + ], + 'Transaction' => [ + 'Type' => $this->type, + 'InstallmentCnt' => $this->order->installment > 1 ? $this->order->installment : '', + 'Amount' => $this->amountFormat($this->order->amount), + 'CurrencyCode' => $this->order->currency, + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + 'Description' => '', + 'OriginalRetrefNum' => '', + ], + ] + ]; + + return $this->createXML($nodes); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $security_data = $this->makeSecurityData(); + $hash_data = $this->makeHashData($security_data); + + $nodes = [ + 'GVPSRequest' => [ + 'Mode' => $this->mode, + 'Version' => 'v0.1', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT',//$this->account->username, + 'UserID' => $this->account->username, + 'HashData' => $hash_data, + 'ID' => $this->account->terminal_id, + 'MerchantID' => $this->account->client_id, + ], + 'Customer' => [ + 'IPAddress' => $this->order->ip, + 'EmailAddress' => isset($this->order->email) ? $this->order->email : null, + ], + 'Order' => [ + 'OrderID' => $this->order->id, + ], + 'Transaction' => [ + 'Type' => $this->types[$this->order->transaction], + 'Amount' => $this->amountFormat($this->order->amount), + 'CurrencyCode' => $this->order->currency, + 'OriginalRetrefNum' => $this->order->ref_ret_num, + ], + ] + ]; + + return $this->createXML($nodes); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $security_data = $this->makeSecurityData(); + $hash_data = $this->makeHashData($security_data); + + $nodes = [ + 'GVPSRequest' => [ + 'Mode' => $this->mode, + 'Version' => $this->version, + 'ChannelCode' => '', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT',//$this->account->username, + 'UserID' => $this->account->username, + 'HashData' => $hash_data, + 'ID' => $this->account->terminal_id, + 'MerchantID' => $this->account->client_id, + ], + 'Customer' => [ + 'IPAddress' => $this->request->get('customeripaddress'), + 'EmailAddress' => $this->request->get('customeremailaddress'), + ], + 'Card' => [ + 'Number' => '', + 'ExpireDate' => '', + 'CVV2' => '', + ], + 'Order' => [ + 'OrderID' => $this->request->get('orderid'), + 'GroupID' => '', + 'AddressList' => [ + 'Address' => [ + 'Type' => 'B', + 'Name' => $this->order->name, + 'LastName' => '', + 'Company' => '', + 'Text' => '', + 'District' => '', + 'City' => '', + 'PostalCode' => '', + 'Country' => '', + 'PhoneNumber' => '', + ], + ], + ], + 'Transaction' => [ + 'Type' => $this->request->get('txntype'), + 'InstallmentCnt' => $this->order->installment ? $this->order->installment : '', + 'Amount' => $this->request->get('txnamount'), + 'CurrencyCode' => $this->request->get('txncurrencycode'), + 'CardholderPresentCode' => '13', + 'MotoInd' => 'N', + 'Secure3D' => [ + 'AuthenticationCode' => $this->request->get('cavv'), + 'SecurityLevel' => $this->request->get('eci'), + 'TxnID' => $this->request->get('xid'), + 'Md' => $this->request->get('md'), + ], + ], + ] + ]; + + return $this->createXML($nodes); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->Transaction->Response->Code) ? (string)$this->data->Transaction->Response->Code : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + + if ($this->account->model == '3d') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->order->rand . $this->account->store_key; + } elseif ($this->account->model == '3d_pay') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->order->transaction_type . $this->order->installment . $this->order->rand . $this->account->store_key; + } + + return base64_encode(sha1($hash_str, true)); + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + $contents = ''; + if (in_array($this->order->transaction, ['pay', 'pre'])) { + $contents = $this->createRegularPaymentXML(); + } elseif ($this->order->transaction == 'post') { + $contents = $this->createRegularPostXML(); + } + + $this->send($contents); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'order_id' => isset($this->data->Order->OrderID) ? $this->printData($this->data->Order->OrderID) : null, + 'group_id' => isset($this->data->Order->GroupID) ? $this->printData($this->data->Order->GroupID) : null, + 'trans_id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'response' => isset($this->data->Transaction->Response->Message) ? $this->printData($this->data->Transaction->Response->Message) : null, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'auth_code' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'host_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'ret_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'hash_data' => isset($this->data->Transaction->HashData) ? $this->printData($this->data->Transaction->HashData) : null, + 'proc_return_code' => $this->getProcReturnCode(), + 'code' => $this->getProcReturnCode(), + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Transaction->Response->Code) ? $this->printData($this->data->Transaction->Response->Code) : null, + 'error_message' => isset($this->data->Transaction->Response->ErrorMsg) ? $this->printData($this->data->Transaction->Response->ErrorMsg) : null, + 'campaign_url' => isset($this->data->Transaction->CampaignChooseLink) ? $this->printData($this->data->Transaction->CampaignChooseLink) : null, + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + return $this; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + $status = 'declined'; + $response = 'Declined'; + $proc_return_code = '99'; + $transaction_security = 'MPI fallback'; + if (in_array($this->request->get('mdstatus'), [1, 2, 3, 4])) { + if ($this->request->get('mdstatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdstatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + + $contents = $this->create3DPaymentXML(); + $this->send($contents); + + if ($this->data->Transaction->Response->ReasonCode == '00') { + $response = 'Approved'; + $proc_return_code = $this->data->Transaction->Response->ReasonCode; + $status = 'approved'; + } + } + + $this->response = (object)[ + 'id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'order_id' => $this->request->get('oid'), + 'group_id' => isset($this->data->Transaction->SequenceNum) ? $this->printData($this->data->Transaction->SequenceNum) : null, + 'trans_id' => $this->request->get('transid'), + 'response' => $response, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'auth_code' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'host_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'proc_return_code' => $proc_return_code, + 'ret_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'batch_num' => isset($this->data->Transaction->BatchNum) ? $this->printData($this->data->Transaction->BatchNum) : null, + 'code' => $proc_return_code, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Transaction->Response->ErrorCode) ? $this->printData($this->data->Transaction->Response->ErrorCode) : null, + 'error_message' => isset($this->data->Transaction->Response->ErrorMsg) ? $this->printData($this->data->Transaction->Response->ErrorMsg) : null, + 'reason_code' => isset($this->data->Transaction->Response->ReasonCode) ? $this->printData($this->data->Transaction->Response->ReasonCode) : null, + 'campaign_url' => isset($this->data->Transaction->CampaignChooseLink) ? $this->printData($this->data->Transaction->CampaignChooseLink) : null, + 'md_status' => $this->request->get('mdstatus'), + 'rand' => (string)$this->request->get('rnd'), + 'hash' => (string)$this->request->get('secure3dhash'), + 'hash_params' => (string)$this->request->get('hashparams'), + 'hash_params_val' => (string)$this->request->get('hashparamsval'), + 'secure_3d_hash' => (string)$this->request->get('secure3dhash'), + 'secure_3d_level' => (string)$this->request->get('secure3dsecuritylevel'), + 'masked_number' => (string)$this->request->get('MaskedPan'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'md_error_message' => (string)$this->request->get('mderrormessage'), + 'name' => (string)$this->request->get('firmaadi'), + 'email' => (string)$this->request->get('Email'), + 'extra' => null, + 'all' => $this->data, + '3d_all' => $this->request->all(), + ]; + + return $this; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $status = 'declined'; + $response = 'Declined'; + $proc_return_code = (string)$this->request->get('procreturncode'); + + $transaction_security = 'MPI fallback'; + if (in_array($this->request->get('mdstatus'), [1, 2, 3, 4]) && $proc_return_code == '00') { + if ($this->request->get('mdstatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdstatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + + $status = 'approved'; + $response = 'Approved'; + } + + $this->response = (object)[ + 'id' => (string)$this->request->get('authcode'), + 'order_id' => (string)$this->request->get('oid'), + 'trans_id' => (string)$this->request->get('hostrefnum'), + 'auth_code' => (string)$this->request->get('authcode'), + 'host_ref_num' => (string)$this->request->get('hostrefnum'), + 'response' => $response, + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'proc_return_code' => $proc_return_code, + 'code' => $proc_return_code, + 'md_status' => $this->request->get('mdStatus'), + 'status' => $status, + 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, + 'hash' => (string)$this->request->get('secure3dhash'), + 'rand' => (string)$this->request->get('rnd'), + 'hash_params' => (string)$this->request->get('hashparams'), + 'hash_params_val' => (string)$this->request->get('hashparamsval'), + 'masked_number' => (string)$this->request->get('MaskedPan'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'error_code' => (string)$this->request->get('errcode'), + 'error_message' => (string)$this->request->get('errmsg'), + 'md_error_message' => (string)$this->request->get('mderrormessage'), + 'campaign_url' => null, + 'name' => (string)$this->request->get('firmaadi'), + 'email' => (string)$this->request->get('Email'), + 'extra' => $this->request->get('Extra'), + 'all' => $this->request->all(), + ]; + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $security_data = $this->makeSecurityData(); + $hash_data = $this->make3dHashData($security_data); + + $inputs = [ + 'secure3dsecuritylevel' => $this->account->model == '3d_pay' ? '3D_PAY' : '3D', + 'mode' => $this->mode, + 'apiversion' => $this->version, + 'terminalprovuserid' => 'PROVAUT',//$this->account->username, + 'terminaluserid' => $this->account->username, + 'terminalmerchantid' => $this->account->client_id, + 'txntype' => $this->type, + 'txnamount' => $this->amountFormat($this->order->amount), + 'txncurrencycode' => $this->order->currency, + 'txninstallmentcount' => $this->order->installment > 1 ? $this->order->installment : '', + 'orderid' => $this->order->id, + 'terminalid' => $this->account->terminal_id, + 'successurl' => $this->order->success_url, + 'errorurl' => $this->order->fail_url, + 'customeremailaddress' => isset($this->order->email) ? $this->order->email : null, + 'customeripaddress' => $this->order->ip, + 'cardnumber' => $this->card->number, + 'cardexpiredatemonth' => $this->card->month, + 'cardexpiredateyear' => substr($this->card->year, -2), + 'cardcvv2' => $this->card->cvv, + 'secure3dhash' => $hash_data, + ]; + + //dd($inputs); + + return [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $hash_data, + 'inputs' => $inputs, + ]; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + + if ($this->card) { + $this->card->month = str_pad($this->card->month, 2, '0', STR_PAD_LEFT); + } + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund or Cancel Order + * + * @param array $meta + * @param $type + * @return $this + * @throws GuzzleException + */ + protected function refundOrCancel(array $meta, $type) + { + $this->order = (object)[ + 'id' => $meta['order_id'], + 'amount' => isset($meta['amount']) ? $meta['amount'] : null, + ]; + + $security_data = $this->makeSecurityData(true); + $hash_data = $this->makeHashData($security_data); + + $currency = (int)$this->currencies[$meta['currency']]; + + $nodes = [ + 'GVPSRequest' => [ + 'Mode' => $this->mode, + 'Version' => $this->version, + 'ChannelCode' => '', + 'Terminal' => [ + 'ProvUserID' => 'PROVRFN',//$this->account->username, + 'UserID' => $this->account->refund_username, + 'HashData' => $hash_data, + 'ID' => $this->account->terminal_id, + 'MerchantID' => $this->account->client_id, + ], + 'Customer' => [ + 'IPAddress' => isset($meta['ip']) ? $meta['ip'] : null, + 'EmailAddress' => isset($meta['email']) ? $meta['email'] : null, + ], + 'Order' => [ + 'OrderID' => $this->order->id, + 'GroupID' => '', + ], + 'Transaction' => [ + 'Type' => $type, + 'InstallmentCnt' => '', + 'Amount' => $this->amountFormat($this->order->amount), + 'CurrencyCode' => $currency, + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + 'OriginalRetrefNum' => $meta['ref_ret_num'], + ], + ] + ]; + + $xml = $this->createXML($nodes); + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $this->response = (object)[ + 'id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'order_id' => isset($this->data->Order->OrderID) ? $this->printData($this->data->Order->OrderID) : null, + 'group_id' => isset($this->data->Order->GroupID) ? $this->printData($this->data->Order->GroupID) : null, + 'trans_id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'response' => isset($this->data->Transaction->Response->Message) ? $this->printData($this->data->Transaction->Response->Message) : null, + 'auth_code' => isset($this->data->Transaction->AuthCode) ? $this->data->Transaction->AuthCode : null, + 'host_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'ret_ref_num' => isset($this->data->Transaction->RetrefNum) ? $this->printData($this->data->Transaction->RetrefNum) : null, + 'hash_data' => isset($this->data->Transaction->HashData) ? $this->printData($this->data->Transaction->HashData) : null, + 'proc_return_code' => $this->getProcReturnCode(), + 'code' => $this->getProcReturnCode(), + 'error_code' => isset($this->data->Transaction->Response->Code) ? $this->printData($this->data->Transaction->Response->Code) : null, + 'error_message' => isset($this->data->Transaction->Response->ErrorMsg) ? $this->printData($this->data->Transaction->Response->ErrorMsg) : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'all' => $this->data, + ]; + + return $this; + } + + /** + * Refund Order + * + * @param $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + return $this->refundOrCancel($meta, 'refund'); + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + return $this->refundOrCancel($meta, 'void'); + } + + /** + * Order Status or History + * + * @param array $meta + * @param $type + * @return $this + * @throws GuzzleException + */ + protected function statusOrHistory(array $meta, $type) + { + $obj_item = 'OrderInqResult'; + if ($type == 'orderhistoryinq') { + $obj_item = 'OrderHistInqResult'; + } + + $this->order = (object)[ + 'id' => isset($meta['order_id']) ? $meta['order_id'] : null, + 'currency' => isset($this->currencies[$meta['currency']]) ? $this->currencies[$meta['currency']] : null, + 'amount' => '1', + ]; + + $security_data = $this->makeSecurityData(); + $hash_data = $this->makeHashData($security_data); + + $xml = $this->createXML([ + 'GVPSRequest' => [ + 'Mode' => $this->mode, + 'Version' => 'v0.01', + 'ChannelCode' => '', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT',//$this->account->username, + 'UserID' => $this->account->username, + 'HashData' => $hash_data, + 'ID' => $this->account->terminal_id, + 'MerchantID' => $this->account->client_id, + ], + 'Customer' => [ + 'IPAddress' => isset($meta['ip']) ? $meta['ip'] : null, + 'EmailAddress' => isset($meta['email']) ? $meta['email'] : null, + ], + 'Order' => [ + 'OrderID' => $this->order->id, + 'GroupID' => '', + ], + 'Card' => [ + 'Number' => '', + 'ExpireDate' => '', + 'CVV2' => '', + ], + 'Transaction' => [ + 'Type' => $type, + 'InstallmentCnt' => '', + 'Amount' => $this->order->amount ? $this->amountFormat($this->order->amount) : null, + 'CurrencyCode' => $this->order->currency, + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + ], + ] + ]); + + $this->send($xml); + + $status = 'declined'; + if ($this->getProcReturnCode() == '00') { + $status = 'approved'; + } + + $data = [ + 'id' => isset($this->data->Order->{$obj_item}->AuthCode) ? $this->printData($this->data->Order->{$obj_item}->AuthCode) : null, + 'order_id' => isset($this->data->Order->OrderID) ? $this->printData($this->data->Order->OrderID) : null, + 'group_id' => isset($this->data->Order->GroupID) ? $this->printData($this->data->Order->GroupID) : null, + 'trans_id' => isset($this->data->Transaction->AuthCode) ? $this->printData($this->data->Transaction->AuthCode) : null, + 'response' => isset($this->data->Transaction->Response->Message) ? $this->printData($this->data->Transaction->Response->Message) : null, + 'auth_code' => isset($this->data->Order->{$obj_item}->AuthCode) ? $this->printData($this->data->Order->{$obj_item}->AuthCode) : null, + 'host_ref_num' => isset($this->data->Order->{$obj_item}->RetrefNum) ? $this->printData($this->data->Order->{$obj_item}->RetrefNum) : null, + 'ret_ref_num' => isset($this->data->Order->{$obj_item}->RetrefNum) ? $this->printData($this->data->Order->{$obj_item}->RetrefNum) : null, + 'hash_data' => isset($this->data->Transaction->HashData) ? $this->printData($this->data->Transaction->HashData) : null, + 'proc_return_code' => $this->getProcReturnCode(), + 'code' => $this->getProcReturnCode(), + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => isset($this->data->Transaction->Response->Code) ? $this->printData($this->data->Transaction->Response->Code) : null, + 'error_message' => isset($this->data->Transaction->Response->ErrorMsg) ? $this->printData($this->data->Transaction->Response->ErrorMsg) : null, + 'extra' => isset($this->data->Extra) ? $this->data->Extra : null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + if ($type == 'orderhistoryinq') { + $data = array_merge($data, [ + 'order_txn' => isset($this->data->Order->OrderHistInqResult->OrderTxnList->OrderTxn) ? $this->data->Order->OrderHistInqResult->OrderTxnList->OrderTxn : [] + ]); + } + + $this->response = (object)$data; + + return $this; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + return $this->statusOrHistory($meta, 'orderinq'); + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + return $this->statusOrHistory($meta, 'orderhistoryinq'); + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } +} diff --git a/app/Core/Payment/Pos/Pos.php b/app/Core/Payment/Pos/Pos.php new file mode 100644 index 0000000..4591a01 --- /dev/null +++ b/app/Core/Payment/Pos/Pos.php @@ -0,0 +1,230 @@ +config = $config ? $config : require __DIR__ . '/config/pos.php'; + + // API Account + $this->account = (object) $account; + + // Bank API Exist + if ( ! array_key_exists($this->account->bank, $this->config['banks'])) { + throw new BankNotFoundException(); + } + + // Instance Bank Class + $this->instance(); + } + + /** + * Instance Bank Class + * + * @throws BankClassNullException + */ + public function instance() + { + // Bank Class + $class = $this->config['banks'][$this->account->bank]['class']; + + if ( ! $class) throw new BankClassNullException(); + + // Create Bank Class Object + $this->bank = new $class($this->config['banks'][$this->account->bank], $this->account, $this->config['currencies']); + } + + /** + * Prepare Order + * + * @param array $order + * @param array [] $card + * @return Pos + */ + public function prepare(array $order, array $card = []) + { + // Installment + $installment = 0; + if (isset($order['installment'])) { + $installment = $order['installment'] ? (int) $order['installment'] : 0; + } + + // Currency + $currency = null; + if (isset($order['currency'])) { + $currency = (int) $this->config['currencies'][$order['currency']]; + } + + // Order + $this->order = (object) array_merge($order, [ + 'installment' => $installment, + 'currency' => $currency, + ]); + + // Card + $this->card = $card ? (object) $card : null; + + // Prepare Order + $this->bank->prepare($this->order, $this->card); + + return $this; + } + + /** + * Make Payment + * + * @param array [] $card + * @return mixed + */ + public function payment(array $card = []) + { + // Credit Card + if ($card) { + $card = array_merge($card, [ + 'month' => str_pad((int) $card['month'], 2, 0, STR_PAD_LEFT), + 'year' => str_pad((int) $card['year'], 2, 0, STR_PAD_LEFT), + ]); + } + + $this->card = (object) $card; + + // Make Payment + return $this->bank->payment($this->card); + } + + /** + * Get gateway URL + * + * @return string|null + */ + public function getGatewayUrl() + { + return isset($this->bank->gateway) ? $this->bank->gateway : 'null'; + } + + /** + * @return array + */ + public function getConfig(){ + return $this->bank->getConfig(); + } + + /** + * @return mixed + */ + public function getAccount(){ + return $this->bank->getAccount(); + } + + /** + * @return array + */ + public function getCurrencies(){ + return $this->bank->getCurrencies(); + } + + /** + * @return mixed + */ + public function getOrder(){ + return $this->bank->getOrder(); + } + + /** + * @return mixed + */ + public function getCard(){ + return $this->bank->getCard(); + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3dFormData() + { + $data = []; + + try { + $data = $this->bank->get3dFormData(); + } catch (Exception $e) {} + + return $data; + } + + /** + * Is success + * + * @return bool + */ + public function isSuccess() + { + return $this->bank->isSuccess(); + } + + /** + * Is error + * + * @return bool + */ + public function isError() + { + return $this->bank->isError(); + } +} diff --git a/app/Core/Payment/Pos/PosHelpersTrait.php b/app/Core/Payment/Pos/PosHelpersTrait.php new file mode 100644 index 0000000..461a29e --- /dev/null +++ b/app/Core/Payment/Pos/PosHelpersTrait.php @@ -0,0 +1,99 @@ +encode($nodes[$rootNodeName], 'xml', [ + XmlEncoder::ROOT_NODE_NAME => $rootNodeName, + XmlEncoder::ENCODING => $encoding + ]); + return $xml; + } + + /** + * Print Data + * + * @param $data + * @return null|string + */ + public function printData($data) + { + if ((is_object($data) || is_array($data)) && !count((array)$data)) { + $data = null; + } + + return (string)$data; + } + + /** + * Is success + * + * @return bool + */ + public function isSuccess() + { + $success = false; + if (isset($this->response) && $this->response->status == 'approved') { + $success = true; + } + + return $success; + } + + /** + * Is error + * + * @return bool + */ + public function isError() + { + return !$this->isSuccess(); + } + + /** + * Converts XML string to object + * + * @param string data + * @return object + */ + public function XMLStringToObject($data) + { + $encoder = new XmlEncoder(); + $xml = $encoder->decode($data, 'xml'); + return (object)json_decode(json_encode($xml)); + } +} diff --git a/app/Core/Payment/Pos/PosInterface.php b/app/Core/Payment/Pos/PosInterface.php new file mode 100644 index 0000000..2e5c239 --- /dev/null +++ b/app/Core/Payment/Pos/PosInterface.php @@ -0,0 +1,141 @@ + 'declined', + '1' => 'approved', + '2' => 'declined', + '00' => 'approved', + '0001' => 'bank_call', + '0005' => 'reject', + '0007' => 'bank_call', + '0012' => 'reject', + '0014' => 'reject', + '0030' => 'bank_call', + '0041' => 'reject', + '0043' => 'reject', + '0051' => 'reject', + '0053' => 'bank_call', + '0054' => 'reject', + '0057' => 'reject', + '0058' => 'reject', + '0062' => 'reject', + '0065' => 'reject', + '0091' => 'bank_call', + '0123' => 'transaction_not_found', + '0444' => 'bank_call', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Sale', + 'pre' => 'Auth', + 'post' => 'Capt', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Fixed Currencies + * @var array + */ + protected $_currencies = [ + 'TRY' => 'TL', + 'USD' => 'US', + 'EUR' => 'EU', + 'GBP' => 'GB', + 'JPY' => 'JP', + 'RUB' => 'RU', + ]; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * @var PosNetCrypt|null + */ + public $crypt; + + /** + * PosNet constructor. + * + * @param array $config + * @param array $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $request = Request::createFromGlobals(); + $this->request = $request->request; + + $this->crypt = new PosNetCrypt(); + + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + return $this; + } + + /** + * Get currency + * + * @return int|string + */ + protected function getCurrency() { + $search = array_search($this->order->currency, $this->currencies); + $currency = $this->order->currency; + if ($search) { + $currency = $this->_currencies[$search]; + } + + return $currency; + } + + /** + * Get amount + * + * @return int + */ + protected function getAmount() + { + return (int) str_replace('.', '', number_format($this->order->amount, 2, '.', '')); + } + + /** + * Get PrefixedOrderId + * To check the status of an order or cancel/refund order Yapikredi + * - requires the order length to be 24 + * - and order id prefix which is "TDSC" for 3D payments + * @return string + */ + protected function getPrefixedOrderId() + { + if($this->account->model == '3d'){ + return $this->config['order']['id_3d_prefix'] . $this->getOrderId($this->config['order']['id_total_length'] - strlen($this->config['order']['id_3d_prefix'])); + }elseif($this->account->model == '3d_pay') { + return $this->config['order']['id_3d_pay_prefix'] . $this->getOrderId($this->config['order']['id_total_length'] - strlen($this->config['order']['id_3d_pay_prefix'])); + } + return $this->config['order']['id_regular_prefix'] . $this->getOrderId($this->config['order']['id_total_length'] - strlen($this->config['order']['id_regular_prefix'])); + } + + /** + * Get orderId + * + * @param int $pad_length + * @return string + */ + protected function getOrderId(int $pad_length = null) + { + $this->order->id = str_replace('_','',$this->order->id); + if($pad_length === null) $pad_length = $this->config['order']['id_length']; + return (string) str_pad($this->order->id, $pad_length, '0', STR_PAD_LEFT); + } + + /** + * Get Installment + * + * @return int|string + */ + protected function getInstallment() + { + $installment = (int) $this->order->installment; + if (!$this->order->installment) { + $installment = '00'; + } + + return $installment; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $transaction = strtolower($this->type); + + $nodes = [ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'tranDateRequired' => '1', + $transaction => [ + 'orderID' => $this->getOrderId(), + 'installment' => $this->getInstallment(), + 'amount' => $this->getAmount(), + 'currencyCode' => $this->getCurrency(), + 'ccno' => $this->card->number, + 'expDate' => $this->card->year . $this->card->month, + 'cvc' => $this->card->cvv, + ], + ] + ]; + + return $this->createXML($nodes, $encoding = 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'tranDateRequired' => '1', + 'capt' => [ + 'hostLogKey' => $this->order->host_ref_num, + 'amount' => $this->getAmount(), + 'currencyCode' => $this->getCurrency(), + 'installment' => $this->order->installment ? $this->getInstallment() : null + ], + ] + ]; + + return $this->createXML($nodes); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'oosResolveMerchantData' => [ + 'bankData' => $this->request->get('BankPacket'), + 'merchantData' => $this->request->get('MerchantPacket'), + 'sign' => $this->request->get('Sign'), + 'mac' => $this->create3DHash() + ], + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return (string) $this->data->approved == '1' ? '00' : $this->data->approved; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return isset($this->codes[$proc_return_code]) ? (string) $this->codes[$proc_return_code] : null; + } + + /** + * Get card exp date + * + * @return string + */ + protected function getCardExpDate() + { + $expDate = (string) substr($this->card->year, -2).$this->card->month; + return (string) $expDate; + } + + /** + * Get OOS transaction data + * + * @return object + * @throws GuzzleException + */ + public function getOosTransactionData() + { + $name = isset($this->card->name) ? $this->card->name : null; + if (!$name) { + $name = isset($this->order->name) ? $this->order->name : null; + } + + $contents = $this->createXML([ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'oosRequestData' => [ + 'posnetid' => $this->account->posnet_id, + 'ccno' => $this->card->number, + 'expDate' => $this->getCardExpDate(), + 'cvc' => $this->card->cvv, + 'amount' => $this->getAmount(), + 'currencyCode' => $this->getCurrency(), + 'installment' => $this->getInstallment(), + 'XID' => $this->getOrderId(), + 'cardHolderName' => $name, + 'tranType' => $this->type, + ] + ], + ]); + + $this->send($contents); + + return $this->data; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + $contents = ''; + if (in_array($this->order->transaction, ['pay', 'pre'])) { + $contents = $this->createRegularPaymentXML(); + } elseif ($this->order->transaction == 'post') { + $contents = $this->createRegularPostXML(); + } + + $this->send($contents); + + $status = 'declined'; + $code = '1'; + $proc_return_code = '01'; + $obj = isset($this->data) ? $this->data : null; + $error_code = !empty($obj->respCode) ? $obj->respCode : null; + + if ($this->getProcReturnCode() == '00' && $this->getStatusDetail() == 'approved' && $obj && !$error_code) { + $status = 'approved'; + $code = isset($obj->approved) ? $obj->approved : null; + $proc_return_code = $this->getProcReturnCode(); + } + + $this->response = (object) [ + 'id' => isset($obj->authCode) ? $this->printData($obj->authCode) : null, + 'order_id' => $this->order->id, + 'fixed_order_id' => $this->getOrderId(), + 'group_id' => isset($obj->groupID) ? $this->printData($obj->groupID) : null, + 'trans_id' => isset($obj->authCode) ? $this->printData($obj->authCode) : null, + 'response' => $this->getStatusDetail(), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'auth_code' => isset($obj->authCode) ? $this->printData($obj->authCode) : null, + 'host_ref_num' => isset($obj->hostlogkey) ? $this->printData($obj->hostlogkey) : null, + 'ret_ref_num' => isset($obj->hostlogkey) ? $this->printData($obj->hostlogkey) : null, + 'proc_return_code' => $proc_return_code, + 'code' => $code, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => $error_code, + 'error_message' => !empty($obj->respText) ? $this->printData($obj->respText) : null, + 'campaign_url' => null, + 'extra' => null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + return $this; + } + + /** + * Check 3D Hash + * + * @return bool + */ + protected function check3DHash() + { + $check = false; + + if ($this->crypt instanceof PosNetCrypt) { + $decrypted_data = $this->crypt->decrypt($this->request->get('MerchantPacket'), $this->account->store_key); + + $decrypted_data_array = explode(';', $decrypted_data); + + $original_data = array_map('strval', [ + $this->account->client_id, + $this->account->terminal_id, + $this->getAmount(), + $this->getInstallment(), + $this->getOrderId() + ]); + + $decrypted_data_list = array_map('strval', [ + $decrypted_data_array[0], + $decrypted_data_array[1], + $decrypted_data_array[2], + $decrypted_data_array[3], + $decrypted_data_array[4] + ]); + + if ($original_data == $decrypted_data_list) { + $check = true; + } + } else { + $check = false; + } + + return $check; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + $status = 'declined'; + $transaction_security = 'MPI fallback'; + + if ($this->check3DHash()) { + $contents = $this->create3DPaymentXML(); + $this->send($contents); + }else{ + goto end; + } + + if($this->getProcReturnCode() != '00'){ + goto end; + } + + if(!$this->verifyResponseMAC($this->data->oosResolveMerchantDataResponse)) { + goto end; + } + + if ($this->getProcReturnCode() == '00' && $this->getStatusDetail() == 'approved') { + if ($this->data->oosResolveMerchantDataResponse->mdStatus == '1') { + $transaction_security = 'Full 3D Secure'; + $status = 'approved'; + } elseif (in_array($this->data->oosResolveMerchantDataResponse->mdStatus, [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + $status = 'approved'; + } + + //if 3D Authentication is failed + if($status != 'approved') goto end; + + $nodes = [ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'oosTranData' => [ + 'bankData' => $this->request->get('BankPacket'), + 'merchantData' => $this->request->get('MerchantPacket'), + 'sign' => $this->request->get('Sign'), + 'wpAmount' => 0, + 'mac' => $this->create3DHash() + ], + ] + ]; + + $contents = $this->createXML($nodes, $encoding = 'ISO-8859-9'); + $this->send($contents); + } + + if ($this->data->approved != 1) { + $status = 'declined'; + } + + end: + $this->response = (object) [ + 'id' => isset($this->data->authCode) ? $this->printData($this->data->authCode) : null, + 'order_id' => isset($this->order->id) ? $this->printData($this->order->id) : null, + 'fixed_order_id' => $this->getOrderId(), + 'group_id' => isset($this->data->groupID) ? $this->printData($this->data->groupID) : null, + 'trans_id' => isset($this->data->authCode) ? $this->printData($this->data->authCode) : null, + 'response' => $this->getStatusDetail(), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'auth_code' => isset($this->data->authCode) ? $this->printData($this->data->authCode) : null, + 'host_ref_num' => isset($this->data->hostlogkey) ? $this->printData($this->data->hostlogkey) : null, + 'ret_ref_num' => isset($this->data->transaction->hostlogkey) ? $this->printData($this->data->transaction->hostlogkey) : null, + 'proc_return_code' => $this->getProcReturnCode(), + 'code' => $this->getProcReturnCode(), + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => !empty($this->data->respCode) ? $this->printData($this->data->respCode) : null, + 'error_message' => !empty($this->data->respText) ? $this->printData($this->data->respText) : null, + 'md_status' => isset($this->data->oosResolveMerchantDataResponse->mdStatus) ? $this->printData($this->data->oosResolveMerchantDataResponse->mdStatus) : null, + 'hash' => [ + 'merchant_packet' => $this->request->get('MerchantPacket'), + 'bank_packet' => $this->request->get('BankPacket'), + 'sign' => $this->request->get('Sign'), + ], + 'xid' => isset($this->data->oosResolveMerchantDataResponse->xid) ? $this->data->oosResolveMerchantDataResponse->xid : null, + 'md_error_message' => isset($this->data->oosResolveMerchantDataResponse->mdErrorMessage) ? $this->data->oosResolveMerchantDataResponse->mdErrorMessage : null, + 'campaign_url' => null, + 'all' => $this->data, + ]; + + if(empty($this->response->error_message)) { + $this->response->error_message = $this->response->md_error_message; + } + + return $this; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + //TODO + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + * @throws GuzzleException + */ + public function get3DFormData() + { + $inputs = []; + $data = null; + + if ($this->card && $this->order) { + $data = $this->getOosTransactionData(); + + if($data->approved == 0) { + Log::debug('PosNET getOosTransactionData'); + Log::debug($data); + } + + $inputs = [ + 'posnetData' => $data->oosRequestDataResponse->data1, + 'posnetData2' => $data->oosRequestDataResponse->data2, + 'mid' => $this->account->client_id, + 'posnetID' => $this->account->posnet_id, + 'digest' => $data->oosRequestDataResponse->sign, + 'vftCode' => isset($this->account->promotion_code) ? $this->account->promotion_code : null, + 'merchantReturnURL' => $this->order->success_url, + 'url' => '', + 'lang' => $this->order->lang, + ]; + } + + return [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $data->oosRequestDataResponse->sign, + 'hash' => $data->oosRequestDataResponse->data1, + 'inputs' => $inputs, + ]; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $headers = [ + 'Content-Type' => 'application/x-www-form-urlencoded' + ]; + + $response = $client->request('POST', $this->url, [ + 'headers' => $headers, + 'body' => "xmldata=" . $contents, + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + + + Log::debug($this->url); + Log::debug($contents); + Log::debug(json_decode(json_encode($this->data),1)); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + //$this->make3DPayPayment(); + $this->make3DPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund or Cancel Order + * + * @param array $meta + * @param string $type + * @return $this + * @throws GuzzleException + */ + protected function refundOrCancel(array $meta, $type = 'cancel') + { + $this->order = (object) [ + 'id' => $meta['order_id'], + 'host_ref_num' => isset($meta['host_ref_num']) ? $meta['host_ref_num'] : null, + 'auth_code' => isset($meta['auth_code']) ? $meta['auth_code'] : null, + 'amount' => isset($meta['amount']) ? $meta['amount'] : null, + 'currency' => isset($meta['currency']) ? $this->_currencies[$meta['currency']] : null, + ]; + + $nodes = [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'tranDateRequired' => '1', + ]; + + if ($type == 'refund') { + $return = [ + 'amount' => $this->getAmount(), + 'currencyCode' => $this->getCurrency(), + 'orderID' => $this->getPrefixedOrderId(), + ]; + + if ($this->order->host_ref_num) { + $return['hostLogKey'] = $this->order->host_ref_num; + unset($return['orderID']); + } + + $append = [ + 'return' => $return, + ]; + } else { + $reverse = [ + 'transaction' => 'pointUsage', + 'orderID' => $this->getPrefixedOrderId(), + 'authCode' => $this->order->auth_code, + ]; + + if ($this->order->host_ref_num) { + $reverse = [ + 'transaction' => 'pointUsage', + 'hostLogKey' => $this->order->host_ref_num, + 'authCode' => $this->order->auth_code, + ]; + } + + $append = [ + 'reverse' => $reverse, + ]; + } + + $nodes = array_merge($nodes, $append); + + $xml = $this->createXML([ + 'posnetRequest' => $nodes + ]); + + $this->send($xml); + + $status = 'declined'; + $code = '1'; + $proc_return_code = '01'; + $obj = isset($this->data) ? $this->data : null; + $error_code = !empty($obj->respCode) ? $obj->respCode : null; + + if ($this->getProcReturnCode() == '00' && $obj && !$error_code) { + $status = 'approved'; + $code = isset($obj->approved) ? $obj->approved : null; + $proc_return_code = $this->getProcReturnCode(); + } + + $transaction = null; + $transaction_type = null; + $state = isset($obj->state) ? $obj->state : null; + if ($state == 'Sale') { + $transaction = 'pay'; + $transaction_type = $this->types[$transaction]; + } elseif ($state == 'Authorization') { + $transaction = 'pre'; + $transaction_type = $this->types[$transaction]; + } elseif ($state == 'Capture') { + $transaction = 'post'; + $transaction_type = $this->types[$transaction]; + } + + $data = [ + 'id' => isset($obj->transaction->authCode) ? $this->printData($obj->transaction->authCode) : null, + 'order_id' => isset($this->order->id) ? $this->printData($this->order->id) : null, + 'fixed_order_id' => isset($obj->transaction->orderID) ? $this->printData($obj->transaction->orderID) : null, + 'group_id' => isset($obj->transaction->groupID) ? $this->printData($obj->transaction->groupID) : null, + 'trans_id' => isset($obj->transaction->authCode) ? $this->printData($obj->transaction->authCode) : null, + 'response' => $this->getStatusDetail(), + 'auth_code' => isset($obj->transaction->authCode) ? $this->printData($obj->transaction->authCode) : null, + 'host_ref_num' => isset($obj->transaction->hostlogkey) ? $this->printData($obj->transaction->hostlogkey) : null, + 'ret_ref_num' => isset($obj->transaction->hostlogkey) ? $this->printData($obj->transaction->hostlogkey) : null, + 'transaction' => $transaction, + 'transaction_type' => $transaction_type, + 'state' => $state, + 'date' => isset($obj->transaction->tranDate) ? $this->printData($obj->transaction->tranDate) : null, + 'proc_return_code' => $proc_return_code, + 'code' => $code, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => $error_code, + 'error_message' => !empty($obj->respText) ? $this->printData($obj->respText) : null, + 'extra' => null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + $this->response = (object) $data; + + return $this; + } + + /** + * Refund Order + * + * @param $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + return $this->refundOrCancel($meta, 'refund'); + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + return $this->refundOrCancel($meta, 'cancel'); + } + + /** + * Order Status + * + * @param array $meta + * @param bool $history + * @return $this + * @throws GuzzleException + */ + public function status(array $meta, $history = false) + { + $this->order = (object) [ + 'id' => isset($meta['order_id']) ? $meta['order_id'] : null, + ]; + + $xml = $this->createXML([ + 'posnetRequest' => [ + 'mid' => $this->account->client_id, + 'tid' => $this->account->terminal_id, + 'agreement' => [ + 'orderID' => $this->getPrefixedOrderId(), + ], + ] + ]); + + $this->send($xml); + + $status = 'declined'; + $code = '1'; + $proc_return_code = '01'; + $obj = isset($this->data->transactions) ? $this->data->transactions : null; + $error_code = !empty($this->data->respCode) ? $this->data->respCode : null; + + if ($this->getProcReturnCode() == '00' && $obj && !$error_code) { + $status = 'approved'; + $code = isset($obj->approved) ? $obj->approved : null; + $proc_return_code = $this->getProcReturnCode(); + } + + $transaction = null; + $transaction_type = null; + + $state = null; + $auth_code = null; + $refunds = []; + if (isset($this->data->transactions->transaction)) { + $state = isset($this->data->transactions->transaction->state) ? + $this->data->transactions->transaction->state : + null; + + $auth_code = isset($obj->transaction->authCode) ? $this->printData($obj->transaction->authCode) : null; + + if (is_array($this->data->transactions->transaction) && count($this->data->transactions->transaction)) { + $state = $this->data->transactions->transaction[0]->state; + $auth_code = $this->data->transactions->transaction[0]->authCode; + + if (count($this->data->transactions->transaction) > 1 && $history) { + $_currencies = array_flip($this->_currencies); + + foreach ($this->data->transactions->transaction as $key => $_transaction) { + if ($key > 0) { + $currency = isset($_currencies[$_transaction->currencyCode]) ? + (string) $_currencies[$_transaction->currencyCode] : + $_transaction->currencyCode; + $refunds[] = [ + 'amount' => (double) $_transaction->amount, + 'currency' => $currency, + 'auth_code' => $_transaction->authCode, + 'date' => $_transaction->tranDate, + ]; + } + } + } + } + } + + if ($state == 'Sale') { + $transaction = 'pay'; + $state = $transaction; + $transaction_type = $this->types[$transaction]; + } elseif ($state == 'Authorization') { + $transaction = 'pre'; + $state = $transaction; + $transaction_type = $this->types[$transaction]; + } elseif ($state == 'Capture') { + $transaction = 'post'; + $state = $transaction; + $transaction_type = $this->types[$transaction]; + } elseif ($state == 'Bonus_Reverse') { + $state = 'cancel'; + } else { + $state = 'mixed'; + } + + $data = [ + 'id' => $auth_code, + 'order_id' => isset($this->order->id) ? $this->printData($this->order->id) : null, + 'fixed_order_id' => $this->getOrderId(), + 'group_id' => isset($obj->transaction->groupID) ? $this->printData($obj->transaction->groupID) : null, + 'trans_id' => $auth_code, + 'response' => $this->getStatusDetail(), + 'auth_code' => $auth_code, + 'host_ref_num' => isset($obj->transaction->hostLogKey) ? $this->printData($obj->transaction->hostLogKey) : null, + 'ret_ref_num' => null, + 'transaction' => $transaction, + 'transaction_type' => $transaction_type, + 'state' => $state, + 'date' => isset($obj->transaction->tranDate) ? $this->printData($obj->transaction->tranDate) : null, + 'refunds' => $refunds, + 'proc_return_code' => $proc_return_code, + 'code' => $code, + 'status' => $status, + 'status_detail' => $this->getStatusDetail(), + 'error_code' => $error_code, + 'error_message' => !empty($this->data->respText) ? $this->printData($this->data->respText) : null, + 'extra' => null, + 'all' => $this->data, + 'original' => $this->data, + ]; + + if (!$history) { + unset($data['refunds']); + } + + $this->response = (object) $data; + + return $this; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + return $this->status($meta, true); + } + + /** + * @return array + */ + public function getConfig(){ + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount(){ + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies(){ + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder(){ + return $this->order; + } + + /** + * @return mixed + */ + public function getCard(){ + return $this->card; + } + + /** + * Hash string + * + * @return string + */ + public function hashString(string $str) + { + return base64_encode(hash('sha256',$str,true)); + } + + /** + * Create 3D Hash (MAC) + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + + $firstHash = $this->hashString($this->account->store_key . ";" . $this->account->terminal_id); + + if ($this->account->model == '3d' || $this->account->model == '3d_pay') { + $hash_str = $this->hashString($this->getOrderId() . ";" . $this->getAmount() . ";" . $this->getCurrency() . ";" . $this->account->client_id . ";" . $firstHash); + } + + return $hash_str; + } + + /** + * verifies the if request came from bank + * + * @param mixed $data oosResolveMerchantDataResponse + * @return boolean + */ + public function verifyResponseMAC($data) + { + $hash_str = ''; + + $firstHash = $this->hashString($this->account->store_key . ";" . $this->account->terminal_id); + + if ($this->account->model == '3d' || $this->account->model == '3d_pay') { + $hash_str = $this->hashString($data->mdStatus . ";" . $this->getOrderId() . ";" . $this->getAmount() . ";" . $this->getCurrency() . ";" . $this->account->client_id . ";" . $firstHash); + } + + return $hash_str == $data->mac; + } +} diff --git a/app/Core/Payment/Pos/PosNetCrypt.php b/app/Core/Payment/Pos/PosNetCrypt.php new file mode 100644 index 0000000..80c1955 --- /dev/null +++ b/app/Core/Payment/Pos/PosNetCrypt.php @@ -0,0 +1,170 @@ +algo = 'des-ede3-cbc'; + $this->block = 8; + $this->ks = 24; + $this->error = ''; + } + + /** + * This function is used to get encryption errors. + * + * @return string + */ + public function getLastError () + { + return $this->error; + } + + /** + * @return string + */ + public function createIV () + { + $temp = sprintf("%05d", rand()); + $temp .= sprintf("%05d", rand()); + $temp .= sprintf("%05d", rand()); + $temp .= sprintf("%05d", rand()); + + return pack("H*", substr($temp, 0, 16)); + } + + /** + * @param $data + * @param $key + * @return string + */ + public function encrypt($data, $key) + { + // Create IV + $iv = $this->createIV(); + + // Encrypt Data + $encrypted_data = openssl_encrypt($data, $this->algo, $this->detKey($key), OPENSSL_RAW_DATA, $iv); + + // Add IV and Convert to HEX + $hex_encrypted_data = strtoupper(bin2hex($iv)).strtoupper(bin2hex($encrypted_data)); + + // Add CRC + $hex_encrypted_data = $this->addCrc($hex_encrypted_data); + + return $hex_encrypted_data; + } + + /** + * @param $data + * @param $key + * @return bool|string + */ + public function decrypt($data, $key) { + + $parsed_data = $this->parseEncryptedData($data); + + if (!$parsed_data) return false; + + // Check CRC + if (!$this->checkCrc($parsed_data['crc_data'], $parsed_data['crc'])) { + $this->error = "CRC is not valid! (" . $parsed_data['crc'] . ")"; + return FALSE; + } + + // Get IV + $iv = pack("H*", $parsed_data['iv']); + + // Get Encrypted Data + $encrypted_data = pack("H*", $parsed_data['payload']); + + // Decrypt Data + $decrypted_data = openssl_decrypt($encrypted_data, $this->algo, $this->detKey($key), OPENSSL_RAW_DATA, $iv); + + return $decrypted_data; + } + + /** + * @param $key + * @return bool|string + */ + public function detKey($key) + { + $deskey = substr(strtoupper(md5($key)), 0, $this->ks); + return $deskey; + } + + /** + * @param $data + * @return string + */ + public function addCrc($data) + { + $crc = crc32($data); + $hex_crc = sprintf("%08x", $crc); + $data .= strtoupper($hex_crc); + + return $data; + } + + /** + * @param $data + * @param $crc + * @return bool + */ + public function checkCrc($data, $crc) + { + $crc_calc = crc32($data); + $hex_crc = sprintf("%08x", $crc_calc); + $crc_calc = strtoupper($hex_crc); + + return strcmp($crc_calc, $crc) == 0 ? true : false; + } + + /** + * @param string $data + * @return array|bool + */ + private function parseEncryptedData(string $data){ + + if (strlen($data) < 16 + 8) return false; + + return [ + 'crc' => substr($data, -8), + 'crc_data' => substr($data, 0, strlen($data)-8), + 'iv' => substr($data, 0, 16), + 'payload' => substr($data, 16, strlen($data)-16-8) + ]; + } +} diff --git a/app/Core/Payment/Pos/QPos.php b/app/Core/Payment/Pos/QPos.php new file mode 100644 index 0000000..37b7323 --- /dev/null +++ b/app/Core/Payment/Pos/QPos.php @@ -0,0 +1,644 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * Response Raw Data + * + * @var object + */ + protected $mbrId = 5; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + + return $this; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + $hash_str = $this->mbrId . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->merchant_pass; + + return base64_encode(pack('H*', sha1($hash_str))); + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + $return = false; + $responseHash = $data['ResponseHash']; + + //MerchantID + MerchantPass + OrderId + AuthCode + ProcReturnCode + 3DStatus + ResponseRnd + UserCode + $generatedHash = $this->account->merchant_id . $this->account->merchant_pass . $data['OrderId'] . $data['AuthCode'] . $data['ProcReturnCode'] . $data['3DStatus'] . $data['ResponseRnd'] . $this->account->user_code; + $generatedHash = base64_encode(pack('H*', sha1($generatedHash))); + + if ($generatedHash == $responseHash) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + return false; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + return false; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + + if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') { + if (in_array($this->request->get('3DStatus'), [1])) { + $status = 'approved'; + } + } + + $transaction_security = 'MPI fallback'; + if ($status == 'approved') { + if ($this->request->get('3DStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('3DStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + } + + $this->response = (object)[ + 'id' => (string)$this->request->get('RequestGuid'), + 'trans_id' => (string)$this->request->get('HostRefNum'), + 'auth_code' => (string)$this->request->get('AuthCode'), + 'host_ref_num' => (string)$this->request->get('HostRefNum'), + //'response' => (string)$this->request->get('Response'), + 'order_id' => (string)$this->request->get('OrderId'), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'code' => (string)$this->request->get('ProcReturnCode'), + 'md_status' => $this->request->get('3DStatus'), + 'status' => $status, + 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, + 'hash' => (string)$this->request->get('ResponseHash'), + 'rand' => (string)$this->request->get('Rnd'), + //'hash_params' => (string)$this->request->get('HASHPARAMS'), + //'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), + 'masked_number' => (string)$this->request->get('CardMask'), + //'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + //'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('PurchAmount'), + 'currency' => (string)$this->request->get('Currency'), + 'tx_status' => (string)$this->request->get('TxnStatus'), + 'eci' => (string)$this->request->get('Eci'), + 'cavv' => (string)$this->request->get('CavvResult'), + //'xid' => (string)$this->request->get('xid'), + //'error_code' => (string)$this->request->get('ErrCode'), + 'error_message' => (string)$this->request->get('ErrMsg'), + //'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'name' => (string)$this->request->get('MrcName'), + //'email' => (string)$this->request->get('Email'), + 'extra' => $this->request->get('Extra'), + 'response_rnd' => $this->request->get('ResponseRnd'), + 'all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $data = []; + + if ($this->order) { + $this->order->hash = $this->create3DHash(); + + $inputs = [ + 'MbrId' => $this->mbrId, + 'MerchantID' => $this->account->merchant_id, + 'UserCode' => $this->account->user_code, + 'UserPass' => $this->account->user_pass, + 'SecureType' => $this->account->model == '3d_pay' ? '3DPay' : '3D', + 'TxnType' => $this->type, + 'InstallmentCount' => $this->order->installment, + 'Currency' => $this->order->currency, + 'OkUrl' => $this->order->success_url, + 'FailUrl' => $this->order->fail_url, + 'OrderId' => $this->order->id, + 'PurchAmount' => $this->order->amount, + 'Lang' => $this->order->lang, + 'Rnd' => $this->order->rand, + 'Hash' => $this->order->hash, + 'Pan' => $this->card->number, + 'Cvv2' => $this->card->cvv, + 'Expiry' => $this->getCardExpDate(), + ]; + + $data = [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $this->order->hash, + 'inputs' => $inputs, + ]; + } + + return $data; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + + $this->order->installment = $this->order->installment == 0 ? 0 : $this->order->installment; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + return false; + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + return false; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + return false; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + return false; + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } + + /** + * @return string|null + */ + public function getCardCode() + { + $card_type = null; + if (isset($this->card->type)) { + if ($this->card->type == 'visa') { + $card_type = '0'; + } elseif ($this->card->type == 'master') { + $card_type = '1'; + } elseif ($this->card->type == '1' || $this->card->type == '2') { + $card_type = $this->card->type; + } + } + return $card_type; + } + + protected function getCardExpDate() + { + $year = (string)substr($this->card->year, 2, 2); + $month = (string)substr($this->card->month, 0, 2); + + return (string)$month . $year; + } + + +} diff --git a/app/Core/Payment/Pos/VPos.php b/app/Core/Payment/Pos/VPos.php new file mode 100644 index 0000000..3db8465 --- /dev/null +++ b/app/Core/Payment/Pos/VPos.php @@ -0,0 +1,656 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + + return $this; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + + if ($this->account->model == '3d') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->order->rand . $this->account->store_key; + } elseif ($this->account->model == '3d_pay') { + $hash_str = $this->account->client_id . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->store_key; + } + + return base64_encode(pack('H*',sha1($hash_str))); + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + $hash_params = $data['HASHPARAMS']; + $hash_params_val = $data['HASHPARAMSVAL']; + $hash_param = $data['HASH']; + $params_val = ''; + + $hashparams_arr = explode(':', $hash_params); + foreach ($hashparams_arr as $value) { + if(!empty($value) && isset($data[$value])){ + $params_val = $params_val . $data[$value]; + } + } + + $hash_val = $params_val . $this->account->store_key; + $hash = base64_encode(sha1($hash_val, true)); + + $return = false; + if ($hash_params && !($params_val != $hash_params_val || $hash_param != $hash)) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + return false; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + return false; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + + $status = 'declined'; + + if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') { + if (in_array($this->request->get('mdStatus'), [1, 2, 3, 4])) { + $status = 'approved'; + } + } + + $transaction_security = 'MPI fallback'; + if ($status == 'approved') { + if ($this->request->get('mdStatus') == '1') { + $transaction_security = 'Full 3D Secure'; + } elseif (in_array($this->request->get('mdStatus'), [2, 3, 4])) { + $transaction_security = 'Half 3D Secure'; + } + } + + $this->response = (object)[ + 'id' => (string)$this->request->get('AuthCode'), + 'trans_id' => (string)$this->request->get('TransId'), + 'auth_code' => (string)$this->request->get('AuthCode'), + 'host_ref_num' => (string)$this->request->get('HostRefNum'), + 'response' => (string)$this->request->get('Response'), + 'order_id' => (string)$this->request->get('oid'), + 'transaction_type' => $this->type, + 'transaction' => $this->order->transaction, + 'transaction_security' => $transaction_security, + 'code' => (string)$this->request->get('ProcReturnCode'), + 'md_status' => $this->request->get('mdStatus'), + 'status' => $status, + 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, + 'hash' => (string)$this->request->get('HASH'), + 'rand' => (string)$this->request->get('rnd'), + 'hash_params' => (string)$this->request->get('HASHPARAMS'), + 'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), + 'masked_number' => (string)$this->request->get('maskedCreditCard'), + 'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), + 'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), + 'amount' => (string)$this->request->get('amount'), + 'currency' => (string)$this->request->get('currency'), + 'tx_status' => (string)$this->request->get('txstatus'), + 'eci' => (string)$this->request->get('eci'), + 'cavv' => (string)$this->request->get('cavv'), + 'xid' => (string)$this->request->get('xid'), + 'error_code' => (string)$this->request->get('ErrCode'), + 'error_message' => (string)$this->request->get('ErrMsg'), + 'md_error_message' => (string)$this->request->get('mdErrorMsg'), + 'name' => (string)$this->request->get('firmaadi'), + 'email' => (string)$this->request->get('Email'), + 'campaign_url' => null, + 'extra' => $this->request->get('Extra'), + 'all' => $this->request->request->all(), + ]; + + return $this; + } + + /** + * Get 3d Form Data + * + * @return array + */ + public function get3DFormData() + { + $data = []; + + if ($this->order) { + $this->order->hash = $this->create3DHash(); + + $inputs = [ + 'Version3D' => '2.0', + 'ShopCode' => $this->account->client_id, + 'PurchAmount' => $this->order->amount, + 'Currency' => $this->order->currency, + 'OrderId' => $this->order->id, + 'OkUrl' => $this->order->success_url, + 'FailUrl' => $this->order->fail_url, + 'Rnd' => $this->order->rand, + 'Hash' => $this->order->hash, + 'TxnType' => $this->type, + 'Pan' => $this->card->number, + 'Cvv2' => $this->card->cvv, + 'Expiry' => $this->getCardExpDate(), + 'CardType' => $this->getCardCode(), + 'BonusAmount' => '', + 'Lang' => $this->order->lang + ]; + + if ($this->account->model == '3d_pay') { + $inputs = array_merge($inputs, [ + 'SecureType' => '3DPay', + 'InstallmentCount' => $this->order->installment, + ]); + } + + $data = [ + 'gateway' => $this->gateway, + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $this->order->hash, + 'inputs' => $inputs, + ]; + } + + return $data; + } + + /** + * Send contents to WebService + * + * @param $contents + * @return $this + * @throws GuzzleException + */ + public function send($contents) + { + $client = new Client(); + + $response = $client->request('POST', $this->url, [ + 'body' => $contents + ]); + + $this->data = $this->XMLStringToObject($response->getBody()->getContents()); + + return $this; + } + + /** + * Prepare Order + * + * @param object $order + * @param object null $card + * @return mixed + * @throws UnsupportedTransactionTypeException + */ + public function prepare($order, $card = null) + { + $this->type = $this->types['pay']; + if (isset($order->transaction)) { + if (array_key_exists($order->transaction, $this->types)) { + $this->type = $this->types[$order->transaction]; + } else { + throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); + } + } + + $this->order = $order; + $this->card = $card; + + $this->order->installment = $this->order->installment == 0 ? '' : $this->order->installment; + } + + /** + * Make Payment + * + * @param object $card + * @return mixed + * @throws UnsupportedPaymentModelException + * @throws GuzzleException + */ + public function payment($card) + { + $this->card = $card; + + $model = 'regular'; + if (isset($this->account->model) && $this->account->model) { + $model = $this->account->model; + } + + if ($model == 'regular') { + $this->makeRegularPayment(); + } elseif ($model == '3d') { + $this->make3DPayment(); + } elseif ($model == '3d_pay') { + $this->make3DPayPayment(); + } else { + throw new UnsupportedPaymentModelException(); + } + + return $this; + } + + /** + * Refund Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function refund(array $meta) + { + return false; + } + + /** + * Cancel Order + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function cancel(array $meta) + { + return false; + } + + /** + * Order Status + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function status(array $meta) + { + return false; + } + + /** + * Order History + * + * @param array $meta + * @return $this + * @throws GuzzleException + */ + public function history(array $meta) + { + return false; + } + + /** + * @return array + */ + public function getConfig() + { + return $this->config; + } + + /** + * @return mixed + */ + public function getAccount() + { + return $this->account; + } + + /** + * @return array + */ + public function getCurrencies() + { + return $this->currencies; + } + + /** + * @return mixed + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return mixed + */ + public function getCard() + { + return $this->card; + } + + /** + * @return string|null + */ + public function getCardCode() + { + $card_type = null; + if (isset($this->card->type)) { + if ($this->card->type == 'visa') { + $card_type = '0'; + } elseif ($this->card->type == 'master') { + $card_type = '1'; + }elseif($this->card->type == '1' || $this->card->type == '2'){ + $card_type = $this->card->type; + } + } + return $card_type; + } + + protected function getCardExpDate() + { + $year = (string) substr($this->card->year, 2,2); + $month = (string) substr($this->card->month, 0,2); + + return (string) $month . $year; + } + + +} diff --git a/app/Core/Payment/Pos/VkfPos.php b/app/Core/Payment/Pos/VkfPos.php new file mode 100644 index 0000000..ef5e51d --- /dev/null +++ b/app/Core/Payment/Pos/VkfPos.php @@ -0,0 +1,689 @@ + 'approved', + '01' => 'bank_call', + '02' => 'bank_call', + '05' => 'reject', + '09' => 'try_again', + '12' => 'invalid_transaction', + '28' => 'reject', + '51' => 'insufficient_balance', + '54' => 'expired_card', + '57' => 'does_not_allow_card_holder', + '62' => 'restricted_card', + '77' => 'request_rejected', + '99' => 'general_error', + ]; + + /** + * Transaction Types + * + * @var array + */ + public $types = [ + 'pay' => 'Auth', + 'pre' => 'PreAuth', + 'post' => 'PostAuth', + ]; + + /** + * Currencies + * + * @var array + */ + public $currencies = []; + + /** + * Transaction Type + * + * @var string + */ + public $type; + + /** + * API Account + * + * @var array + */ + protected $account = []; + + /** + * Order Details + * + * @var array + */ + protected $order = []; + + /** + * Credit Card + * + * @var object + */ + protected $card; + + /** + * Request + * + * @var Request + */ + protected $request; + + /** + * Response Raw Data + * + * @var object + */ + protected $data; + + /** + * Processed Response Data + * + * @var mixed + */ + public $response; + + /** + * Configuration + * + * @var array + */ + protected $config = []; + + /** + * Processed Response Data + * + * @var mixed + */ + public $client; + + /** + * EstPos constructor. + * + * @param array $config + * @param mixed $account + * @param array $currencies + */ + public function __construct($config, $account, array $currencies) + { + $client = new Client(); + $this->client = $client; + $this->config = $config; + $this->account = $account; + $this->currencies = $currencies; + + $this->url = isset($this->config['urls'][$this->account->env]) ? + $this->config['urls'][$this->account->env] : + $this->config['urls']['production']; + + $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? + $this->config['urls']['gateway'][$this->account->env] : + $this->config['urls']['gateway']['production']; + + + return $this; + } + + /** + * Create Regular Payment XML + * + * @return string + */ + protected function createRegularPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'CardType' => isset($this->card->type) ? $this->card->type : null, + 'Number' => $this->card->number, + 'Expires' => $this->card->month . '/' . $this->card->year, + 'Cvv2Val' => $this->card->cvv, + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + 'BillTo' => [ + 'Name' => $this->order->name ? $this->order->name : null, + ] + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create Regular Payment Post XML + * + * @return string + */ + protected function createRegularPostXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->types[$this->order->transaction], + 'OrderId' => $this->order->id, + ] + ]; + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Create 3D Payment XML + * @return string + */ + protected function create3DPaymentXML() + { + $nodes = [ + 'CC5Request' => [ + 'Name' => $this->account->username, + 'Password' => $this->account->password, + 'ClientId' => $this->account->client_id, + 'Type' => $this->type, + 'IPAddress' => $this->order->ip, + 'Email' => $this->order->email, + 'OrderId' => $this->order->id, + 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, + 'Total' => $this->order->amount, + 'Currency' => $this->order->currency, + 'Taksit' => $this->order->installment, + 'Number' => $this->request->get('md'), + 'Expires' => '', + 'Cvv2Val' => '', + 'PayerTxnId' => $this->request->get('xid'), + 'PayerSecurityLevel' => $this->request->get('eci'), + 'PayerAuthenticationCode' => $this->request->get('cavv'), + 'CardholderPresentCode' => '13', + 'Mode' => 'P', + 'GroupId' => '', + 'TransId' => '', + ] + ]; + + if ($this->order->name) { + $nodes['BillTo'] = [ + 'Name' => $this->order->name, + ]; + } + + return $this->createXML($nodes, 'ISO-8859-9'); + } + + /** + * Get ProcReturnCode + * + * @return string|null + */ + protected function getProcReturnCode() + { + return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; + } + + /** + * Get Status Detail Text + * + * @return string|null + */ + protected function getStatusDetail() + { + $proc_return_code = $this->getProcReturnCode(); + + return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; + } + + /** + * Create 3D Hash + * + * @return string + */ + public function create3DHash() + { + $hash_str = ''; + $hash_str = $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->merchant_pass; + + return base64_encode(pack('H*', sha1($hash_str))); + } + + /** + * Check 3D Hash + * + * @param array $data + * @return bool + */ + public function check3DHash($data) + { + $return = false; + $responseHash = $data['ResponseHash']; + + //MerchantID + MerchantPass + OrderId + AuthCode + ProcReturnCode + 3DStatus + ResponseRnd + UserCode + $generatedHash = $this->account->merchant_id . $this->account->merchant_pass . $data['OrderId'] . $data['AuthCode'] . $data['ProcReturnCode'] . $data['3DStatus'] . $data['ResponseRnd'] . $this->account->user_code; + $generatedHash = base64_encode(pack('H*', sha1($generatedHash))); + + if ($generatedHash == $responseHash) { + $return = true; + } + + return $return; + } + + /** + * Regular Payment + * + * @return $this + * @throws GuzzleException + */ + public function makeRegularPayment() + { + return false; + } + + /** + * Make 3D Payment + * + * @return $this + * @throws GuzzleException + */ + public function make3DPayment() + { + return false; + } + + /** + * Make 3D Pay Payment + * + * @return $this + */ + public function make3DPayPayment() + { + $this->request = Request::createFromGlobals(); + $requestAll = $this->request->request->all(); + $ipAddress = $this->request->getClientIp(); + + /*echo "
";
+        print_r($this->order);
+        die();*/
+
+        $paymentCheck = null;
+        $status = 'declined';
+        $transaction_security = 'MPI fallback';
+        $errorMessage = null;
+
+        try {
+
+            $requestParam = new \SimpleXMLElement('');
+
+            $requestParam->addChild('MerchantId', $this->account->merchant_id);
+            $requestParam->addChild('Password', $this->account->merchant_password);
+            $requestParam->addChild('TerminalNo', $this->account->terminal_no);
+            $requestParam->addChild('TransactionType', 'Sale');
+            $requestParam->addChild('OrderId', $this->order->id);
+            $requestParam->addChild('CurrencyAmount', number_format(($requestAll['PurchAmount'] / 100), 2, '.', ''));
+            $requestParam->addChild('CurrencyCode', $requestAll['PurchCurrency']);
+            $requestParam->addChild('Pan', $requestAll['Pan']);
+            $requestParam->addChild('Expiry', $this->order->creditCardYear . $this->order->creditCardMonth);
+            $requestParam->addChild('Cvv', $this->order->creditCardYearCvv);
+            $requestParam->addChild('ECI', $requestAll['Eci']);
+            $requestParam->addChild('CAVV', $requestAll['Cavv']);
+            $requestParam->addChild('MpiTransactionId', $requestAll['VerifyEnrollmentRequestId']);
+            $requestParam->addChild('ClientIp', $ipAddress);
+            $requestParam->addChild('TransactionDeviceSource', 0);
+
+            if (!empty($requestAll['InstallmentCount'])) {
+                $requestParam->addChild('NumberOfInstallments', $requestAll['InstallmentCount']);
+            }
+
+            $payment = $this->client->request('POST', $this->url, [
+                'form_params' => ['prmstr' => $requestParam->asXML()]
+            ]);
+
+            $paymentCheck = $this->XMLStringToObject($payment->getBody()->getContents());
+
+            if ($paymentCheck->ResultCode == '0000') {
+                $status = 'approved';
+            } else {
+                $errorMessage = $paymentCheck->ResultDetail;
+            }
+
+            if ($paymentCheck->ThreeDSecureType == '2') {
+                $transaction_security = 'Full 3D Secure';
+            } elseif ($paymentCheck->ThreeDSecureType == '3') {
+                $transaction_security = 'Half 3D Secure';
+            }
+
+        } catch (Exception $e) {
+            Log::error($this->account->bank . ' Error!');
+            Log::error($e->getMessage());
+        }
+
+
+
+        $this->response = (object)[
+            'id' => isset($paymentCheck->TransactionId) ? (string)$paymentCheck->TransactionId : null,
+            'trans_id' => isset($paymentCheck->TransactionId) ? (string)$paymentCheck->TransactionId : null,
+            'auth_code' => isset($paymentCheck->AuthCode) ? (string)$paymentCheck->AuthCode : null,
+            'host_ref_num' => isset($paymentCheck->TransactionId) ? (string)$paymentCheck->TransactionId : null,
+            'order_id' => isset($paymentCheck->TransactionId) ? (string)$paymentCheck->TransactionId : null,
+            'status' => $status,
+            'response' => $paymentCheck,
+            'transaction_security' => $transaction_security,
+            'error_code' => isset($paymentCheck->ResultCode) ? (string)$paymentCheck->ResultCode : null,
+            'error_message' => $errorMessage,
+            'all' => $paymentCheck
+        ];
+
+        /*echo "
";
+        print_r($this->response);
+        die();*/
+
+        return $this;
+    }
+
+    /**
+     * Get 3d Form Data
+     *
+     * @return array
+     */
+    public function get3DFormData()
+    {
+        $threeDFormData = [];
+
+        try {
+
+            if ($this->order) {
+
+                $threeDCheckParam = [
+                    'Pan' => $this->card->number,
+                    'ExpiryDate' => $this->getCardExpDate(),
+                    'PurchaseAmount' => number_format(($this->order->amount * 100 / 100), 2, '.', ''),
+                    'Currency' => $this->order->currency,
+                    'BrandName' => null,
+                    'VerifyEnrollmentRequestId' => $this->order->id,
+                    'MerchantId' => $this->account->merchant_id,
+                    'MerchantPassword' => $this->account->merchant_password,
+                    'SuccessUrl' => $this->order->success_url,
+                    'FailUrl' => $this->order->success_url,
+                ];
+
+                $response = $this->client->request('POST', $this->gateway, [
+                    'form_params' => $threeDCheckParam
+                ]);
+
+                $threeDCheck = $this->XMLStringToObject($response->getBody()->getContents());
+
+                if ($threeDCheck->MessageErrorCode != 200) {
+                    throw new Exception($threeDCheck->MessageErrorCode . ' - ' . $threeDCheck->ErrorMessage);
+                }
+
+                $threeDFormData = [
+                    'status' => $threeDCheck->Message->VERes->Status,
+                    'gateway' => $threeDCheck->Message->VERes->ACSUrl,
+                    'success_url' => $this->order->success_url,
+                    'fail_url' => $this->order->success_url,
+                    'inputs' => [
+                        'PaReq' => $threeDCheck->Message->VERes->PaReq,
+                        'TermUrl' => $threeDCheck->Message->VERes->TermUrl,
+                        'MD' => $threeDCheck->Message->VERes->MD
+                    ]
+                ];
+
+                if ($threeDFormData['status'] != 'Y') {
+                    throw new Exception('3D Secure is not supported for this card.');
+                }
+
+            }
+
+        } catch (Exception $e) {
+            Log::error($this->account->bank . ' Error!');
+            Log::error($e->getMessage());
+            $threeDFormData = [];
+        }
+
+        return $threeDFormData;
+    }
+
+    /**
+     * Send contents to WebService
+     *
+     * @param $contents
+     * @return $this
+     * @throws GuzzleException
+     */
+    public function send($contents)
+    {
+        $client = new Client();
+
+        $response = $client->request('POST', $this->url, [
+            'body' => $contents
+        ]);
+
+        $this->data = $this->XMLStringToObject($response->getBody()->getContents());
+
+        return $this;
+    }
+
+    /**
+     * Prepare Order
+     *
+     * @param object $order
+     * @param object null $card
+     * @return mixed
+     * @throws UnsupportedTransactionTypeException
+     */
+    public function prepare($order, $card = null)
+    {
+        $this->type = $this->types['pay'];
+        if (isset($order->transaction)) {
+            if (array_key_exists($order->transaction, $this->types)) {
+                $this->type = $this->types[$order->transaction];
+            } else {
+                throw new UnsupportedTransactionTypeException('Unsupported transaction type!');
+            }
+        }
+
+        $this->order = $order;
+        $this->card = $card;
+
+        $this->order->installment = $this->order->installment == 0 ? 0 : $this->order->installment;
+    }
+
+    /**
+     * Make Payment
+     *
+     * @param object $card
+     * @return mixed
+     * @throws UnsupportedPaymentModelException
+     * @throws GuzzleException
+     */
+    public function payment($card)
+    {
+        $this->card = $card;
+
+        $model = 'regular';
+        if (isset($this->account->model) && $this->account->model) {
+            $model = $this->account->model;
+        }
+
+        if ($model == 'regular') {
+            $this->makeRegularPayment();
+        } elseif ($model == '3d') {
+            $this->make3DPayment();
+        } elseif ($model == '3d_pay') {
+            $this->make3DPayPayment();
+        } else {
+            throw new UnsupportedPaymentModelException();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Refund Order
+     *
+     * @param array $meta
+     * @return $this
+     * @throws GuzzleException
+     */
+    public function refund(array $meta)
+    {
+        return false;
+    }
+
+    /**
+     * Cancel Order
+     *
+     * @param array $meta
+     * @return $this
+     * @throws GuzzleException
+     */
+    public function cancel(array $meta)
+    {
+        return false;
+    }
+
+    /**
+     * Order Status
+     *
+     * @param array $meta
+     * @return $this
+     * @throws GuzzleException
+     */
+    public function status(array $meta)
+    {
+        return false;
+    }
+
+    /**
+     * Order History
+     *
+     * @param array $meta
+     * @return $this
+     * @throws GuzzleException
+     */
+    public function history(array $meta)
+    {
+        return false;
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfig()
+    {
+        return $this->config;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getAccount()
+    {
+        return $this->account;
+    }
+
+    /**
+     * @return array
+     */
+    public function getCurrencies()
+    {
+        return $this->currencies;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getOrder()
+    {
+        return $this->order;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getCard()
+    {
+        return $this->card;
+    }
+
+    /**
+     * @return string|null
+     */
+    public function getCardCode()
+    {
+        $card_type = null;
+        if (isset($this->card->type)) {
+            if ($this->card->type == 'visa') {
+                $card_type = '0';
+            } elseif ($this->card->type == 'master') {
+                $card_type = '1';
+            } elseif ($this->card->type == '1' || $this->card->type == '2') {
+                $card_type = $this->card->type;
+            }
+        }
+        return $card_type;
+    }
+
+    protected function getCardExpDate()
+    {
+        $year = (string)substr($this->card->year, 2, 2);
+        $month = (string)substr($this->card->month, 0, 2);
+
+        return (string)$year . $month;
+    }
+
+
+}
diff --git a/app/Core/Payment/Pos/config/pos.php b/app/Core/Payment/Pos/config/pos.php
new file mode 100644
index 0000000..0c7916f
--- /dev/null
+++ b/app/Core/Payment/Pos/config/pos.php
@@ -0,0 +1,202 @@
+ [
+        'TRY' => 949,
+        'USD' => 840,
+        'EUR' => 978,
+        'GBP' => 826,
+        'JPY' => 392,
+        'RUB' => 643,
+    ],
+
+    // Banks
+    'banks' => [
+        'akbank' => [
+            'name' => 'AKBANK T.A.S.', ////Test - 5571135571135575, 12, 2026, 000, a
+            'class' => AkPos::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://api.akbank.com/api/v1/payment/virtualpos/transaction/process',
+                'test' => 'https://apipre.akbank.com/api/v1/payment/virtualpos/transaction/process',
+                'gateway' => [
+                    'production' => 'https://virtualpospaymentgateway.akbank.com/securepay',
+                    'test' => 'https://virtualpospaymentgatewaypre.akbank.com/securepay',
+                ],
+            ]
+        ],
+        'denizbank' => [ //https://test.inter-vpos.com.tr, 3123, InterTest11, InterTest11
+            'name' => 'DENIZ BANK', //Test - 4090700090840057, 11, 2022, 592, 123
+            'class' => VPos::class,
+            'urls' => [
+                'production' => 'https://spos.denizbank.com/mpi/Default.aspx',
+                'test' => 'https://sanaltest.denizbank.com/mpi/Default.aspx',
+                'gateway' => [
+                    'production' => 'https://spos.denizbank.com/mpi/Default.aspx',
+                    'test' => 'https://sanaltest.denizbank.com/mpi/Default.aspx',
+                ],
+            ]
+        ],
+        'ziraat' => [
+            'name' => 'Ziraat Bankası',
+            'class' => EstPosV3::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://sanalpos2.ziraatbank.com.tr/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://sanalpos2.ziraatbank.com.tr/fim/est3dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'finansbank' => [
+            'name' => 'QNB Finansbank',
+            'class' => QPos::class,
+            'urls' => [
+                'production' => 'https://vpos.qnbfinansbank.com/Gateway/Default.aspx',
+                'test' => 'https://vpostest.qnbfinansbank.com/Gateway/Default.aspx',
+                'gateway' => [
+                    'production' => 'https://vpos.qnbfinansbank.com/Gateway/Default.aspx',
+                    'test' => 'https://vpostest.qnbfinansbank.com/Gateway/Default.aspx',
+                ],
+            ]
+        ],
+        'vakifbank' => [
+            'name' => 'Vakıfbank',
+            'class' => VkfPos::class,
+            'urls' => [
+                'production' => 'https://onlineodeme.vakifbank.com.tr:4443/VposService/v3/Vposreq.aspx',
+                'test' => 'https://onlineodemetest.vakifbank.com.tr:4443/VposService/v3/Vposreq.aspx',
+                'gateway' => [
+                    'production' => 'https://3dsecure.vakifbank.com.tr/MPIAPI/MPI_Enrollment.aspx',
+                    'test' => 'https://3dsecuretest.vakifbank.com.tr/MPIAPI/MPI_Enrollment.aspx',
+                ],
+            ]
+        ],
+        'turkiyefinans' => [ //TODO: Check this infos
+            'name' => 'Türkiye Finans',
+            'class' => EstPosV3::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://www.fbwebpos.com/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://www.fbwebpos.com/fim/est3dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'halkbank' => [
+            'name' => 'Halkbank',
+            'class' => EstPosV3::class,
+            'urls' => [
+                'production' => 'https://sanalpos.halkbank.com.tr/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://sanalpos.halkbank.com.tr/fim/est3dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'teb' => [
+            'name' => 'TEB',
+            'class' => EstPosV3::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://sanalpos.teb.com.tr/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://sanalpos.teb.com.tr/fim/est3Dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'ingbank' => [
+            'name' => 'ING Bank',
+            'class' => EstPosV3::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://sanalpos.ingbank.com.tr/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://sanalpos.ingbank.com.tr/fim/est3Dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'isbank' => [
+            'name' => 'İşbank',
+            'class' => EstPosV3::class,//EstPos::class,
+            'urls' => [
+                'production' => 'https://sanalpos.isbank.com.tr/fim/api',
+                'test' => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway' => [
+                    'production' => 'https://sanalpos.isbank.com.tr/fim/est3Dgate',
+                    'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+        'isbank-payflex' => [
+            'name' => 'İşbank - PayFlex',
+            'class' => Mews\Pos\PayFlex::class,
+            'urls' => [
+                'production' => 'https://trx.payflex.com.tr/VposWeb/v3/Vposreq.aspx',
+                'test' => 'https://sanalpos.innova.com.tr/ISBANK_v4/VposWeb/v3/Vposreq.aspx',
+                'gateway' => [
+                    'production' => 'https://mpi.vpos.isbank.com.tr/MPIEnrollment.aspx',
+                    'test' => 'https://sanalpos.innova.com.tr/ISBANK/MpiWeb/Enrollment.aspx',
+                ],
+            ]
+        ],
+        'yapikredi' => [
+            'name' => 'Yapıkredi',
+            'class' => PosNet::class,
+            'urls' => [
+                'production' => 'https://posnet.yapikredi.com.tr/PosnetWebService/XML',
+                'test' => 'https://setmpos.ykb.com/PosnetWebService/XML',
+                'gateway' => [
+                    'production' => 'https://posnet.yapikredi.com.tr/3DSWebService/YKBPaymentService',
+                    'test' => 'https://setmpos.ykb.com/3DSWebService/YKBPaymentService',
+                ],
+            ],
+            'order' => [
+                'id_total_length' => 24,
+                'id_length' => 20,
+                'id_3d_prefix' => 'TDSC',
+                'id_3d_pay_prefix' => '', //?
+                'id_regular_prefix' => '' //?
+            ]
+        ],
+        'garanti' => [
+            'name' => 'Garanti',
+            'class' => GarantiPos::class,
+            'urls' => [
+                'production' => 'https://sanalposprov.garanti.com.tr/VPServlet',
+                'test' => 'https://sanalposprovtest.garanti.com.tr/VPServlet',
+                'gateway' => [
+                    'production' => 'https://sanalposprov.garanti.com.tr/servlet/gt3dengine',
+                    'test' => 'https://sanalposprovtest.garanti.com.tr/servlet/gt3dengine',
+                ],
+            ]
+        ]
+    ],
+
+];
+//STRIPE
+//4000000000003063 3D required
+//4000000000003089 3D recommended
+//4000000000003055 3d optional
+//378282246310005  3d not_supported direct pay
+
+//Vakıfbank
+//4938460158754205 2024/11 715 123456
+//4119790155203496 2024/04 579 123456
+//4119790166544284 2024/04 961 123456
+//6501700161161969 2024/11 390 123456
diff --git a/app/Core/Payment/Pos/ex/.gitignore b/app/Core/Payment/Pos/ex/.gitignore
new file mode 100644
index 0000000..8a09a34
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/.gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+composer.lock
+/vendor
+/.idea
diff --git a/app/Core/Payment/Pos/ex/LICENCE.md b/app/Core/Payment/Pos/ex/LICENCE.md
new file mode 100644
index 0000000..9f5c8fa
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/LICENCE.md
@@ -0,0 +1,3 @@
+© 2018 Muharrem ERİN (me@mewebstudio.com)
+
+http://www.opensource.org/licenses/mit-license.php The MIT License
diff --git a/app/Core/Payment/Pos/ex/LICENSE.txt b/app/Core/Payment/Pos/ex/LICENSE.txt
new file mode 100644
index 0000000..05a7c57
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 MeWebStudio - Muharrem ERİN
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/app/Core/Payment/Pos/ex/README.md b/app/Core/Payment/Pos/ex/README.md
new file mode 100644
index 0000000..65c6268
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/README.md
@@ -0,0 +1,190 @@
+# Türk bankaları için sanal pos paketi (PHP)
+
+Bu paket ile amaçlanan; ortak bir arayüz sınıfı ile, tüm Türk banka sanal pos sistemlerinin kullanılabilmesidir.
+EST altyapısı tam olarak test edilmiş ve kullanıma hazırdır.
+Garanti Ödeme sistemi çalışmaktadır, fakat 3D ödeme kısmının üretim ortamında test edilmesi gerekiyor.
+YapıKredi Posnet sistemi çalışmaktadır, fakat 3D ödeme kısmının üretim ortamında test edilmesi gerekiyor.
+
+> EST altyapısında olan Akbank ve Ziraat bankası test edilmiştir.
+
+### Özellikler
+  - Standart E-Commerce modeliyle ödeme (model => regular)
+  - 3D modeliyle ödeme (model => 3d)
+  - 3D Pay modeliyle ödeme (model => 3d_pay)
+  - Sipariş/Ödeme sorgulama (query)
+  - Sipariş/Ödeme geçmişi sorgulama (history)
+  - Sipariş/Para iadesi yapma (refund)
+  - Sipariş iptal etme (cancel)
+
+### Minimum Gereksinimler
+  - PHP >= 7.1.3
+  - ext-dom
+  - ext-json
+  - ext-openssl
+  - ext-SimpleXML
+
+### Kurulum
+Test sunucunuz üzerinde;
+```sh
+$ mkdir pos-test && cd pos-test
+$ composer require mews/pos
+```
+
+**config.php (Ayar dosyası)**
+```php
+getClientIp();
+
+// API kullanıcı bilgileri
+$account = [
+    'bank'          => 'akbank',
+    'model'         => 'regular',
+    'client_id'     => 'XXXXXXXX',
+    'username'      => 'XXXXXXXX',
+    'password'      => 'XXXXXXXX',
+    'env'           => 'test', // test veya production. test ise; API Test Url, production ise; API Production URL kullanılır.
+];
+
+// API kullanıcı hesabı ile paket bir değişkene aktarılıyor
+try {
+    $pos = new \Mews\Pos\Pos($account);
+} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) {
+    var_dump($e->getCode(), $e->getMessage());
+    exit();
+} catch (\Mews\Pos\Exceptions\BankClassNullException $e) {
+    var_dump($e->getCode(), $e->getMessage());
+    exit();
+}
+```
+
+**test.php (Test Dosyası)**
+```php
+ 'BENZERSIZ-SIPERIS-ID',
+    'name'          => 'John Doe', // zorunlu değil
+    'email'         => 'mail@customer.com', // zorunlu değil
+    'user_id'       => '12', // zorunlu değil
+    'amount'        => (double) 20, // Sipariş tutarı
+    'installment'   => '0',
+    'currency'      => 'TRY',
+    'ip'            => $ip,
+    'transaction'   => 'pay', // pay => Auth, pre PreAuth (Direkt satış için pay, ön provizyon için pre)
+];
+
+// Kredi kartı bilgieri
+$card = [
+    'number'        => 'XXXXXXXXXXXXXXXX', // Kredi kartı numarası
+    'month'         => 'XX', // SKT ay
+    'year'          => 'XX', // SKT yıl, son iki hane
+    'cvv'           => 'XXX', // Güvenlik kodu, son üç hane
+];
+
+// API kullanıcısı ile oluşturulan $pos değişkenine prepare metoduyla sipariş bilgileri gönderiliyor
+$pos->prepare($order);
+
+// Ödeme tamamlanıyor
+$payment = $pos->payment($card);
+
+// Ödeme başarılı mı?
+$payment->isSuccess();
+//veya
+$pos->isSuccess();
+
+// Ödeme başarısız mı?
+$payment->isError();
+//veya
+$pos->isError();
+
+// Sonuç çıktısı
+var_dump($payment->response);
+
+````
+
+### Farklı Banka Sanal Poslarını Eklemek
+Kendi projenizin dizinindeyken
+```sh
+$ cp ./vendor/mews/pos/config/pos.php ./pos_ayarlar.php
+```
+ya da;
+
+Projenizde bir ayar dosyası oluşturup (pos_ayarlar.php gibi), paket içerisinde `./config/pos.php` dosyasının içeriğini buraya kopyalayın.
+
+```php
+ [
+        'TRY'       => 949,
+        'USD'       => 840,
+        'EUR'       => 978,
+        'GBP'       => 826,
+        'JPY'       => 392,
+        'RUB'       => 643,
+    ],
+
+    // Banka sanal pos tanımlamaları
+    'banks'         => [
+        'akbank'    => [
+            'name'  => 'AKBANK T.A.S.',
+            'class' => \Mews\Pos\EstPos::class,
+            'urls'  => [
+                'production'    => 'https://www.sanalakpos.com/fim/api',
+                'test'          => 'https://entegrasyon.asseco-see.com.tr/fim/api',
+                'gateway'       => [
+                    'production'    => 'https://www.sanalakpos.com/fim/est3Dgate',
+                    'test'          => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate',
+                ],
+            ]
+        ],
+
+        // Yeni eklenen banka
+        'isbank'    => [
+            'name'  => 'İŞ BANKASI .A.S.',
+            'class' => \Mews\Pos\EstPos::class, // Altyapı sınıfı
+            'urls'  => [
+                'production'    => 'xxxx', // API Url
+                'test'          => 'xxxx', // API Test Url
+                'gateway'       => [
+                    'production'    => 'xxxx', // 3d Kapı Url
+                    'test'          => 'xxxx', // 3d Test Kapı Url
+                ],
+            ]
+        ],
+    ]
+];
+
+```
+
+Bundan sonra nesnemizi, yeni ayarlarımıza göre oluşturup kullanmamız gerekir. Örnek:
+```php
+$yeni_ayarlar = require './pos_ayarlar.php';
+$pos = new \Mews\Pos\Pos($account, $yeni_ayarlar);
+```
+
+### Örnek Kodlar
+`./pos/examples` dizini içerisinde.
+
+### Yol Haritası
+  - Dökümantasyon hazırlanacak
+  - UnitTest yazılacak -> Bu hiçbir zaman olmayabilir, birisi el atarsa sevinirim :)
+
+> Değerli yorum, öneri ve katkılarınızı bekliyorum.
+
+License
+----
+
+MIT
diff --git a/app/Core/Payment/Pos/ex/composer.json b/app/Core/Payment/Pos/ex/composer.json
new file mode 100644
index 0000000..70584f0
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/composer.json
@@ -0,0 +1,31 @@
+{
+    "name": "mews/pos",
+    "description": "Türk bankaları için sanal pos kütüphanesi",
+	"keywords": ["pos", "sanal pos", "est", "est pos", "akbank"],
+	"homepage": "https://github.com/mewebstudio/pos",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Muharrem ERİN",
+            "email": "me@mewebstudio.com"
+        }
+    ],
+    "require": {
+        "php": "^7.1.3",
+        "ext-dom": "*",
+        "ext-json": "*",
+        "ext-openssl": "*",
+        "ext-SimpleXML": "*",
+        "guzzlehttp/guzzle": "^6.3.3",
+        "symfony/http-foundation": "^5.0",
+        "symfony/serializer": "^5.0"
+    },
+	"autoload": {
+		"psr-4": {
+			"Mews\\Pos\\": "src/"
+		}
+	},
+    "require-dev": {
+        "phpunit/phpunit": "^9.0"
+    }
+}
diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/_config.php b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/_config.php
new file mode 100644
index 0000000..efdf9c5
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/_config.php
@@ -0,0 +1,30 @@
+getClientIp();
+
+$account = [
+    'bank'          => 'akbank',
+    'model'         => '3d_pay',
+    'client_id'     => 'XXXXXXX',
+    'store_key'     => 'XXXXXXX',
+    'env'           => 'test',
+];
+
+try {
+    $pos = new \Mews\Pos\Pos($account);
+} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) {
+    var_dump($e->getCode(), $e->getMessage());
+} catch (\Mews\Pos\Exceptions\BankClassNullException $e) {
+    var_dump($e->getCode(), $e->getMessage());
+}
+
+$template_title = '3D Pay Model Payment';
diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/form.php b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/form.php
new file mode 100644
index 0000000..7765b93
--- /dev/null
+++ b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/form.php
@@ -0,0 +1,64 @@
+getMethod() !== 'POST') {
+    echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url);
+    exit();
+}
+
+$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4));
+
+$amount = (double) 320;
+$instalment = '0';
+
+$success_url = $base_url . 'response.php';
+$fail_url = $base_url . 'response.php';
+
+$rand = microtime();
+
+$order = [
+    'id'                => $order_id,
+    'email'             => 'mail@customer.com', // optional
+    'name'              => 'John Doe', // optional
+    'amount'            => $amount,
+    'installment'       => $instalment,
+    'currency'          => 'TRY',
+    'ip'                => $ip,
+    'success_url'       => $success_url,
+    'fail_url'          => $fail_url,
+    'transaction'       => 'pay', // pay => Auth, pre PreAuth
+    'lang'              => 'tr',
+    'rand'              => $rand,
+];
+
+$_SESSION['order'] = $order;
+
+$card = [
+    'name'      => $request->get('name'),
+    'type'      => $request->get('type'),
+    'number'    => $request->get('number'),
+    'month'     => $request->get('month'),
+    'year'      => $request->get('year'),
+    'cvv'       => $request->get('cvv'),
+];
+
+$pos->prepare($order, $card);
+
+$form_data = $pos->get3dFormData();
+?>
+
+
+ $value): ?> + + +
Redirecting...
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/index.php b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/index.php new file mode 100644 index 0000000..f2b550f --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/index.php @@ -0,0 +1,57 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/response.php b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/response.php new file mode 100644 index 0000000..6da7c2e --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d-pay/response.php @@ -0,0 +1,108 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = $_SESSION['order']; + +$pos->prepare($order); +$payment = $pos->payment(); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ status == 'approved' ? 'Payment is successful!' : 'Payment is not successful'; ?> +

+
+
+
Response:
+
response; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Transaction Security:
+
transaction_security; ?>
+
+
+
+
Hash:
+
hash; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code ? $response->code : '-'; ?>
+
+
+
+
mdStatus:
+
md_status ? $response->md_status : '-'; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
Md Error Message:
+
md_error_message ? $response->md_error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d/_config.php b/app/Core/Payment/Pos/ex/examples/akbank/3d/_config.php new file mode 100644 index 0000000..87bf932 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d/_config.php @@ -0,0 +1,32 @@ +getClientIp(); + +$account = [ + 'bank' => 'akbank', + 'model' => '3d', + 'client_id' => 'XXXXXXX', + 'username' => 'XXXXXXX', + 'password' => 'XXXXXXX', + 'store_key' => 'XXXXXXX', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$template_title = '3D Model Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d/form.php b/app/Core/Payment/Pos/ex/examples/akbank/3d/form.php new file mode 100644 index 0000000..38f4e00 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d/form.php @@ -0,0 +1,64 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); + +$amount = (double) 320; +$instalment = '0'; + +$success_url = $base_url . 'response.php'; +$fail_url = $base_url . 'response.php'; + +$rand = microtime(); + +$order = [ + 'id' => $order_id, + 'email' => 'mail@customer.com', // optional + 'name' => 'John Doe', // optional + 'amount' => $amount, + 'installment' => $instalment, + 'currency' => 'TRY', + 'ip' => $ip, + 'success_url' => $success_url, + 'fail_url' => $fail_url, + 'transaction' => 'pay', // pay => Auth, pre PreAuth, + 'lang' => 'tr', + 'rand' => $rand, +]; + +$_SESSION['order'] = $order; + +$card = [ + 'name' => $request->get('name'), + 'type' => $request->get('type'), + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$pos->prepare($order, $card); + +$form_data = $pos->get3dFormData(); +?> + +
+ $value): ?> + + +
Redirecting...
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d/index.php b/app/Core/Payment/Pos/ex/examples/akbank/3d/index.php new file mode 100644 index 0000000..f2b550f --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d/index.php @@ -0,0 +1,57 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/3d/response.php b/app/Core/Payment/Pos/ex/examples/akbank/3d/response.php new file mode 100644 index 0000000..04b70d9 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/3d/response.php @@ -0,0 +1,108 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = $_SESSION['order']; + +$pos->prepare($order); +$payment = $pos->payment(); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ status == 'approved' ? 'Payment is successful!' : 'Payment is not successful'; ?> +

+
+
+
Response:
+
response ? $response->response : '-'; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Transaction Security:
+
transaction_security; ?>
+
+
+
+
Hash:
+
hash; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code ? $response->code : '-'; ?>
+
+
+
+
mdStatus:
+
md_status ? $response->md_status : '-'; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
Md Error Message:
+
md_error_message ? $response->md_error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/_config.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/_config.php new file mode 100644 index 0000000..e0844fe --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/_config.php @@ -0,0 +1,31 @@ +getClientIp(); + +$account = [ + 'bank' => 'akbank', + 'model' => 'regular', + 'client_id' => 'XXXXXXX', + 'username' => 'XXXXXXX', + 'password' => 'XXXXXXX', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$gateway = $base_url . 'response.php'; + +$template_title = 'Regular Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/cancel.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/cancel.php new file mode 100644 index 0000000..37bd6ed --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/cancel.php @@ -0,0 +1,34 @@ +bank->cancel([ + 'order_id' => '20181029A3C1', +]); + +$response = $cancel->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Cancel Order is successful!' : 'Cancel Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/direct.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/direct.php new file mode 100644 index 0000000..21f8531 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/direct.php @@ -0,0 +1,35 @@ + $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => '0', + 'currency' => 'TRY', + 'ip' => $ip, + 'transaction' => 'pay', // pay => Auth, pre PreAuth +]; + +$card = [ + 'number' => '4355084355084358', + 'month' => '12', + 'year' => '18', + 'cvv' => '000', +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment($card); + +var_dump($payment->response); diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/history.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/history.php new file mode 100644 index 0000000..9d1de9c --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/history.php @@ -0,0 +1,34 @@ +bank->history([ + 'order_id' => '201810297189', +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'History Order is successful!' : 'History Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/index.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/index.php new file mode 100644 index 0000000..92e7bb9 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/index.php @@ -0,0 +1,48 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/post.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/post.php new file mode 100644 index 0000000..db7e7db --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/post.php @@ -0,0 +1,66 @@ +getClientIp(); + +$account = [ + 'bank' => 'akbank', + 'model' => 'regular', + 'client_id' => '100100000', + 'username' => 'mewsapi', + 'password' => 'ME12345.', + 'env' => 'test', +]; + +$template_title = 'Post Auth Order'; + +require '../../template/_header.php'; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$order = [ + 'id' => '201810297189', + 'transaction' => 'post', +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment(); + +$response = $payment->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() == '00' ? 'Post Auth Order is successful!' : 'Post Auth Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/refund.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/refund.php new file mode 100644 index 0000000..a86a475 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/refund.php @@ -0,0 +1,35 @@ +bank->refund([ + 'order_id' => '201810297E8B', + 'amount' => '100', +]); + +$response = $refund->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Refund Order is successful!' : 'Refund Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/response.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/response.php new file mode 100644 index 0000000..1f0b3c2 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/response.php @@ -0,0 +1,114 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); +$amount = (double) 100; + +$order = [ + 'id' => $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => '0', + 'currency' => 'TRY', + 'ip' => $ip, + 'transaction' => 'pre', // pay => Auth, pre PreAuth +]; + +$pos->prepare($order); + +$card = [ + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$payment = $pos->payment($card); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Payment is successful!' : 'Payment is not successful!'; ?> +

+
+
+
Response:
+
response; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
Group ID:
+
group_id ? $response->group_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/akbank/regular/status.php b/app/Core/Payment/Pos/ex/examples/akbank/regular/status.php new file mode 100644 index 0000000..229612b --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/akbank/regular/status.php @@ -0,0 +1,34 @@ +bank->status([ + 'order_id' => '201810297189' +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'Query Order is successful!' : 'Query Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/_config.php b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/_config.php new file mode 100644 index 0000000..d2ac7de --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/_config.php @@ -0,0 +1,33 @@ +getClientIp(); + +$account = [ + 'bank' => 'garanti', + 'model' => '3d_pay', + 'client_id' => '7000679', + 'terminal_id' => '30691298', + 'username' => 'PROVAUT', + 'password' => '123qweASD/', + 'store_key' => '12345678', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$template_title = '3D Pay Model Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/form.php b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/form.php new file mode 100644 index 0000000..9b41fa8 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/form.php @@ -0,0 +1,68 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); + +$amount = (double) 1; +$instalment = '0'; + +$success_url = $base_url . 'response.php'; +$fail_url = $base_url . 'response.php'; + +$transaction = 'pay'; // pay => Auth, pre PreAuth +$transaction_type = $pos->bank->types[$transaction]; + +$rand = microtime(); + +$order = [ + 'id' => $order_id, + 'email' => 'mail@customer.com', // optional + 'name' => 'John Doe', // optional + 'amount' => $amount, + 'installment' => $instalment, + 'currency' => 'TRY', + 'ip' => $ip, + 'success_url' => $success_url, + 'fail_url' => $fail_url, + 'transaction' => $transaction, + 'lang' => 'tr', + 'rand' => $rand, +]; + +$_SESSION['order'] = $order; + +$card = [ + 'name' => $request->get('name'), + 'type' => $request->get('type'), + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$pos->prepare($order, $card); + +$form_data = $pos->get3dFormData(); +?> + +
+ $value): ?> + + +
Redirecting...
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/index.php b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/index.php new file mode 100644 index 0000000..f2b550f --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/index.php @@ -0,0 +1,57 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/response.php b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/response.php new file mode 100644 index 0000000..d63ff94 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d-pay/response.php @@ -0,0 +1,109 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = $_SESSION['order']; + +$pos->prepare($order); +$payment = $pos->payment(); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+
+

+ isSuccess() ? 'Payment is successful!' : 'Payment is not successful'; ?> +

+
+
+
Response:
+
response ? $response->response : '-'; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Transaction Security:
+
transaction_security; ?>
+
+
+
+
Hash:
+
hash; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code ? $response->code : '-'; ?>
+
+
+
+
mdStatus:
+
md_status ? $response->md_status : '-'; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
Md Error Message:
+
md_error_message ? $response->md_error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d/_config.php b/app/Core/Payment/Pos/ex/examples/garanti/3d/_config.php new file mode 100644 index 0000000..7d73fc1 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d/_config.php @@ -0,0 +1,33 @@ +getClientIp(); + +$account = [ + 'bank' => 'garanti', + 'model' => '3d', + 'client_id' => '7000679', + 'terminal_id' => '30691298', + 'username' => 'PROVAUT', + 'password' => '123qweASD/', + 'store_key' => '12345678', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$template_title = '3D Model Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d/form.php b/app/Core/Payment/Pos/ex/examples/garanti/3d/form.php new file mode 100644 index 0000000..dd3c640 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d/form.php @@ -0,0 +1,64 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); + +$amount = (double) 1; +$instalment = '0'; + +$success_url = $base_url . 'response.php'; +$fail_url = $base_url . 'response.php'; + +$rand = microtime(); + +$order = [ + 'id' => $order_id, + 'email' => 'mail@customer.com', // optional + 'name' => 'John Doe', // optional + 'amount' => $amount, + 'installment' => $instalment, + 'currency' => 'TRY', + 'ip' => $ip, + 'success_url' => $success_url, + 'fail_url' => $fail_url, + 'transaction' => 'pay', // pay => Auth, pre PreAuth, + 'lang' => 'tr', + 'rand' => $rand, +]; + +$_SESSION['order'] = $order; + +$card = [ + 'name' => $request->get('name'), + 'type' => $request->get('type'), + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$pos->prepare($order, $card); + +$form_data = $pos->get3dFormData(); +?> + +
+ $value): ?> + + +
Redirecting...
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d/index.php b/app/Core/Payment/Pos/ex/examples/garanti/3d/index.php new file mode 100644 index 0000000..f2b550f --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d/index.php @@ -0,0 +1,57 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/3d/response.php b/app/Core/Payment/Pos/ex/examples/garanti/3d/response.php new file mode 100644 index 0000000..e54c065 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/3d/response.php @@ -0,0 +1,108 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = $_SESSION['order']; + +$pos->prepare($order); +$payment = $pos->payment(); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Payment is successful!' : 'Payment is not successful'; ?> +

+
+
+
Response:
+
response ? $response->response : '-'; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Transaction Security:
+
transaction_security; ?>
+
+
+
+
Hash:
+
hash; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code ? $response->code : '-'; ?>
+
+
+
+
mdStatus:
+
md_status ? $response->md_status : '-'; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
Md Error Message:
+
md_error_message ? $response->md_error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/_config.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/_config.php new file mode 100644 index 0000000..c4664f7 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/_config.php @@ -0,0 +1,34 @@ +getClientIp(); + +$account = [ + 'bank' => 'garanti', + 'model' => 'regular', + 'client_id' => '7000679', + 'terminal_id' => '30691298', + 'username' => 'PROVAUT', + 'password' => '123qweASD/', + 'refund_username' => 'PROVRFN', + 'refund_password' => '123qweASD/', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$gateway = $base_url . 'response.php'; + +$template_title = 'Regular Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/cancel.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/cancel.php new file mode 100644 index 0000000..c77d011 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/cancel.php @@ -0,0 +1,39 @@ +bank->cancel([ + 'order_id' => '20181114DF2C', + 'ip' => $ip, + 'email' => 'mail@customer.com', + 'ref_ret_num' => '831803579226', + 'amount' => 1, + 'currency' => 'TRY', +]); + +$response = $cancel->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'Cancel Order is successful!' : 'Cancel Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/direct.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/direct.php new file mode 100644 index 0000000..6d88021 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/direct.php @@ -0,0 +1,35 @@ + $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => '0', + 'currency' => 'TRY', + 'ip' => $ip, + 'transaction' => 'pay', // pay => Auth, pre PreAuth +]; + +$card = [ + 'number' => '4282209027132016', + 'month' => '05', + 'year' => '20', + 'cvv' => '165', +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment($card); + +var_dump($payment->response); diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/history.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/history.php new file mode 100644 index 0000000..4ae31a3 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/history.php @@ -0,0 +1,36 @@ +bank->history([ + 'order_id' => '2018111377EF', + 'currency' => 'TRY', + 'ip' => $ip, +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'History Order is successful!' : 'History Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/index.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/index.php new file mode 100644 index 0000000..2999bdd --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/index.php @@ -0,0 +1,44 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/post.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/post.php new file mode 100644 index 0000000..7d78dab --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/post.php @@ -0,0 +1,70 @@ +getClientIp(); + +$account = [ + 'bank' => 'garanti', + 'model' => 'regular', + 'client_id' => '7000679', + 'terminal_id' => '30691297', + 'username' => 'PROVAUT', + 'password' => '123qweASD/', + 'env' => 'test', +]; + +$template_title = 'Post Auth Order'; + +require '../../template/_header.php'; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$order = [ + 'id' => '201810231553', + 'transaction' => 'post', + 'amount' => '1', + 'ref_ret_num' => '829603332856', + 'ip' => $ip, +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment(); + +$response = $payment->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'Post Auth Order is successful!' : 'Post Auth Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/refund.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/refund.php new file mode 100644 index 0000000..89d6b5b --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/refund.php @@ -0,0 +1,39 @@ +bank->refund([ + 'order_id' => '201811142A0A', + 'ip' => $ip, + 'email' => 'mail@customer.com', + 'ref_ret_num' => '831803586333', + 'amount' => 1, + 'currency' => 'TRY', +]); + +$response = $refund->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'Refund Order is successful!' : 'Refund Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/response.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/response.php new file mode 100644 index 0000000..b3a99bd --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/response.php @@ -0,0 +1,125 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); +$amount = (double) 1; + +$order = [ + 'id' => $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => '1', + 'currency' => 'TRY', + 'ip' => $ip, + 'transaction' => 'pay', // pay => S, pre => preauth +]; + +$pos->prepare($order); + +$card = [ + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$payment = $pos->payment($card); + +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Payment is successful!' : 'Payment is not successful!'; ?> +

+
+
+
Response:
+
response; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
Group ID:
+
group_id ? $response->group_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
RetrefNum:
+
ret_ref_num ? $response->ret_ref_num : '-'; ?>
+
+
+
+
HashData:
+
hash_data ? $response->hash_data : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/garanti/regular/status.php b/app/Core/Payment/Pos/ex/examples/garanti/regular/status.php new file mode 100644 index 0000000..eba5176 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/garanti/regular/status.php @@ -0,0 +1,36 @@ +bank->status([ + 'order_id' => '201812195CF2', + 'currency' => 'TRY', + 'ip' => $ip +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ proc_return_code == '00' ? 'Query Order is successful!' : 'Query Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/template/_footer.php b/app/Core/Payment/Pos/ex/examples/template/_footer.php new file mode 100644 index 0000000..da75efc --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/template/_footer.php @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/app/Core/Payment/Pos/ex/examples/template/_header.php b/app/Core/Payment/Pos/ex/examples/template/_header.php new file mode 100644 index 0000000..8aad334 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/template/_header.php @@ -0,0 +1,16 @@ + + + + <?php echo $template_title; ?> + + + + + + + + +
+
+

+
diff --git a/app/Core/Payment/Pos/ex/examples/ykb/3d/_config.php b/app/Core/Payment/Pos/ex/examples/ykb/3d/_config.php new file mode 100644 index 0000000..b27c6dc --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/3d/_config.php @@ -0,0 +1,38 @@ +getClientIp(); + +$account = [ + 'bank' => 'yapikredi', + 'model' => '3d', + 'client_id' => 'XXXXXX', + 'terminal_id' => 'XXXXXX', + 'posnet_id' => 'XXXXXX', + 'username' => 'XXXXXX', + 'password' => 'XXXXXX', + 'store_key' => '10,10,10,10,10,10,10,10', + 'promotion_code' => '', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$template_title = '3D Model Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/ykb/3d/form.php b/app/Core/Payment/Pos/ex/examples/ykb/3d/form.php new file mode 100644 index 0000000..2460624 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/3d/form.php @@ -0,0 +1,48 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = [ + 'id' => $_POST['order_id'], + 'name' => $_POST['name'], + 'amount' => $_POST['amount'], + 'currency' => $_POST['currency'], + 'transaction' => $_POST['transaction'], + 'success_url' => $_POST['success_url'], + 'fail_url' => $_POST['fail_url'], + 'lang' => $_POST['lang'], +]; + +$_SESSION['order'] = $order; + +$card = [ + 'type' => $_POST['type'], + 'name' => $_POST['name'], + 'number' => $_POST['number'], + 'month' => $_POST['month'], + 'year' => $_POST['year'], + 'cvv' => $_POST['cvv'], +]; + +$pos->prepare($order, $card); + +$form_data = $pos->get3dFormData(); +?> + +Redirecting... +
+ $value): ?> + + +
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/3d/index.php b/app/Core/Payment/Pos/ex/examples/ykb/3d/index.php new file mode 100644 index 0000000..c38e7b1 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/3d/index.php @@ -0,0 +1,77 @@ + $order_id, + 'amount' => $amount, + 'installment' => $instalment, + 'currency' => 'TRY', + 'success_url' => $success_url, + 'fail_url' => $fail_url, + 'transaction' => 'pay', // pay => Sale, pre Auth + 'lang' => 'tr', +]; +?> + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + + +
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/3d/response.php b/app/Core/Payment/Pos/ex/examples/ykb/3d/response.php new file mode 100644 index 0000000..8b4ee8e --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/3d/response.php @@ -0,0 +1,112 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order = $_SESSION['order']; + +$pos->prepare($order); +$payment = $pos->payment(); +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ status == 'approved' ? 'Payment is successful!' : 'Payment is not successful'; ?> +

+
+
+
Response:
+
response ? $response->response : '-'; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Transaction Security:
+
transaction_security; ?>
+
+
+
+
Hash:
+
+ hash as $key => $hash): ?> + + +
+
+
+
+
Order ID:
+
id; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
code ? $response->code : '-'; ?>
+
+
+
+
mdStatus:
+
md_status ? $response->md_status : '-'; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
Md Error Message:
+
md_error_message ? $response->md_error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/_config.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/_config.php new file mode 100644 index 0000000..956952e --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/_config.php @@ -0,0 +1,31 @@ +getClientIp(); + +$account = [ + 'bank' => 'yapikredi', + 'model' => 'regular', + 'client_id' => '6706598320', + 'terminal_id' => '67322946', + 'posnet_id' => '27426', + 'env' => 'test', +]; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$gateway = $base_url . 'response.php'; + +$template_title = 'Regular Payment'; diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/cancel.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/cancel.php new file mode 100644 index 0000000..5aa24cb --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/cancel.php @@ -0,0 +1,43 @@ +bank->cancel([ + 'order_id' => '201811133F3F', +]); + +/* +// faster params... +$cancel = $pos->bank->cancel([ + 'order_id' => '201810295863', + 'host_ref_num' => '018711539490000181', + 'auth_code' => '115394', +]); +*/ + +$response = $cancel->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Cancel Order is successful!' : 'Cancel Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/direct.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/direct.php new file mode 100644 index 0000000..21f8531 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/direct.php @@ -0,0 +1,35 @@ + $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => '0', + 'currency' => 'TRY', + 'ip' => $ip, + 'transaction' => 'pay', // pay => Auth, pre PreAuth +]; + +$card = [ + 'number' => '4355084355084358', + 'month' => '12', + 'year' => '18', + 'cvv' => '000', +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment($card); + +var_dump($payment->response); diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/history.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/history.php new file mode 100644 index 0000000..114f028 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/history.php @@ -0,0 +1,34 @@ +bank->history([ + 'order_id' => '201811133F3F', +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() == '00' ? 'History Order is successful!' : 'History Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/index.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/index.php new file mode 100644 index 0000000..2999bdd --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/index.php @@ -0,0 +1,44 @@ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/post.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/post.php new file mode 100644 index 0000000..5fcbd30 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/post.php @@ -0,0 +1,70 @@ +getClientIp(); + +$account = [ + 'bank' => 'yapikredi', + 'model' => 'regular', + 'client_id' => '6706598320', + 'terminal_id' => '67322946', + 'posnet_id' => '27426', + 'env' => 'test', +]; + +$template_title = 'Post Auth Order'; + +require '../../template/_header.php'; + +try { + $pos = new \Mews\Pos\Pos($account); +} catch (\Mews\Pos\Exceptions\BankNotFoundException $e) { + var_dump($e->getCode(), $e->getMessage()); +} catch (\Mews\Pos\Exceptions\BankClassNullException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$order = [ + 'id' => '2018102949E0', + 'host_ref_num' => '018711533790000181', + 'amount' => '100', + 'currency' => 'TRY', + 'installment' => '2', + 'transaction' => 'post', +]; + +try { + $pos->prepare($order); +} catch (\Mews\Pos\Exceptions\UnsupportedTransactionTypeException $e) { + var_dump($e->getCode(), $e->getMessage()); +} + +$payment = $pos->payment(); + +$response = $payment->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Post Auth Order is successful!' : 'Post Auth Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/refund.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/refund.php new file mode 100644 index 0000000..71f89c5 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/refund.php @@ -0,0 +1,36 @@ +bank->refund([ + 'order_id' => '20181113DCDB', + 'amount' => '1', + 'currency' => 'TRY', +]); + +$response = $refund->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Refund Order is successful!' : 'Refund Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/response.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/response.php new file mode 100644 index 0000000..0b73b49 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/response.php @@ -0,0 +1,119 @@ +getMethod() !== 'POST') { + echo new \Symfony\Component\HttpFoundation\RedirectResponse($base_url); + exit(); +} + +$order_id = date('Ymd') . strtoupper(substr(uniqid(sha1(time())),0,4)); +$amount = (double) 100; + +$order = [ + 'id' => $order_id, + 'name' => 'John Doe', // optional + 'email' => 'mail@customer.com', // optional + 'user_id' => '12', // optional + 'amount' => $amount, + 'installment' => 1, + 'currency' => 'TRY', + 'transaction' => 'pay', // pay => Sale, pre Auth +]; + +$pos->prepare($order); + +$card = [ + 'number' => $request->get('number'), + 'month' => $request->get('month'), + 'year' => $request->get('year'), + 'cvv' => $request->get('cvv'), +]; + +$payment = $pos->payment($card); + +$response = $payment->response; + +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Payment is successful!' : 'Payment is not successful!'; ?> +

+
+
+
Response:
+
response; ?>
+
+
+
+
Status:
+
status; ?>
+
+
+
+
Transaction:
+
transaction; ?>
+
+
+
+
Transaction Type:
+
transaction_type; ?>
+
+
+
+
Order ID:
+
order_id ? $response->order_id : '-'; ?>
+
+
+
+
Group ID:
+
group_id ? $response->group_id : '-'; ?>
+
+
+
+
AuthCode:
+
auth_code ? $response->auth_code : '-'; ?>
+
+
+
+
HostRefNum:
+
host_ref_num ? $response->host_ref_num : '-'; ?>
+
+
+
+
ProcReturnCode:
+
proc_return_code; ?>
+
+
+
+
Code:
+
code; ?>
+
+
+
+
Error Code:
+
error_code ? $response->error_code : '-'; ?>
+
+
+
+
Error Message:
+
error_message ? $response->error_message : '-'; ?>
+
+
+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/examples/ykb/regular/status.php b/app/Core/Payment/Pos/ex/examples/ykb/regular/status.php new file mode 100644 index 0000000..59fec19 --- /dev/null +++ b/app/Core/Payment/Pos/ex/examples/ykb/regular/status.php @@ -0,0 +1,34 @@ +bank->status([ + 'order_id' => '201811133F3F', +]); + +$response = $query->response; +$dump = get_object_vars($response); +?> + +
+

+ isSuccess() ? 'Query Order is successful!' : 'Query Order is not successful!'; ?> +

+
+
All Data Dump:
+
+
+
+
+
+ +
+ + diff --git a/app/Core/Payment/Pos/ex/phpunit.xml b/app/Core/Payment/Pos/ex/phpunit.xml new file mode 100644 index 0000000..d67d7da --- /dev/null +++ b/app/Core/Payment/Pos/ex/phpunit.xml @@ -0,0 +1,25 @@ + + + + + tests + + + + + src + + vendor + + + + diff --git a/app/Core/Payment/Pos/ex/tests/EstPostTest.php b/app/Core/Payment/Pos/ex/tests/EstPostTest.php new file mode 100644 index 0000000..f514aaa --- /dev/null +++ b/app/Core/Payment/Pos/ex/tests/EstPostTest.php @@ -0,0 +1,149 @@ +config = require __DIR__ . '/../config/pos.php'; + + $this->account = (object)[ + 'bank' => 'akbank', + 'model' => '3d', + 'client_id' => 'XXXXXXX', + 'username' => 'XXXXXXX', + 'password' => 'XXXXXXX', + 'store_key' => 'VnM5WZ3sGrPusmWP', + 'env' => 'test', + ]; + + $this->card = (object)[ + 'number' => '5555444433332222', + 'year' => '21', + 'month' => '12', + 'cvv' => '122', + 'name' => 'ahmet', + 'type' => 'visa' + ]; + + $this->order = (object)[ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '100.25', + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'rand' => microtime() + ]; + + $this->estpos = new EstPos( + $this->config['banks'][$this->account->bank], + $this->account, + $this->config['currencies']); + } + + public function testInit() + { + $this->assertEquals($this->config['banks'][$this->account->bank], $this->estpos->getConfig()); + $this->assertEquals($this->account, $this->estpos->getAccount()); + $this->assertEquals($this->config['currencies'], $this->estpos->getCurrencies()); + } + + public function testPrepare() + { + + $this->estpos->prepare($this->order, $this->card); + $this->assertEquals($this->card, $this->estpos->getCard()); + $this->assertEquals($this->order, $this->estpos->getOrder()); + } + + public function testGetCardCode() + { + $card = $this->card; + + $card->type = '1'; + $this->estpos->prepare($this->order, $card); + $this->assertEquals($card->type, $this->estpos->getCardCode()); + + $card->type = 'visa'; + $this->estpos->prepare($this->order, $card); + $this->assertNotNull($this->estpos->getCardCode()); + + $card->type = 'master'; + $this->estpos->prepare($this->order, $card); + $this->assertNotNull($this->estpos->getCardCode()); + } + + public function testGet3DFormData() + { + $this->estpos->prepare($this->order, $this->card); + + $form = [ + 'gateway' => $this->config['banks'][$this->account->bank]['urls']['gateway'][$this->account->env], + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand, + 'hash' => $this->estpos->create3DHash(), + 'inputs' => [ + 'clientid' => $this->account->client_id, + 'storetype' => $this->account->model, + 'hash' => $this->estpos->create3DHash(), + 'cardType' => $this->estpos->getCardCode(), + 'pan' => $this->card->number, + 'Ecom_Payment_Card_ExpDate_Month' => $this->card->month, + 'Ecom_Payment_Card_ExpDate_Year' => $this->card->year, + 'cv2' => $this->card->cvv, + 'firmaadi' => $this->order->name, + 'Email' => $this->order->email, + 'amount' => $this->order->amount, + 'oid' => $this->order->id, + 'okUrl' => $this->order->success_url, + 'failUrl' => $this->order->fail_url, + 'rnd' => $this->order->rand, + 'lang' => $this->order->lang, + 'currency' => $this->order->currency, + ] + ]; + $this->assertEquals($form, $this->estpos->get3DFormData()); + } + + public function testCheck3DHash() + { + $data = [ + "md" => "478719:0373D10CFD8BDED34FA0546D27D5BE76F8BA4A947D1EC499102AE97B880EB1B9:4242:##400902568", + "cavv" => "BwAQAhIYRwEAABWGABhHEE6v5IU=", + "AuthCode" => "", + "oid" => "880", + "mdStatus" => "4", + "eci" => "06", + "clientid" => "400902568", + "rnd" => "hDx50d0cq7u1vbpWQMae", + "ProcReturnCode" => "N7", + "Response" => "Declined", + "HASH" => "D+B5fFWXEWFqVSkwotyuTPUW800=", + "HASHPARAMS" => "clientid:oid:AuthCode:ProcReturnCode:Response:mdStatus:cavv:eci:md:rnd:", + "HASHPARAMSVAL" => "400902568880N7Declined4BwAQAhIYRwEAABWGABhHEE6v5IU=06478719:0373D10CFD8BDED34FA0546D27D5BE76F8BA4A947D1EC499102AE97B880EB1B9:4242:##400902568hDx50d0cq7u1vbpWQMae" + ]; + + $this->assertTrue($this->estpos->check3DHash($data)); + + $data['mdStatus'] = ''; + $this->assertFalse($this->estpos->check3DHash($data)); + } +} diff --git a/app/Core/Payment/Pos/ex/tests/GarantiPosTest.php b/app/Core/Payment/Pos/ex/tests/GarantiPosTest.php new file mode 100644 index 0000000..dc80dca --- /dev/null +++ b/app/Core/Payment/Pos/ex/tests/GarantiPosTest.php @@ -0,0 +1,98 @@ +config = require __DIR__ . '/../config/pos.php'; + + $this->account = (object)[ + 'bank' => 'akbank', + 'model' => '3d', + 'client_id' => 'XXXXXXX', + 'terminal_id' => '13456', + 'username' => 'XXXXXXX', + 'password' => 'XXXXXXX', + 'store_key' => 'XXXXXXX', + 'env' => 'test', + ]; + + $this->card = (object)[ + 'number' => '5555444433332222', + 'year' => '21', + 'month' => '12', + 'cvv' => '122', + 'name' => 'ahmet', + 'type' => 'visa' + ]; + + $this->order = (object)[ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '100.25', + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'rand' => microtime(), + 'ip' => '156.155.154.153' + ]; + + $this->garantiPos = new GarantiPos( + $this->config['banks'][$this->account->bank], + $this->account, + $this->config['currencies']); + } + + public function testInit() + { + $this->assertEquals($this->config['banks'][$this->account->bank], $this->garantiPos->getConfig()); + $this->assertEquals($this->account, $this->garantiPos->getAccount()); + $this->assertEquals($this->config['currencies'], $this->garantiPos->getCurrencies()); + } + + public function testPrepare() + { + + $this->garantiPos->prepare($this->order, $this->card); + $this->assertEquals($this->card, $this->garantiPos->getCard()); + $this->assertEquals($this->order, $this->garantiPos->getOrder()); + } + + public function testGet3DFormData() + { + $this->garantiPos->prepare($this->order, $this->card); + + $form = [ + 'gateway' => $this->config['banks'][$this->account->bank]['urls']['gateway'][$this->account->env], + 'success_url' => $this->order->success_url, + 'fail_url' => $this->order->fail_url, + 'rand' => $this->order->rand + ]; + $actualForm = $this->garantiPos->get3DFormData(); + $this->assertNotEmpty($actualForm['inputs']); + $this->assertNotEmpty($actualForm['hash']); + + unset($actualForm['inputs']); + unset($actualForm['hash']); + $this->assertEquals($form, $actualForm); + } + + +} diff --git a/app/Core/Payment/Pos/ex/tests/PosNetCryptTest.php b/app/Core/Payment/Pos/ex/tests/PosNetCryptTest.php new file mode 100644 index 0000000..d8a81e5 --- /dev/null +++ b/app/Core/Payment/Pos/ex/tests/PosNetCryptTest.php @@ -0,0 +1,35 @@ +crypt = new PosNetCrypt(); + } + + public function testDecrypt(){ + $data = '9ACF38C842B3522415364850EAD1909BD43FD590BE3CBD539AD5FF6C7465973ABD61E8371E03282605ED06C994DF394244B7E7DAD54A046510484FAA724330C4C95A527D7891151E7C195D4136CBD70A87D1BD1F75473CF6B45A3F2FA8231DD71FFB4150E0BF4B133ECAA5ACC82CFD74903E21BC6EECB4B33AF39B8AF0C183A64002CFC125A55685C69A13192F3A9A4FDAC860E90C3FB6D125285E9E687BEFBE05707E131FC7ABE25FE35AB114FAE8A247B8C0F3DBA8AA74396D10564B7A0617EED913ED'; + + $key = '10,10,10,10,10,10,10,10'; + $expected_output = '6706598320;67005551;100;00;YKB_TST_090519001330;0;0;https://setmpos.ykb.com/PosnetWebService/YKBTransactionService;posnettest.ykb.com;2225;N;0;Not authenticated;1557398383820;TL'; + + $dc = $this->crypt->decrypt($data, $key); + $this->assertEquals($expected_output, $dc); + + $data = '1974BC4B9984FF173F9DF305090E44241243CCC9648349C0D607AECACCB55C1F1ED47452B3AD90785F9BCC6AC7E65450D4E72F31B9FC8F9F55A7D109C2BE966C6DD3F3DE12B3457FF0C6FA8BCDBB4B8E5341C1C3DA327992C28354EB3B5C62472C06B8FB6DF34E351206D2CCD5E323FA26EC3EFF2C25656C74C836954F193E634AF391761F88B5D53DBE1FC61A89DB713DFC983D9605D080ACA857196DD3E7B3C52BFCC914CE47961D76B590ECB34B28113A6E4FAA572958D836B09546A9A62D24F829FE18628DF84504FB02'; + $expected_output = '6706598320;67825768;100;00;00000000000000000892;0;0;https://setmpos.ykb.com/PosnetWebService/YKBTransactionService;posnettest.ykb.com;2225;N;9;None 3D - Secure Transaction;1586175747626;TL'; + + $dc = $this->crypt->decrypt($data, $key); + $this->assertEquals($expected_output, $dc); + } + +} diff --git a/app/Core/Payment/Pos/ex/tests/PosNetTest.php b/app/Core/Payment/Pos/ex/tests/PosNetTest.php new file mode 100644 index 0000000..8403ea9 --- /dev/null +++ b/app/Core/Payment/Pos/ex/tests/PosNetTest.php @@ -0,0 +1,110 @@ +account = (object)[ + 'bank' => 'yapikredi', + 'model' => 'regular', + 'client_id' => '6706598320', + 'terminal_id' => '67005551', + 'posnet_id' => '27426', + 'env' => 'test', + 'store_key' => '10,10,10,10,10,10,10,10', + 'model' => '3d' + ]; + + $this->card = (object)[ + 'number' => '5555444433332222', + 'year' => '21', + 'month' => '12', + 'cvv' => '122', + 'name' => 'ahmet', + 'type' => 'visa' + ]; + + $this->order = (object)[ + 'id' => 'YKB_TST_190620093100_024', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '1.75', + 'installment' => 0, + 'currency' => 'TL', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'rand' => microtime() + ]; + + + $this->config = require __DIR__ . '/../config/pos.php'; + $this->posnet = new PosNet( + $this->config['banks'][$this->account->bank], + $this->account, + $this->config['currencies']); + } + + public function testInit() + { + $this->assertEquals($this->config['banks'][$this->account->bank], $this->posnet->getConfig()); + $this->assertEquals($this->account, $this->posnet->getAccount()); + $this->assertEquals($this->config['currencies'], $this->posnet->getCurrencies()); + } + + public function testPrepare() + { + $this->posnet->prepare($this->order, $this->card); + $this->assertEquals($this->card, $this->posnet->getCard()); + $this->assertEquals($this->order, $this->posnet->getOrder()); + } + + public function testCreate3DHash(){ + + $this->posnet->prepare($this->order, $this->card); + $this->assertEquals('J/7/Xprj7F/KDf98luVfIGyUPRQzUCqGwpmvz3KT7oQ=', $this->posnet->create3DHash()); + } + + public function testVerifyResponseMAC(){ + + $order = $this->order; + $order->id = '895'; + $order->amount = 1; + $order->currency = 'TL'; + + $account = $this->account; + $account->client_id = '6706598320'; + $account->terminal_id = '67825768'; + $account->store_key = '10,10,10,10,10,10,10,10'; + + $this->posnet->prepare($order, $account); + $data = (object)[ + 'mdStatus' => '9', + 'mac' => 'U2kU/JWjclCvKZjILq8xBJUXhyB4DswKvN+pKfxl0u0=' + ]; + $this->assertTrue($this->posnet->verifyResponseMAC($data)); + + $order->id = '800'; + $this->posnet->prepare($order, $account); + $data = (object)[ + 'mdStatus' => '9', + 'mac' => 'U2kU/JWjclCvKZjILq8xBJUXhyB4DswKvN+pKfxl0u0=' + ]; + $this->assertFalse($this->posnet->verifyResponseMAC($data)); + } +} diff --git a/app/Core/Payment/Pos/ex/tests/PosTest.php b/app/Core/Payment/Pos/ex/tests/PosTest.php new file mode 100644 index 0000000..650e16b --- /dev/null +++ b/app/Core/Payment/Pos/ex/tests/PosTest.php @@ -0,0 +1,94 @@ +config = require __DIR__ . '/../config/pos.php'; + $this->account = [ + 'bank' => 'yapikredi', + 'model' => 'regular', + 'client_id' => '6706598320', + 'terminal_id' => '67322946', + 'posnet_id' => '27426', + 'env' => 'test', + 'store_key' => '10,10,10,10,10,10,10,10' + ]; + + $this->card = [ + 'number' => '5555444433332222', + 'year' => '21', + 'month' => '12', + 'cvv' => '122', + 'name' => 'ahmet', + 'type' => 'visa' + ]; + + $this->order = [ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '100.25', + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'rand' => microtime() + ]; + + $this->pos = new Pos($this->account); + } + + public function testInit() + { + $this->assertEquals($this->config['banks'][$this->account['bank']], $this->pos->getConfig()); + $this->assertEquals((object)$this->account, $this->pos->getAccount()); + $this->assertEquals($this->config['currencies'], $this->pos->getCurrencies()); + $this->assertInstanceOf(PosNet::class, $this->pos->bank); + } + + public function testCreateXML() + { + $xml_str = $this->createXML($this->order); + $this->assertIsString($xml_str); + } + + public function testXMLStringToObject() + { + $xml_str = $this->createXML(['order' => $this->order]); + $this->assertEquals((object)$this->order, $this->XMLStringToObject($xml_str)); + } + + public function testPrepare() + { + + $this->pos->prepare($this->order, $this->card); + $this->assertEquals((object)$this->card, $this->pos->getCard()); + //$this->assertEquals((object)$order, $this->pos->getOrder()); + } + + public function testGetGatewayUrl() + { + $this->assertEquals($this->config['banks'][$this->account['bank']]['urls']['gateway'][$this->account['env']], $this->pos->getGatewayUrl()); + } +} diff --git a/app/Core/Payment/QNBPay/QNBPay.php b/app/Core/Payment/QNBPay/QNBPay.php new file mode 100644 index 0000000..7fd729b --- /dev/null +++ b/app/Core/Payment/QNBPay/QNBPay.php @@ -0,0 +1,254 @@ +restClient = new Client(); + + $this->requestUrl = 'https://portal.qnbpay.com.tr/ccpayment'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://test.qnbpay.com.tr/ccpayment'; + } + + + $this->merchantId = $paymentInitializeParam['merchantId']; + $this->merchantKey = $paymentInitializeParam['merchantKey']; + $this->appKey = $paymentInitializeParam['appKey']; + $this->appSecret = $paymentInitializeParam['appSecret']; + + $this->getAccessToken = $this->getAccessToken(); + + } + + private function makeRequest($method, $payloadData) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + if ($method != 'api/token') { + $requestParams['headers']['Authorization'] = 'Bearer ' . $this->getAccessToken; + } + + + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->post($this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData['status_code'] == 100) { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } else { + $response['message'] = $getResponseData['status_description']; + $response['serviceResponse'] = $getResponseData; + } + + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + + private function getAccessToken() + { + + $method = 'api/token'; + $payloadData = [ + 'app_id' => $this->appKey, + 'app_secret' => $this->appSecret, + ]; + + $getTokenDataRequest = $this->makeRequest($method, $payloadData); + + if ($getTokenDataRequest['status']) { + $getTokenData = $getTokenDataRequest['serviceResponse']['data']['token']; + } + + return $getTokenData; + } + + public function generateHashKey($total, $installment, $currency_code, $invoice_id) + { + + $data = $total . '|' . $installment . '|' . $currency_code . '|' . $this->merchantKey . '|' . $invoice_id; + + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($this->appSecret); + + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + + $encrypted = openssl_encrypt("$data", 'aes-256-cbc', "$saltWithPassword", null, $iv); + + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $msg_encrypted_bundle = str_replace('/', '__', $msg_encrypted_bundle); + + return $msg_encrypted_bundle; + } + + public function generateRefundHashKey($invoice_id, $merchant_key, $app_secret) + { + $data = $invoice_id . '|' . $merchant_key; + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($app_secret); + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + $encrypted = openssl_encrypt( + $data, 'aes-256-cbc', "$saltWithPassword", null, $iv + ); + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $hash_key = str_replace('/', '__', $msg_encrypted_bundle); + return $hash_key; + } + + public function paySmart3D($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $generateHashKey = $this->generateHashKey($param['amount'], $param['creditCard']['installment'], $param['currencyCode'], $param['orderId']); + + $items = []; + $items[] = [ + 'name' => 'Booking', + 'price' => $param['amount'], + 'quantity' => 1, + 'description' => $param['orderCode'], + ]; + + $payment3dFormData['gateway'] = $this->requestUrl . '/api/paySmart3D'; + + $payment3dFormData['inputs'] = [ + 'currency_code' => $param['currencyCode'], + 'installments_number' => $param['creditCard']['installment'], + 'invoice_id' => $param['orderId'], + 'invoice_description' => $param['orderCode'], + 'total' => $param['amount'], + 'merchant_key' => $this->merchantKey, + 'items' => json_encode($items), + //'name' => $param['name'], + //'surname' => $param['surname'], + 'hash_key' => $generateHashKey, + 'return_url' => $param['paymentCheckUrl'], + 'cancel_url' => $param['paymentCheckUrl'], + 'cc_holder_name' => $param['creditCard']['holderName'], + 'cc_no' => $param['creditCard']['number'], + 'expiry_month' => $param['creditCard']['expiryMonth'], + 'expiry_year' => $param['creditCard']['expiryYear'], + 'cvv' => $param['creditCard']['cvv'], + 'transaction_type' => 'Auth', + 'is_comission_from_user' => '2', + 'response_method' => 'GET', + ]; + + $response = [ + 'status' => true, + 'data' => $payment3dFormData + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $generateHashKey = $this->generateRefundHashKey($orderId, $this->merchantKey, $this->appSecret); + + $method = 'api/checkstatus'; + $payloadData = [ + 'invoice_id' => $orderId, + 'merchant_key' => $this->merchantKey, + 'include_pending_status' => true, + 'hash_key' => $generateHashKey + ]; + + $checkstatusRequest = $this->makeRequest($method, $payloadData); + + if (!$checkstatusRequest['status']) { + throw new ApiErrorException($checkstatusRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkstatusRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkstatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkstatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/RetailPay/RetailPay.php b/app/Core/Payment/RetailPay/RetailPay.php new file mode 100644 index 0000000..b329376 --- /dev/null +++ b/app/Core/Payment/RetailPay/RetailPay.php @@ -0,0 +1,268 @@ +restClient = new Client(); + + $this->requestUrl = 'https://api.sprynto-psp.com'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://api.sprynto-psp-test.com'; + } + + + $this->userName = $paymentInitializeParam['userName']; + $this->password = $paymentInitializeParam['password']; + $this->ipAddress = isset($paymentInitializeParam['ipAddress']) ? $paymentInitializeParam['ipAddress'] : '185.137.215.118'; + + } + + private function makeRequest($type, $method, $payloadData = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Authorization'] = 'Basic ' . base64_encode($this->userName . ':' . $this->password); + $requestParams['headers']['Content-Type'] = 'application/json'; + + if (!empty($payloadData)) { + $requestParams['body'] = json_encode($payloadData); + } + + $result = $this->restClient->request($type, $this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData) { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } + + } catch (RequestException $e) { + + $message = null; + if ($e->hasResponse()) { + $responseError = $e->getResponse(); + $responseErrorBody = $responseError->getBody()->getContents(); + $responseErrorArray = json_decode($responseErrorBody, true); + if (isset($responseErrorArray['failure_message'])) { + $message = $responseErrorArray['failure_message']; + } + } else { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + } + + $response['message'] = $message; + Log::debug($message); + + } catch (ClientException | ServerException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + $response['message'] = $message; + Log::debug($message); + + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + public function ordersAuthorize($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $method = 'orders/authorize'; + $payloadData = [ + 'amount' => $param['amount'], + 'pan' => $param['creditCard']['number'], + 'card' => [ + 'cvv' => $param['creditCard']['cvv'], + 'holder' => $param['creditCard']['holderName'], + 'expiration_month' => $param['creditCard']['expiryMonth'], + 'expiration_year' => $param['creditCard']['expiryYear'], + ], + 'client' => [ + 'name' => $param['client']['name'], + 'email' => $param['client']['email'], + 'phone' => $param['client']['phone'], + ], + 'location' => [ + 'ip' => $this->ipAddress + ], + 'currency' => $param['currencyCode'], + 'merchant_order_id' => $param['orderId'], + 'description' => 'Order Code: ' . $param['orderCode'], + 'options' => [ + 'force3d' => 1, + 'return_url' => $param['paymentCheckUrl'], + 'secure3d20_return_url' => $param['paymentCheckUrl'], + ] + + ]; + + + \Illuminate\Support\Facades\Log::debug(json_encode($payloadData)); + + $checkRequest = $this->makeRequest('POST', $method, $payloadData); + + //dd($checkRequest); + + if (!$checkRequest['status']) { + throw new ApiErrorException($checkRequest['message']); + } + + $serviceResponse = $checkRequest['serviceResponse']; + $serviceResponseOrder = reset($serviceResponse['orders']); + + $response = [ + 'status' => true, + 'data' => $serviceResponseOrder + ]; + + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function orderCharge($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'orders/' . $orderId . '/charge'; + $orderCharge = $this->makeRequest('POST', $method); + + if (!$orderCharge['status']) { + throw new ApiErrorException($orderCharge['message']); + } + + + $serviceResponse = $orderCharge['serviceResponse']; + $serviceResponseOrder = reset($serviceResponse['orders']); + + + if ($serviceResponseOrder['status'] != 'charged') { + if (isset($serviceResponseOrder['failure_message'])) { + throw new ApiErrorException($serviceResponseOrder['failure_message']); + } else { + throw new ApiErrorException('authorized, but not charged'); + } + + } + + $response = [ + 'status' => true, + 'data' => $serviceResponseOrder + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkStatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkStatusRequest['serviceResponse']; + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'orders/' . $orderId; + $checkStatusRequest = $this->makeRequest('GET', $method); + + if (!$checkStatusRequest['status']) { + throw new ApiErrorException($checkStatusRequest['message']); + } + + $serviceResponse = $checkStatusRequest['serviceResponse']; + $serviceResponseOrder = reset($serviceResponse['orders']); + + + if ($serviceResponseOrder['status'] != 'charged') { + if (isset($serviceResponseOrder['failure_message'])) { + throw new ApiErrorException($serviceResponseOrder['failure_message']); + } else { + throw new ApiErrorException('authorized, but not charged'); + } + + } + + $response = [ + 'status' => true, + 'data' => $serviceResponseOrder + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkStatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkStatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/Sipay/Sipay.php b/app/Core/Payment/Sipay/Sipay.php new file mode 100644 index 0000000..9355856 --- /dev/null +++ b/app/Core/Payment/Sipay/Sipay.php @@ -0,0 +1,253 @@ +restClient = new Client(); + + $this->requestUrl = 'https://app.sipay.com.tr/ccpayment'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://provisioning.sipay.com.tr/ccpayment'; + } + + + $this->merchantId = $paymentInitializeParam['merchantId']; + $this->merchantKey = $paymentInitializeParam['merchantKey']; + $this->appKey = $paymentInitializeParam['appKey']; + $this->appSecret = $paymentInitializeParam['appSecret']; + + $this->getAccessToken = $this->getAccessToken(); + + } + + private function makeRequest($method, $payloadData) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + if ($method != 'api/token') { + $requestParams['headers']['Authorization'] = 'Bearer ' . $this->getAccessToken; + } + + + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->post($this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData['status_code'] == 100) { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } else { + $response['message'] = $getResponseData['status_description']; + $response['serviceResponse'] = $getResponseData; + } + + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + private function getAccessToken() + { + + $method = 'api/token'; + $payloadData = [ + 'app_id' => $this->appKey, + 'app_secret' => $this->appSecret, + ]; + + $getTokenDataRequest = $this->makeRequest($method, $payloadData); + + if ($getTokenDataRequest['status']) { + $getTokenData = $getTokenDataRequest['serviceResponse']['data']['token']; + } + + return $getTokenData; + } + + public function generateHashKey($total, $installment, $currency_code, $invoice_id) + { + + $data = $total . '|' . $installment . '|' . $currency_code . '|' . $this->merchantKey . '|' . $invoice_id; + + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($this->appSecret); + + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + + $encrypted = openssl_encrypt("$data", 'aes-256-cbc', "$saltWithPassword", null, $iv); + + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $msg_encrypted_bundle = str_replace('/', '__', $msg_encrypted_bundle); + + return $msg_encrypted_bundle; + } + + public function generateRefundHashKey($invoice_id, $merchant_key, $app_secret) + { + $data = $invoice_id . '|' . $merchant_key; + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($app_secret); + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + $encrypted = openssl_encrypt( + $data, 'aes-256-cbc', "$saltWithPassword", null, $iv + ); + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $hash_key = str_replace('/', '__', $msg_encrypted_bundle); + return $hash_key; + } + + public function paySmart3D($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $generateHashKey = $this->generateHashKey($param['amount'], $param['creditCard']['installment'], $param['currencyCode'], $param['orderId']); + + $items = []; + $items[] = [ + 'name' => 'Booking', + 'price' => $param['amount'], + 'quantity' => 1, + 'description' => $param['orderCode'], + ]; + + $payment3dFormData['gateway'] = $this->requestUrl . '/api/paySmart3D'; + + $payment3dFormData['inputs'] = [ + 'currency_code' => $param['currencyCode'], + 'installments_number' => $param['creditCard']['installment'], + 'invoice_id' => $param['orderId'], + 'invoice_description' => $param['orderCode'], + 'total' => $param['amount'], + 'merchant_key' => $this->merchantKey, + 'items' => json_encode($items), + //'name' => $param['name'], + //'surname' => $param['surname'], + 'hash_key' => $generateHashKey, + 'return_url' => $param['paymentCheckUrl'], + 'cancel_url' => $param['paymentCheckUrl'], + 'cc_holder_name' => $param['creditCard']['holderName'], + 'cc_no' => $param['creditCard']['number'], + 'expiry_month' => $param['creditCard']['expiryMonth'], + 'expiry_year' => $param['creditCard']['expiryYear'], + 'cvv' => $param['creditCard']['cvv'], + 'transaction_type' => 'Auth', + 'is_comission_from_user' => '2', + 'response_method' => 'GET', + ]; + + $response = [ + 'status' => true, + 'data' => $payment3dFormData + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $generateHashKey = $this->generateRefundHashKey($orderId, $this->merchantKey, $this->appSecret); + + $method = 'api/checkstatus'; + $payloadData = [ + 'invoice_id' => $orderId, + 'merchant_key' => $this->merchantKey, + 'include_pending_status' => true, + 'hash_key' => $generateHashKey + ]; + + $checkstatusRequest = $this->makeRequest($method, $payloadData); + + if (!$checkstatusRequest['status']) { + throw new ApiErrorException($checkstatusRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkstatusRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkstatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkstatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/TBCBankGeorgia/TBCBankGeorgia.php b/app/Core/Payment/TBCBankGeorgia/TBCBankGeorgia.php new file mode 100644 index 0000000..08db9cf --- /dev/null +++ b/app/Core/Payment/TBCBankGeorgia/TBCBankGeorgia.php @@ -0,0 +1,230 @@ +restClient = new Client(['http_errors' => false]); + + $this->requestUrl = 'https://api.tbcbank.ge/v1'; + + $this->clientId = $paymentInitializeParam['clientId']; + $this->clientSecret = $paymentInitializeParam['clientSecret']; + $this->apiKey = '3pkukzNSrBd5G7BbgG2ksu4gCzgZGkGy'; + + $tbcBankTokenCacheKey = 'TBCBankGeorgia'; + $accessToken = Cache::get($tbcBankTokenCacheKey); + if (empty($accessToken)) { + $accessToken = $this->getAccessToken(); + if ($accessToken['status']) { + $accessToken = $accessToken['token']; + } + Cache::put($tbcBankTokenCacheKey, $accessToken, 60 * 60 * 23); // 23h + } + + $this->accessToken = $accessToken; + + } + + private function makeRequest($method, $payloadData, $methodType = 'POST') + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['apikey'] = $this->apiKey; + $requestParams['headers']['Content-Type'] = 'application/json'; + $requestParams['headers']['Authorization'] = 'Bearer ' . $this->accessToken; + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->request($methodType, $this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if (isset($getResponseData['httpStatusCode']) && $getResponseData['httpStatusCode'] == 200) { + + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + + } else { + throw new Exception($getResponseData['status'] . ': ' . $getResponseData['detail']); + } + + + } catch (ClientException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + private function getAccessToken() + { + + $getTokenData = null; + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['apikey'] = $this->apiKey; + $requestParams['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; + + $requestParams['form_params']['client_id'] = $this->clientId; + $requestParams['form_params']['client_secret'] = $this->clientSecret; + + + $result = $this->restClient->request('POST', $this->requestUrl . '/tpay/access-token', $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if (isset($getResponseData['error_code'])) { + throw new ApiErrorException($getResponseData['error_message']); + } + + $response['status'] = true; + $response['token'] = $getResponseData['access_token']; + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function paymentInitialize($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + //5, Pan (Payment with card) + //7, Internet Bank Login + //9, Apple Pay + //14 Google Pay + + $localeLanguageCode = app('translator')->getLocale(); + $paymentInitializeParam = [ + 'amount' => [ + 'currency' => $param['currencyCode'], + 'total' => $param['amount'] + ], + 'returnurl' => $param['paymentCheckUrl'], + 'userIpAddress' => $param['ipAddress'], + 'expirationMinutes' => 5, + 'methods' => [5, 7, 9, 14], + 'preAuth' => false, + 'language' => $localeLanguageCode == 'ka' ? 'KA' : 'EN', + 'merchantPaymentId' => $param['orderId'], + ]; + + $paymentInitialize = $this->makeRequest('tpay/payments', $paymentInitializeParam); + + if (!$paymentInitialize['status']) { + throw new ApiErrorException($paymentInitialize['message']); + } + + $response = [ + 'status' => true, + 'data' => $paymentInitialize['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkoutOrderInfo($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'tpay/payments/' . $orderId; + $payloadData = []; + + $checkoutOrderInfoRequest = $this->makeRequest($method, $payloadData, 'GET'); + + if (!$checkoutOrderInfoRequest['status']) { + throw new ApiErrorException($checkoutOrderInfoRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkoutOrderInfoRequest['serviceResponse'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkoutOrderInfoRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkoutOrderInfoRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Payment/WeePay/WeePay.php b/app/Core/Payment/WeePay/WeePay.php new file mode 100644 index 0000000..f554acd --- /dev/null +++ b/app/Core/Payment/WeePay/WeePay.php @@ -0,0 +1,283 @@ +restClient = new Client(); + + $this->requestUrl = 'https://api.weepay.co'; + if ($paymentInitializeParam['env'] == 'test') { + $this->requestUrl = 'https://testapi.weepay.co'; + } + + + $this->merchantId = $paymentInitializeParam['merchantId']; + $this->apiKey = $paymentInitializeParam['apiKey']; + $this->secretKey = $paymentInitializeParam['secretKey']; + $this->ipAddress = isset($paymentInitializeParam['ipAddress']) ? $paymentInitializeParam['ipAddress'] : '185.137.215.118'; + + $this->currencyMapping = [ + 'TRY' => 'TL', + 'USD' => 'USD', + 'EUR' => 'EUR', + 'GBP' => 'GBP', + ]; + + } + + private function makeRequest($method, $payloadData) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParams['headers']['Content-Type'] = 'application/json'; + + $requestParams['body'] = json_encode($payloadData); + + $result = $this->restClient->post($this->requestUrl . '/' . $method, $requestParams); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : []; + + if ($getResponseData['status'] == 'success') { + $response = [ + 'status' => true, + 'serviceResponse' => $getResponseData + ]; + } + + } catch (ClientException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + $getResponseErrorBody = $e->getResponse()->getBody()->getContents(); + $getResponseError = $getResponseErrorBody ? json_decode($getResponseErrorBody, 1) : []; + + + $errorList = []; + if(is_array($getResponseError['message'])) { + foreach ($getResponseError['message'] as $errorKey => $error) { + $errorList[] = implode(', ', $error); + } + } else { + $errorList[] = $getResponseError['message']; + } + + $message = implode(', ', $errorList); + $response['message'] = $message; + Log::debug($message); + + } catch (ServerException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::debug($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + Log::error($method); + Log::error($payloadData); + Log::error($response); + } + + return $response; + + } + + + public function generateHashKey($total, $installment, $currency_code, $invoice_id) + { + + $data = $total . '|' . $installment . '|' . $currency_code . '|' . $this->merchantKey . '|' . $invoice_id; + + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($this->appSecret); + + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + + $encrypted = openssl_encrypt("$data", 'aes-256-cbc', "$saltWithPassword", null, $iv); + + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $msg_encrypted_bundle = str_replace('/', '__', $msg_encrypted_bundle); + + return $msg_encrypted_bundle; + } + + public function generateRefundHashKey($invoice_id, $merchant_key, $app_secret) + { + $data = $invoice_id . '|' . $merchant_key; + $iv = substr(sha1(mt_rand()), 0, 16); + $password = sha1($app_secret); + $salt = substr(sha1(mt_rand()), 0, 4); + $saltWithPassword = hash('sha256', $password . $salt); + $encrypted = openssl_encrypt( + $data, 'aes-256-cbc', "$saltWithPassword", null, $iv + ); + $msg_encrypted_bundle = "$iv:$salt:$encrypted"; + $hash_key = str_replace('/', '__', $msg_encrypted_bundle); + return $hash_key; + } + + public function paySmart3D($param) + { + + $response = ['status' => false, 'message' => '']; + try { + + $param['creditCard']['installment'] = $param['creditCard']['installment'] == 0 ? 1 : $param['creditCard']['installment']; + + $items = []; + $items[] = [ + 'productId' => $param['orderCode'], + 'name' => 'Booking', + 'productPrice' => $param['amount'], + 'itemType' => 'VIRTUAL', + ]; + + $method = 'Payment/PaymentRequestThreeD'; + $payloadData = [ + 'Auth' => [ + 'bayiId' => $this->merchantId, + 'apiKey' => $this->apiKey, + 'secretKey' => $this->secretKey, + ], + 'Data' => [ + 'orderId' => $param['orderId'], + 'currency' => isset($this->currencyMapping[$param['currencyCode']]) ? $this->currencyMapping[$param['currencyCode']] : $param['currencyCode'], + 'locale' => 'tr', + 'paidPrice' => $param['amount'], + 'ipAddress' => $this->ipAddress, + 'cardHolderName' => $param['creditCard']['holderName'], + 'cardNumber' => $param['creditCard']['number'], + 'expireMonth' => $param['creditCard']['expiryMonth'], + 'expireYear' => mb_substr($param['creditCard']['expiryYear'], 2, 2), + 'cvcNumber' => $param['creditCard']['cvv'], + 'installmentNumber' => $param['creditCard']['installment'], + 'description' => $param['orderCode'], + 'callBackUrl' => $param['paymentCheckUrl'] + ], + 'Customer' => [ + 'customerId' => $param['orderId'], + 'customerName' => $param['orderId'], + 'customerSurname' => $param['orderId'], + 'gsmNumber' => $param['orderId'], + 'email' => 'support@extranetwork.com', + 'identityNumber' => '11111111111', + 'city' => $param['orderId'], + 'country' => $param['orderId'], + ], + 'BillingAddress' => [ + 'contactName' => $param['orderId'], + 'address' => $param['orderId'], + 'city' => $param['orderId'], + 'country' => $param['orderId'], + ], + 'Products' => $items + + ]; + + $checkRequest = $this->makeRequest($method, $payloadData); + + if (!$checkRequest['status']) { + throw new ApiErrorException($checkRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkRequest['serviceResponse'] + ]; + + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + return $response; + + } + + public function checkPaymentStatus($orderId) + { + + $response = ['status' => false, 'message' => '']; + try { + + $method = 'GetPayment/Detail'; + $payloadData = [ + 'Auth' => [ + 'bayiId' => $this->merchantId, + 'apiKey' => $this->apiKey, + 'secretKey' => $this->secretKey, + ], + 'Data' => [ + 'ipAddress' => $this->ipAddress, + 'orderId' => $orderId, + 'locale' => 'tr' + ] + ]; + + $checkStatusRequest = $this->makeRequest($method, $payloadData); + + if (!$checkStatusRequest['status']) { + throw new ApiErrorException($checkStatusRequest['message']); + } + + if ($checkStatusRequest['serviceResponse']['paymentStatus'] != 'SUCCESS') { + throw new ApiErrorException($checkStatusRequest['message']); + } + + $response = [ + 'status' => true, + 'data' => $checkStatusRequest['serviceResponse']['data'] + ]; + + } catch (ApiErrorException $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + } catch (Exception $e) { + $response = ['status' => false, 'message' => $e->getMessage()]; + Log::error($response); + } + + if (isset($checkStatusRequest['serviceResponse'])) { + $response['serviceResponse'] = $checkStatusRequest['serviceResponse']; + } + + return $response; + + } + +} diff --git a/app/Core/Permission/AbstractRelatedPermission.php b/app/Core/Permission/AbstractRelatedPermission.php new file mode 100644 index 0000000..f6392ec --- /dev/null +++ b/app/Core/Permission/AbstractRelatedPermission.php @@ -0,0 +1,153 @@ +userService = $userService; + $this->permissionGroupUserMappingService = $permissionGroupUserMappingService; + $this->permissionGroupService = $permissionGroupService; + $this->permissionService = $permissionService; + } + + protected function checkIfUserIdSet () + { + if ($this->userData) + { + return $this->userData; + }else + { + throw new Exception("You need to call 'setUser' function first"); + } + } + + + public function setUserWithPermissionId ( $userId,$propertyId,$permission_id ) + { + $permission_id = $permission_id ? $permission_id : 0; + return $this->setUserData ($userId,$propertyId,$permission_id ); + } + + + private function setUserData ($userId,$propertyId,$permission_id ) + { + $userCriteria = + [ + "criteria"=> + [ + ["field"=>"id","condition"=>"=","value"=>$userId], + ["field"=>"status","condition"=>"=","value"=>1] + ], + "addAppends"=>["isPropertyAdmin"], + "firstRow"=>true + ]; + $userData = $this->userService->getUserList($userCriteria); + if(!$userData) + { + throw new Exception("User Not Found"); + } + + + $isUserRelatedActiveProperty = $this->userService->isUserRelatedActiveProperty($userId,$propertyId); + if ( !$isUserRelatedActiveProperty) + { + throw new Exception("User : ".$userId." Has No Relation With Property : ".$propertyId); + } + + $permissionCriteria = + [ + "criteria"=> + [ + ["field"=>"id","condition"=>"=","value"=>$permission_id] + ], + "with"=>["permissionGroupMapping"], + "firstRow"=>true + ]; + + $permissionData = $this->permissionService->findByCriteria($permissionCriteria); + $permissionData = $permissionData ? $permissionData : []; + + if ( !$permissionData && (!$userData["isSuperUser"] && !$userData["isPropertyAdmin"])) + { + throw new Exception("PermissionId Has Not Found : ".json_encode($permission_id)); + } + + $permissionGroupInfo = fillOnUndefined($permissionData,"permission_group_mapping"); + + $userData["property_id"] = $isUserRelatedActiveProperty["property_id"]; + $userData["property"] = $isUserRelatedActiveProperty["property"]; + + $this->userData = $userData; + $this->userData["relatedParameters"] = []; + $this->userData["selectedGroupMapping"] = []; + try + { + if ($this->userData[ "isSuperUser" ]) + { + return false; + } + $this->userData["is_admin"] = false; + $userRelatedParametersCriteria = + [ + "criteria"=> + [ + ["field"=>"user_id","condition"=>"=","value"=>$userId], + ["field"=>"property_id","condition"=>"=","value"=>$propertyId], + ], + "with"=>["permissionGroup"], + ]; + $userRelatedParams = $this->permissionGroupUserMappingService->findByCriteria($userRelatedParametersCriteria); + $this->userData["userAllRelatedParams"] = $userRelatedParams; + $this->userData["permission_group"] = []; + foreach ($userRelatedParams as $perParam) + { + if ($perParam["permission_group"]) + { + $this->userData["permission_group"][] = $perParam["permission_group"]; + } + + if ($perParam["permission_group"]["is_admin"]) + { + $this->userData["is_admin"] = true; + $this->userData["selectedGroupMapping"] = $perParam; + return false; + } + + if ($permissionGroupInfo && $perParam["permission_group"]["id"] == $permissionGroupInfo["permission_group_id"]) + { + $this->userData["relatedParameters"] = $perParam["relatedParametersArray"]; + $this->userData["selectedGroupMapping"] = $perParam; + } + } + + } catch ( Exception $e ) + { + return false; + } + } +} diff --git a/app/Core/Permission/RoutePermissionAuthorize.php b/app/Core/Permission/RoutePermissionAuthorize.php new file mode 100644 index 0000000..d64440e --- /dev/null +++ b/app/Core/Permission/RoutePermissionAuthorize.php @@ -0,0 +1,171 @@ +permissionGroupUserMappingService = $permissionGroupUserMappingService; + $this->userService = $userService; + $this->permissionService = $permissionService; + $this->request = $request; + $this->currentRoute = $this->request->route(); + } + + + public function setCurrentRoute ( Route $route ) + { + $this->currentRoute = $route; + $this->routePermissionData = $this->getRoutePermissionData(); + } + + protected function getRouteAliasName(){ + + $url = collect($this->request->route()); + $getNameArray = $url->where('as' , '!=', null)->first(); + return fillOnUndefined($getNameArray, 'as'); + + } + + protected function getRoutePermissionData () + { + + if ( !$this->currentRoute) + { + throw new Exception("Current Route is Null"); + } + + if ($this->routePermissionData) + { + return $this->routePermissionData; + } + + $criteria = + [ + "criteria" => + [ + [ "field" => "code", "condition" => "=", "value" => $this->getRouteAliasName() ] + ], + "with" => [ "permissionGroupMapping.permissionGroup"], + "firstRow" => 1 + ]; + $result = $this->permissionService->findByCriteria ( $criteria ); + return $result; + } + + public function getRoutePermissionGroupId () + { + return fillOnUndefined($this->getRoutePermissionData(),"permission_group_mapping.permission_group.id"); + } + + public function isUserAuthorizedForCurrentRoute ( $params ) + { + try + { + $user_id = $params['user_id'] ; + $property_id = $params['property_id'] ; + + $userCriteria = + [ + "criteria"=> + [ + ["field"=>"id","condition"=>"=","value"=>$user_id], + ["field"=>"status","condition"=>"=","value"=>1] + ], + "firstRow"=>1 + ]; + + $userData = $this->userService->select($userCriteria); + + if ( !$userData['data'] ) + { + return false; + } + + $userData = $userData['data'] ; + + + if ($userData["user_type"] == 1) + { + return true; + } + + $userGroupCriteria = + [ + "criteria" => + [ + ["field" => "user_id", "condition" => "=", "value" => $user_id], + ["field" => "property_id", "condition" => "=", "value" => $property_id], + ["field" => "status", "condition" => "=", "value" => 1] + ], + "with" => ["permissionGroup", "permissionGroupMapping"] + ]; + + $userGroups = $this->permissionGroupUserMappingService->findByCriteria($userGroupCriteria); + + + if ( !$userGroups) + { + return false; + } + + foreach ($userGroups as $perGroup) + { + if(isset($perGroup["permission_group"]["is_admin"]) && $perGroup["permission_group"]["is_admin"]) + { + return true; + } + } + + + if ( !$routePermissionData = $this->getRoutePermissionData()) + { + return false; + } + + + foreach ($userGroups as $perGroup) + { + foreach ($perGroup["permission_group_mapping"] as $perPermissionGroup) + { + if($routePermissionData["id"] == $perPermissionGroup["permission_id"]) + { + return true; + } + } + } + return false; + + } catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return false; + } + } + +} \ No newline at end of file diff --git a/app/Core/Repository/ApiAccessToken/ApiAccessTokenRepository.php b/app/Core/Repository/ApiAccessToken/ApiAccessTokenRepository.php new file mode 100644 index 0000000..79f1195 --- /dev/null +++ b/app/Core/Repository/ApiAccessToken/ApiAccessTokenRepository.php @@ -0,0 +1,19 @@ +apiAccessToken = $apiAccessToken; + $this->defaultModel = $this->apiAccessToken; + } + +} diff --git a/app/Core/Repository/ApplicationCache/ApplicationCacheRepository.php b/app/Core/Repository/ApplicationCache/ApplicationCacheRepository.php new file mode 100644 index 0000000..0cc2ba6 --- /dev/null +++ b/app/Core/Repository/ApplicationCache/ApplicationCacheRepository.php @@ -0,0 +1,57 @@ +cache = $cache; + $this->carbon = $carbon; + + } + + private function createCacheStoreKey ( $cacheId ) + { + return $this->cachePrefix.$cacheId; + } + + public function storeCache($cacheId , $param){ + $result = $param; + $result["cacheId"] = $cacheId; + $cacheSignature = $this->createCacheStoreKey($cacheId); + $expiresAt = $this->carbon->addMinutes($this->cacheLife/60)->toDateTimeString(); + + $this->cache->put($cacheSignature, $result, $this->cacheLife); + + return [ + 'cacheId' => $cacheId, + 'expiresAt' => $expiresAt + ]; + + } + + public function getCache($cacheId){ + + $cacheId = $this->createCacheStoreKey($cacheId); + $cacheInfo = $this->cache->get($cacheId); + return $cacheInfo; + + } + +} \ No newline at end of file diff --git a/app/Core/Repository/AwardsCertificateCategory/AwardsCertificateCategoryRepository.php b/app/Core/Repository/AwardsCertificateCategory/AwardsCertificateCategoryRepository.php new file mode 100644 index 0000000..c219501 --- /dev/null +++ b/app/Core/Repository/AwardsCertificateCategory/AwardsCertificateCategoryRepository.php @@ -0,0 +1,19 @@ +awardsCertificateCategory = $awardsCertificateCategory; + $this->defaultModel = $this->awardsCertificateCategory; + } + +} diff --git a/app/Core/Repository/Booking/BookingAddonRepository.php b/app/Core/Repository/Booking/BookingAddonRepository.php new file mode 100644 index 0000000..66a9cf7 --- /dev/null +++ b/app/Core/Repository/Booking/BookingAddonRepository.php @@ -0,0 +1,19 @@ +bookingAddon = $bookingAddon; + $this->defaultModel = $this->bookingAddon; + } + +} diff --git a/app/Core/Repository/Booking/BookingContactRepository.php b/app/Core/Repository/Booking/BookingContactRepository.php new file mode 100644 index 0000000..af70bdc --- /dev/null +++ b/app/Core/Repository/Booking/BookingContactRepository.php @@ -0,0 +1,19 @@ +bookingContact = $bookingContact; + $this->defaultModel = $this->bookingContact; + } + +} diff --git a/app/Core/Repository/Booking/BookingPaymentDataCheckRepository.php b/app/Core/Repository/Booking/BookingPaymentDataCheckRepository.php new file mode 100644 index 0000000..ea42248 --- /dev/null +++ b/app/Core/Repository/Booking/BookingPaymentDataCheckRepository.php @@ -0,0 +1,19 @@ +bookingPaymentDataCheck = $bookingPaymentDataCheck; + $this->defaultModel = $this->bookingPaymentDataCheck; + } + +} diff --git a/app/Core/Repository/Booking/BookingPaymentDataRepository.php b/app/Core/Repository/Booking/BookingPaymentDataRepository.php new file mode 100644 index 0000000..de892c1 --- /dev/null +++ b/app/Core/Repository/Booking/BookingPaymentDataRepository.php @@ -0,0 +1,19 @@ +bookingPaymentData = $bookingPaymentData; + $this->defaultModel = $this->bookingPaymentData; + } + +} diff --git a/app/Core/Repository/Booking/BookingPaymentRepository.php b/app/Core/Repository/Booking/BookingPaymentRepository.php new file mode 100644 index 0000000..0b7abef --- /dev/null +++ b/app/Core/Repository/Booking/BookingPaymentRepository.php @@ -0,0 +1,19 @@ +bookingPayment = $bookingPayment; + $this->defaultModel = $this->bookingPayment; + } + +} diff --git a/app/Core/Repository/Booking/BookingRepository.php b/app/Core/Repository/Booking/BookingRepository.php new file mode 100644 index 0000000..ce412c5 --- /dev/null +++ b/app/Core/Repository/Booking/BookingRepository.php @@ -0,0 +1,19 @@ +booking = $booking; + $this->defaultModel = $this->booking; + } + +} diff --git a/app/Core/Repository/Booking/BookingRoomPaxRepository.php b/app/Core/Repository/Booking/BookingRoomPaxRepository.php new file mode 100644 index 0000000..e97900d --- /dev/null +++ b/app/Core/Repository/Booking/BookingRoomPaxRepository.php @@ -0,0 +1,19 @@ +bookingRoomPax = $bookingRoomPax; + $this->defaultModel = $this->bookingRoomPax; + } + +} diff --git a/app/Core/Repository/Booking/BookingRoomRepository.php b/app/Core/Repository/Booking/BookingRoomRepository.php new file mode 100644 index 0000000..fc7d47e --- /dev/null +++ b/app/Core/Repository/Booking/BookingRoomRepository.php @@ -0,0 +1,19 @@ +bookingRoom = $bookingRoom; + $this->defaultModel = $this->bookingRoom; + } + +} diff --git a/app/Core/Repository/Booking/BookingStatusRepository.php b/app/Core/Repository/Booking/BookingStatusRepository.php new file mode 100644 index 0000000..03cb0bf --- /dev/null +++ b/app/Core/Repository/Booking/BookingStatusRepository.php @@ -0,0 +1,19 @@ +bookingStatus = $bookingStatus; + $this->defaultModel = $this->bookingStatus; + } + +} diff --git a/app/Core/Repository/Booking/BookingTicketRepository.php b/app/Core/Repository/Booking/BookingTicketRepository.php new file mode 100644 index 0000000..175d527 --- /dev/null +++ b/app/Core/Repository/Booking/BookingTicketRepository.php @@ -0,0 +1,19 @@ +bookingTicket = $bookingTicket; + $this->defaultModel = $this->bookingTicket; + } + +} diff --git a/app/Core/Repository/Booking/PropertyChannelCouponRepository.php b/app/Core/Repository/Booking/PropertyChannelCouponRepository.php new file mode 100644 index 0000000..74aac61 --- /dev/null +++ b/app/Core/Repository/Booking/PropertyChannelCouponRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/ChannelManager/ChannelManagerRepository.php b/app/Core/Repository/ChannelManager/ChannelManagerRepository.php new file mode 100644 index 0000000..e2d95ec --- /dev/null +++ b/app/Core/Repository/ChannelManager/ChannelManagerRepository.php @@ -0,0 +1,19 @@ +channelManager = $channelManager; + $this->defaultModel = $this->channelManager; + } + +} diff --git a/app/Core/Repository/ChannelManagerBooking/ChannelManagerBookingRepository.php b/app/Core/Repository/ChannelManagerBooking/ChannelManagerBookingRepository.php new file mode 100644 index 0000000..2b35fa1 --- /dev/null +++ b/app/Core/Repository/ChannelManagerBooking/ChannelManagerBookingRepository.php @@ -0,0 +1,19 @@ +channelManagerBooking = $channelManagerBooking; + $this->defaultModel = $this->channelManagerBooking; + } + +} diff --git a/app/Core/Repository/ChannelManagerLog/ChannelManagerLogRepository.php b/app/Core/Repository/ChannelManagerLog/ChannelManagerLogRepository.php new file mode 100644 index 0000000..f7dda73 --- /dev/null +++ b/app/Core/Repository/ChannelManagerLog/ChannelManagerLogRepository.php @@ -0,0 +1,19 @@ +channelManagerLog = $channelManagerLog; + $this->defaultModel = $this->channelManagerLog; + } + +} diff --git a/app/Core/Repository/ChannelManagerMapping/ChannelManagerMappingRepository.php b/app/Core/Repository/ChannelManagerMapping/ChannelManagerMappingRepository.php new file mode 100644 index 0000000..457f901 --- /dev/null +++ b/app/Core/Repository/ChannelManagerMapping/ChannelManagerMappingRepository.php @@ -0,0 +1,19 @@ +channelManagerMapping = $channelManagerMapping; + $this->defaultModel = $this->channelManagerMapping; + } + +} diff --git a/app/Core/Repository/ChannelManagerPropertyMapping/ChannelManagerPropertyMappingRepository.php b/app/Core/Repository/ChannelManagerPropertyMapping/ChannelManagerPropertyMappingRepository.php new file mode 100644 index 0000000..4937917 --- /dev/null +++ b/app/Core/Repository/ChannelManagerPropertyMapping/ChannelManagerPropertyMappingRepository.php @@ -0,0 +1,19 @@ +channelManagerPropertyMapping = $channelManagerPropertyMapping; + $this->defaultModel = $this->channelManagerPropertyMapping; + } + +} diff --git a/app/Core/Repository/ChannelManagerPropertyRateMapping/ChannelManagerPropertyRateMappingRepository.php b/app/Core/Repository/ChannelManagerPropertyRateMapping/ChannelManagerPropertyRateMappingRepository.php new file mode 100644 index 0000000..2e2beb1 --- /dev/null +++ b/app/Core/Repository/ChannelManagerPropertyRateMapping/ChannelManagerPropertyRateMappingRepository.php @@ -0,0 +1,19 @@ +channelManagerPropertyRateMapping = $channelManagerPropertyRateMapping; + $this->defaultModel = $this->channelManagerPropertyRateMapping; + } + +} diff --git a/app/Core/Repository/Country/CountryRepository.php b/app/Core/Repository/Country/CountryRepository.php new file mode 100644 index 0000000..0f84bbf --- /dev/null +++ b/app/Core/Repository/Country/CountryRepository.php @@ -0,0 +1,19 @@ +country = $country; + $this->defaultModel = $this->country; + } + +} diff --git a/app/Core/Repository/Currency/CurrencyRepository.php b/app/Core/Repository/Currency/CurrencyRepository.php new file mode 100644 index 0000000..766585e --- /dev/null +++ b/app/Core/Repository/Currency/CurrencyRepository.php @@ -0,0 +1,20 @@ +currency = $currency; + $this->defaultModel = $this->currency; + } +} diff --git a/app/Core/Repository/CurrencyRates/CurrencyRatesRepository.php b/app/Core/Repository/CurrencyRates/CurrencyRatesRepository.php new file mode 100644 index 0000000..e43e82e --- /dev/null +++ b/app/Core/Repository/CurrencyRates/CurrencyRatesRepository.php @@ -0,0 +1,19 @@ +currencyRates = $currencyRates; + $this->defaultModel = $this->currencyRates; + } + +} diff --git a/app/Core/Repository/EleqouentAbstractRepository.php b/app/Core/Repository/EleqouentAbstractRepository.php new file mode 100644 index 0000000..07c050c --- /dev/null +++ b/app/Core/Repository/EleqouentAbstractRepository.php @@ -0,0 +1,522 @@ + "id", "condition" => "=", "value" => $id]; + $param["firstRow"] = true; + + return $this->findByCriteria($model, $param, $column); + } + + protected function all(Model $model) + { + return $this->findByCriteria($model); + } + + private function withCriteria($get, $param) + { + foreach ($param as $key => $value) { + $get->with([$value['method'] => function ($query) use ($value) { + + if (isset($value['orderBy'])) { + foreach ($value['orderBy'] as $orderByKey => $orderByValue) { + $query->orderBy($orderByValue['field'], $orderByValue['value']); + } + } + + if (isset($value['field'])) { + foreach ($value['field'] as $fieldValue) { + $query->where($fieldValue['field'], $fieldValue['condition'], $fieldValue['value']); + } + } + + if (isset($value['whereIn'])) { + foreach ($value['whereIn'] as $fieldValue) { + $query->whereIn($fieldValue['field'], $fieldValue['value']); + } + } + + }]); + } + return $get; + } + + private function withBuild(Builder $builder, array $withParams) + { + + foreach ($withParams as $perParamKey => $perParamValue) { + if (!is_array($perParamValue)) { + $builder->with($perParamValue); + continue; + } else { + $builder->with($perParamKey); + } + + if (isset($perParamValue["with"])) { + $builder = $this->withBuild($builder, $perParamValue); + } + + } + + return $builder; + + } + + protected function findByCriteria(Model $model, $param = null, $column = ['*']) + { + try { + if (isset($param["removeAppends"])) { + $model->removeAppends($param["removeAppends"]); + } else { + $model->removeAppends([]); + } + + if (isset($param["addAppends"])) { + $model->addAppends($param["addAppends"]); + } else { + $model->addAppends([]); + } + + $get = $model->on('mysql'); + + + if (isset($param["selectRaw"])) { + $get = $get->select(DB::raw($param["selectRaw"])); + } + + if (isset($param["criteria"])) { + $get->where( + function ($query) use ($param) { + if (isset($param['whereOr'])) { + foreach ($param['whereOr'] as $key => $value) { + $query->whereOr($value['field'], $value['condition'], $value['value']); + } + } + + if (isset($param['criteria'])) { + foreach ($param['criteria'] as $key => $value) { + $query->where($value['field'], $value['condition'], $value['value']); + } + } + } + ); + } + + if (isset($param['criteriaWhere'])) { + $whereType = fillOnUndefined($param['criteriaWhere'], 'whereType', 'where'); + $get->$whereType ( + function ($query) use ($param) { + foreach ($param['criteriaWhere'] as $criteria) { + $whereType = $criteria['whereType']; + $query->$whereType( + function ($q) use ($criteria) { + foreach ($criteria['params'] as $key => $value) { + if (isset($value['where'])) { + if ($value['where'] == 'OR') { + $q->whereOr($value['field'], $value['condition'], $value['value']); + } else { + $q->where($value['field'], $value['condition'], $value['value']); + } + } + } + } + ); + } + } + ); + } + + if (isset($param["criteriaWhereRaw"])) { + $get->where( + function ($query) use ($param) { + if (isset($param['criteriaWhereRaw'])) { + foreach ($param['criteriaWhereRaw'] as $key => $value) { + $query->whereRaw($value['query'], $value['binds']); + } + } + } + ); + } + + + if (isset($param["whereOr"])) { + $get->where( + function ($query) use ($param) { + if (isset($param['whereOr'])) { + foreach ($param['whereOr'] as $key => $value) { + $query->orWhere($value['field'], $value['condition'], $value['value']); + } + } + + } + ); + } + + if (isset($param['whereIn'])) { + foreach ($param['whereIn'] as $whereInKey => $whereInValue) { + $get->whereIn($whereInValue['field'], $whereInValue['value']); + } + } + + + if (isset($param['whereNotIn'])) { + foreach ($param['whereNotIn'] as $whereInKey => $whereInValue) { + $get->whereNotIn($whereInValue['field'], $whereInValue['value']); + } + } + + + if (isset($param['has'])) { + foreach ($param["has"] as $perHas) { + $get->has($perHas["title"], $perHas["condition"], $perHas["value"]); + } + } + + if (isset($param['whereHas'])) { + foreach ($param['whereHas'] as $key => $value) { + $get->whereHas($value['title'], function ($get) use ($value) { + foreach ($value['criteria']['param'] as $criteria) { + $queryType = $value['criteria']['type']; + + if ($queryType == 'whereIn') { + $get->whereIn($criteria['field'], $criteria['value']); + } else { + $get->$queryType($criteria['field'], $criteria['condition'], $criteria['value']); + } + } + }); + } + } + + /*Ex With Algorithm*/ + if (isset($param['with'])) { + foreach ($param['with'] as $withKey => $withValue) { + $get->with($withValue); + } + } + + if (isset($param['withCriteria'])) { + $get = $this->withCriteria($get, $param['withCriteria']); + } + + if (isset($param['orderBy'])) { + foreach ($param['orderBy'] as $orderByKey => $orderByValue) { + $get->orderBy($orderByValue['field'], $orderByValue['value']); + } + } + + if (isset($param['groupBy'])) { + foreach ($param['groupBy'] as $perOrderBy) { + $get->groupBy($perOrderBy); + } + } + + if (isset($param['skip'])) { + $get->skip($param['skip']); + } + + if (isset($param['take'])) { + $get->take($param['take']); + } + + if (isset($param['sum'])) { + return $get->sum($param['sum']); + } + + if (isset($param['count'])) { + return $get->count(); + } + + if (isset($param["toSql"])) { + return $get->toSql(); + } + $get = isset($param["firstRow"]) ? $get->first($column) : $get->get($column); + if (isset($param['keyBy'])) { + $get = $get->keyBy($param['keyBy']); + } + if (isset($param["getRaw"])) { + return $get; + } + + return ($get) ? $get->toArray() : []; + + } catch (Exception $e) { + Log::error($e->getMessage()); + } + } + + protected function update(Model $model, $id, $param) + { + try { + $update = $model->where('id', $id)->update($param); + + $update = $update ? $this->find($model, $id) : false; + + return output(['data' => $update]); + } catch (Exception $e) { + $message = $e->getMessage(); + + return output(['status' => -1, 'message' => $message]); + } + + } + + protected function updateWhere(Model $model, $value, $param) + { + try { + $update = $model->where( + function ($query) use ($value) { + if (isset($value['criteria'])) { + foreach ($value['criteria'] as $key => $value) { + $query->where($value['field'], $value['condition'], $value['value']); + } + } + } + ); + + if (isset($value['orderBy'])) { + foreach ($value['orderBy'] as $orderByKey => $orderByValue) { + $update->orderBy($orderByValue['field'], $orderByValue['value']); + } + } + + $update->first(); + $update = $update->update($param); + + $update = $update ? true : false; + + return output(['data' => $update]); + } catch (Exception $e) { + $message = $e->getTraceAsString(); + + return output(['status' => -1, 'message' => $message]); + } + + } + + protected function updateWhereIn(Model $model, $id, $param) + { + try { + $update = $model->whereIn('id', $id)->update($param); + $update = $update ? $update : false; + return output(['data' => $update]); + } catch (Exception $e) { + $message = $e->getMessage(); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function updateWhereBulk(Model $model, $value, $param) + { + try { + $update = $model->where( + function ($query) use ($value) { + if (isset($value['criteria'])) { + foreach ($value['criteria'] as $key => $value) { + $query->where($value['field'], $value['condition'], $value['value']); + } + } + } + ); + + if (isset($value['orderBy'])) { + foreach ($value['orderBy'] as $orderByKey => $orderByValue) { + $update->orderBy($orderByValue['field'], $orderByValue['value']); + } + } + + $update = $update->update($param); + + $update = $update ? true : false; + + return output(['data' => $update]); + } catch (Exception $e) { + $message = $e->getTraceAsString(); + + return output(['status' => -1, 'message' => $message]); + } + + } + + protected function create(Model $model, $data) + { + try { + $create = $model->create($data); + + return output(['data' => $create->toArray()]); + } catch (Exception $e) { + $message = $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function insert(Model $model, $data) + { + try { + $create = $model->insert($data); + + return output(['data' => $create]); + } catch (QueryException $e) { + $message = $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } catch (Exception $e) { + $message = $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function createAll(Model $model, $data) + { + try { + $create = []; + foreach ($data as $perData) { + $result = $this->create($model, $perData); + + if ($result["status"] != "success") { + throw new Exception($result["message"]); + } + + $create[] = $result["data"]; + } + + return output(['data' => $create]); + } catch (Exception $e) { + $message = $e->getTraceAsString(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function updateOrCreate(Model $model, array $criteria, array $saveData) + { + try { + + + $findRow = $this->findByCriteria + ( + $model, + ["criteria" => $criteria, "firstRow" => 1, "getRaw" => 1] + ); + + + + $model->on("mysql"); + if ($findRow) { + $result = $this->update($model, $findRow["id"], $saveData); + } else { + $result = $this->create($model, $saveData); + } + + return $result; + } catch (Exception $e) { + $message = $e->getTraceAsString(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function delete(Model $model, array $param) + { + try { + $param["removeAppends"] = ["*"]; + $param["with"] = []; + $deleteRows = $this->findByCriteria($model, $param, ["id"]); + + if (!$deleteRows) { + return null; + } + $deleteRows = singleElementArray($deleteRows); + $deleteIds = pickItemFromArray("id", $deleteRows); + $result = $model->whereIn("id", $deleteIds); + if ($result->count() > 0) { + $deletedRows = $result->get()->toArray(); + if ($result->delete()) { + return $deletedRows; + } + } + return null; + } catch (Exception $e) { + $message = $e->getTraceAsString(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + protected function destroy(Model $model, array $param) + { + try { + + if (!$param) { + return null; + } + + $deletedRows = $model->destroy($param); + + return output(['data' => $deletedRows]);; + } catch (Exception $e) { + $message = $e->getTraceAsString(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + + //Todo: Bu fonksiyon iyileştirilecek + protected function deleteById(Model $model, $id) + { + try { + $result = $model->whereIn("id", $id); + if ($result->count() > 0) { + $deletedRows = $result->get()->toArray(); + if ($result->delete()) { + return $deletedRows; + } + } + return null; + } catch (Exception $e) { + $message = $e->getTraceAsString(); + Log::error($message); + return output(['status' => -1, 'message' => $message]); + } + } + + public function __call($method, $args) + { + try { + if (method_exists($this, $method)) { + array_unshift($args, $this->defaultModel); + return call_user_func_array(array(&$this, $method), $args); + } else { + throw new Exception("'" . __CLASS__ . "' does not have '" . $method . "' method", 1); + } + } catch (Exception $e) { + die($e->getMessage()); + } + } + +} diff --git a/app/Core/Repository/GeneralTimezone/GeneralTimezoneRepository.php b/app/Core/Repository/GeneralTimezone/GeneralTimezoneRepository.php new file mode 100644 index 0000000..6579acb --- /dev/null +++ b/app/Core/Repository/GeneralTimezone/GeneralTimezoneRepository.php @@ -0,0 +1,19 @@ +GeneralTimezone = $GeneralTimezone; + $this->defaultModel = $this->GeneralTimezone; + } + +} diff --git a/app/Core/Repository/Ip2NationCountries/Ip2NationCountriesRepository.php b/app/Core/Repository/Ip2NationCountries/Ip2NationCountriesRepository.php new file mode 100644 index 0000000..bf8ce08 --- /dev/null +++ b/app/Core/Repository/Ip2NationCountries/Ip2NationCountriesRepository.php @@ -0,0 +1,19 @@ +ip2nationCountries = $ip2nationCountries; + $this->defaultModel = $this->ip2nationCountries; + } + +} diff --git a/app/Core/Repository/IpNation/IpNationRepository.php b/app/Core/Repository/IpNation/IpNationRepository.php new file mode 100644 index 0000000..fb38c54 --- /dev/null +++ b/app/Core/Repository/IpNation/IpNationRepository.php @@ -0,0 +1,19 @@ +ipNation = $ipNation; + $this->defaultModel = $this->ipNation; + } + +} diff --git a/app/Core/Repository/Jobs/JobsRepository.php b/app/Core/Repository/Jobs/JobsRepository.php new file mode 100644 index 0000000..07992ca --- /dev/null +++ b/app/Core/Repository/Jobs/JobsRepository.php @@ -0,0 +1,19 @@ +jobs = $jobs; + $this->defaultModel = $this->jobs; + } + +} diff --git a/app/Core/Repository/Language/LanguageRepository.php b/app/Core/Repository/Language/LanguageRepository.php new file mode 100644 index 0000000..2f314d2 --- /dev/null +++ b/app/Core/Repository/Language/LanguageRepository.php @@ -0,0 +1,19 @@ +language = $language; + $this->defaultModel = $this->language; + } + +} diff --git a/app/Core/Repository/LanguageBase/LanguageBaseRepository.php b/app/Core/Repository/LanguageBase/LanguageBaseRepository.php new file mode 100644 index 0000000..4c4b185 --- /dev/null +++ b/app/Core/Repository/LanguageBase/LanguageBaseRepository.php @@ -0,0 +1,19 @@ +languageBase = $languageBase; + $this->defaultModel = $this->languageBase; + } + +} diff --git a/app/Core/Repository/LanguageTranslate/LanguageTranslateRepository.php b/app/Core/Repository/LanguageTranslate/LanguageTranslateRepository.php new file mode 100644 index 0000000..856e6e7 --- /dev/null +++ b/app/Core/Repository/LanguageTranslate/LanguageTranslateRepository.php @@ -0,0 +1,19 @@ +languageTranslate = $languageTranslate; + $this->defaultModel = $this->languageTranslate; + } + +} diff --git a/app/Core/Repository/Offer/OfferRepository.php b/app/Core/Repository/Offer/OfferRepository.php new file mode 100644 index 0000000..d73f9a2 --- /dev/null +++ b/app/Core/Repository/Offer/OfferRepository.php @@ -0,0 +1,19 @@ +offer = $offer; + $this->defaultModel = $this->offer; + } + +} diff --git a/app/Core/Repository/OfferAccommodationMapping/OfferAccommodationMappingRepository.php b/app/Core/Repository/OfferAccommodationMapping/OfferAccommodationMappingRepository.php new file mode 100644 index 0000000..2eb30a1 --- /dev/null +++ b/app/Core/Repository/OfferAccommodationMapping/OfferAccommodationMappingRepository.php @@ -0,0 +1,19 @@ +offerAccommodationMapping = $offerAccommodationMapping; + $this->defaultModel = $this->offerAccommodationMapping; + } + +} diff --git a/app/Core/Repository/OfferCancellationPolicy/OfferCancellationPolicyRepository.php b/app/Core/Repository/OfferCancellationPolicy/OfferCancellationPolicyRepository.php new file mode 100644 index 0000000..758bcdd --- /dev/null +++ b/app/Core/Repository/OfferCancellationPolicy/OfferCancellationPolicyRepository.php @@ -0,0 +1,19 @@ +offerCancellationPolicy = $offerCancellationPolicy; + $this->defaultModel = $this->offerCancellationPolicy; + } + +} diff --git a/app/Core/Repository/OfferConfirmType/OfferConfirmTypeRepository.php b/app/Core/Repository/OfferConfirmType/OfferConfirmTypeRepository.php new file mode 100644 index 0000000..f486a1b --- /dev/null +++ b/app/Core/Repository/OfferConfirmType/OfferConfirmTypeRepository.php @@ -0,0 +1,19 @@ +offerConfirmType = $offerConfirmType; + $this->defaultModel = $this->offerConfirmType; + } + +} diff --git a/app/Core/Repository/OfferContactMapping/OfferContactMappingRepository.php b/app/Core/Repository/OfferContactMapping/OfferContactMappingRepository.php new file mode 100644 index 0000000..0583440 --- /dev/null +++ b/app/Core/Repository/OfferContactMapping/OfferContactMappingRepository.php @@ -0,0 +1,19 @@ +offerContactMapping = $offerContactMapping; + $this->defaultModel = $this->offerContactMapping; + } + +} diff --git a/app/Core/Repository/OfferFactMapping/OfferFactMappingRepository.php b/app/Core/Repository/OfferFactMapping/OfferFactMappingRepository.php new file mode 100644 index 0000000..0572ad7 --- /dev/null +++ b/app/Core/Repository/OfferFactMapping/OfferFactMappingRepository.php @@ -0,0 +1,19 @@ +offerFactMapping = $offerFactMapping; + $this->defaultModel = $this->offerFactMapping; + } + +} diff --git a/app/Core/Repository/OfferImportantNotes/OfferImportantNotesRepository.php b/app/Core/Repository/OfferImportantNotes/OfferImportantNotesRepository.php new file mode 100644 index 0000000..c0ca6bb --- /dev/null +++ b/app/Core/Repository/OfferImportantNotes/OfferImportantNotesRepository.php @@ -0,0 +1,19 @@ +offerImportantNotes = $offerImportantNotes; + $this->defaultModel = $this->offerImportantNotes; + } + +} diff --git a/app/Core/Repository/OfferPaymentType/OfferPaymentTypeRepository.php b/app/Core/Repository/OfferPaymentType/OfferPaymentTypeRepository.php new file mode 100644 index 0000000..66002e5 --- /dev/null +++ b/app/Core/Repository/OfferPaymentType/OfferPaymentTypeRepository.php @@ -0,0 +1,19 @@ +offerPaymentType = $offerPaymentType; + $this->defaultModel = $this->offerPaymentType; + } + +} diff --git a/app/Core/Repository/OfferPhotoMapping/OfferPhotoMappingRepository.php b/app/Core/Repository/OfferPhotoMapping/OfferPhotoMappingRepository.php new file mode 100644 index 0000000..5f2590f --- /dev/null +++ b/app/Core/Repository/OfferPhotoMapping/OfferPhotoMappingRepository.php @@ -0,0 +1,19 @@ +offerPhotoMapping = $offerPhotoMapping; + $this->defaultModel = $this->offerPhotoMapping; + } + +} diff --git a/app/Core/Repository/OfferPrice/OfferPriceRepository.php b/app/Core/Repository/OfferPrice/OfferPriceRepository.php new file mode 100644 index 0000000..f0842d0 --- /dev/null +++ b/app/Core/Repository/OfferPrice/OfferPriceRepository.php @@ -0,0 +1,19 @@ +offerPrice = $offerPrice; + $this->defaultModel = $this->offerPrice; + } + +} diff --git a/app/Core/Repository/OfferRoomMapping/OfferRoomMappingRepository.php b/app/Core/Repository/OfferRoomMapping/OfferRoomMappingRepository.php new file mode 100644 index 0000000..59e95dc --- /dev/null +++ b/app/Core/Repository/OfferRoomMapping/OfferRoomMappingRepository.php @@ -0,0 +1,19 @@ +offerRoomMapping = $offerRoomMapping; + $this->defaultModel = $this->offerRoomMapping; + } + +} diff --git a/app/Core/Repository/PaymentBinNumber/PaymentBinNumberRepository.php b/app/Core/Repository/PaymentBinNumber/PaymentBinNumberRepository.php new file mode 100644 index 0000000..9f0d1ff --- /dev/null +++ b/app/Core/Repository/PaymentBinNumber/PaymentBinNumberRepository.php @@ -0,0 +1,19 @@ +paymentBinNumber = $paymentBinNumber; + $this->defaultModel = $this->paymentBinNumber; + } + +} diff --git a/app/Core/Repository/PaymentTransaction/PaymentTransactionRepository.php b/app/Core/Repository/PaymentTransaction/PaymentTransactionRepository.php new file mode 100644 index 0000000..2922185 --- /dev/null +++ b/app/Core/Repository/PaymentTransaction/PaymentTransactionRepository.php @@ -0,0 +1,19 @@ +paymentTransaction = $paymentTransaction; + $this->defaultModel = $this->paymentTransaction; + } + +} diff --git a/app/Core/Repository/PaymentType/PaymentTypeRepository.php b/app/Core/Repository/PaymentType/PaymentTypeRepository.php new file mode 100644 index 0000000..7ec0ae4 --- /dev/null +++ b/app/Core/Repository/PaymentType/PaymentTypeRepository.php @@ -0,0 +1,19 @@ +paymentType = $paymentType; + $this->defaultModel = $this->paymentType; + } + +} diff --git a/app/Core/Repository/Permission/PermissionRepository.php b/app/Core/Repository/Permission/PermissionRepository.php new file mode 100644 index 0000000..597c9e9 --- /dev/null +++ b/app/Core/Repository/Permission/PermissionRepository.php @@ -0,0 +1,27 @@ +permission = $permission; + $this->permissionMenuModel = $permissionMenuModel; + $this->defaultModel = $this->permission; + } + + public function permissionMenuModelFindByCriteria ( array $params ) + { + return $this->findByCriteria($this->permissionMenuModel,$params); + } + +} diff --git a/app/Core/Repository/PermissionGroup/PermissionGroupRepository.php b/app/Core/Repository/PermissionGroup/PermissionGroupRepository.php new file mode 100644 index 0000000..43c3115 --- /dev/null +++ b/app/Core/Repository/PermissionGroup/PermissionGroupRepository.php @@ -0,0 +1,19 @@ +permissionGroup = $permissionGroup; + $this->defaultModel = $this->permissionGroup; + } + +} diff --git a/app/Core/Repository/PermissionGroupMapping/PermissionGroupMappingRepository.php b/app/Core/Repository/PermissionGroupMapping/PermissionGroupMappingRepository.php new file mode 100644 index 0000000..28e35ba --- /dev/null +++ b/app/Core/Repository/PermissionGroupMapping/PermissionGroupMappingRepository.php @@ -0,0 +1,19 @@ +permissionGroupMapping = $permissionGroupMapping; + $this->defaultModel = $this->permissionGroupMapping; + } + +} diff --git a/app/Core/Repository/PermissionGroupUserMapping/PermissionGroupUserMappingRepository.php b/app/Core/Repository/PermissionGroupUserMapping/PermissionGroupUserMappingRepository.php new file mode 100644 index 0000000..c244de7 --- /dev/null +++ b/app/Core/Repository/PermissionGroupUserMapping/PermissionGroupUserMappingRepository.php @@ -0,0 +1,19 @@ +permissionGroupUserMapping = $permissionGroupUserMapping; + $this->defaultModel = $this->permissionGroupUserMapping; + } + +} diff --git a/app/Core/Repository/PhotoGoogleLabel/PhotoGoogleLabelRepository.php b/app/Core/Repository/PhotoGoogleLabel/PhotoGoogleLabelRepository.php new file mode 100644 index 0000000..1ae8d27 --- /dev/null +++ b/app/Core/Repository/PhotoGoogleLabel/PhotoGoogleLabelRepository.php @@ -0,0 +1,20 @@ +photoGoogleLabel = $photoGoogleLabel; + $this->defaultModel = $this->photoGoogleLabel; + } + +} diff --git a/app/Core/Repository/PlaceCategoryField/PlaceCategoryFieldRepository.php b/app/Core/Repository/PlaceCategoryField/PlaceCategoryFieldRepository.php new file mode 100644 index 0000000..3009903 --- /dev/null +++ b/app/Core/Repository/PlaceCategoryField/PlaceCategoryFieldRepository.php @@ -0,0 +1,19 @@ +placeCategoryField = $placeCategoryField; + $this->defaultModel = $this->placeCategoryField; + } + +} diff --git a/app/Core/Repository/PlaceCategoryFieldMapping/PlaceCategoryFieldMappingRepository.php b/app/Core/Repository/PlaceCategoryFieldMapping/PlaceCategoryFieldMappingRepository.php new file mode 100644 index 0000000..e050564 --- /dev/null +++ b/app/Core/Repository/PlaceCategoryFieldMapping/PlaceCategoryFieldMappingRepository.php @@ -0,0 +1,19 @@ +placeCategoryFieldMapping = $placeCategoryFieldMapping; + $this->defaultModel = $this->placeCategoryFieldMapping; + } + +} diff --git a/app/Core/Repository/PlaceCategoryFieldOption/PlaceCategoryFieldOptionRepository.php b/app/Core/Repository/PlaceCategoryFieldOption/PlaceCategoryFieldOptionRepository.php new file mode 100644 index 0000000..5d3be07 --- /dev/null +++ b/app/Core/Repository/PlaceCategoryFieldOption/PlaceCategoryFieldOptionRepository.php @@ -0,0 +1,19 @@ +placeCategoryFieldOption = $placeCategoryFieldOption; + $this->defaultModel = $this->placeCategoryFieldOption; + } + +} diff --git a/app/Core/Repository/PlaceCategoryFieldOptionFieldMapping/PlaceCategoryFieldOptionFieldMappingRepository.php b/app/Core/Repository/PlaceCategoryFieldOptionFieldMapping/PlaceCategoryFieldOptionFieldMappingRepository.php new file mode 100644 index 0000000..d58df22 --- /dev/null +++ b/app/Core/Repository/PlaceCategoryFieldOptionFieldMapping/PlaceCategoryFieldOptionFieldMappingRepository.php @@ -0,0 +1,19 @@ +placeCategoryFieldOptionFieldMapping = $placeCategoryFieldOptionFieldMapping; + $this->defaultModel = $this->placeCategoryFieldOptionFieldMapping; + } + +} diff --git a/app/Core/Repository/Product/ProductParameterMappingRepository.php b/app/Core/Repository/Product/ProductParameterMappingRepository.php new file mode 100644 index 0000000..478c11c --- /dev/null +++ b/app/Core/Repository/Product/ProductParameterMappingRepository.php @@ -0,0 +1,20 @@ +productParameterMapping = $productParameterMapping; + $this->defaultModel = $this->productParameterMapping; + } + +} diff --git a/app/Core/Repository/Product/ProductRepository.php b/app/Core/Repository/Product/ProductRepository.php new file mode 100644 index 0000000..76b4def --- /dev/null +++ b/app/Core/Repository/Product/ProductRepository.php @@ -0,0 +1,20 @@ +product = $product; + $this->defaultModel = $this->product; + } + +} \ No newline at end of file diff --git a/app/Core/Repository/Product/PropertyProductMappingRepository.php b/app/Core/Repository/Product/PropertyProductMappingRepository.php new file mode 100644 index 0000000..f54ad76 --- /dev/null +++ b/app/Core/Repository/Product/PropertyProductMappingRepository.php @@ -0,0 +1,20 @@ +propertyProductMapping = $propertyProductMapping; + $this->defaultModel = $this->propertyProductMapping; + } + +} \ No newline at end of file diff --git a/app/Core/Repository/PromotionType/PromotionTypeRepository.php b/app/Core/Repository/PromotionType/PromotionTypeRepository.php new file mode 100644 index 0000000..7ae03ae --- /dev/null +++ b/app/Core/Repository/PromotionType/PromotionTypeRepository.php @@ -0,0 +1,20 @@ +promotionType = $promotionType; + $this->defaultModel = $this->promotionType; + } + +} diff --git a/app/Core/Repository/Property/PropertyRepository.php b/app/Core/Repository/Property/PropertyRepository.php new file mode 100644 index 0000000..4b33f2a --- /dev/null +++ b/app/Core/Repository/Property/PropertyRepository.php @@ -0,0 +1,19 @@ +Property = $Property; + $this->defaultModel = $this->Property; + } + +} diff --git a/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoKeyRepository.php b/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoKeyRepository.php new file mode 100644 index 0000000..dca5700 --- /dev/null +++ b/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoKeyRepository.php @@ -0,0 +1,19 @@ +propertyAdditionalInfoKey = $propertyAdditionalInfoKey; + $this->defaultModel = $this->propertyAdditionalInfoKey; + } + +} diff --git a/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoRepository.php b/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoRepository.php new file mode 100644 index 0000000..6b40c18 --- /dev/null +++ b/app/Core/Repository/PropertyAdditionalInfo/PropertyAdditionalInfoRepository.php @@ -0,0 +1,19 @@ +propertyAdditionalInfo= $propertyAdditionalInfo; + $this->defaultModel = $this->propertyAdditionalInfo; + } + +} diff --git a/app/Core/Repository/PropertyAddon/PropertyAddonRepository.php b/app/Core/Repository/PropertyAddon/PropertyAddonRepository.php new file mode 100644 index 0000000..5f58ee4 --- /dev/null +++ b/app/Core/Repository/PropertyAddon/PropertyAddonRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyAddon/PropertyChannelAddonRepository.php b/app/Core/Repository/PropertyAddon/PropertyChannelAddonRepository.php new file mode 100644 index 0000000..4aa6011 --- /dev/null +++ b/app/Core/Repository/PropertyAddon/PropertyChannelAddonRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyAvailabilityType/PropertyAvailabilityTypeRepository.php b/app/Core/Repository/PropertyAvailabilityType/PropertyAvailabilityTypeRepository.php new file mode 100644 index 0000000..3031069 --- /dev/null +++ b/app/Core/Repository/PropertyAvailabilityType/PropertyAvailabilityTypeRepository.php @@ -0,0 +1,19 @@ +propertyAvailabilityType = $propertyAvailabilityType; + $this->defaultModel = $this->propertyAvailabilityType; + } + +} diff --git a/app/Core/Repository/PropertyAwardsCertificate/PropertyAwardsCertificateRepository.php b/app/Core/Repository/PropertyAwardsCertificate/PropertyAwardsCertificateRepository.php new file mode 100644 index 0000000..1c71933 --- /dev/null +++ b/app/Core/Repository/PropertyAwardsCertificate/PropertyAwardsCertificateRepository.php @@ -0,0 +1,20 @@ +propertyAwardsCertificate = $propertyAwardsCertificate; + $this->defaultModel = $this->propertyAwardsCertificate; + + } + +} diff --git a/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineRepository.php b/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineRepository.php new file mode 100644 index 0000000..0753014 --- /dev/null +++ b/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineRepository.php @@ -0,0 +1,19 @@ +propertyBookingEngine = $propertyBookingEngine; + $this->defaultModel = $this->propertyBookingEngine; + } + +} diff --git a/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineSearchRepository.php b/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineSearchRepository.php new file mode 100644 index 0000000..a1bfd0b --- /dev/null +++ b/app/Core/Repository/PropertyBookingEngine/PropertyBookingEngineSearchRepository.php @@ -0,0 +1,19 @@ +propertyBookingEngineSearch = $propertyBookingEngineSearch; + $this->defaultModel = $this->propertyBookingEngineSearch; + } + +} diff --git a/app/Core/Repository/PropertyBookingPaymentType/PropertyBookingPaymentTypeRepository.php b/app/Core/Repository/PropertyBookingPaymentType/PropertyBookingPaymentTypeRepository.php new file mode 100644 index 0000000..a106287 --- /dev/null +++ b/app/Core/Repository/PropertyBookingPaymentType/PropertyBookingPaymentTypeRepository.php @@ -0,0 +1,19 @@ +propertyBookingPaymentType = $propertyBookingPaymentType; + $this->defaultModel = $this->propertyBookingPaymentType; + } + +} diff --git a/app/Core/Repository/PropertyBookingType/PropertyBookingTypeRepository.php b/app/Core/Repository/PropertyBookingType/PropertyBookingTypeRepository.php new file mode 100644 index 0000000..3b8e41a --- /dev/null +++ b/app/Core/Repository/PropertyBookingType/PropertyBookingTypeRepository.php @@ -0,0 +1,19 @@ +propertyBookingType = $propertyBookingType; + $this->defaultModel = $this->propertyBookingType; + } + +} diff --git a/app/Core/Repository/PropertyBrand/PropertyBrandRepository.php b/app/Core/Repository/PropertyBrand/PropertyBrandRepository.php new file mode 100644 index 0000000..401f8a9 --- /dev/null +++ b/app/Core/Repository/PropertyBrand/PropertyBrandRepository.php @@ -0,0 +1,19 @@ +propertyBrand = $propertyBrand; + $this->defaultModel = $this->propertyBrand; + } + +} diff --git a/app/Core/Repository/PropertyCancellationPolicy/PropertyCancellationPolicyRepository.php b/app/Core/Repository/PropertyCancellationPolicy/PropertyCancellationPolicyRepository.php new file mode 100644 index 0000000..8bcc1d1 --- /dev/null +++ b/app/Core/Repository/PropertyCancellationPolicy/PropertyCancellationPolicyRepository.php @@ -0,0 +1,19 @@ +propertyCancellationPolicy = $propertyCancellationPolicy; + $this->defaultModel = $this->propertyCancellationPolicy; + } + +} diff --git a/app/Core/Repository/PropertyChain/PropertyChainRepository.php b/app/Core/Repository/PropertyChain/PropertyChainRepository.php new file mode 100644 index 0000000..db73184 --- /dev/null +++ b/app/Core/Repository/PropertyChain/PropertyChainRepository.php @@ -0,0 +1,20 @@ +propertyChain = $propertyChain; + $this->defaultModel = $this->propertyChain; + } + +} diff --git a/app/Core/Repository/PropertyChannel/PropertyChannelContactRepository.php b/app/Core/Repository/PropertyChannel/PropertyChannelContactRepository.php new file mode 100644 index 0000000..28441fd --- /dev/null +++ b/app/Core/Repository/PropertyChannel/PropertyChannelContactRepository.php @@ -0,0 +1,19 @@ +propertyChannelContact = $propertyChannelContact; + $this->defaultModel = $this->propertyChannelContact; + } + +} diff --git a/app/Core/Repository/PropertyChannel/PropertyChannelRepository.php b/app/Core/Repository/PropertyChannel/PropertyChannelRepository.php new file mode 100644 index 0000000..1439e51 --- /dev/null +++ b/app/Core/Repository/PropertyChannel/PropertyChannelRepository.php @@ -0,0 +1,19 @@ +propertyChannel = $propertyChannel; + $this->defaultModel = $this->propertyChannel; + } + +} diff --git a/app/Core/Repository/PropertyChannel/PropertyChannelTaxRepository.php b/app/Core/Repository/PropertyChannel/PropertyChannelTaxRepository.php new file mode 100644 index 0000000..a433ecb --- /dev/null +++ b/app/Core/Repository/PropertyChannel/PropertyChannelTaxRepository.php @@ -0,0 +1,19 @@ +propertyChannelTax = $propertyChannelTax; + $this->defaultModel = $this->propertyChannelTax; + } + +} diff --git a/app/Core/Repository/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupRepository.php b/app/Core/Repository/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupRepository.php new file mode 100644 index 0000000..7ab1092 --- /dev/null +++ b/app/Core/Repository/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupRepository.php @@ -0,0 +1,19 @@ +propertyChannelBookingPaymentSetup = $propertyChannelBookingPaymentSetup; + $this->defaultModel = $this->propertyChannelBookingPaymentSetup; + } + +} diff --git a/app/Core/Repository/PropertyChannelCategory/PropertyChannelCategoryRepository.php b/app/Core/Repository/PropertyChannelCategory/PropertyChannelCategoryRepository.php new file mode 100644 index 0000000..cd4f7e7 --- /dev/null +++ b/app/Core/Repository/PropertyChannelCategory/PropertyChannelCategoryRepository.php @@ -0,0 +1,19 @@ +propertyChannelCategory = $propertyChannelCategory; + $this->defaultModel = $this->propertyChannelCategory; + } + +} diff --git a/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupChannelMappingRepository.php b/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupChannelMappingRepository.php new file mode 100644 index 0000000..6ebeb2f --- /dev/null +++ b/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupChannelMappingRepository.php @@ -0,0 +1,19 @@ +propertyChannelGroupChannelMapping = $propertyChannelGroupChannelMapping; + $this->defaultModel = $this->propertyChannelGroupChannelMapping; + } + +} diff --git a/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupRepository.php b/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupRepository.php new file mode 100644 index 0000000..ad613a6 --- /dev/null +++ b/app/Core/Repository/PropertyChannelGroup/PropertyChannelGroupRepository.php @@ -0,0 +1,19 @@ +propertyChannelGroup = $propertyChannelGroup; + $this->defaultModel = $this->propertyChannelGroup; + } + +} diff --git a/app/Core/Repository/PropertyChannelMapping/PropertyChannelMappingRepository.php b/app/Core/Repository/PropertyChannelMapping/PropertyChannelMappingRepository.php new file mode 100644 index 0000000..461854f --- /dev/null +++ b/app/Core/Repository/PropertyChannelMapping/PropertyChannelMappingRepository.php @@ -0,0 +1,19 @@ +userPropertyMapping = $userPropertyMapping; + $this->defaultModel = $this->userPropertyMapping; + } + +} diff --git a/app/Core/Repository/PropertyChannelRoomRateCancellationPolicyMapping/PropertyChannelRoomRateCancellationPolicyMappingRepository.php b/app/Core/Repository/PropertyChannelRoomRateCancellationPolicyMapping/PropertyChannelRoomRateCancellationPolicyMappingRepository.php new file mode 100644 index 0000000..5a02c44 --- /dev/null +++ b/app/Core/Repository/PropertyChannelRoomRateCancellationPolicyMapping/PropertyChannelRoomRateCancellationPolicyMappingRepository.php @@ -0,0 +1,19 @@ +propertyChannelRoomRateCancellationPolicyMapping = $propertyChannelRoomRateCancellationPolicyMapping; + $this->defaultModel = $this->propertyChannelRoomRateCancellationPolicyMapping; + } + +} diff --git a/app/Core/Repository/PropertyChannelRoomRatePricingPolicyAdultMapping/PropertyChannelRoomRatePricingPolicyAdultMappingRepository.php b/app/Core/Repository/PropertyChannelRoomRatePricingPolicyAdultMapping/PropertyChannelRoomRatePricingPolicyAdultMappingRepository.php new file mode 100644 index 0000000..7ecf2aa --- /dev/null +++ b/app/Core/Repository/PropertyChannelRoomRatePricingPolicyAdultMapping/PropertyChannelRoomRatePricingPolicyAdultMappingRepository.php @@ -0,0 +1,19 @@ +propertyChannelRoomRatePricingPolicyAdultMapping = $propertyChannelRoomRatePricingPolicyAdultMapping; + $this->defaultModel = $this->propertyChannelRoomRatePricingPolicyAdultMapping; + } + +} diff --git a/app/Core/Repository/PropertyChannelRoomRatePricingPolicyChildMapping/PropertyChannelRoomRatePricingPolicyChildMappingRepository.php b/app/Core/Repository/PropertyChannelRoomRatePricingPolicyChildMapping/PropertyChannelRoomRatePricingPolicyChildMappingRepository.php new file mode 100644 index 0000000..14a0a6d --- /dev/null +++ b/app/Core/Repository/PropertyChannelRoomRatePricingPolicyChildMapping/PropertyChannelRoomRatePricingPolicyChildMappingRepository.php @@ -0,0 +1,19 @@ +propertyChannelRoomRatePricingPolicyChildMapping = $propertyChannelRoomRatePricingPolicyChildMapping; + $this->defaultModel = $this->propertyChannelRoomRatePricingPolicyChildMapping; + } + +} diff --git a/app/Core/Repository/PropertyCompetitorGroup/PropertyCompetitorGroupRepository.php b/app/Core/Repository/PropertyCompetitorGroup/PropertyCompetitorGroupRepository.php new file mode 100644 index 0000000..42b527c --- /dev/null +++ b/app/Core/Repository/PropertyCompetitorGroup/PropertyCompetitorGroupRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyCompetitorGroupMapping/PropertyCompetitorGroupMappingRepository.php b/app/Core/Repository/PropertyCompetitorGroupMapping/PropertyCompetitorGroupMappingRepository.php new file mode 100644 index 0000000..c77c1bb --- /dev/null +++ b/app/Core/Repository/PropertyCompetitorGroupMapping/PropertyCompetitorGroupMappingRepository.php @@ -0,0 +1,18 @@ +model = $model; + $this->defaultModel = $this->model; + } +} diff --git a/app/Core/Repository/PropertyCompetitorMapping/PropertyCompetitorMappingRepository.php b/app/Core/Repository/PropertyCompetitorMapping/PropertyCompetitorMappingRepository.php new file mode 100644 index 0000000..8eaba2b --- /dev/null +++ b/app/Core/Repository/PropertyCompetitorMapping/PropertyCompetitorMappingRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyConfig/PropertyConfigRepository.php b/app/Core/Repository/PropertyConfig/PropertyConfigRepository.php new file mode 100644 index 0000000..bad326c --- /dev/null +++ b/app/Core/Repository/PropertyConfig/PropertyConfigRepository.php @@ -0,0 +1,19 @@ +propertyConfig = $propertyConfig; + $this->defaultModel = $this->propertyConfig; + } + +} diff --git a/app/Core/Repository/PropertyContact/PropertyContactRepository.php b/app/Core/Repository/PropertyContact/PropertyContactRepository.php new file mode 100644 index 0000000..961fb3b --- /dev/null +++ b/app/Core/Repository/PropertyContact/PropertyContactRepository.php @@ -0,0 +1,19 @@ +propertyContact = $propertyContact; + $this->defaultModel = $this->propertyContact; + } + +} diff --git a/app/Core/Repository/PropertyContent/PropertyContentRepository.php b/app/Core/Repository/PropertyContent/PropertyContentRepository.php new file mode 100644 index 0000000..380742d --- /dev/null +++ b/app/Core/Repository/PropertyContent/PropertyContentRepository.php @@ -0,0 +1,19 @@ +propertyContent = $propertyContent; + $this->defaultModel = $this->propertyContent; + } + +} diff --git a/app/Core/Repository/PropertyContentCategory/PropertyContentCategoryRepository.php b/app/Core/Repository/PropertyContentCategory/PropertyContentCategoryRepository.php new file mode 100644 index 0000000..38374d2 --- /dev/null +++ b/app/Core/Repository/PropertyContentCategory/PropertyContentCategoryRepository.php @@ -0,0 +1,19 @@ +propertyContentCategory = $propertyContentCategory; + $this->defaultModel = $this->propertyContentCategory; + } + +} diff --git a/app/Core/Repository/PropertyExecutive/PropertyExecutiveRepository.php b/app/Core/Repository/PropertyExecutive/PropertyExecutiveRepository.php new file mode 100644 index 0000000..31f4903 --- /dev/null +++ b/app/Core/Repository/PropertyExecutive/PropertyExecutiveRepository.php @@ -0,0 +1,19 @@ +propertyExecutive = $propertyExecutive; + $this->defaultModel = $this->propertyExecutive; + } + +} diff --git a/app/Core/Repository/PropertyExecutiveType/PropertyExecutiveTypeRepository.php b/app/Core/Repository/PropertyExecutiveType/PropertyExecutiveTypeRepository.php new file mode 100644 index 0000000..fd6a3cf --- /dev/null +++ b/app/Core/Repository/PropertyExecutiveType/PropertyExecutiveTypeRepository.php @@ -0,0 +1,19 @@ +propertyExecutiveType = $propertyExecutiveType; + $this->defaultModel = $this->propertyExecutiveType; + } + +} diff --git a/app/Core/Repository/PropertyFact/PropertyFactRepository.php b/app/Core/Repository/PropertyFact/PropertyFactRepository.php new file mode 100644 index 0000000..0ca5ce6 --- /dev/null +++ b/app/Core/Repository/PropertyFact/PropertyFactRepository.php @@ -0,0 +1,19 @@ +propertyFact = $propertyFact; + $this->defaultModel = $this->propertyFact; + } + +} diff --git a/app/Core/Repository/PropertyFactAttribute/PropertyFactAttributeRepository.php b/app/Core/Repository/PropertyFactAttribute/PropertyFactAttributeRepository.php new file mode 100644 index 0000000..ce68f47 --- /dev/null +++ b/app/Core/Repository/PropertyFactAttribute/PropertyFactAttributeRepository.php @@ -0,0 +1,19 @@ +propertyFactAttribute = $propertyFactAttribute; + $this->defaultModel = $this->propertyFactAttribute; + } + +} diff --git a/app/Core/Repository/PropertyFactMapping/PropertyFactMappingRepository.php b/app/Core/Repository/PropertyFactMapping/PropertyFactMappingRepository.php new file mode 100644 index 0000000..d474caf --- /dev/null +++ b/app/Core/Repository/PropertyFactMapping/PropertyFactMappingRepository.php @@ -0,0 +1,19 @@ +propertyFactMapping = $propertyFactMapping; + $this->defaultModel = $this->propertyFactMapping; + } + +} diff --git a/app/Core/Repository/PropertyGroup/PropertyGroupRepository.php b/app/Core/Repository/PropertyGroup/PropertyGroupRepository.php new file mode 100644 index 0000000..adf1959 --- /dev/null +++ b/app/Core/Repository/PropertyGroup/PropertyGroupRepository.php @@ -0,0 +1,19 @@ +propertyGroup = $propertyGroup; + $this->defaultModel = $this->propertyGroup; + } + +} diff --git a/app/Core/Repository/PropertyGroupMapping/PropertyGroupMappingRepository.php b/app/Core/Repository/PropertyGroupMapping/PropertyGroupMappingRepository.php new file mode 100644 index 0000000..17e52e0 --- /dev/null +++ b/app/Core/Repository/PropertyGroupMapping/PropertyGroupMappingRepository.php @@ -0,0 +1,19 @@ +propertyGroupMapping = $propertyGroupMapping; + $this->defaultModel = $this->propertyGroupMapping; + } + +} diff --git a/app/Core/Repository/PropertyInvoice/PropertyInvoiceRepository.php b/app/Core/Repository/PropertyInvoice/PropertyInvoiceRepository.php new file mode 100644 index 0000000..9419ade --- /dev/null +++ b/app/Core/Repository/PropertyInvoice/PropertyInvoiceRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyLanguageSpoken/PropertyLanguageSpokenRepository.php b/app/Core/Repository/PropertyLanguageSpoken/PropertyLanguageSpokenRepository.php new file mode 100644 index 0000000..a762760 --- /dev/null +++ b/app/Core/Repository/PropertyLanguageSpoken/PropertyLanguageSpokenRepository.php @@ -0,0 +1,19 @@ +PropertyLanguageSpoken = $PropertyLanguageSpoken; + $this->defaultModel = $this->PropertyLanguageSpoken; + } + +} diff --git a/app/Core/Repository/PropertyModule/PropertyModuleRepository.php b/app/Core/Repository/PropertyModule/PropertyModuleRepository.php new file mode 100644 index 0000000..95f7723 --- /dev/null +++ b/app/Core/Repository/PropertyModule/PropertyModuleRepository.php @@ -0,0 +1,20 @@ +propertyModule = $propertyModule; + $this->defaultModel = $this->propertyModule; + } + +} diff --git a/app/Core/Repository/PropertyModuleMapping/PropertyModuleMappingRepository.php b/app/Core/Repository/PropertyModuleMapping/PropertyModuleMappingRepository.php new file mode 100644 index 0000000..b2d7322 --- /dev/null +++ b/app/Core/Repository/PropertyModuleMapping/PropertyModuleMappingRepository.php @@ -0,0 +1,20 @@ +propertyModuleMapping = $propertyModuleMapping; + $this->defaultModel = $this->propertyModuleMapping; + } + +} diff --git a/app/Core/Repository/PropertyNonrefundable/PropertyNonrefundableRepository.php b/app/Core/Repository/PropertyNonrefundable/PropertyNonrefundableRepository.php new file mode 100644 index 0000000..770bdbd --- /dev/null +++ b/app/Core/Repository/PropertyNonrefundable/PropertyNonrefundableRepository.php @@ -0,0 +1,19 @@ +propertyNonrefundable = $propertyNonrefundable; + $this->defaultModel = $this->propertyNonrefundable; + } + +} diff --git a/app/Core/Repository/PropertyPaymentInstallment/PropertyPaymentInstallmentRepository.php b/app/Core/Repository/PropertyPaymentInstallment/PropertyPaymentInstallmentRepository.php new file mode 100644 index 0000000..09a9f92 --- /dev/null +++ b/app/Core/Repository/PropertyPaymentInstallment/PropertyPaymentInstallmentRepository.php @@ -0,0 +1,19 @@ +propertyPaymentInstallment = $propertyPaymentInstallment; + $this->defaultModel = $this->propertyPaymentInstallment; + } + +} diff --git a/app/Core/Repository/PropertyPaymentMapping/PropertyPaymentMappingRepository.php b/app/Core/Repository/PropertyPaymentMapping/PropertyPaymentMappingRepository.php new file mode 100644 index 0000000..dc0cf1c --- /dev/null +++ b/app/Core/Repository/PropertyPaymentMapping/PropertyPaymentMappingRepository.php @@ -0,0 +1,19 @@ +propertyPaymentMapping = $propertyPaymentMapping; + $this->defaultModel = $this->propertyPaymentMapping; + } + +} diff --git a/app/Core/Repository/PropertyPhoto/PropertyPhotoRepository.php b/app/Core/Repository/PropertyPhoto/PropertyPhotoRepository.php new file mode 100644 index 0000000..1f2015e --- /dev/null +++ b/app/Core/Repository/PropertyPhoto/PropertyPhotoRepository.php @@ -0,0 +1,20 @@ +propertyPhoto = $propertyPhoto; + $this->defaultModel = $this->propertyPhoto; + } + +} diff --git a/app/Core/Repository/PropertyPhotoCategory/PropertyPhotoCategoryRepository.php b/app/Core/Repository/PropertyPhotoCategory/PropertyPhotoCategoryRepository.php new file mode 100644 index 0000000..e2677d1 --- /dev/null +++ b/app/Core/Repository/PropertyPhotoCategory/PropertyPhotoCategoryRepository.php @@ -0,0 +1,20 @@ +propertyPhotoCategory = $propertyPhotoCategory; + $this->defaultModel = $this->propertyPhotoCategory; + } + +} diff --git a/app/Core/Repository/PropertyPhotoCategoryLabelMapping/PropertyPhotoCategoryLabelMappingRepository.php b/app/Core/Repository/PropertyPhotoCategoryLabelMapping/PropertyPhotoCategoryLabelMappingRepository.php new file mode 100644 index 0000000..529bbfe --- /dev/null +++ b/app/Core/Repository/PropertyPhotoCategoryLabelMapping/PropertyPhotoCategoryLabelMappingRepository.php @@ -0,0 +1,20 @@ +propertyPhotoCategoryLabelMapping = $propertyPhotoCategoryLabelMapping; + $this->defaultModel = $this->propertyPhotoCategoryLabelMapping; + } + +} diff --git a/app/Core/Repository/PropertyPlace/PropertyPlaceRepository.php b/app/Core/Repository/PropertyPlace/PropertyPlaceRepository.php new file mode 100644 index 0000000..da786e0 --- /dev/null +++ b/app/Core/Repository/PropertyPlace/PropertyPlaceRepository.php @@ -0,0 +1,19 @@ +propertyPlace = $propertyPlace; + $this->defaultModel = $this->propertyPlace; + } + +} diff --git a/app/Core/Repository/PropertyPlaceCategory/PropertyPlaceCategoryRepository.php b/app/Core/Repository/PropertyPlaceCategory/PropertyPlaceCategoryRepository.php new file mode 100644 index 0000000..76e21c2 --- /dev/null +++ b/app/Core/Repository/PropertyPlaceCategory/PropertyPlaceCategoryRepository.php @@ -0,0 +1,19 @@ +propertyPlaceCategory = $propertyPlaceCategory; + $this->defaultModel = $this->propertyPlaceCategory; + } + +} diff --git a/app/Core/Repository/PropertyPlaceCategoryFieldValue/PropertyPlaceCategoryFieldValueRepository.php b/app/Core/Repository/PropertyPlaceCategoryFieldValue/PropertyPlaceCategoryFieldValueRepository.php new file mode 100644 index 0000000..4b88389 --- /dev/null +++ b/app/Core/Repository/PropertyPlaceCategoryFieldValue/PropertyPlaceCategoryFieldValueRepository.php @@ -0,0 +1,19 @@ +propertyPlaceCategoryFieldValue = $propertyPlaceCategoryFieldValue; + $this->defaultModel = $this->propertyPlaceCategoryFieldValue; + } + +} diff --git a/app/Core/Repository/PropertyPlaceFact/PropertyPlaceFactRepository.php b/app/Core/Repository/PropertyPlaceFact/PropertyPlaceFactRepository.php new file mode 100644 index 0000000..310cf83 --- /dev/null +++ b/app/Core/Repository/PropertyPlaceFact/PropertyPlaceFactRepository.php @@ -0,0 +1,19 @@ +propertyPlaceFact = $propertyPlaceFact; + $this->defaultModel = $this->propertyPlaceFact; + } + +} diff --git a/app/Core/Repository/PropertyPlaceFactMapping/PropertyPlaceFactMappingRepository.php b/app/Core/Repository/PropertyPlaceFactMapping/PropertyPlaceFactMappingRepository.php new file mode 100644 index 0000000..044eb9b --- /dev/null +++ b/app/Core/Repository/PropertyPlaceFactMapping/PropertyPlaceFactMappingRepository.php @@ -0,0 +1,19 @@ +propertyPlaceFactMapping = $propertyPlaceFactMapping; + $this->defaultModel = $this->propertyPlaceFactMapping; + } + +} diff --git a/app/Core/Repository/PropertyPlaceFactTitle/PropertyPlaceFactTitleRepository.php b/app/Core/Repository/PropertyPlaceFactTitle/PropertyPlaceFactTitleRepository.php new file mode 100644 index 0000000..877981f --- /dev/null +++ b/app/Core/Repository/PropertyPlaceFactTitle/PropertyPlaceFactTitleRepository.php @@ -0,0 +1,19 @@ +propertyPlaceFactTitle = $propertyPlaceFactTitle; + $this->defaultModel = $this->propertyPlaceFactTitle; + } + +} diff --git a/app/Core/Repository/PropertyPlaceFactTitleFactMapping/PropertyPlaceFactTitleFactMappingRepository.php b/app/Core/Repository/PropertyPlaceFactTitleFactMapping/PropertyPlaceFactTitleFactMappingRepository.php new file mode 100644 index 0000000..3f6100c --- /dev/null +++ b/app/Core/Repository/PropertyPlaceFactTitleFactMapping/PropertyPlaceFactTitleFactMappingRepository.php @@ -0,0 +1,19 @@ +propertyPlaceFactTitleFactMapping = $propertyPlaceFactTitleFactMapping; + $this->defaultModel = $this->propertyPlaceFactTitleFactMapping; + } + +} diff --git a/app/Core/Repository/PropertyPlacePhotoMapping/PropertyPlacePhotoMappingRepository.php b/app/Core/Repository/PropertyPlacePhotoMapping/PropertyPlacePhotoMappingRepository.php new file mode 100644 index 0000000..a32bda5 --- /dev/null +++ b/app/Core/Repository/PropertyPlacePhotoMapping/PropertyPlacePhotoMappingRepository.php @@ -0,0 +1,19 @@ +propertyPlacePhotoMapping = $propertyPlacePhotoMapping; + $this->defaultModel = $this->propertyPlacePhotoMapping; + } + +} diff --git a/app/Core/Repository/PropertyPlaceWorkingHour/PropertyPlaceWorkingHourRepository.php b/app/Core/Repository/PropertyPlaceWorkingHour/PropertyPlaceWorkingHourRepository.php new file mode 100644 index 0000000..b1c18c6 --- /dev/null +++ b/app/Core/Repository/PropertyPlaceWorkingHour/PropertyPlaceWorkingHourRepository.php @@ -0,0 +1,19 @@ +propertyPlaceWorkingHour = $propertyPlaceWorkingHour; + $this->defaultModel = $this->propertyPlaceWorkingHour; + } + +} diff --git a/app/Core/Repository/PropertyPricingPolicyAdult/PropertyPricingPolicyAdultRepository.php b/app/Core/Repository/PropertyPricingPolicyAdult/PropertyPricingPolicyAdultRepository.php new file mode 100644 index 0000000..0fac2d9 --- /dev/null +++ b/app/Core/Repository/PropertyPricingPolicyAdult/PropertyPricingPolicyAdultRepository.php @@ -0,0 +1,19 @@ +propertyPricingPolicyAdult = $propertyPricingPolicyAdult; + $this->defaultModel = $this->propertyPricingPolicyAdult; + } + +} diff --git a/app/Core/Repository/PropertyPricingPolicyChild/PropertyPricingPolicyChildRepository.php b/app/Core/Repository/PropertyPricingPolicyChild/PropertyPricingPolicyChildRepository.php new file mode 100644 index 0000000..bbe406d --- /dev/null +++ b/app/Core/Repository/PropertyPricingPolicyChild/PropertyPricingPolicyChildRepository.php @@ -0,0 +1,19 @@ +propertyPricingPolicyChild = $propertyPricingPolicyChild; + $this->defaultModel = $this->propertyPricingPolicyChild; + } + +} diff --git a/app/Core/Repository/PropertyPromotion/PropertyPromotionRepository.php b/app/Core/Repository/PropertyPromotion/PropertyPromotionRepository.php new file mode 100644 index 0000000..41356f5 --- /dev/null +++ b/app/Core/Repository/PropertyPromotion/PropertyPromotionRepository.php @@ -0,0 +1,20 @@ +propertyPromotion = $propertyPromotion; + $this->defaultModel = $this->propertyPromotion; + } + +} diff --git a/app/Core/Repository/PropertyPromotionMapping/PropertyPromotionMappingRepository.php b/app/Core/Repository/PropertyPromotionMapping/PropertyPromotionMappingRepository.php new file mode 100644 index 0000000..3a9b6ab --- /dev/null +++ b/app/Core/Repository/PropertyPromotionMapping/PropertyPromotionMappingRepository.php @@ -0,0 +1,20 @@ +propertyPromotionMapping = $propertyPromotionMapping; + $this->defaultModel = $this->propertyPromotionMapping; + } + +} diff --git a/app/Core/Repository/PropertyQuickPricingMapping/PropertyQuickPricingMappingRepository.php b/app/Core/Repository/PropertyQuickPricingMapping/PropertyQuickPricingMappingRepository.php new file mode 100644 index 0000000..78a38f9 --- /dev/null +++ b/app/Core/Repository/PropertyQuickPricingMapping/PropertyQuickPricingMappingRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyRoom/PropertyRoomRepository.php b/app/Core/Repository/PropertyRoom/PropertyRoomRepository.php new file mode 100644 index 0000000..281ba77 --- /dev/null +++ b/app/Core/Repository/PropertyRoom/PropertyRoomRepository.php @@ -0,0 +1,19 @@ +propertyRoom = $propertyRoom; + $this->defaultModel = $this->propertyRoom; + } + +} diff --git a/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityQueueRepository.php b/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityQueueRepository.php new file mode 100644 index 0000000..8c4b782 --- /dev/null +++ b/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityQueueRepository.php @@ -0,0 +1,19 @@ +propertyRoomAvailabilityQueue = $propertyRoomAvailabilityQueue; + $this->defaultModel = $this->propertyRoomAvailabilityQueue; + } + +} diff --git a/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityRepository.php b/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityRepository.php new file mode 100644 index 0000000..a2267ba --- /dev/null +++ b/app/Core/Repository/PropertyRoomAvailability/PropertyRoomAvailabilityRepository.php @@ -0,0 +1,19 @@ +propertyRoomAvailability = $propertyRoomAvailability; + $this->defaultModel = $this->propertyRoomAvailability; + } + +} diff --git a/app/Core/Repository/PropertyRoomBed/PropertyRoomBedRepository.php b/app/Core/Repository/PropertyRoomBed/PropertyRoomBedRepository.php new file mode 100644 index 0000000..1acc1c2 --- /dev/null +++ b/app/Core/Repository/PropertyRoomBed/PropertyRoomBedRepository.php @@ -0,0 +1,19 @@ +propertyRoomBed = $propertyRoomBed; + $this->defaultModel = $this->propertyRoomBed; + } + +} diff --git a/app/Core/Repository/PropertyRoomBedType/PropertyRoomBedTypeRepository.php b/app/Core/Repository/PropertyRoomBedType/PropertyRoomBedTypeRepository.php new file mode 100644 index 0000000..be50f15 --- /dev/null +++ b/app/Core/Repository/PropertyRoomBedType/PropertyRoomBedTypeRepository.php @@ -0,0 +1,19 @@ +propertyRoomBedType = $propertyRoomBedType; + $this->defaultModel = $this->propertyRoomBedType; + } + +} diff --git a/app/Core/Repository/PropertyRoomConnected/PropertyRoomConnectedRepository.php b/app/Core/Repository/PropertyRoomConnected/PropertyRoomConnectedRepository.php new file mode 100644 index 0000000..6d0fb12 --- /dev/null +++ b/app/Core/Repository/PropertyRoomConnected/PropertyRoomConnectedRepository.php @@ -0,0 +1,19 @@ +propertyRoomConnected = $propertyRoomConnected; + $this->defaultModel = $this->propertyRoomConnected; + } + +} diff --git a/app/Core/Repository/PropertyRoomFactMapping/PropertyRoomFactMappingRepository.php b/app/Core/Repository/PropertyRoomFactMapping/PropertyRoomFactMappingRepository.php new file mode 100644 index 0000000..82cb310 --- /dev/null +++ b/app/Core/Repository/PropertyRoomFactMapping/PropertyRoomFactMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomFactMapping = $propertyRoomFactMapping; + $this->defaultModel = $this->propertyRoomFactMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomPhotoMapping/PropertyRoomPhotoMappingRepository.php b/app/Core/Repository/PropertyRoomPhotoMapping/PropertyRoomPhotoMappingRepository.php new file mode 100644 index 0000000..66545e7 --- /dev/null +++ b/app/Core/Repository/PropertyRoomPhotoMapping/PropertyRoomPhotoMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomPhotoMapping = $propertyRoomPhotoMapping; + $this->defaultModel = $this->propertyRoomPhotoMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomPricingType/PropertyRoomPricingTypeRepository.php b/app/Core/Repository/PropertyRoomPricingType/PropertyRoomPricingTypeRepository.php new file mode 100644 index 0000000..f7352ff --- /dev/null +++ b/app/Core/Repository/PropertyRoomPricingType/PropertyRoomPricingTypeRepository.php @@ -0,0 +1,19 @@ +propertyRoomPricingType = $propertyRoomPricingType; + $this->defaultModel = $this->propertyRoomPricingType; + } + +} diff --git a/app/Core/Repository/PropertyRoomRate/PropertyRoomRateRepository.php b/app/Core/Repository/PropertyRoomRate/PropertyRoomRateRepository.php new file mode 100644 index 0000000..5dd8cbb --- /dev/null +++ b/app/Core/Repository/PropertyRoomRate/PropertyRoomRateRepository.php @@ -0,0 +1,19 @@ +propertyRoomRate = $propertyRoomRate; + $this->defaultModel = $this->propertyRoomRate; + } + +} diff --git a/app/Core/Repository/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingRepository.php b/app/Core/Repository/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingRepository.php new file mode 100644 index 0000000..cae8c67 --- /dev/null +++ b/app/Core/Repository/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping; + $this->defaultModel = $this->propertyRoomRateChannelMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingRepository.php b/app/Core/Repository/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingRepository.php new file mode 100644 index 0000000..bb399f9 --- /dev/null +++ b/app/Core/Repository/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomRateInclusionMapping = $propertyRoomRateInclusionMapping; + $this->defaultModel = $this->propertyRoomRateInclusionMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomRateMapping/PropertyRoomRateMappingRepository.php b/app/Core/Repository/PropertyRoomRateMapping/PropertyRoomRateMappingRepository.php new file mode 100644 index 0000000..2e89d5a --- /dev/null +++ b/app/Core/Repository/PropertyRoomRateMapping/PropertyRoomRateMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomRateMapping = $propertyRoomRateMapping; + $this->defaultModel = $this->propertyRoomRateMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupRepository.php b/app/Core/Repository/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupRepository.php new file mode 100644 index 0000000..f9ce3ce --- /dev/null +++ b/app/Core/Repository/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupRepository.php @@ -0,0 +1,19 @@ +propertyRoomRateMappingSetup = $propertyRoomRateMappingSetup; + $this->defaultModel = $this->propertyRoomRateMappingSetup; + } + +} diff --git a/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceQueueRepository.php b/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceQueueRepository.php new file mode 100644 index 0000000..427cd50 --- /dev/null +++ b/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceQueueRepository.php @@ -0,0 +1,19 @@ +propertyRoomRatePriceQueue = $propertyRoomRatePriceQueue; + $this->defaultModel = $this->propertyRoomRatePriceQueue; + } + +} diff --git a/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceRepository.php b/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceRepository.php new file mode 100644 index 0000000..b1adfb0 --- /dev/null +++ b/app/Core/Repository/PropertyRoomRatePrice/PropertyRoomRatePriceRepository.php @@ -0,0 +1,19 @@ +propertyRoomRatePrice = $propertyRoomRatePrice; + $this->defaultModel = $this->propertyRoomRatePrice; + } + +} diff --git a/app/Core/Repository/PropertyRoomSizeType/PropertyRoomSizeTypeRepository.php b/app/Core/Repository/PropertyRoomSizeType/PropertyRoomSizeTypeRepository.php new file mode 100644 index 0000000..cd07732 --- /dev/null +++ b/app/Core/Repository/PropertyRoomSizeType/PropertyRoomSizeTypeRepository.php @@ -0,0 +1,20 @@ +propertyRoomSizeType = $propertyRoomSizeType; + $this->defaultModel = $this->propertyRoomSizeType; + } + +} diff --git a/app/Core/Repository/PropertyRoomType/PropertyRoomTypeRepository.php b/app/Core/Repository/PropertyRoomType/PropertyRoomTypeRepository.php new file mode 100644 index 0000000..3e18246 --- /dev/null +++ b/app/Core/Repository/PropertyRoomType/PropertyRoomTypeRepository.php @@ -0,0 +1,19 @@ +propertyRoomType = $propertyRoomType; + $this->defaultModel = $this->propertyRoomType; + } + +} diff --git a/app/Core/Repository/PropertyRoomViewMapping/PropertyRoomViewMappingRepository.php b/app/Core/Repository/PropertyRoomViewMapping/PropertyRoomViewMappingRepository.php new file mode 100644 index 0000000..ea59fcb --- /dev/null +++ b/app/Core/Repository/PropertyRoomViewMapping/PropertyRoomViewMappingRepository.php @@ -0,0 +1,19 @@ +propertyRoomViewMapping = $propertyRoomViewMapping; + $this->defaultModel = $this->propertyRoomViewMapping; + } + +} diff --git a/app/Core/Repository/PropertyRoomViewType/PropertyRoomViewTypeRepository.php b/app/Core/Repository/PropertyRoomViewType/PropertyRoomViewTypeRepository.php new file mode 100644 index 0000000..063522b --- /dev/null +++ b/app/Core/Repository/PropertyRoomViewType/PropertyRoomViewTypeRepository.php @@ -0,0 +1,20 @@ +propertyRoomViewType = $propertyRoomViewType; + $this->defaultModel = $this->propertyRoomViewType; + } + +} diff --git a/app/Core/Repository/PropertySummary/PropertySummaryRepository.php b/app/Core/Repository/PropertySummary/PropertySummaryRepository.php new file mode 100644 index 0000000..50fbdbc --- /dev/null +++ b/app/Core/Repository/PropertySummary/PropertySummaryRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyType/PropertyTypeRepository.php b/app/Core/Repository/PropertyType/PropertyTypeRepository.php new file mode 100644 index 0000000..3af30f4 --- /dev/null +++ b/app/Core/Repository/PropertyType/PropertyTypeRepository.php @@ -0,0 +1,20 @@ +propertyType = $propertyType; + $this->defaultModel = $this->propertyType; + } + +} diff --git a/app/Core/Repository/PropertyUnit/PropertyUnitRepository.php b/app/Core/Repository/PropertyUnit/PropertyUnitRepository.php new file mode 100644 index 0000000..483b376 --- /dev/null +++ b/app/Core/Repository/PropertyUnit/PropertyUnitRepository.php @@ -0,0 +1,19 @@ +propertyUnit = $propertyUnit; + $this->defaultModel = $this->propertyUnit; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebComponentMappingRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebComponentMappingRepository.php new file mode 100644 index 0000000..f72d039 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebComponentMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebComponentMapping = $propertyWebComponentMapping; + $this->defaultModel = $this->propertyWebComponentMapping; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebComponentRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebComponentRepository.php new file mode 100644 index 0000000..d2793b6 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebComponentRepository.php @@ -0,0 +1,19 @@ +propertyWebComponent = $propertyWebComponent; + $this->defaultModel = $this->propertyWebComponent; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebGroupRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebGroupRepository.php new file mode 100644 index 0000000..cb83ad7 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebGroupRepository.php @@ -0,0 +1,19 @@ +propertyWebGroup = $propertyWebGroup; + $this->defaultModel = $this->propertyWebGroup; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebMetaMappingRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebMetaMappingRepository.php new file mode 100644 index 0000000..17c6c06 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebMetaMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebMetaMapping = $propertyWebMetaMapping; + $this->defaultModel = $this->propertyWebMetaMapping; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebMetaRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebMetaRepository.php new file mode 100644 index 0000000..bf8051a --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebMetaRepository.php @@ -0,0 +1,19 @@ +propertyWebMeta = $propertyWebMeta; + $this->defaultModel = $this->propertyWebMeta; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebMetaTagRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebMetaTagRepository.php new file mode 100644 index 0000000..c7e18d4 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebMetaTagRepository.php @@ -0,0 +1,19 @@ +propertyWebMetaTag = $propertyWebMetaTag; + $this->defaultModel = $this->propertyWebMetaTag; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebRepository.php new file mode 100644 index 0000000..cc5aed8 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebRepository.php @@ -0,0 +1,19 @@ +propertyWeb = $propertyWeb; + $this->defaultModel = $this->propertyWeb; + } + +} diff --git a/app/Core/Repository/PropertyWeb/PropertyWebReviewRepository.php b/app/Core/Repository/PropertyWeb/PropertyWebReviewRepository.php new file mode 100644 index 0000000..1203780 --- /dev/null +++ b/app/Core/Repository/PropertyWeb/PropertyWebReviewRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyWebAboutUs/PropertyWebAboutUsRepository.php b/app/Core/Repository/PropertyWebAboutUs/PropertyWebAboutUsRepository.php new file mode 100644 index 0000000..da5cb92 --- /dev/null +++ b/app/Core/Repository/PropertyWebAboutUs/PropertyWebAboutUsRepository.php @@ -0,0 +1,18 @@ +propertyWebAboutUs = $propertyWebAboutUs; + $this->defaultModel = $this->propertyWebAboutUs; + } + +} diff --git a/app/Core/Repository/PropertyWebColorMapping/PropertyWebColorMappingRepository.php b/app/Core/Repository/PropertyWebColorMapping/PropertyWebColorMappingRepository.php new file mode 100644 index 0000000..a24c127 --- /dev/null +++ b/app/Core/Repository/PropertyWebColorMapping/PropertyWebColorMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebColorMapping = $propertyWebColorMapping; + $this->defaultModel = $this->propertyWebColorMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebContent/PropertyWebContentCategoryRepository.php b/app/Core/Repository/PropertyWebContent/PropertyWebContentCategoryRepository.php new file mode 100644 index 0000000..e6c6e7a --- /dev/null +++ b/app/Core/Repository/PropertyWebContent/PropertyWebContentCategoryRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyWebContent/PropertyWebContentRepository.php b/app/Core/Repository/PropertyWebContent/PropertyWebContentRepository.php new file mode 100644 index 0000000..321d460 --- /dev/null +++ b/app/Core/Repository/PropertyWebContent/PropertyWebContentRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyWebLanguageMapping/PropertyWebLanguageMappingRepository.php b/app/Core/Repository/PropertyWebLanguageMapping/PropertyWebLanguageMappingRepository.php new file mode 100644 index 0000000..e7f3b82 --- /dev/null +++ b/app/Core/Repository/PropertyWebLanguageMapping/PropertyWebLanguageMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebLanguageMapping = $propertyWebLanguageMapping; + $this->defaultModel = $this->propertyWebLanguageMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebLog/PropertyWebLogRepository.php b/app/Core/Repository/PropertyWebLog/PropertyWebLogRepository.php new file mode 100644 index 0000000..ec64dab --- /dev/null +++ b/app/Core/Repository/PropertyWebLog/PropertyWebLogRepository.php @@ -0,0 +1,19 @@ +propertyWebLog = $propertyWebLog; + $this->defaultModel = $this->propertyWebLog; + } + +} diff --git a/app/Core/Repository/PropertyWebMenu/PropertyWebMenuRepository.php b/app/Core/Repository/PropertyWebMenu/PropertyWebMenuRepository.php new file mode 100644 index 0000000..2123b78 --- /dev/null +++ b/app/Core/Repository/PropertyWebMenu/PropertyWebMenuRepository.php @@ -0,0 +1,19 @@ +propertyWebMenu = $propertyWebMenu; + $this->defaultModel = $this->propertyWebMenu; + } + +} diff --git a/app/Core/Repository/PropertyWebMenuMapping/PropertyWebMenuMappingRepository.php b/app/Core/Repository/PropertyWebMenuMapping/PropertyWebMenuMappingRepository.php new file mode 100644 index 0000000..884c3db --- /dev/null +++ b/app/Core/Repository/PropertyWebMenuMapping/PropertyWebMenuMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebMenuMapping = $propertyWebMenuMapping; + $this->defaultModel = $this->propertyWebMenuMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebPhotoMapping/PropertyWebPhotoMappingRepository.php b/app/Core/Repository/PropertyWebPhotoMapping/PropertyWebPhotoMappingRepository.php new file mode 100644 index 0000000..4456526 --- /dev/null +++ b/app/Core/Repository/PropertyWebPhotoMapping/PropertyWebPhotoMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebPhotoMapping = $propertyWebPhotoMapping; + $this->defaultModel = $this->propertyWebPhotoMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebPlaceMapping/PropertyWebPlaceMappingRepository.php b/app/Core/Repository/PropertyWebPlaceMapping/PropertyWebPlaceMappingRepository.php new file mode 100644 index 0000000..54c6458 --- /dev/null +++ b/app/Core/Repository/PropertyWebPlaceMapping/PropertyWebPlaceMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebPlaceMapping = $propertyWebPlaceMapping; + $this->defaultModel = $this->propertyWebPlaceMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebPopup/PropertyWebPopupRepository.php b/app/Core/Repository/PropertyWebPopup/PropertyWebPopupRepository.php new file mode 100644 index 0000000..3009d54 --- /dev/null +++ b/app/Core/Repository/PropertyWebPopup/PropertyWebPopupRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/PropertyWebRoomMapping/PropertyWebRoomMappingRepository.php b/app/Core/Repository/PropertyWebRoomMapping/PropertyWebRoomMappingRepository.php new file mode 100644 index 0000000..510eeab --- /dev/null +++ b/app/Core/Repository/PropertyWebRoomMapping/PropertyWebRoomMappingRepository.php @@ -0,0 +1,19 @@ +propertyWebRoomMapping = $propertyWebRoomMapping; + $this->defaultModel = $this->propertyWebRoomMapping; + } + +} diff --git a/app/Core/Repository/PropertyWebSetup/PropertyWebSetupRepository.php b/app/Core/Repository/PropertyWebSetup/PropertyWebSetupRepository.php new file mode 100644 index 0000000..2997cb3 --- /dev/null +++ b/app/Core/Repository/PropertyWebSetup/PropertyWebSetupRepository.php @@ -0,0 +1,19 @@ +propertyWebSetup = $propertyWebSetup; + $this->defaultModel = $this->propertyWebSetup; + } + +} diff --git a/app/Core/Repository/PropertyWebTemplate/PropertyWebTemplateRepository.php b/app/Core/Repository/PropertyWebTemplate/PropertyWebTemplateRepository.php new file mode 100644 index 0000000..19876bf --- /dev/null +++ b/app/Core/Repository/PropertyWebTemplate/PropertyWebTemplateRepository.php @@ -0,0 +1,19 @@ +propertyWebTemplate = $propertyWebTemplate; + $this->defaultModel = $this->propertyWebTemplate; + } + +} diff --git a/app/Core/Repository/ReputationManagement/PropertyReviewCategoryRepository.php b/app/Core/Repository/ReputationManagement/PropertyReviewCategoryRepository.php new file mode 100644 index 0000000..4fff1ad --- /dev/null +++ b/app/Core/Repository/ReputationManagement/PropertyReviewCategoryRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/ReputationManagement/PropertyReviewChannelMappingRepository.php b/app/Core/Repository/ReputationManagement/PropertyReviewChannelMappingRepository.php new file mode 100644 index 0000000..e69bb04 --- /dev/null +++ b/app/Core/Repository/ReputationManagement/PropertyReviewChannelMappingRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/ReputationManagement/PropertyReviewChannelRepository.php b/app/Core/Repository/ReputationManagement/PropertyReviewChannelRepository.php new file mode 100644 index 0000000..0d20b32 --- /dev/null +++ b/app/Core/Repository/ReputationManagement/PropertyReviewChannelRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/ReputationManagement/PropertyReviewRepository.php b/app/Core/Repository/ReputationManagement/PropertyReviewRepository.php new file mode 100644 index 0000000..7f6d85b --- /dev/null +++ b/app/Core/Repository/ReputationManagement/PropertyReviewRepository.php @@ -0,0 +1,19 @@ +model = $model; + $this->defaultModel = $this->model; + } + +} diff --git a/app/Core/Repository/ServiceLog/ServiceLogRepository.php b/app/Core/Repository/ServiceLog/ServiceLogRepository.php new file mode 100644 index 0000000..f2da8c2 --- /dev/null +++ b/app/Core/Repository/ServiceLog/ServiceLogRepository.php @@ -0,0 +1,19 @@ +siteConfig = $serviceLog; + $this->defaultModel = $this->siteConfig; + } + +} diff --git a/app/Core/Repository/SiteConfig/SiteConfigRepository.php b/app/Core/Repository/SiteConfig/SiteConfigRepository.php new file mode 100644 index 0000000..6fa51bd --- /dev/null +++ b/app/Core/Repository/SiteConfig/SiteConfigRepository.php @@ -0,0 +1,19 @@ +siteConfig = $siteConfig; + $this->defaultModel = $this->siteConfig; + } + +} diff --git a/app/Core/Repository/TempProperty/TempPropertyRepository.php b/app/Core/Repository/TempProperty/TempPropertyRepository.php new file mode 100644 index 0000000..0719606 --- /dev/null +++ b/app/Core/Repository/TempProperty/TempPropertyRepository.php @@ -0,0 +1,70 @@ +tempProperty = $tempProperty; + $this->defaultModel = $this->tempProperty; + } + + public function searchTempProperty($param, $column = ['*']) + { + $get = $this->tempProperty->on('mysql') + ->orWhere( + function ($query) use ($param) { + if (isset($param['orWhere'])) + { + foreach ($param['orWhere'] as $key => $value) + { + $query->orWhere($value['field'], $value['condition'], '%'.$value['value'].'%' ); + } + } + } + ); + + if (isset($param['orWhere'])) + { + $rawBindings = []; + $increment = 1; + $likeTokens = [':fieldName',':fieldName%','%:fieldName','%:fieldName%']; + + $rawSqlPiece = 'case '; + foreach ($likeTokens as $perLikeToken) + { + foreach ($param['orWhere'] as $key => $value) + { + $rawSqlPiece.= 'when '.$value['field'].' LIKE ? then '.$increment.' '; + $increment++; + } + } + foreach ($likeTokens as $perLikeToken) + { + foreach ($param['orWhere'] as $key => $value) + { + $rawBindings[] = str_replace(":fieldName",$value['value'],$perLikeToken); + } + } + + $rawSqlPiece .= 'end'; + } + + if (isset($rawSqlPiece)) + { + $get->orderByRaw($rawSqlPiece . " ASC",$rawBindings); + } + $get->take(10); + $get = isset($param["firstRow"]) ? $get->first($column) : $get->get($column); + + return ($get) ? $get->toArray() : []; + } + +} diff --git a/app/Core/Repository/User/UserRepository.php b/app/Core/Repository/User/UserRepository.php new file mode 100644 index 0000000..bc21ef4 --- /dev/null +++ b/app/Core/Repository/User/UserRepository.php @@ -0,0 +1,19 @@ +user = $user; + $this->defaultModel = $this->user; + } + +} diff --git a/app/Core/Repository/UserPropertyMapping/UserPropertyMappingRepository.php b/app/Core/Repository/UserPropertyMapping/UserPropertyMappingRepository.php new file mode 100644 index 0000000..dd34061 --- /dev/null +++ b/app/Core/Repository/UserPropertyMapping/UserPropertyMappingRepository.php @@ -0,0 +1,19 @@ +userPropertyMapping = $userPropertyMapping; + $this->defaultModel = $this->userPropertyMapping; + } + +} diff --git a/app/Core/Repository/VWDestination/VWDestinationRepository.php b/app/Core/Repository/VWDestination/VWDestinationRepository.php new file mode 100644 index 0000000..1134c10 --- /dev/null +++ b/app/Core/Repository/VWDestination/VWDestinationRepository.php @@ -0,0 +1,19 @@ +VWDestination = $VWDestination; + $this->defaultModel = $this->VWDestination; + } + +} diff --git a/app/Core/Service/ApiAccessTokenService.php b/app/Core/Service/ApiAccessTokenService.php new file mode 100644 index 0000000..12e2a53 --- /dev/null +++ b/app/Core/Service/ApiAccessTokenService.php @@ -0,0 +1,114 @@ +apiAccessTokenRepository = $apiAccessTokenRepository; + + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->apiAccessTokenRepository->findByCriteria($param, $column); + if(!$data){ + throw new ApiErrorException(lang('An unknown error occurred')); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $tokenData = + [ + "token" => fillOnUndefined($param, "token"), + "expire_date" => fillOnUndefined($param, "expire_date"), + "user_id" => fillOnUndefined($param, "user_id"), + "invalidate" => fillOnUndefined($param, "invalidate"), + "created_at" => time(), + "updated_at" => time(), + + ]; + $tokenCreateResult = $this->apiAccessTokenRepository->create($tokenData); + + if ($tokenCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $tokenCreateResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null ]; + try { + + $updateResult = $this->apiAccessTokenRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $updateResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/ApplicationCacheService.php b/app/Core/Service/ApplicationCacheService.php new file mode 100644 index 0000000..fc57372 --- /dev/null +++ b/app/Core/Service/ApplicationCacheService.php @@ -0,0 +1,103 @@ +applicationCacheRepository = $applicationCacheRepository ; + $this->request = $request ; + } + + public function applicationCacheCreate($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + if(!fillOnUndefined($params, 'token')){ + throw new ApiErrorException(lang('Token Required')); + } + $cacheId = md5($params['token']) ; + unset($params['token']); + + $cacheResult = $this->applicationCacheRepository->storeCache($cacheId, $params); + $response = [ + 'status' => true, + 'data' => $cacheResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + + } + + public function getApplicationCache($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $token = $this->request->header('authToken'); + + + if(!$token){ + throw new ApiErrorException(lang('Token Required')); + } + $cacheId = md5($token) ; + + + $cacheResult = $this->applicationCacheRepository->getCache($cacheId); + + if(!$cacheResult){ + + throw new ApiErrorException(lang('Cache Info not found')); + } + + $response = [ + 'status' => true, + 'data' => $cacheResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + + } +} \ No newline at end of file diff --git a/app/Core/Service/BookingAddonService.php b/app/Core/Service/BookingAddonService.php new file mode 100644 index 0000000..2df790f --- /dev/null +++ b/app/Core/Service/BookingAddonService.php @@ -0,0 +1,155 @@ +bookingAddonRepository = $bookingAddonRepository; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'property_channel_addon_id' => fillOnUndefined($params, 'property_channel_addon_id'), + 'count' => fillOnUndefined($params, 'count'), + 'amount' => fillOnUndefined($params, 'amount'), + 'total' => fillOnUndefined($params, 'total'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'attribute' => fillOnUndefined($params, 'attribute'), + 'status' => fillOnUndefined($params, 'status', 1), + ]; + + $createResult = $this->bookingAddonRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingAddonRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingAddonRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->bookingAddonRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/BookingContactService.php b/app/Core/Service/BookingContactService.php new file mode 100644 index 0000000..c22dcee --- /dev/null +++ b/app/Core/Service/BookingContactService.php @@ -0,0 +1,137 @@ +bookingContactRepository = $bookingContactRepository; + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'name' => fillOnUndefined($params, 'name'), + 'surname' => fillOnUndefined($params, 'surname'), + 'phone_code' => fillOnUndefined($params, 'phone_code'), + 'phone_number' => fillOnUndefined($params, 'phone_number'), + 'email' => fillOnUndefined($params, 'email'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'note' => fillOnUndefined($params, 'note'), + 'invoice_request' => fillOnUndefined($params, 'invoice_request'), + 'language_code' => fillOnUndefined($params, 'language_code', 'en'), + 'extra_param' => fillOnUndefined($params, 'extra_param'), + 'status' => fillOnUndefined($params, 'status', 1), + ]; + + $userCreateResult = $this->bookingContactRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingContactRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingContactRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/BookingPaymentService.php b/app/Core/Service/BookingPaymentService.php new file mode 100644 index 0000000..d465207 --- /dev/null +++ b/app/Core/Service/BookingPaymentService.php @@ -0,0 +1,386 @@ +bookingPaymentRepository = $bookingPaymentRepository; + $this->bookingPaymentDataRepository = $bookingPaymentDataRepository; + $this->bookingPaymentDataCheckRepository = $bookingPaymentDataCheckRepository; + $this->bookingRepository = $bookingRepository ; + $this->propertyPaymentMappingRepository = $propertyPaymentMappingRepository ; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'payment_code' => fillOnUndefined($params, 'payment_code'), + 'payment_type_code' => fillOnUndefined($params, 'payment_type_code'), + 'payment_source_code' => fillOnUndefined($params, 'payment_source_code'), + 'extra_param' => fillOnUndefined($params, 'extra_param'), + 'total' => fillOnUndefined($params, 'total'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'status' => fillOnUndefined($params, 'status', 1), + ]; + + $userCreateResult = $this->bookingPaymentRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingPaymentRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingPaymentRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPaymentDashboard($param){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')] + ], + 'orderBy' => [["field" => "id", "value" => "DESC"]], + 'with' => ['bookingPaymentTransaction'], + ]; + + $bookingList = $this->bookingRepository->findByCriteria($requestData, ['id', 'channel_id','booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']); + $bookings = collect($bookingList); + + $bookingPayments = $bookings->map(function ($booking){ + + $paymentTransactions = collect($booking['booking_payment_transaction']) ; + $allTransactions = $paymentTransactions->count(); + $confirmedTransactions = $paymentTransactions->where('status' , '=' , 1)->count(); + $pendingTransactions = $paymentTransactions->where('status' , '=' , 2)->count(); + $errorTransactions = $paymentTransactions->where('status' , '=' , 0)->count(); + $startTransactions = $paymentTransactions->where('status' , '=' , 3)->count(); + $cancelTransactions = $paymentTransactions->where('status' , '=' , 4)->count(); + + return [ + 'booking_id' => $booking['id'], + 'all_transactions' => $allTransactions, + 'confirmed_transactions' => $confirmedTransactions, + 'pending_transactions' => $pendingTransactions, + 'error_transactions' => $errorTransactions, + 'start_transactions' => $startTransactions, + 'cancel_transactions' => $cancelTransactions, + ] ; + + })->values()->all() ; + + $requestPropertyPaymentMapping = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + + $propertyPaymentMappingList = $this->propertyPaymentMappingRepository->findByCriteria($requestPropertyPaymentMapping); + $paymentMappings = collect($propertyPaymentMappingList)->count(); + + $totalAllTransactions = collect($bookingPayments)->sum('all_transactions') ; + $totalConfirmedTransactions = collect($bookingPayments)->sum('confirmed_transactions') ; + $conversionRate = $totalAllTransactions ? ($totalConfirmedTransactions * 100) / $totalAllTransactions : 0; + $totalAllTransactions = collect($bookingPayments)->sum('all_transactions') ; + + + $responseData = [ + 'all_transactions' => $totalAllTransactions, + 'confirmed_transactions' => $totalConfirmedTransactions, + 'conversion_rate' => number_format($conversionRate, 2), + 'active_pos_count' => $paymentMappings + ]; + + $response = [ + 'status' => true, + 'data' => $responseData + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function createPaymentData($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'type' => fillOnUndefined($params, 'type'), + 'data' => fillOnUndefined($params, 'data'), + 'status' => fillOnUndefined($params, 'status', 1), + ]; + + $createResult = $this->bookingPaymentDataRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception($createResult['message']); + } + $createData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectPaymentData($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingPaymentDataRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePaymentData($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingPaymentDataRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPaymentDataCheck($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'code' => fillOnUndefined($params, 'code'), + 'status' => fillOnUndefined($params, 'status', 2), + 'request_time' => fillOnUndefined($params, 'request_time'), + 'expiry_time' => fillOnUndefined($params, 'expiry_time'), + 'confirm_time' => fillOnUndefined($params, 'confirm_time'), + 'created_by' => fillOnUndefined($params, 'created_by'), + 'updated_by' => fillOnUndefined($params, 'updated_by'), + + ]; + + $userCreateResult = $this->bookingPaymentDataCheckRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectPaymentDataCheck($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingPaymentDataCheckRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/BookingRoomPaxService.php b/app/Core/Service/BookingRoomPaxService.php new file mode 100644 index 0000000..2d910c3 --- /dev/null +++ b/app/Core/Service/BookingRoomPaxService.php @@ -0,0 +1,131 @@ +bookingRoomPaxRepository = $bookingRoomPaxRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'booking_room_id' => fillOnUndefined($params, 'booking_room_id'), + 'type' => fillOnUndefined($params, 'type'), + 'name' => fillOnUndefined($params, 'name'), + 'surname' => fillOnUndefined($params, 'surname'), + 'gender' => fillOnUndefined($params, 'gender'), + 'citizen' => fillOnUndefined($params, 'citizen'), + 'birth_date' => fillOnUndefined($params, 'birth_date'), + 'status' => fillOnUndefined($params, 'status', 1), + ]; + + $userCreateResult = $this->bookingRoomPaxRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingRoomPaxRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingRoomPaxRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/BookingRoomService.php b/app/Core/Service/BookingRoomService.php new file mode 100644 index 0000000..7d6b7a5 --- /dev/null +++ b/app/Core/Service/BookingRoomService.php @@ -0,0 +1,144 @@ +bookingRoomRepository = $bookingRoomRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'room_order_number' => fillOnUndefined($params, 'room_order_number'), + 'occupancy_code' => fillOnUndefined($params, 'occupancy_code'), + 'checkin_date' => fillOnUndefined($params, 'checkin_date'), + 'checkout_date' => fillOnUndefined($params, 'checkout_date'), + 'rate_key' => fillOnUndefined($params, 'rate_key'), + 'rate_key_code' => fillOnUndefined($params, 'rate_key_code'), + 'availability_id' => fillOnUndefined($params, 'availability_id'), + 'availability_code' => fillOnUndefined($params, 'availability_code'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_name' => fillOnUndefined($params, 'room_name'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'room_rate_name' => fillOnUndefined($params, 'room_rate_name'), + 'cancellation_policy' => fillOnUndefined($params, 'cancellation_policy'), + 'payment_type_code' => fillOnUndefined($params, 'payment_type_code'), + 'daily_amount' => fillOnUndefined($params, 'daily_amount'), + 'extra_param' => fillOnUndefined($params, 'extra_param'), + 'rate_detail' => fillOnUndefined($params, 'rate_detail'), + 'amount' => fillOnUndefined($params, 'amount'), + 'discount_amount' => fillOnUndefined($params, 'discount_amount'), + 'total' => fillOnUndefined($params, 'total'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'status' => fillOnUndefined($params, 'status', 1), + + ]; + + $userCreateResult = $this->bookingRoomRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingRoomRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingRoomRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/BookingService.php b/app/Core/Service/BookingService.php new file mode 100644 index 0000000..1dae9d5 --- /dev/null +++ b/app/Core/Service/BookingService.php @@ -0,0 +1,952 @@ +bookingRepository = $bookingRepository; + $this->bookingRoomRepository = $bookingRoomRepository; + $this->bookingRoomPaxRepository = $bookingRoomPaxRepository; + $this->bookingContactRepository = $bookingContactRepository; + $this->bookingPaymentRepository = $bookingPaymentRepository; + $this->bookingPaymentDataCheckRepository = $bookingPaymentDataCheckRepository; + $this->paymentTransactionRepository = $paymentTransactionRepository; + $this->bookingStatusRepository = $bookingStatusRepository; + $this->propertyBookingEngineRepository = $propertyBookingEngineRepository; + $this->propertyChannelRepository = $propertyChannelRepository; + $this->propertyBookingPaymentTypeRepository = $propertyBookingPaymentTypeRepository; + $this->mailer = $mailer; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'channel_manager_id' => fillOnUndefined($params, 'channel_manager_id'), + 'booking_code' => fillOnUndefined($params, 'booking_code'), + 'channel_booking_code' => fillOnUndefined($params, 'channel_booking_code'), + 'search_key' => fillOnUndefined($params, 'search_key'), + 'checkin_date' => fillOnUndefined($params, 'checkin_date'), + 'checkout_date' => fillOnUndefined($params, 'checkout_date'), + 'rooms' => fillOnUndefined($params, 'rooms'), + 'payment_type_code' => fillOnUndefined($params, 'payment_type_code'), + 'room_amount' => fillOnUndefined($params, 'room_amount'), + 'addon_amount' => fillOnUndefined($params, 'addon_amount', 0), + 'discount_amount' => fillOnUndefined($params, 'discount_amount', 0), + 'total' => fillOnUndefined($params, 'total'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'channel_discount' => fillOnUndefined($params, 'channel_discount'), + 'channel_markup' => fillOnUndefined($params, 'channel_markup'), + 'channel_currency_code' => fillOnUndefined($params, 'channel_currency_code'), + 'channel_currency_exchange' => fillOnUndefined($params, 'channel_currency_exchange'), + 'channel_token' => fillOnUndefined($params, 'channel_token'), + 'booking_engine_token' => fillOnUndefined($params, 'booking_engine_token'), + 'extra_param' => fillOnUndefined($params, 'extra_param'), + 'status' => fillOnUndefined($params, 'status', 1), + 'reservation_time' => fillOnUndefined($params, 'reservation_time', Carbon::now()->timestamp), + 'coupon_code' => fillOnUndefined($params,'coupon_code') + ]; + + $createResult = $this->bookingRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $createData = $createResult['data']; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult['data']; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingList($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $getListCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ], + 'orderBy' => [/*['field' => 'is_viewed', 'value' => 'ASC'],*/ + ['field' => 'id', 'value' => 'DESC']], + 'with' => ['bookingContact', 'bookingChannel', 'bookingPayment', 'bookingPaymentType', 'bookingStatus', 'bookingActiveMessageCount'], + ]; + + if (isset($param['filter']) && !empty($param['filter'])) { + + $filterParams = [ + 'channel_id' => [ + 'criteriaType' => 'EQUAL' + ], + 'booking_code' => [ + 'criteriaType' => 'LIKE' + ], + 'payment_type_code' => [ + 'criteriaType' => 'LIKE' + ], + 'status' => [ + 'criteriaType' => 'EQUAL' + ], + ]; + + foreach ($param['filter'] as $inputName => $inputValue) { + if (!is_null($inputValue) && key_exists($inputName, $filterParams)) { + if ($filterParams[$inputName]['criteriaType'] == 'EQUAL') { + $getListCriteria['criteria'][] = ['field' => $inputName, 'condition' => '=', 'value' => $inputValue]; + } elseif ($filterParams[$inputName]['criteriaType'] == 'LIKE') { + $getListCriteria['criteria'][] = ['field' => $inputName, 'condition' => 'LIKE', 'value' => '%' . $inputValue . '%']; + } + } + } + + + if (isset($param['filter']['date_type']) && isset($param['filter']['date_range'])) { + if (in_array($param['filter']['date_type'], ['checkin_date', 'checkout_date'])) { + $dateRange = explode(' ', $param['filter']['date_range']); + $getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->toDateString()]; + $getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->toDateString()]; + } + + if (in_array($param['filter']['date_type'], ['reservation_time'])) { + $dateRange = explode(' ', $param['filter']['date_range']); + $getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->unix()]; + $getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->unix()]; + } + } + + $getListCriteria['take'] = 10000; + + } else { + $getListCriteria['take'] = 200; + } + + $booking = $this->select($getListCriteria, ['id', 'channel_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'reservation_time', 'created_at', 'updated_at', 'status', 'is_viewed', 'channel_booking_code']); + + if ($booking['status'] != 'success') { + throw new ApiErrorException('Property Booking Data not found'); + } + + $bookingStatusColor = [ + 0 => '#CC0000', + 1 => '#007E33', + 2 => '#FF8800', + 3 => '#9933CC', + ]; + + if (!empty($booking['data'])) { + foreach ($booking['data'] as $dataKey => $data) { + $booking['data'][$dataKey]['booking_active_message_count'] = count($data['booking_active_message_count']); + $booking['data'][$dataKey]['booking_status']['bg-color'] = isset($bookingStatusColor[$booking['data'][$dataKey]['status']]) ? $bookingStatusColor[$booking['data'][$dataKey]['status']] : '#E0E0E0'; + $booking['data'][$dataKey]['is_viewed'] = empty($data['is_viewed']) ? false : true; + } + } + + $response = [ + 'status' => true, + 'data' => $booking['data'] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getPropertyBookingListFilter($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $filter = []; + + $propertyChannelParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]]; + $propertyChannel = $this->propertyChannelRepository->findByCriteria($propertyChannelParam, ['id', 'name', 'restriction']); + + $propertyChannel = array_filter($propertyChannel, function ($channel) use ($param) { + if (!empty($channel['restriction'])) { + $channelRestriction = json_decode($channel['restriction'], 1); + if (in_array($param['property_id'], $channelRestriction)) { + return $channel; + } + } else { + return $channel; + } + }); + + $filter['channel'] = array_values($propertyChannel); + + $propertyBookingPaymentTypeParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]]; + $propertyBookingPaymentType = $this->propertyBookingPaymentTypeRepository->findByCriteria($propertyBookingPaymentTypeParam, ['code', 'name', 'language_key']); + $filter['payment_type'] = $propertyBookingPaymentType; + + $bookingStatusParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]]; + $bookingStatus = $this->bookingStatusRepository->findByCriteria($bookingStatusParam, ['id', 'name', 'language_key']); + $filter['status'] = $bookingStatus; + + $filter['date_type'] = []; + $filter['date_type'][] = ['code' => 'checkin_date', 'name' => 'Checkin Date', 'language_key' => 'enw-filter-checkin_date']; + $filter['date_type'][] = ['code' => 'checkout_date', 'name' => 'Checkout Date', 'language_key' => 'enw-filter-checkout_date']; + $filter['date_type'][] = ['code' => 'reservation_time', 'name' => 'Booking Date', 'language_key' => 'enw-filter-booking_date']; + + $response = [ + 'status' => true, + 'data' => $filter + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingDetail($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'booking_id')] + ], + 'with' => [ + 'bookingContact', 'bookingChannel', 'bookingAddon.propertyChannelAddon.propertyAddon.fact', + 'bookingRoom.roomRateMapping.propertyRoom.propertyRoomType', 'bookingRoom.roomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'bookingRoom.roomPax.paxCountry', 'bookingPayment', 'bookingPaymentType', 'bookingPaymentTransaction.paymentTypeMapping.paymentType', + 'bookingPaymentData', + 'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', 'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact', + 'bookingRoom.smokingFact','propertyBookingEngineSearch' + ], + 'firstRow' => true + ]; + + $booking = $this->select($requestData, ['id', 'property_id', 'channel_id', 'booking_code', 'search_key','channel_booking_code', 'coupon_code', 'reservation_time', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status', 'is_viewed']); + + if ($booking['status'] != 'success') { + throw new ApiErrorException('Property Booking Data not found'); + } + + $booking['data']['voucher'] = null; + $propertyBookingEngineParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $booking['data']['property_id']], + //['field' => 'channel_id', 'condition' => '=', 'value' => $booking['data']['channel_id']], + ], + 'firstRow' => true, + ]; + + $propertyBookingEngine = $this->propertyBookingEngineRepository->findByCriteria($propertyBookingEngineParam); + if (!empty($propertyBookingEngine)) { + $booking['data']['voucher'] = Config::get('app.bookingEngineUrl') . '/' . $propertyBookingEngine['token'] . '/' . fillOnUndefined($param, 'locale', 'en') . '/booking-detail/' . $booking['data']['booking_code']; + } + + + if (!empty($booking['data']) && !empty($booking['data']['booking_room'])) { + $bookingRooms = &$booking['data']['booking_room']; + + foreach ($bookingRooms as &$bookingRoom) { + $bookingRoom['cancellation_policy'] = json_decode($bookingRoom['cancellation_policy'], true); + $bookingRoom['rate_detail'] = json_decode($bookingRoom['rate_detail'], true); + + + //80678 + + //property_room_bed_group + //unset($bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group']); + $propertyRoomBedGroup = collect($bookingRoom['room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group'); + $propertyRoomBedGroup = $propertyRoomBedGroup ? $propertyRoomBedGroup->toArray() : null; + + $bookingRoom['property_room_bed_group'] = null; + if(isset($propertyRoomBedGroup[$bookingRoom['property_room_bed_group_id']])) { + $bookingRoom['property_room_bed_group'] = $propertyRoomBedGroup[$bookingRoom['property_room_bed_group_id']]; + } + + } + } + + $booking = $booking['data']; + $booking['booking_payment_transaction'] = collect($booking['booking_payment_transaction'])->map(function ($value) { + $return = $value; + unset($return['params']); + unset($return['extra_params']); + unset($return['response']); + unset($return['extraParamsArray']); + unset($return['paramsArray']); + unset($return['responseArray']); + unset($return['payment_type_mapping']); + + $return['credit_card_number'] = isset($value['paramsArray']['creditCard']['number']) ? $value['paramsArray']['creditCard']['number'] : null; + $return['bank_name'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['name'] : null; + $return['bank_icon'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['icon'] : null; + $return['created_at'] = date('Y-m-d H:i:s', $value['created_at']); + $return['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']); + return $return; + + }); + + $booking['isThereBookingPaymentData'] = !empty($booking['booking_payment_data']) ? true : false; + unset($booking['booking_payment_data']); + + $response = [ + 'status' => true, + 'data' => $booking + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingListCount($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1] // status 1 = booking + ], + 'count' => true + + ]; + + if (fillOnUndefined($param, 'channel_id')) { + $requestData['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'channel_id')]; + } + + $booking = $this->select($requestData, ['id']); + + if ($booking['status'] != 'success') { + throw new ApiErrorException('Property Booking Count Data not found'); + } + $response = [ + 'status' => true, + 'data' => $booking['data'] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getTransactionList($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')] + ], + 'orderBy' => [['field' => 'id', 'value' => 'DESC']], + 'with' => ['bookingDetail.bookingContact', 'paymentTypeMapping.paymentType', 'paymentTransactionStatus', 'parentTransaction'] + ]; + + + if (isset($param['filter']) && !empty($param['filter'])) { + + $filterParams = [ + 'code' => [ + 'criteriaType' => 'LIKE' + ], + 'order_id' => [ + 'criteriaType' => 'LIKE' + ], + 'status' => [ + 'criteriaType' => 'EQUAL' + ], + ]; + + foreach ($param['filter'] as $inputName => $inputValue) { + if (!is_null($inputValue) && key_exists($inputName, $filterParams)) { + if ($filterParams[$inputName]['criteriaType'] == 'EQUAL') { + $requestData['criteria'][] = ['field' => $inputName, 'condition' => '=', 'value' => $inputValue]; + } elseif ($filterParams[$inputName]['criteriaType'] == 'LIKE') { + $requestData['criteria'][] = ['field' => $inputName, 'condition' => 'LIKE', 'value' => '%' . $inputValue . '%']; + } + } + } + + if (isset($param['filter']['date_range'])) { + $dateRange = explode(' ', $param['filter']['date_range']); + $requestData['criteria'][] = ['field' => 'created_at', 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->timestamp]; + $requestData['criteria'][] = ['field' => 'created_at', 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->timestamp]; + } + + $requestData['take'] = 10000; + + } else { + $requestData['take'] = 200; + } + + //dd($requestData); + + + $transactions = $this->paymentTransactionRepository->findByCriteria($requestData); + + $transactions = collect($transactions)->map(function ($value) { + + $return = $value; + unset($return['params']); + unset($return['extra_params']); + unset($return['response']); + unset($return['extraParamsArray']); + unset($return['paramsArray']); + unset($return['responseArray']); + unset($return['payment_type_mapping']); + + $return['credit_card_number'] = isset($value['paramsArray']['creditCard']['number']) ? $value['paramsArray']['creditCard']['number'] : null; + $return['bank_name'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['name'] : null; + $return['bank_icon'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['icon'] : null; + $return['created_at'] = date('Y-m-d H:i:s', $value['created_at']); + $return['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']); + $return['payment_link'] = $value['status'] == 5 && $value['transaction_type'] != 'BKG' ? Config::get('app.paymentFormLink') . $value['order_id'] : null; + $return['status_language_key'] = isset($value['payment_transaction_status']['language_key']) ? $value['payment_transaction_status']['language_key'] : null; + if ($value['parent_transaction']) { + if ($value['parent_transaction']['status'] == 5) { + $return['id'] = $value['parent_transaction']['id']; + } + } + return $return; + + }); + + $response = [ + 'status' => true, + 'data' => $transactions + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingDetailedList($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')] + ], + 'orderBy' => [['field' => 'id', 'value' => 'DESC']], + 'with' => ['bookingContact', 'bookingChannel', 'bookingRoom', 'bookingRoom.roomPax.paxCountry', 'bookingPayment', 'bookingPaymentType', 'bookingPaymentTransaction.paymentTypeMapping.paymentType'], + ]; + + if (fillOnUndefined($param, 'channel_id')) { + $requestData['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'channel_id')]; + } + + $booking = $this->select($requestData, ['id', 'channel_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']); + + if ($booking['status'] != 'success') { + throw new ApiErrorException('Property Booking Data not found'); + } + + $response = [ + 'status' => true, + 'data' => $booking['data'] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingstatusList($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingStatusRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getBookingPayment($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + DB::beginTransaction(); + + try { + + //TODO: Validator + + $confirmCode = fillOnUndefined($param, 'confirmCode'); + + $requestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'booking_id')] + ], + 'with' => ['bookingPaymentData', 'bookingPaymentDataCheck'], + 'firstRow' => true + ]; + + $bookingDetail = $this->select($requestData, ['id', 'property_id', 'channel_id', 'channel_manager_id', 'search_key', 'booking_code', 'channel_booking_code', 'reservation_time', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException('Property Booking Data not found'); + } + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException('Booking not found'); + } + + $bookingDetail = $bookingDetail['data']; + + if (in_array($bookingDetail['channel_manager_id'], [null])) { + if (!in_array($bookingDetail['payment_type_code'], ['HTL', 'CHN'])) { + throw new ApiErrorException('Only available for pay at hotel'); + } + } elseif (in_array($bookingDetail['channel_manager_id'], [1, 2])) { + if (!in_array($bookingDetail['payment_type_code'], ['CRD', 'CHN'])) { + throw new ApiErrorException('Only available for pay at credit card'); + } + } + + if (empty($bookingDetail['booking_payment_data'])) { + throw new ApiErrorException('Payment information not available'); + } + + $bookingPaymentDataCheck = $bookingDetail['booking_payment_data_check']; + + + switch ($bookingDetail['channel_manager_id']) { + case '1': + + $bookingPaymentData = $bookingDetail['booking_payment_data']; + + $getBookingPaymentDataCollect = collect($bookingPaymentData); + $isChannelManagerPaymentData = $getBookingPaymentDataCollect->where('type', 'ch')->first(); + + if ($isChannelManagerPaymentData) { + $channelPaymentDataUrl = 'https://www.reseliva.com/siteBase/REST/tsr/?lang=tr&res_id=' . $bookingDetail['search_key'] . '&hash=' . $isChannelManagerPaymentData['data']; + + $response = [ + 'status' => true, + 'data' => [ + 'type' => 'redirect', + 'redirectUrl' => $channelPaymentDataUrl, + 'channel_manager_id' => $bookingDetail['channel_manager_id'] + ], + ]; + + } else { + throw new ApiErrorException('Payment data not found.'); + } + + break; + case '2': + + $isConfirmCodeRequire = true; + + if (empty($confirmCode) && $isConfirmCodeRequire) { + + if (count($bookingPaymentDataCheck) > 2) { + throw new ApiErrorException('Payment information can only be viewed 3 times'); + } + + $unlockCode = rand(1000, 9999); + $paymentDataCheckParam = [ + 'booking_id' => $bookingDetail['id'], + 'code' => md5($unlockCode), + 'status' => 2, + 'expiry_time' => Carbon::now()->addMinutes(30)->timestamp, + 'created_by' => fillOnUndefined($param, 'user_id'), + 'updated_by' => fillOnUndefined($param, 'user_id'), + ]; + + $createPaymentDataCheck = $this->bookingPaymentDataCheckRepository->create($paymentDataCheckParam); + + if ($createPaymentDataCheck['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'type' => 'code', + 'expiry_time' => Carbon::createFromTimestamp($paymentDataCheckParam['expiry_time'])->toDateTimeString(), + 'channel_manager_id' => $bookingDetail['channel_manager_id'] + //'code' => $unlockCode + ] + + ]; + + //BookingPaymentDataCode + $mailParams = [ + 'user_id' => $param['user_id'], + 'booking_id' => $bookingDetail['id'], + 'unlock_code' => $unlockCode + ]; + + $this->mailer->send(new BookingPaymentDataCodeMail($mailParams)); + //BookingPaymentDataCode + + } else { + + if ($isConfirmCodeRequire) { + + $bookingPaymentDataCheckCollect = collect($bookingPaymentDataCheck); + + $bookingPaymentDataCheckRow = $bookingPaymentDataCheckCollect + ->where('code', md5($confirmCode)) + ->where('status', 2) + ->where('expiry_time', '>', Carbon::now()->timestamp) + ->first(); + + if (empty($bookingPaymentDataCheckRow)) { + throw new ApiErrorException('Code could not be verified, please check again'); + } + + } + + $bookingPaymentData = $bookingDetail['booking_payment_data']; + + $getBookingPaymentDataCollect = collect($bookingPaymentData); + $isChannelManagerPaymentData = $getBookingPaymentDataCollect->where('type', 'ch')->sortByDesc('id')->first(); + + $channelService = App::make("App\Core\Service\ChannelManager\Channex"); + + + $sessionTokenParam = [ + 'session_token' => [ + //'scope' => 'card' + 'scope' => 'show_card' + ] + ]; + + $sessionToken = $channelService->getSessionToken($sessionTokenParam); + $sessionToken = $sessionToken['status'] ? $sessionToken['data']['id'] : null; + + $serviceCodeTokenParam = [ + 'session_token' => [ + //'scope' => 'service_code' + 'scope' => 'show_service_code' + ] + ]; + + $serviceCodeToken = $channelService->getSessionToken($serviceCodeTokenParam); + $serviceCodeToken = $serviceCodeToken['status'] ? $serviceCodeToken['data']['id'] : null; + + + $channelPaymentDataUrl = 'https://pci.channex.io/api/v1/show_card?card_token=' . $isChannelManagerPaymentData['data'] . '&session_token=' . $sessionToken . '&service_code_token=' . $serviceCodeToken; + + $response = [ + 'status' => true, + 'data' => [ + 'type' => 'redirect', + 'redirectUrl' => $channelPaymentDataUrl, + 'channel_manager_id' => $bookingDetail['channel_manager_id'] + ], + ]; + + } + + break; + default : + + if (empty($confirmCode)) { + + if (count($bookingPaymentDataCheck) > 2) { + throw new ApiErrorException('Payment information can only be viewed 3 times'); + } + + $unlockCode = rand(1000, 9999); + $paymentDataCheckParam = [ + 'booking_id' => $bookingDetail['id'], + 'code' => md5($unlockCode), + 'status' => 2, + 'expiry_time' => Carbon::now()->addMinutes(30)->timestamp, + 'created_by' => fillOnUndefined($param, 'user_id'), + 'updated_by' => fillOnUndefined($param, 'user_id'), + ]; + + $createPaymentDataCheck = $this->bookingPaymentDataCheckRepository->create($paymentDataCheckParam); + + if ($createPaymentDataCheck['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'type' => 'code', + 'expiry_time' => Carbon::createFromTimestamp($paymentDataCheckParam['expiry_time'])->toDateTimeString(), + 'channel_manager_id' => $bookingDetail['channel_manager_id'] + //'code' => $unlockCode + ] + + ]; + + //BookingPaymentDataCode + $mailParams = [ + 'user_id' => $param['user_id'], + 'booking_id' => $bookingDetail['id'], + 'unlock_code' => $unlockCode + ]; + + $this->mailer->send(new BookingPaymentDataCodeMail($mailParams)); + //$this->mailer->onQueue('bookingPaymentDataCode', new BookingPaymentDataCodeMail($mailParams)); + //BookingPaymentDataCode + + } else { + + if (empty($bookingPaymentDataCheck)) { + throw new ApiErrorException('No request to view payment information yet'); + } + + $bookingPaymentDataCheckCollect = collect($bookingPaymentDataCheck); + + $bookingPaymentDataCheckRow = $bookingPaymentDataCheckCollect + ->where('code', md5($confirmCode)) + ->where('status', 2) + ->where('expiry_time', '>', Carbon::now()->timestamp) + ->first(); + + if (empty($bookingPaymentDataCheckRow)) { + throw new ApiErrorException('Code could not be verified, please check again'); + } + + $bookingPaymentDataEncrypted = collect($bookingDetail['booking_payment_data'])->groupBy('type')->toArray(); + + + $bookingPaymentData = []; + foreach ($bookingPaymentDataEncrypted as $type => $value) { + + if ($type == 'cc') { + $value = collect($value)->sortBy('id')->toArray(); + foreach ($value as $cardValue) { + $bookingPaymentData[$type][] = Crypt::decrypt($cardValue['data']); + } + $bookingPaymentData[$type] = implode(' ', $bookingPaymentData[$type]); + } else { + $cardValue = reset($value); + $bookingPaymentData[$type] = Crypt::decrypt($cardValue['data']); + } + + } + + $this->bookingPaymentDataCheckRepository->update($bookingPaymentDataCheckRow['id'], ['status' => 1, 'confirm_time' => Carbon::now()->timestamp]); + + $bookingPaymentData['bookingCode'] = $bookingDetail['booking_code']; + + $response = [ + 'status' => true, + 'data' => $bookingPaymentData + ]; + + } + + break; + + } + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/BookingTicketService.php b/app/Core/Service/BookingTicketService.php new file mode 100644 index 0000000..67ba611 --- /dev/null +++ b/app/Core/Service/BookingTicketService.php @@ -0,0 +1,160 @@ +bookingTicketRepository = $bookingTicketRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + + $insertData = [ + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'code' => fillOnUndefined($params, 'code'), + 'user_id' => fillOnUndefined($params, 'user_id'), + 'message' => fillOnUndefined($params, 'message'), + 'is_note' => fillOnUndefined($params, 'is_note'), + 'is_viewed' => fillOnUndefined($params, 'is_viewed'), + 'is_log' => fillOnUndefined($params, 'is_log'), + 'log' => fillOnUndefined($params, 'log'), + 'ip_address' => fillOnUndefined($params, 'ip_address'), + 'status' => fillOnUndefined($params, 'status', 1) + ]; + + + $userCreateResult = $this->bookingTicketRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->bookingTicketRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateWhere($criteria, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->bookingTicketRepository->updateWhereBulk($criteria, $param); + + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->bookingTicketRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/ChannelManager/Athena.php b/app/Core/Service/ChannelManager/Athena.php new file mode 100644 index 0000000..808f1c7 --- /dev/null +++ b/app/Core/Service/ChannelManager/Athena.php @@ -0,0 +1,304 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = [ + 546 => 'http://46.175.134.18:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 541 => 'http://94.43.46.153:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 545 => 'http://92.51.70.35:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + //538 => 'http://92.51.72.105:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 538 => 'http://146.255.233.146:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 548 => 'http://92.51.72.105:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 549 => 'http://92.51.72.105:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking', + 550 => 'http://146.255.239.106:6161/HotelEx/api/v1/hotel/ors/extranetwork/booking' + ]; + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->channelManagerId = 5; + $this->channelManagerName = 'Athena'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + $jsonResponse = []; + $jsonResponse['hotel_id'] = $propertyId; + + + $jsonResponse['reservation']['code'] = $bookingDetail['booking_code']; + $jsonResponse['reservation']['status'] = $type; + + $jsonResponse['reservation']['time'] = Carbon::createFromTimestamp($param['booking_detail']['created_at'])->toDateTimeString(); + + $jsonResponse['reservation']['checkin_date'] = $bookingDetail['checkin_date']; + $jsonResponse['reservation']['checkout_date'] = $bookingDetail['checkout_date']; + $jsonResponse['reservation']['currency'] = $bookingDetail['currency_code']; + $jsonResponse['reservation']['total'] = $bookingDetail['total']; + + + $jsonResponse['reservation']['contact'] = [ + 'name' => $bookingDetail['booking_contact']['name'], + 'surname' => $bookingDetail['booking_contact']['surname'], + 'email' => $bookingDetail['booking_contact']['email'], + 'phone' => $bookingDetail['booking_contact']['phoneFormatted'], + 'note' => $bookingDetail['booking_contact']['note'], + ]; + + + $jsonResponse['reservation']['rooms'] = []; + + $roomKey = 0; + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + if($roomDetail['status'] != 1) { + continue; + } + + $occupancy = occupancyCodeParser($roomDetail['occupancy_code']); + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + + //Additional Fee + $additionalFees = null; + if (!empty($roomDetail['rate_detail'])) { + $rateDetail = json_decode($roomDetail['rate_detail'], 1); + if(isset($rateDetail['taxes']) && $bookingDetail['channel_manager_id'] == 2) { + $additionalFees = $rateDetail['taxes']; + } + } + + $additionalFeeTotal = null; + if(!empty($additionalFees)) { + foreach ($additionalFees as $additionalFee) { + + if(!$additionalFee['is_inclusive']) { + $additionalFeeTotal+=$additionalFee['total_price']; + } + } + } + + $additionalFeePerDay = 0; + if(!empty($additionalFeeTotal)) { + $additionalFeePerDay = moneyDoubleFormatDecimal($additionalFeeTotal / $diffInDays); + } + //Additional Fee + + + $roomDailyAmount = []; + if (!empty($roomDetail['daily_amount'])) { + $roomDetailDailyAmount = json_decode($roomDetail['daily_amount'], 1); + if (!empty($roomDetailDailyAmount) && isset($roomDetailDailyAmount)) { + foreach ($roomDetailDailyAmount as $roomRateAmount) { + $calculatedAmount = $roomRateAmount['amount'] + $additionalFeePerDay; + $roomDailyAmount[] = [ + 'date' => $roomRateAmount['date'], + 'amount' => moneyDoubleFormatDecimal($calculatedAmount), + 'currency_code' => $roomRateAmount['currency_code'], + ]; + } + } + + $totalFromRoomDaily = collect($roomDailyAmount)->sum('amount'); + if($totalFromRoomDaily != $roomDetail['total']) { + $totalFromDifference = moneyDoubleFormatDecimal($roomDetail['total'] - $totalFromRoomDaily); + $roomDailyAmount[count($roomDailyAmount)-1]['amount']+= $totalFromDifference; + } + + } + + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + if (empty($roomDailyAmount)) { + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $roomDailyAmount[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily, + 'currency_code' => $roomDetail['currency_code'], + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + } + + $roomPax = []; + foreach ($roomDetail['room_pax'] as $pax) { + $roomPax[] = [ + 'type' => $pax['type'], + 'name' => $pax['name'], + 'surname' => $pax['surname'], + 'gender' => $pax['gender'], + 'citizen' => $pax['citizen'], + 'birth_date' => $pax['birth_date'], + ]; + } + + $jsonResponse['reservation']['rooms'][$roomKey] = [ + 'id' => $roomDetail['id'], + 'room_id' => $roomDetail['room_id'], + 'room_name' => $roomDetail['room_name'], + 'rate_id' => $roomDetail['room_rate_mapping_id'], + 'rate_name' => $roomDetail['room_rate_name'], + 'occupancy' => [ + 'adults' => $occupancy['ADT'], + 'children' => $occupancy['CHD'], + 'age' => $occupancy['AGE'], + ], + 'total' => $roomDetail['total'], + //'totalFromDaily' => collect($roomDailyAmount)->sum('amount'), + 'daily' => $roomDailyAmount, + 'pax' => $roomPax + + ]; + + + } + + $jsonResponse['reservation']['channel'] = [ + 'id' => $bookingDetail['booking_channel']['id'], + 'name' => $bookingDetail['booking_channel']['id'] == 1 ? 'Extranetwork' : $bookingDetail['booking_channel']['name'], + 'booking_code' => !empty($bookingDetail['channel_booking_code']) ? $bookingDetail['channel_booking_code'] : $bookingDetail['booking_code'] + ]; + + $jsonResponse['reservation']['payment'] = [ + 'code' => $bookingDetail['booking_payment_type']['code'], + 'name' => $bookingDetail['booking_payment_type']['name'], + ]; + + //CHN - For Offline Agency Booking Engine + if($bookingDetail['booking_channel']['channel_category_id'] == 2) { + if($bookingDetail['booking_payment']['payment_type_code'] == 'HTL') { + $jsonResponse['reservation']['payment'] = [ + 'code' => 'CHN', + 'name' => 'Channel Manager', + ]; + } + } + + if($bookingDetail['booking_payment']['payment_type_code'] == 'CRD' && $bookingDetail['booking_payment']['payment_source_code'] == 'GST') { + $jsonResponse['reservation']['payment'] = [ + 'code' => 'HTL', + 'name' => 'Pay at Hotel', + ]; + } + + + //Expedia Net Commission + if($jsonResponse['reservation']['total'] != $bookingDetail['booking_payment']['total']) { + + if($jsonResponse['reservation']['total'] == 0) { + $netRate = 0; + } else { + $netRate = $bookingDetail['booking_payment']['total'] / $jsonResponse['reservation']['total']; + } + + foreach ($jsonResponse['reservation']['rooms'] as $roomKey => $roomDetail) { + foreach ($roomDetail['daily'] as $roomDailyKey => $roomDaily) { + $jsonResponse['reservation']['rooms'][$roomKey]['daily'][$roomDailyKey]['amount'] = $roomDaily['amount'] * $netRate; + } + + $jsonResponse['reservation']['rooms'][$roomKey]['total'] = collect($jsonResponse['reservation']['rooms'][$roomKey]['daily'])->sum('amount'); + $jsonResponse['reservation']['rooms'][$roomKey]['total'] = moneyDoubleFormatDecimal($jsonResponse['reservation']['rooms'][$roomKey]['total']); + } + + $jsonResponse['reservation']['total'] = collect($jsonResponse['reservation']['rooms'])->sum('total'); + $jsonResponse['reservation']['total'] = moneyDoubleFormatDecimal($jsonResponse['reservation']['total']); + + } + + return json_encode($jsonResponse); + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + $jsonData = json_decode($jsonPayload,1); + + try { + + if(!isset($this->reservationPushUrl[$jsonData['hotel_id']])) { + throw new ApiErrorException('Athena live reservation no push url'); + } + + $this->restClient = new Client(['http_errors' => false, 'timeout' => 30]); + $res = $this->restClient->post($this->reservationPushUrl[$jsonData['hotel_id']], + [ + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseJsonBase = $getResponseBody->getContents(); + + $getResponse = json_decode($getResponseJsonBase, 1); + + if (!$getResponse['success']) { + throw new ApiErrorException($getResponse['errorReason']); + } + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/Channex.php b/app/Core/Service/ChannelManager/Channex.php new file mode 100644 index 0000000..8a67d32 --- /dev/null +++ b/app/Core/Service/ChannelManager/Channex.php @@ -0,0 +1,1277 @@ +restClient = $restClient; + $this->mailer = $mailer; + + //if (App::environment() == 'production') { + $this->url = 'https://app.channex.io/api/v1/'; + $this->userApiKey = 'uuyx1aEdP2whpT58mKbyxynLtgo0XQZZTq277Ww2Z8okT4FUhspFvIwrHD54+T6+'; + + $this->pciApiKey = '570751ea538845078a80be6ec0eee6d2'; + $this->pciSecureUrl = 'https://secure.channex.io/'; + /*} else { + $this->url = 'https://staging.channex.io/api/v1/'; + $this->userApiKey = 'uYOZRhv3tVK+AYNcFNWGwFfwz7+iMtqJaWvsT9p6rYA3RZENe9bAri7eIl95SbV+'; + + $this->pciApiKey = '076d9599ffe04159bd280659f13579e4'; + $this->pciSecureUrl = 'https://secure-staging.channex.io/'; + }*/ + + $this->pciUrl = 'https://pci.channex.io/api/v1/'; + + $this->channelManagerId = 2; + $this->channelManagerName = 'Channex'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function request($type, $method, $jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + + if ($type == 'POST') { + + $parameter = [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'user-api-key' => $this->userApiKey + ] + ]; + + if (!empty($jsonPayload)) { + $parameter['body'] = $jsonPayload; + } + + $res = $this->restClient->request('POST', $this->url . $method, $parameter); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + } else if ($type == 'GET') { + + $res = $this->restClient->request('GET', $this->url . $method, + [ + 'headers' => [ + //'Content-Type' => 'application/x-www-form-urlencoded', + 'user-api-key' => $this->userApiKey + ], + 'query' => $jsonPayload + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + + } + + /*Log::debug('__REQ__'); + Log::debug($this->url); + Log::debug($type); + Log::debug($method); + Log::debug($jsonPayload); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL);*/ + + if ($res->getStatusCode() != 200) { + $errors = singleElementArray($getResponse['errors']); + $firstError = reset($errors); + + Log::debug('__REQ__'); + Log::debug($this->url); + Log::debug($type); + Log::debug($method); + Log::debug($jsonPayload); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL); + + throw new ApiErrorException($firstError['code'] . ': ' . $firstError['title']); + } + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function requestPCI($type, $method, $jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + + $parameter = [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'user-api-key' => $this->userApiKey + ] + ]; + + if (!empty($jsonPayload)) { + $parameter['body'] = $jsonPayload; + } + + $res = $this->restClient->request($type, $this->pciUrl . $method, $parameter); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + /*Log::debug('__REQ__'); + Log::debug($this->url); + Log::debug($type); + Log::debug($method); + Log::debug($jsonPayload); + Log::debug($parameter); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL);*/ + + if (!in_array($res->getStatusCode(), [200, 201, 204])) { + $errors = []; + if (isset($getResponse['errors'])) { + $errors = singleElementArray($getResponse['errors']); + } elseif (isset($getResponse['error'])) { + $errors[] = [ + 'code' => null, + 'title' => $getResponse['error'] + ]; + } + + $firstError = reset($errors); + + Log::debug('__REQ__'); + Log::debug($type); + Log::debug($method); + Log::debug($jsonPayload); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL); + + throw new ApiErrorException(fillOnUndefined($firstError, 'code') . ': ' . fillOnUndefined($firstError, 'title')); + } + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function inventoryRoomRateUpdate($method, $jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + + $request = $this->request('POST', $method, $jsonPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => [ + 'confirmId' => reset($request['data'])['id'] + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function getSessionToken($param) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->requestPCI('POST', 'session_tokens?api_key=' . $this->pciApiKey, json_encode($param)); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => $request['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function removeCreditCardToken($token) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->requestPCI('DELETE', 'cards/' . $token . '?api_key=' . $this->pciApiKey, null); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => $request['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function getChannelDetails($channelId) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->request('GET', 'channels/' . $channelId, []); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => $request['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + /** Pattern Functions */ + + public function availabilityUpdateRequestMultiParam($propertyId, $params) + { + + $idList = []; + + $requestParam['values'] = []; + + ksort($params); + + $dataByRoomDate = []; + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $value) { + $uniqueKey = $value['availability']; + $dataByRoomDate[$roomId][$uniqueKey][$currentDate] = $value; + } + } + + + $requestParam = []; + + + $valueKey = 0; + foreach ($dataByRoomDate as $roomId => $rooms) { + + foreach ($rooms as $uniqueKey => $uniqueValues) { + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + + foreach ($dateGroup as $dates) { + + if (count($dates) > 1) { + + $requestParam['values'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'availability' => $currentValue['availability'] + ]; + + } else { + + $requestParam['values'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date' => reset($dates), + 'availability' => $currentValue['availability'] + ]; + + } + + $valueKey++; + + } + + + } + } + + //dd($requestParam); + + return [ + 'idList' => $idList, + 'payload' => json_encode($requestParam) + ]; + } + + public function roomAvailabilityPush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = []; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomAvailabilityQueueForUpdate = []; + $roomAvailabilityQueueForUpdateIdList = []; + $roomAvailabilityQueue = $bulkQueueData; + + + try { + + foreach ($roomAvailabilityQueue as $roomAvailability) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomAvailability['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomAvailability, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomAvailability['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping.room_id', $roomAvailability['property_room_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomAvailability['id']; + + continue; + } + + + $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']][] = $roomAvailability['id']; + + + $roomAvailabilityQueueForUpdate[$roomAvailability['date']] + [$channelManagerRoomRate['channel_manager_room_id']] = [ + 'id' => $roomAvailability['id'], + 'idList' => $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']], + 'date' => $roomAvailability['date'], + 'availability' => $roomAvailability['stop_sell'] == 1 ? 0 : $roomAvailability['availability'] + ]; + + } + + $roomAvailabilityUpdateRequestMultiParam = $this->availabilityUpdateRequestMultiParam($channelManagerPropertyMapping['channel_manager_property_id'], $roomAvailabilityQueueForUpdate); + $request = $this->inventoryRoomRateUpdate('availability', $roomAvailabilityUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomAvailabilityUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode[] = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateAvailabilityUpdate Error', + 'logMessage' => '
' . print_r(array_merge($request, $roomAvailabilityUpdateRequestMultiParam), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + + } catch (ApiErrorException $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . implode(', ', $e->getMessageArr()); + Log::error($message); + //$response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + //$response['message'] = $e->getMessage(); + } + + + } else { + $channelManagerNoneMappingIds = collect($bulkQueueData)->pluck('id')->toArray(); + } + + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + return $response; + } + + + public function roomRateUpdateRequestMultiParam($propertyId, $params) + { + + $idList = []; + + $requestParam['values'] = []; + + ksort($params); + + $dataByRoomRate = []; + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $rates) { + foreach ($rates as $rateId => $value) { + $uniqueKey = $value['amount'] . '|' . $value['stop_sell'] . '|' . $value['min_stay']; + $dataByRoomRate[$rateId][$uniqueKey][$currentDate] = $value; + } + } + } + + //Log::debug(json_encode($dataByRoomRate)); + + $requestParam = []; + + $valueKey = 0; + foreach ($dataByRoomRate as $rateId => $rates) { + + foreach ($rates as $uniqueKey => $uniqueValues) { + + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + foreach ($dateGroup as $dates) { + + if (count($dates) > 1) { + + $requestParam['values'][$valueKey] = [ + 'property_id' => $propertyId, + 'rate_plan_id' => $rateId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'rate' => moneyDoubleFormatDecimal($currentValue['amount'] * 100), + 'stop_sell' => fillOnUndefined($currentValue, 'stop_sell', 0), + 'min_stay_through' => fillOnUndefined($currentValue, 'min_stay', 1) != 0 ? $currentValue['min_stay'] : 1 + ]; + + /*if (isset($currentValue['min_stay']) && $currentValue['min_stay'] != 0) { + $requestParam['values'][$valueKey]['min_stay_through'] = fillOnUndefined($currentValue, 'min_stay', 1); + }*/ + + + } else { + + $requestParam['values'][$valueKey] = [ + 'property_id' => $propertyId, + 'rate_plan_id' => $rateId, + 'date' => reset($dates), + 'rate' => moneyDoubleFormatDecimal($currentValue['amount'] * 100), + 'stop_sell' => fillOnUndefined($currentValue, 'stop_sell', 0), + 'min_stay_through' => fillOnUndefined($currentValue, 'min_stay', 1) != 0 ? $currentValue['min_stay'] : 1 + ]; + + /*if (isset($currentValue['min_stay']) && $currentValue['min_stay'] != 0) { + $requestParam['values'][$valueKey]['min_stay_through'] = fillOnUndefined($currentValue, 'min_stay', 1); + }*/ + + + } + + if ($requestParam['values'][$valueKey]['rate'] == 0) { + unset($requestParam['values'][$valueKey]['rate']); + $requestParam['values'][$valueKey]['stop_sell'] = 1; + } + + $valueKey++; + + } + + } + } + + + return [ + 'idList' => $idList, + 'payload' => json_encode($requestParam) + ]; + + + } + + public function roomRatePricePush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + try { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = null; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomRatePriceQueueForUpdate = []; + $roomRatePriceQueueForUpdateIdList = []; + $roomRatePriceQueue = $bulkQueueData; + + + foreach ($roomRatePriceQueue as $roomRatePrice) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomRatePrice['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomRatePrice, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomRatePrice['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping_id', $roomRatePrice['room_rate_mapping_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomRatePrice['id']; + + //TODO: Burada oda eşleşmiyorsa süreç devam ediyor ama uyarı maili atılabilir. + + continue; + } + + + $roomRatePriceQueueForUpdateIdList + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']][] = $roomRatePrice['id']; + + + $roomRatePriceQueueForUpdate + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']] + [$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']] = [ + 'id' => $roomRatePrice['id'], + 'idList' => $roomRatePriceQueueForUpdateIdList[$channelManagerPropertyMapping['channel_manager_property_id']][$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']][$channelManagerRoomRate['channel_manager_room_rate_id']], + 'date' => $roomRatePrice['date'], + 'amount' => $roomRatePrice['amount'], + 'currency' => $roomRatePrice['currency'], + 'stop_sell' => $roomRatePrice['stop_sell'], + 'min_stay' => $roomRatePrice['min_stay'], + ]; + + } + + + foreach ($roomRatePriceQueueForUpdate as $channelManagerPropertyId => $channelManagerProperty) { + + + if (empty($channelManagerProperty)) { + throw new ApiErrorException('$channelManagerProperty is Empty!'); + } + + + ksort($channelManagerProperty); + $roomRateUpdateRequestMultiParam = $this->roomRateUpdateRequestMultiParam($channelManagerPropertyId, $channelManagerProperty); + + $request = $this->inventoryRoomRateUpdate('restrictions', $roomRateUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomRateUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($request, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + } + + } + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + public function reservationPullFormattedData($propertyId, $channelManagerPropertyId, $param) + { + + $bookingParam = []; + + //TODO: DELETE + /*$propertyId = 545; + $paramX = $param; + $param = []; + $param['attributes'] = $paramX;*/ + + $response = ['status' => false, 'message' => '']; + + //$roomTypes + $roomTypesParam = [ + 'filter[property_id]' => $channelManagerPropertyId + ]; + + $roomTypes = $this->request('GET', 'room_types', $roomTypesParam); + $roomTypes = $roomTypes['status'] ? $roomTypes['data'] : []; + $roomTypesCollect = collect($roomTypes); + + //$ratePlans + $ratePlansParam = [ + 'filter[property_id]' => $channelManagerPropertyId + ]; + + $ratePlans = $this->request('GET', 'rate_plans', $ratePlansParam); + $ratePlans = $ratePlans['status'] ? $ratePlans['data'] : []; + $ratePlansCollect = collect($ratePlans); + + if (strpos($param['attributes']['unique_id'], 'EXP') !== false) { + $param['attributes']['ota_name'] = 'Expedia'; + } + + try { + + //Check Channel Manager Mapping + $channelManagerMappingCriteria = + [ + 'criteria' => + [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyChannelManager'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerMappingData = $this->channelManagerMappingService->select($channelManagerMappingCriteria); + $channelManagerMappingCollect = collect($channelManagerMappingData['data']); + $channelManagerMapping = $channelManagerMappingCollect->where('channel_manager_channel_id', $param['attributes']['ota_name'])->first(); + + //Eğer kanala ait eşleşen bir kanal yok ise devam et + if (empty($channelManagerMapping)) { + //TODO: hata dönecek + throw new ApiErrorException('Channel Mapping Not Found'); + } + //Check Channel Manager Mapping + + + //Check Channel Manager Property Mapping + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + //Eğer kanala ait bir otel yok ise devam et + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + ///TODO: hata dönecek + /// throw new ApiErrorException($request['message']); + } + + $channelManagerRoomRateCollect = collect($channelManagerPropertyMapping['data']['channel_manager_room_rate']); + + + $roomRequest = []; + foreach ($param['attributes']['rooms'] as $room) { + $roomRequest[] = [ + 'adults' => $room['occupancy']['adults'], + 'children' => $room['occupancy']['children'], + 'age' => !empty($room['occupancy']['ages']) ? $room['occupancy']['ages'] : [] + ]; + } + + $paymentTypeCode = 'HTL'; + $paymentSourceCode = null; + if (isset($param['attributes']['payment_type']) && $param['attributes']['payment_type'] == 'credit_card') { + $paymentTypeCode = 'CRD'; + if ($param['attributes']['payment_collect'] == 'property') { + $paymentSourceCode = 'GST'; + } + if ($param['attributes']['payment_collect'] == 'ota') { + $paymentSourceCode = 'OTA'; + } + } + + + //Booking + $bookingParam['booking'] = [ + 'id' => null, + 'booking_code' => null, + 'property_id' => $propertyId, + 'channel_manager_id' => $this->channelManagerId, + 'channel_id' => $channelManagerMapping['property_channel_id'], + 'channel_booking_code' => fillOnUndefined($param['attributes'], 'ota_reservation_code'), + 'search_key' => $param['attributes']['booking_id'], + 'checkin_date' => $param['attributes']['arrival_date'], + 'checkout_date' => $param['attributes']['departure_date'], + 'rooms' => json_encode($roomRequest), + 'payment_type_code' => $paymentTypeCode, + 'room_amount' => $param['attributes']['amount'], + 'addon_amount' => 0, + 'discount_amount' => 0, + 'total' => $param['attributes']['amount'], + 'currency_code' => $param['attributes']['currency'], + 'channel_token' => null, + 'booking_engine_token' => null, + 'reservation_time' => Carbon::parse($param['attributes']['inserted_at'],'UTC')->timestamp, + 'status' => $param['attributes']['status'] == 'cancelled' ? 0 : 1 + ]; + + $extraParamBookingContact = []; + if (isset($param['attributes']['customer']['meta']['is_genius'])) { + $extraParamBookingContact['is_genius'] = $param['attributes']['customer']['meta']['is_genius']; + } + + $phoneNumber['code'] = null; + $phoneNumber['number'] = null; + if (isset($param['attributes']['customer']['phone'])) { + + $phoneNumberExplode = explode(' ', $param['attributes']['customer']['phone']); + + if (!empty($phoneNumberExplode) && count($phoneNumberExplode) > 1) { + $phoneNumber['code'] = reset($phoneNumberExplode); + unset($phoneNumberExplode[0]); + $phoneNumber['number'] = implode(' ', $phoneNumberExplode); + } + + } + + + //Booking Contact + $bookingParam['contact'] = [ + 'name' => $param['attributes']['customer']['name'], + 'surname' => !empty($param['attributes']['customer']['surname']) ? $param['attributes']['customer']['surname'] : null, + 'phone_code' => fillOnUndefined($phoneNumber, 'code'), + 'phone_number' => fillOnUndefined($phoneNumber, 'number'), + 'email' => fillOnUndefined($param['attributes']['customer'], 'mail'), + 'country_code' => fillOnUndefined($param['attributes']['customer'], 'country'), + 'note' => !empty($param['attributes']['notes']) ? $param['attributes']['notes'] : null, + 'language_code' => fillOnUndefined($param['attributes']['customer'], 'language', 'en'), + 'extra_param' => !empty($extraParamBookingContact) ? json_encode($extraParamBookingContact) : null, + 'status' => 1 + ]; + + $bookingParam['contact']['language_code'] = mb_substr($bookingParam['contact']['language_code'], 0, 2); + $bookingParam['contact']['country_code'] = mb_strtolower($bookingParam['contact']['country_code']); + + //Booking Room + $param['attributes']['rooms'] = array_values($param['attributes']['rooms']); + foreach ($param['attributes']['rooms'] as $roomOrder => $room) { + + + //Check Room Rate Mapping + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['room_type_id'])->where('channel_manager_room_rate_id', $room['rate_plan_id'])->first(); + if (empty($channelManagerRoomRate)) { + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['room_type_id'])->first(); + } + + $roomTypesSelected = $roomTypesCollect->where('id', $room['room_type_id'])->first(); + $ratePlanSelected = $ratePlansCollect->where('id', $room['rate_plan_id'])->first(); + + + $dailyAmount = []; + foreach ($room['days'] as $roomDay => $roomAmount) { + $dailyAmount[] = [ + 'date' => Carbon::parse($roomDay)->toDateString(), + 'amount' => $roomAmount, + 'currency_code' => $param['attributes']['currency'] + ]; + } + + $occupancyCodeByRoom = str_repeat('A', $room['occupancy']['adults']); + if ($room['occupancy']['children'] > 0 && !empty($room['occupancy']['ages'])) { + foreach ($room['occupancy']['ages'] as $age) { + $occupancyCodeByRoom .= 'C' . $age; + } + } + + $extraParamRoom = []; + if (isset($room['guests']) && !empty($room['guests'])) { + $guests = []; + foreach ($room['guests'] as $guest) { + $guests[] = ucwords($guest['name']) . ' ' . ucwords($guest['surname']); + } + $extraParamRoom['guests'] = implode(', ', $guests); + } + if (isset($room['meta']['meal_plan'])) { + $extraParamRoom['meal_plan'] = $room['meta']['meal_plan']; + } + if (isset($room['meta']['policies']) && !empty(isset($room['meta']['policies']))) { + $extraParamRoom['policies'] = $room['meta']['policies']; + } + if (isset($room['meta']['cancel_penalties']) && !empty($room['meta']['cancel_penalties'])) { + $extraParamRoom['cancel_penalties'] = $room['meta']['cancel_penalties']; + } + if (isset($room['meta']['bed_preferences'])) { + $extraParamRoom['bed_preferences'] = $room['meta']['bed_preferences']; + } + if (isset($room['meta']['free_text'])) { + $extraParamRoom['free_text'] = $room['meta']['free_text']; + } + if (isset($room['meta']['payment_instruction'])) { + $extraParamRoom['payment_instruction'] = $room['meta']['payment_instruction']; + } + if (isset($room['meta']['promotion_code'])) { + $extraParamRoom['promotion_code'] = $room['meta']['promotion_code']; + } + if (isset($room['meta']['smoking_preferences'])) { + $extraParamRoom['smoking_preferences'] = $room['meta']['smoking_preferences']; + } + + $bookingParam['room'][] = [ + 'room_order_number' => ($roomOrder + 1), + 'occupancy_code' => $occupancyCodeByRoom, + 'checkin_date' => $room['checkin_date'], + 'checkout_date' => $room['checkout_date'], + 'rate_key' => null, + 'rate_key_code' => null, + 'availability_id' => 1, + 'availability_code' => 'ROM', + 'room_id' => $channelManagerRoomRate['property_room_rate_mapping']['room_id'], + 'room_name' => isset($roomTypesSelected['attributes']['title']) ? $roomTypesSelected['attributes']['title'] : null, + 'room_rate_mapping_id' => $channelManagerRoomRate['property_room_rate_mapping']['id'], + 'room_rate_name' => isset($ratePlanSelected['attributes']['title']) ? $ratePlanSelected['attributes']['title'] : null, + 'cancellation_policy' => null, + 'payment_type_code' => $paymentTypeCode, + 'daily_amount' => !empty($dailyAmount) ? json_encode($dailyAmount) : null, + 'extra_param' => !empty($extraParamRoom) ? json_encode($extraParamRoom) : null, + 'rate_detail' => json_encode($room), + 'total' => $room['amount'], + 'currency_code' => $param['attributes']['currency'], + 'status' => $room['is_cancelled'] ? 0 : 1 + ]; + + } + + //Expedia Net Commission + $paymentAmount = $param['attributes']['amount']; + if($paymentTypeCode == 'CRD' && $paymentSourceCode == 'OTA' && in_array($param['attributes']['ota_name'],['Expedia'])) { + if(isset($param['attributes']['guarantee']['meta']) && isset($param['attributes']['guarantee']['meta']['expedia_net_commission'])) { + $paymentAmountNet = moneyDoubleFormatDecimal($param['attributes']['guarantee']['meta']['virtual_card_current_balance'] / 100); + if($paymentAmount != $paymentAmountNet) { + $paymentAmount = $paymentAmountNet; + } + } + } + + //Booking Payment Data + $bookingParam['payment'] = [ + 'payment_code' => null, + 'payment_type_code' => $paymentTypeCode, + 'payment_source_code' => $paymentSourceCode, + 'extra_param' => json_encode($param), + 'total' => $paymentAmount, + 'currency_code' => $param['attributes']['currency'], + 'status' => 2 + ]; + + //Booking Channel Payment Data + $bookingParam['payment_channel'] = null; + if (isset($param['attributes']['guarantee']) && !empty($param['attributes']['guarantee']) && in_array($param['attributes']['status'], ['new', 'modified'])) { + + $urlParam = [ + 'api_key' => $this->pciApiKey, + 'method' => 'get', + 'url' => $this->pciSecureUrl . 'api/v1/bookings/' . $param['attributes']['booking_id'], + 'profile' => 'channex_entity' + ]; + + $creditCardCapture = $this->requestPCI('POST', 'capture?' . http_build_query($urlParam), null); + + if ($creditCardCapture['status'] && isset($creditCardCapture['data']['attributes']['guarantee']['token'])) { + + $bookingParam['payment_channel'] = [ + 'type' => 'ch', + 'data' => $creditCardCapture['data']['attributes']['guarantee']['token'], + 'status' => 2 + ]; + + } + + + } + //Booking Channel Payment Data + + + //Channel Manager ETC Params + $bookingParam['channel_manager'] = [ + 'property_id' => $channelManagerPropertyId, + 'booking_id' => $param['attributes']['booking_id'], + 'sub_channel' => $param['attributes']['ota_name'], + 'sub_channel_booking_id' => $param['attributes']['ota_reservation_code'], + 'unique_id' => $param['attributes']['unique_id'], + 'revision_id' => $param['attributes']['id'], + ]; + + $statusType = null; + if ($param['attributes']['status'] == 'new') { + $statusType = 'createBooking'; + } elseif ($param['attributes']['status'] == 'cancelled') { + $statusType = 'cancelBooking'; + } elseif ($param['attributes']['status'] == 'modified') { + $statusType = 'modifiedBooking'; + } + + //$statusType = 'modifiedBooking'; + + $response['status'] = true; + $response['type'] = $statusType; + $response['data'] = $bookingParam; + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + public function reservationListParam($propertyId) + { + + $requestParam = []; + + $requestParam = [ + 'pagination[page]' => 1, + 'pagination[limit]' => 10, + 'order[inserted_at]' => 'ASC', + 'filter[property_id]' => $propertyId + ]; + + + return $requestParam; + } + + public function reservationList($param) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->request('GET', 'booking_revisions/feed', $param); + + //TODO: Delete + //$request = $this->request('GET', 'booking_revisions/4cb223d2-0259-41f6-b717-fdd4705c57e6', []); + + //a99e36ec-c83a-4b95-b124-2a0c2ba95c78 Expedia + //4cb223d2-0259-41f6-b717-fdd4705c57e6 Booking + //0b7912ef-aeaa-479c-9906-d71b7bc65b64 Booking + //c3426e46-6d6c-440d-a529-fd860b7b3283 Expedia + //d50355b7-c538-49f6-a0e4-898bf92812e0 + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => $request['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function reservationConfirmParam($propertyId, $channelManagerBookingId, $bookingCode, $param = []) + { + + $requestParam = []; + + $requestParam = [ + 'revision_id' => $param['channel_manager']['revision_id'] + ]; + + + return $requestParam; + } + + public function reservationConfirm($param) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->request('POST', 'booking_revisions/' . $param['revision_id'] . '/ack', []); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => $request['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + +} diff --git a/app/Core/Service/ChannelManager/ElektraWeb.php b/app/Core/Service/ChannelManager/ElektraWeb.php new file mode 100644 index 0000000..d6105c5 --- /dev/null +++ b/app/Core/Service/ChannelManager/ElektraWeb.php @@ -0,0 +1,226 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = 'https://channelmanager.elektraweb.com/extranetwork?action=push'; + + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->channelManagerId = 4; + $this->channelManagerName = 'ElektraWeb'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function requestPost($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->url . $method, + [ + 'headers' => [ + 'Content-Type' => 'text/xml; charset=UTF8', + 'Accept' => 'text/xml' + ], + 'body' => $xmlPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponseXml = new \SimpleXMLElement($getResponse, LIBXML_NOCDATA); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + $response = ["status" => true, 'message' => '', "data" => $getResponse]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + + $jsonResponse = []; + $jsonResponse['hotel_id'] = $propertyId; + + + $jsonResponse['reservation']['code'] = $bookingDetail['booking_code']; + $jsonResponse['reservation']['status'] = $type; + + $jsonResponse['reservation']['time'] = Carbon::createFromTimestamp($param['booking_detail']['created_at'])->toDateTimeString(); + + $jsonResponse['reservation']['checkin_date'] = $bookingDetail['checkin_date']; + $jsonResponse['reservation']['checkout_date'] = $bookingDetail['checkout_date']; + $jsonResponse['reservation']['currency'] = $bookingDetail['currency_code']; + $jsonResponse['reservation']['total'] = ($bookingDetail['total'] - $bookingDetail['addon_amount']); + + $jsonResponse['reservation']['contact'] = [ + 'name' => $bookingDetail['booking_contact']['name'], + 'surname' => $bookingDetail['booking_contact']['surname'], + 'email' => $bookingDetail['booking_contact']['email'], + 'phone' => $bookingDetail['booking_contact']['phoneFormatted'], + 'note' => $bookingDetail['booking_contact']['note'], + ]; + + + $jsonResponse['reservation']['rooms'] = []; + + + $roomKey = 0; + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + $occupancy = occupancyCodeParser($roomDetail['occupancy_code']); + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + + $dailyPrices = []; + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $dailyPrices[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + $roomPax = []; + foreach ($roomDetail['room_pax'] as $pax) { + $roomPax[] = [ + 'type' => $pax['type'], + 'name' => $pax['name'], + 'surname' => $pax['surname'], + 'gender' => $pax['gender'], + 'citizen' => $pax['citizen'], + 'birth_date' => $pax['birth_date'], + ]; + } + + $jsonResponse['reservation']['rooms'][$roomKey] = [ + 'room_id' => $roomDetail['room_id'], + 'room_name' => $roomDetail['room_name'], + 'rate_id' => $roomDetail['room_rate_mapping_id'], + 'rate_name' => $roomDetail['room_rate_name'], + 'occupancy' => [ + 'adults' => $occupancy['ADT'], + 'children' => $occupancy['CHD'], + 'age' => $occupancy['AGE'], + ], + 'daily' => $dailyPrices, + 'pax' => $roomPax + + ]; + + + } + + $jsonResponse['reservation']['channel'] = [ + 'id' => $bookingDetail['booking_channel']['id'], + 'name' => $bookingDetail['booking_channel']['id'] == 1 ? 'Extranetwork' : $bookingDetail['booking_channel']['name'], + ]; + + $jsonResponse['reservation']['payment'] = [ + 'code' => $bookingDetail['booking_payment_type']['code'], + 'name' => $bookingDetail['booking_payment_type']['name'], + ]; + + return json_encode($jsonResponse); + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->reservationPushUrl, + [ + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseJsonBase = $getResponseBody->getContents(); + + $getResponse = json_decode($getResponseJsonBase, 1); + + if (!$getResponse['Success']) { + throw new ApiErrorException($getResponse['Message']); + } + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/Fina.php b/app/Core/Service/ChannelManager/Fina.php new file mode 100644 index 0000000..5e48714 --- /dev/null +++ b/app/Core/Service/ChannelManager/Fina.php @@ -0,0 +1,255 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = [ + 790 => 'http://92.51.115.18/api/hotel/saveReservation' + ]; + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->channelManagerId = 8; + $this->channelManagerName = 'Fina'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + $jsonResponse = []; + $jsonResponse['hotel_id'] = $propertyId; + + + $jsonResponse['reservation']['code'] = $bookingDetail['booking_code']; + $jsonResponse['reservation']['status'] = $type; + + $jsonResponse['reservation']['time'] = Carbon::createFromTimestamp($param['booking_detail']['created_at'])->toDateTimeString(); + + $jsonResponse['reservation']['checkin_date'] = $bookingDetail['checkin_date']; + $jsonResponse['reservation']['checkout_date'] = $bookingDetail['checkout_date']; + $jsonResponse['reservation']['currency'] = $bookingDetail['currency_code']; + $jsonResponse['reservation']['total'] = $bookingDetail['total']; + + + $jsonResponse['reservation']['contact'] = [ + 'name' => $bookingDetail['booking_contact']['name'], + 'surname' => $bookingDetail['booking_contact']['surname'], + 'email' => $bookingDetail['booking_contact']['email'], + 'phone' => $bookingDetail['booking_contact']['phoneFormatted'], + 'note' => $bookingDetail['booking_contact']['note'], + ]; + + + $jsonResponse['reservation']['rooms'] = []; + + $roomKey = 0; + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + if ($roomDetail['status'] != 1) { + continue; + } + + $occupancy = occupancyCodeParser($roomDetail['occupancy_code']); + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + + //Additional Fee + $additionalFees = null; + if (!empty($roomDetail['rate_detail'])) { + $rateDetail = json_decode($roomDetail['rate_detail'], 1); + if (isset($rateDetail['taxes']) && $bookingDetail['channel_manager_id'] == 2) { + $additionalFees = $rateDetail['taxes']; + } + } + + $additionalFeeTotal = null; + if (!empty($additionalFees)) { + foreach ($additionalFees as $additionalFee) { + + if (!$additionalFee['is_inclusive']) { + $additionalFeeTotal += $additionalFee['total_price']; + } + } + } + + $additionalFeePerDay = 0; + if (!empty($additionalFeeTotal)) { + $additionalFeePerDay = moneyDoubleFormatDecimal($additionalFeeTotal / $diffInDays); + } + //Additional Fee + + + $roomDailyAmount = []; + if (!empty($roomDetail['daily_amount'])) { + $roomDetailDailyAmount = json_decode($roomDetail['daily_amount'], 1); + if (!empty($roomDetailDailyAmount) && isset($roomDetailDailyAmount)) { + foreach ($roomDetailDailyAmount as $roomRateAmount) { + $calculatedAmount = $roomRateAmount['amount'] + $additionalFeePerDay; + $roomDailyAmount[] = [ + 'date' => $roomRateAmount['date'], + 'amount' => moneyDoubleFormatDecimal($calculatedAmount), + 'currency_code' => $roomRateAmount['currency_code'], + ]; + } + } + + $totalFromRoomDaily = collect($roomDailyAmount)->sum('amount'); + if ($totalFromRoomDaily != $roomDetail['total']) { + $totalFromDifference = moneyDoubleFormatDecimal($roomDetail['total'] - $totalFromRoomDaily); + $roomDailyAmount[count($roomDailyAmount) - 1]['amount'] += $totalFromDifference; + } + + } + + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + if (empty($roomDailyAmount)) { + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $roomDailyAmount[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily, + 'currency_code' => $roomDetail['currency_code'], + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + } + + $roomPax = []; + foreach ($roomDetail['room_pax'] as $pax) { + $roomPax[] = [ + 'type' => $pax['type'], + 'name' => $pax['name'], + 'surname' => $pax['surname'], + 'gender' => $pax['gender'], + 'citizen' => $pax['citizen'], + 'birth_date' => $pax['birth_date'], + ]; + } + + $jsonResponse['reservation']['rooms'][$roomKey] = [ + 'id' => $roomDetail['id'], + 'room_id' => $roomDetail['room_id'], + 'room_name' => $roomDetail['room_name'], + 'rate_id' => $roomDetail['room_rate_mapping_id'], + 'rate_name' => $roomDetail['room_rate_name'], + 'occupancy' => [ + 'adults' => $occupancy['ADT'], + 'children' => $occupancy['CHD'], + 'age' => $occupancy['AGE'], + ], + 'total' => $roomDetail['total'], + //'totalFromDaily' => collect($roomDailyAmount)->sum('amount'), + 'daily' => $roomDailyAmount, + 'pax' => $roomPax + + ]; + + + } + + $jsonResponse['reservation']['channel'] = [ + 'id' => $bookingDetail['booking_channel']['id'], + 'name' => $bookingDetail['booking_channel']['id'] == 1 ? 'Extranetwork' : $bookingDetail['booking_channel']['name'], + 'booking_code' => !empty($bookingDetail['channel_booking_code']) ? $bookingDetail['channel_booking_code'] : $bookingDetail['booking_code'] + ]; + + $jsonResponse['reservation']['payment'] = [ + 'code' => $bookingDetail['booking_payment_type']['code'], + 'source' => $bookingDetail['booking_payment']['payment_source_code'], + 'name' => $bookingDetail['booking_payment_type']['name'], + ]; + + return json_encode($jsonResponse); + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + $jsonData = json_decode($jsonPayload, 1); + + $getResponse = []; + + try { + + /*if(!isset($this->reservationPushUrl[$jsonData['hotel_id']])) { + throw new ApiErrorException('Fina live reservation no push url'); + } + + $this->restClient = new Client(['http_errors' => false, 'timeout' => 30]); + $res = $this->restClient->post($this->reservationPushUrl[$jsonData['hotel_id']], + [ + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseJsonBase = $getResponseBody->getContents(); + + $getResponse = json_decode($getResponseJsonBase, 1); + + if (!$getResponse['success']) { + throw new ApiErrorException($getResponse['errorReason']); + }*/ + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/HotelRunner.php b/app/Core/Service/ChannelManager/HotelRunner.php new file mode 100644 index 0000000..e3c0835 --- /dev/null +++ b/app/Core/Service/ChannelManager/HotelRunner.php @@ -0,0 +1,284 @@ +restClient = $restClient; + $this->mailer = $mailer; + //$this->reservationPushUrl = 'https://cm-staging.hotelrunner.com/api/push/reservation/28fb9e7b18903126e9d71a10ced00db0edec8710'; + $this->reservationPushUrl = 'https://cm.hotelrunner.com/api/push/reservation/da120fb30eae007e41034f5ab7824608ab8250de'; + + + $this->typeMapping = [ + 'Booking' => 'Confirm', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->roomStatusTypeMapping = [ + 1 => 'Confirm', + 0 => 'Cancel' + ]; + + $this->channelManagerId = 3; + $this->channelManagerName = 'HotelRunner'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function requestPost($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->url . $method, + [ + 'headers' => [ + 'Content-Type' => 'text/xml; charset=UTF8', + 'Accept' => 'text/xml' + ], + 'body' => $xmlPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponseXml = new \SimpleXMLElement($getResponse, LIBXML_NOCDATA); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + $response = ["status" => true, 'message' => '', "data" => $getResponse]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addChild('status', $type); + $xmlResponse->addChild('code', $bookingDetail['booking_code']); + $xmlResponse->addChild('time_zone', 'UTC'); + + if (in_array($type, ['Modify', 'Cancel'])) { + $xmlResponse->addChild('date', Carbon::createFromTimestamp($param['booking_detail']['updated_at'], 'UTC')->toDateTimeString()); + } else { + $xmlResponse->addChild('date', Carbon::createFromTimestamp($param['booking_detail']['created_at'], 'UTC')->toDateTimeString()); + } + + //$xmlResponse->addChild('name', $bookingDetail['booking_contact']['nameSurname']); + $xmlResponse->addChild('name', ''); + $xmlResponse->addChild('mail', $bookingDetail['booking_contact']['email']); + $xmlResponse->addChild('address'); + $xmlResponse->addChild('city'); + + $firstRoom = reset($bookingDetail['booking_room']); + $firstPax = reset($firstRoom['room_pax']); + + $xmlResponse->addChild('country', $firstPax['pax_country']['name']); + $xmlResponse->addChild('telephone', $bookingDetail['booking_contact']['phoneFormatted']); + + $xmlResponse->addChild('property_id', $bookingDetail['property_id']); + + $totalAdultCount = 0; + $totalChildrenCount = 0; + $roomSearchOccupancy = json_decode($bookingDetail['rooms'], 1); + foreach ($roomSearchOccupancy as $roomOccupancy) { + $totalAdultCount += $roomOccupancy['adults']; + $totalChildrenCount += $roomOccupancy['children']; + } + + $xmlResponse->addChild('adult_count', $totalAdultCount); + $xmlResponse->addChild('child_count', $totalChildrenCount); + + + $xmlResponse->addChild('total_cost', $bookingDetail['total']); + $xmlResponse->addChild('currency', $bookingDetail['currency_code']); + + if (!empty($bookingDetail['booking_contact']['note'])) { + $xmlResponse->addChild('remark', ''); + } else { + $xmlResponse->addChild('remark', $bookingDetail['booking_contact']['note']); + } + + + $xmlResponse->addChild('arrival_date', $bookingDetail['checkin_date']); + $xmlResponse->addChild('departure_date', $bookingDetail['checkout_date']); + + $xmlResponse->addChild('card');//Credit Card + + + $rooms = $xmlResponse->addChild('rooms'); + + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + $room = $rooms->addChild('room'); + + $roomStatusType = isset($this->roomStatusTypeMapping[$roomDetail['status']]) ? $this->roomStatusTypeMapping[$roomDetail['status']] : 1; + + if (in_array($type, ['Modify']) && $roomDetail['status'] == 1) { + $roomStatusType = $type; + } + + if (in_array($type, ['Cancel'])) { + $roomStatusType = $type; + } + + $room->addChild('room_id', $roomDetail['room_id']); + $room->addChild('rate_id', $roomDetail['room_rate_mapping_id']); + $room->addChild('code', $roomDetail['room_id'] . ':' . $roomDetail['room_rate_mapping_id']); + + + $isNonRefundable = false; + $cancellationPolicy = json_decode($roomDetail['cancellation_policy'], 1); + if (!empty($cancellationPolicy)) { + if (isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable'] == 1) { + $isNonRefundable = true; + } + } + + if ($isNonRefundable) { + $roomName = $roomDetail['room_name'] . ' - ' . $roomDetail['room_rate_name'].' - NonRefundable'; + } else { + $roomName = $roomDetail['room_name'] . ' - ' . $roomDetail['room_rate_name']; + } + + $room->addChild('name', ''); + + $roomPaxCollect = collect($roomDetail['room_pax']); + $room->addChild('adult_count', $roomPaxCollect->where('type', 'ADT')->count()); + $room->addChild('child_count', $roomPaxCollect->where('type', 'CHD')->count()); + + $childAges = isset($roomSearchOccupancy[$roomKey]) && $roomSearchOccupancy[$roomKey]['children'] > 0 ? '[' . implode(',', $roomSearchOccupancy[$roomKey]['age']) . ']' : null; + + $room->addChild('child_ages', $childAges); + + + $room->addChild('arrival_date', $roomDetail['checkin_date']); + $room->addChild('departure_date', $roomDetail['checkout_date']); + + $room->addChild('total_cost', $roomDetail['total']); + $room->addChild('status', $roomStatusType); + + + $room->addChild('non_refundable', $isNonRefundable); + + + $dailyPrices = $room->addChild('daily_prices'); + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $dailyPrice = $dailyPrices->addChild('daily_price'); + $dailyPrice->addChild('date', $currentDate); + $dailyPrice->addChild('price', $baseRateDaily); + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + } + + //Log::debug($xmlResponse->asXML()); + + //dd(html_entity_decode($xmlResponse->asXML())); + + return html_entity_decode($xmlResponse->asXML()); + + } + + public function requestPostReservationPush($xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + $propertyId = null; + $xmlPayloadData = simplexml_load_string($xmlPayload); + $xmlPayloadData = json_decode(json_encode($xmlPayloadData), 1); + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->reservationPushUrl . '/' . $xmlPayloadData['property_id'], + [ + 'headers' => [ + 'Content-Type' => 'text/xml; charset=UTF8', + //'Authorization' => 'Basic dUV4dHJhbmV0V29yazpFeHRybnRXcmsyMSEqMjI=', + 'Accept' => 'text/xml' + ], + 'body' => $xmlPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseXmlBase = $getResponseBody->getContents(); + + $getResponseXml = new \SimpleXMLElement($getResponseXmlBase, LIBXML_NOCDATA); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + //Log::debug($xmlPayload); + //Log::debug($getResponse); + + if ($getResponse['status'] != 0) { + throw new ApiErrorException($getResponse['message']); + } + + $response = ['status' => true, 'message' => '', 'response' => $getResponseXmlBase]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/HyperGuest.php b/app/Core/Service/ChannelManager/HyperGuest.php new file mode 100644 index 0000000..2ef47d9 --- /dev/null +++ b/app/Core/Service/ChannelManager/HyperGuest.php @@ -0,0 +1,416 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = 'https://book-api.hyperguest.com'; + $this->bearerToken = '63d51938dc3749788ac3e88ea6d58950'; + + $this->channelManagerId = 10; + $this->channelManagerName = 'HyperGuest'; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + + $this->paymentTypeMapping = [ + 'CRD' => 'bank_transfer', + 'HTL' => 'external' + ]; + + } + + public function requestPost($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + $this->restClient = new Client(['http_errors' => false]); + + $parameter = [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $this->bearerToken + ] + ]; + + if (!empty($jsonPayload)) { + $parameter['body'] = $jsonPayload; + } + + $request = $this->restClient->request('POST', $this->url . $method, $parameter); + + $getResponseBody = $request->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + if ($request->getStatusCode() != 200) { + $errors = singleElementArray($getResponse['errors']); + $firstError = reset($errors); + throw new ApiErrorException($firstError['code'] . ': ' . $firstError['title']); + } + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $jsonResponse = null; + + try { + + $bookingDetail = $param['booking_detail']; + + $requestParam = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + + $jsonResponse = []; + $jsonResponse['dates']['from'] = $bookingDetail['checkin_date']; + $jsonResponse['dates']['to'] = $bookingDetail['checkout_date']; + + $jsonResponse['propertyId'] = $channelManagerPropertyMapping['channel_manager_property_id']; + + + //$jsonResponse['reservation']['code'] = $bookingDetail['booking_code']; + //$jsonResponse['reservation']['status'] = $type; + + //$jsonResponse['reservation']['time'] = Carbon::createFromTimestamp($param['booking_detail']['created_at'])->toDateTimeString(); + + $jsonResponse['leadGuest']['birthDate'] = '1980-01-01'; + + + $jsonResponse['leadGuest']['contact']['address'] = 'N/A'; + $jsonResponse['leadGuest']['contact']['city'] = 'N/A'; + $jsonResponse['leadGuest']['contact']['country'] = !empty($bookingDetail['booking_contact']['country_code']) ? $bookingDetail['booking_contact']['country_code'] : 'TR'; + $jsonResponse['leadGuest']['contact']['email'] = $bookingDetail['booking_contact']['email']; + $jsonResponse['leadGuest']['contact']['phone'] = $bookingDetail['booking_contact']['phoneFormatted']; + $jsonResponse['leadGuest']['contact']['state'] = 'N/A'; + $jsonResponse['leadGuest']['contact']['zip'] = 'N/A'; + + $jsonResponse['leadGuest']['name']['first'] = $bookingDetail['booking_contact']['name']; + $jsonResponse['leadGuest']['name']['last'] = $bookingDetail['booking_contact']['surname']; + + $jsonResponse['leadGuest']['title'] = 'Mr'; + + $jsonResponse['reference']['agency'] = $bookingDetail['booking_code'];//'Extranetwork'; + + + $jsonResponse['paymentDetails']['type'] = isset($this->paymentTypeMapping[$bookingDetail['payment_type_code']]) ? $this->paymentTypeMapping[$bookingDetail['payment_type_code']] : $this->paymentTypeMapping['HTL']; + //$jsonResponse['paymentDetails']['details']['number'] = null; + //$jsonResponse['paymentDetails']['details']['cvv'] = null; + //$jsonResponse['paymentDetails']['details']['expiry']['month'] = null; + //$jsonResponse['paymentDetails']['details']['name']['first'] = null; + //$jsonResponse['paymentDetails']['details']['name']['last'] = null; + + + $jsonResponse['rooms'] = []; + + + $roomKey = 0; + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + /*$occupancy = occupancyCodeParser($roomDetail['occupancy_code']); + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + */ + + $roomPax = []; + foreach ($roomDetail['room_pax'] as $pax) { + $roomPax[] = [ + 'birthDate' => $pax['birth_date'], + /*'contact' => [ + 'address' => null, + 'city' => null, + 'country' => $pax['citizen'], + 'email' => null, + 'phone' => null, + 'state' => null, + 'zip' => null, + ],*/ + 'name' => [ + 'first' => $pax['name'], + 'last' => $pax['surname'], + ], + //'title' => null + ]; + } + + $channelRoom = collect($channelManagerPropertyMapping['channel_manager_room_rate'])->where('property_room_rate_mapping.room_id', $roomDetail['room_id'])->first(); + $channelRoomRate = collect($channelManagerPropertyMapping['channel_manager_room_rate'])->where('property_room_rate_mapping_id', $roomDetail['room_rate_mapping_id'])->first(); + + $jsonResponse['rooms'][$roomKey] = [ + 'roomCode' => $channelRoom['channel_manager_room_id'], + 'rateCode' => $channelRoomRate['channel_manager_room_rate_id'], + 'expectedPrice' => [ + 'amount' => $roomDetail['total'], + 'currency' => $roomDetail['currency_code'], + ], + 'guests' => $roomPax, + 'specialRequests' => [ + $roomDetail['room_name'], $roomDetail['room_rate_name'], + ] + + ]; + + } + + + $metaNotes = []; + + $metaNotes[] = [ + 'key' => 'Source', + 'value' => 'Extranetwork', + ]; + + $metaNotes[] = [ + 'key' => 'BookingId', + 'value' => $bookingDetail['id'], + ]; + + $metaNotes[] = [ + 'key' => 'BookingCode', + 'value' => $bookingDetail['booking_code'], + ]; + + $metaNotes[] = [ + 'key' => 'ChannelBookingCode', + 'value' => !empty($bookingDetail['channel_booking_code']) ? $bookingDetail['channel_booking_code'] : false, + ]; + + $metaNotes[] = [ + 'key' => 'Channel', + 'value' => $bookingDetail['booking_channel']['name'], + ]; + + $metaNotes[] = [ + 'key' => 'Payment', + 'value' => $bookingDetail['booking_payment_type']['code'] . ': ' . $bookingDetail['booking_payment_type']['name'], + ]; + + $metaNotes[] = [ + 'key' => 'Status', + 'value' => $bookingDetail['booking_status']['name'], + ]; + + if (!empty($bookingDetail['booking_contact']['note'])) { + $metaNotes[] = [ + 'key' => 'Note', + 'value' => $bookingDetail['booking_contact']['note'], + ]; + } + + $jsonResponse['meta'] = $metaNotes; + $jsonResponse['isTest'] = (App::environment() == 'production') ? false : true; + $jsonResponse['groupBooking'] = false; + + return json_encode($jsonResponse); + + + } catch (ApiErrorException | Exception $e) { + + $jsonResponse = null; + + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + + return $jsonResponse; + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + $jsonPayloadArray = json_decode($jsonPayload, 1); + $status = collect($jsonPayloadArray['meta'])->where('key', 'Status')->pluck('value')->first(); + $bookingId = collect($jsonPayloadArray['meta'])->where('key', 'BookingId')->pluck('value')->first(); + $bookingCode = collect($jsonPayloadArray['meta'])->where('key', 'BookingCode')->pluck('value')->first(); + $channelBookingCode = collect($jsonPayloadArray['meta'])->where('key', 'ChannelBookingCode')->pluck('value')->first(); + + if ($status == 'Booking') { + $method = '/2.0/booking/create'; + } elseif ($status == 'Cancel/Refund') { + $method = '/2.0/booking/cancel'; + } + + if ($status == 'Cancel/Refund') { + $jsonResponse = [ + 'bookingId' => $channelBookingCode, + 'reason' => 'N/A', + 'simulation' => false, + ]; + $jsonPayload = json_encode($jsonResponse); + } + + try { + + $this->restClient = new Client(['http_errors' => false]); + + $parameter = [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $this->bearerToken + ] + ]; + + + //$jsonPayload = '{"dates":{"from":"2024-08-30","to":"2024-08-31"},"propertyId":"90365","leadGuest":{"birthDate":"1980-01-01","contact":{"address":false,"city":false,"country":"TR","email":"cem@test.com","phone":"+4932121321","state":false,"zip":false},"name":{"first":"cem","last":"test"},"title":"Mr"},"reference":{"agency":"BKG240730-5VI02ISW"},"paymentDetails":{"type":"external"},"rooms":[{"roomCode":"DBL","rateCode":"BB","expectedPrice":{"amount":200.75,"currency":"EUR"},"guests":[{"birthDate":"1988-07-20","name":{"first":"dsada","last":"sadsa"}},{"birthDate":"1988-07-24","name":{"first":"sad","last":"sadfds"}}],"specialRequests":["Standart Room With Sea View","Bed and Breakfast"]}],"meta":[{"key":"Source","value":"Extranetwork"},{"key":"BookingId","value":46502},{"key":"BookingCode","value":"BKG240730-5VI02ISW"},{"key":"ChannelBookingCode","value":false},{"key":"Channel","value":"Web Booking Engine"},{"key":"Payment","value":"HTL: Pay at Hotel"},{"key":"Status","value":"Booking"},{"key":"Note","value":"asdasd"}],"isTest":true,"groupBooking":false}'; + + if (!empty($jsonPayload)) { + $parameter['body'] = $jsonPayload; + } + + + $request = $this->restClient->request('POST', $this->reservationPushUrl . $method, $parameter); + + $getResponseBody = $request->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + //dd(json_encode($getResponse)); + + //Log::debug($method); + //Log::debug($parameter); + //Log::debug(json_encode($getResponse)); + //Log::debug($request->getStatusCode()); + + if ($request->getStatusCode() != 200) { + + if (isset($getResponse['error'])) { + if (is_array($getResponse['errorDetails']) && !empty($getResponse['errorDetails'])) { + $errors = $getResponse['errorDetails']; + $firstError = reset($errors); + throw new ApiErrorException($firstError['message']); + } elseif (!empty($getResponse['errorDetails'])) { + throw new ApiErrorException($getResponse['errorDetails']); + } else { + throw new ApiErrorException($getResponse['error']); + } + + } else { + $errors = singleElementArray($getResponse); + $firstError = reset($errors); + throw new ApiErrorException($firstError['errorCode'] . ': ' . $firstError['errorDetails']); + } + + } + + if ($status == 'Booking') { + $channelBookingCodeUpdate = $this->bookingService->update($bookingId, ['channel_booking_code' => $getResponse['content']['bookingId']]); + } + + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function reservationListParam($propertyId) + { + + $response = ['status' => false, 'message' => null]; + + return $response; + } + + public function reservationList($propertyId) + { + + $response = ['status' => false, 'message' => null]; + + return $response; + } + + public function roomAvailabilityPush($propertyId) + { + + $response = ['status' => false, 'message' => null]; + + return $response; + } + +} diff --git a/app/Core/Service/ChannelManager/Mirai.php b/app/Core/Service/ChannelManager/Mirai.php new file mode 100644 index 0000000..70f6fce --- /dev/null +++ b/app/Core/Service/ChannelManager/Mirai.php @@ -0,0 +1,685 @@ +restClient = $restClient; + $this->mailer = $mailer; + + /*if (App::environment() == 'production') { + $this->login = 'extranetwork-xml-100378788'; + $this->password = 'Burhan21'; + } else { + $this->login = 'ExtranetWorktest-xml-100378347'; + $this->password = 'ifXHs3EJc-$>'; + }*/ + + $this->login = null; + $this->password = null; + $this->url = 'https://api.mirai.com/XMLIntegrationx/'; + + $this->channelManagerId = 7; + $this->channelManagerName = 'Mirai'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function setupUser($login, $password) + { + $this->login = $login; + $this->password = $password; + } + + public function request($type, $method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + + $formAuthParam = [ + 'login' => $this->login, + 'password' => $this->password, + ]; + + if(empty($this->login)) { + throw new ApiErrorException('Login data not set!'); + } + + $parameter = [ + 'headers' => [], + 'query' => $formAuthParam, + ]; + + if (!empty($xmlPayload)) { + $parameter['body'] = $xmlPayload; + } + + //Log::debug($xmlPayload); + + $request = $this->restClient->request($type, $this->url . $method, $parameter); + + $getResponseBody = $request->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponseXml = new \SimpleXMLElement($getResponse); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + if (isset($getResponse['message']['error'])) { + $errorMessage = is_array($getResponse['message']['error']['comment']) ? implode(',', $getResponse['message']['error']['comment']) : $getResponse['message']['error']['comment']; + throw new ApiErrorException($errorMessage); + } + + if ($request->getStatusCode() != 200) { + + if($request->getReasonPhrase()) { + $firstError = $request->getReasonPhrase(); + } else { + $firstError = is_array($getResponse['message']['error']['comment']) ? implode(',', $getResponse['message']['error']['comment']) : $getResponse['message']['error']['comment']; + } + + /*Log::debug('__REQ__'); + Log::debug($this->url); + Log::debug($type); + Log::debug($method); + Log::debug($xmlPayload); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL); */ + + throw new ApiErrorException($firstError); + } + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function inventoryRoomRateUpdate($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + + $request = $this->request('POST', $method, $xmlPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + /** Pattern Functions */ + /* + public function availabilityUpdateRequestMultiParam($propertyId, $propertyRoomRateMapping, $params) + { + + $idList = []; + + $requestParam['values'] = []; + + ksort($params); + + $dataByRoomDate = []; + $propertyRoomRateMappingCollect = collect($propertyRoomRateMapping); + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $value) { + $uniqueKey = $value['availability']; + + $roomIdManipulate = $roomId; + $roomIdManipulateCheck = $propertyRoomRateMappingCollect->where('channel_manager_room_id', $roomId)->where('property_room_rate_mapping.status', 1)->first(); + if (!empty($roomIdManipulateCheck)) { + $roomIdManipulate = $roomIdManipulateCheck['channel_manager_room_rate_id']; + } + + $dataByRoomDate[$roomIdManipulate][$uniqueKey][$currentDate] = $value; + } + } + + $requestParam = []; + + $valueKey = 0; + foreach ($dataByRoomDate as $roomId => $rooms) { + + foreach ($rooms as $uniqueKey => $uniqueValues) { + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + + foreach ($dateGroup as $dates) { + + if (count($dates) > 1) { + + $requestParam[$roomId]['data'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'availability' => $currentValue['availability'] + ]; + + } else { + + $requestParam[$roomId]['data'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date_from' => reset($dates), + 'date_to' => reset($dates), + 'availability' => $currentValue['availability'] + ]; + + } + + $valueKey++; + + } + + + } + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $propertyId); + + foreach ($requestParam as $roomId => $roomData) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $roomId); + + $roomInventory = $room->addChild('inventory'); + + foreach ($roomData['data'] as $roomRate) { + $roomInventoryAvailability = $roomInventory->addChild('availability'); + + $roomInventoryAvailability->addAttribute('from', $roomRate['date_from']); + $roomInventoryAvailability->addAttribute('to', $roomRate['date_to']); + $roomInventoryAvailability->addAttribute('quantity', $roomRate['availability']); + + } + + } + + return [ + 'idList' => $idList, + 'payload' => $xmlResponse->asXML() + ]; + } + + public function roomAvailabilityPush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = []; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomAvailabilityQueueForUpdate = []; + $roomAvailabilityQueueForUpdateIdList = []; + $roomAvailabilityQueue = $bulkQueueData; + + + try { + + foreach ($roomAvailabilityQueue as $roomAvailability) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomAvailability['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomAvailability, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomAvailability['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping.room_id', $roomAvailability['property_room_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomAvailability['id']; + + continue; + } + + + $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']][] = $roomAvailability['id']; + + + $roomAvailabilityQueueForUpdate[$roomAvailability['date']] + [$channelManagerRoomRate['channel_manager_room_id']] = [ + 'id' => $roomAvailability['id'], + 'idList' => $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']], + 'date' => $roomAvailability['date'], + 'availability' => $roomAvailability['stop_sell'] == 1 ? 0 : $roomAvailability['availability'] + ]; + + } + + $roomAvailabilityUpdateRequestMultiParam = $this->availabilityUpdateRequestMultiParam($channelManagerPropertyMapping['channel_manager_property_id'], $channelManagerPropertyMapping['channel_manager_room_rate'], $roomAvailabilityQueueForUpdate); + $request = $this->inventoryRoomRateUpdate('webservice_updater.apro', $roomAvailabilityUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomAvailabilityUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode[] = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateAvailabilityUpdate Error', + 'logMessage' => '
' . print_r(array_merge($request, $roomAvailabilityUpdateRequestMultiParam), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + + } catch (ApiErrorException $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . implode(', ', $e->getMessageArr()); + Log::error($message); + //$response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + //$response['message'] = $e->getMessage(); + } + + + } else { + $channelManagerNoneMappingIds = collect($bulkQueueData)->pluck('id')->toArray(); + } + + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + return $response; + } + + + public function roomRateUpdateRequestMultiParam($propertyId, $params) + { + + $idList = []; + ksort($params); + + $dataByRoomRate = []; + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $rates) { + foreach ($rates as $rateId => $value) { + $uniqueKey = $value['amount'] . '|' . $value['stop_sell'] . '|' . $value['min_stay']; + $dataByRoomRate[$rateId][$uniqueKey][$currentDate] = $value; + } + } + } + + //Log::debug(json_encode($dataByRoomRate)); + + $requestParam = []; + + $valueKey = 0; + foreach ($dataByRoomRate as $rateId => $rates) { + + $valueKey = 0; + foreach ($rates as $uniqueKey => $uniqueValues) { + + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + foreach ($dateGroup as $dates) { + + $requestParam[$rateId][$valueKey] = [ + 'property_id' => $propertyId, + 'rate_plan_id' => $rateId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'amount' => moneyDoubleFormatDecimal($currentValue['amount']), + 'stop_sell' => fillOnUndefined($currentValue, 'stop_sell', 0), + 'min_stay' => fillOnUndefined($currentValue, 'min_stay', 1) != 0 ? $currentValue['min_stay'] : 1, + 'currency' => $currentValue['currency'], + ]; + + if ($requestParam[$rateId][$valueKey]['amount'] == 0) { + $requestParam[$rateId][$valueKey]['stop_sell'] = 1; + } + + $valueKey++; + + } + + } + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $propertyId); + + foreach ($requestParam as $roomId => $roomData) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $roomId); + + $currencyCode = reset($roomData)['currency']; + + $roomRate = $room->addChild('rate'); + $roomRate->addAttribute('currency', $currencyCode); + + foreach ($roomData as $roomRateData) { + + $roomRatePlaning = $roomRate->addChild('planning'); + + $roomRatePlaning->addAttribute('from', $roomRateData['date_from']); + $roomRatePlaning->addAttribute('to', $roomRateData['date_to']); + $roomRatePlaning->addAttribute('unitPrice', $roomRateData['stop_sell'] == 1 ? 0 : $roomRateData['amount']); + $roomRatePlaning->addAttribute('minimumStay', $roomRateData['min_stay']); + + } + + } + + return [ + 'idList' => $idList, + 'payload' => $xmlResponse->asXML() + ]; + + } + + + public function roomRatePricePush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + try { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = null; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomRatePriceQueueForUpdate = []; + $roomRatePriceQueueForUpdateIdList = []; + $roomRatePriceQueue = $bulkQueueData; + + + foreach ($roomRatePriceQueue as $roomRatePrice) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomRatePrice['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomRatePrice, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomRatePrice['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping_id', $roomRatePrice['room_rate_mapping_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomRatePrice['id']; + + //TODO: Burada oda eşleşmiyorsa süreç devam ediyor ama uyarı maili atılabilir. + + continue; + } + + + $roomRatePriceQueueForUpdateIdList + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']][] = $roomRatePrice['id']; + + + $roomRatePriceQueueForUpdate + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']] + [$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']] = [ + 'id' => $roomRatePrice['id'], + 'idList' => $roomRatePriceQueueForUpdateIdList[$channelManagerPropertyMapping['channel_manager_property_id']][$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']][$channelManagerRoomRate['channel_manager_room_rate_id']], + 'date' => $roomRatePrice['date'], + 'amount' => $roomRatePrice['amount'], + 'currency' => $roomRatePrice['currency'], + 'stop_sell' => $roomRatePrice['stop_sell'], + 'min_stay' => $roomRatePrice['min_stay'], + ]; + + } + + + foreach ($roomRatePriceQueueForUpdate as $channelManagerPropertyId => $channelManagerProperty) { + + + if (empty($channelManagerProperty)) { + throw new ApiErrorException('$channelManagerProperty is Empty!'); + } + + + $roomRateUpdateRequestMultiParam = $this->roomRateUpdateRequestMultiParam($channelManagerPropertyId, $channelManagerProperty); + $request = $this->inventoryRoomRateUpdate('webservice_updater.apro', $roomRateUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomRateUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($request, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + } + + } + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + */ + +} diff --git a/app/Core/Service/ChannelManager/Reseliva.php b/app/Core/Service/ChannelManager/Reseliva.php new file mode 100644 index 0000000..30aeeea --- /dev/null +++ b/app/Core/Service/ChannelManager/Reseliva.php @@ -0,0 +1,1236 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->url = 'https://www.reseliva.net/siteBase/REST/cms/service/'; + //$this->url = 'https://api.reseliva.com/pms/service/'; + $this->reservationPushUrl = 'https://www.reseliva.net/siteBase/utility/CM/ExtranetWork/notify.php'; + + $this->statusMapping = [ + 'A' => 'Active', + 'C' => 'Canceled', + 'M' => 'Modified', + ]; + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->paymentTypeMapping = [ + 'MO' => 'Money Order', + 'CC' => 'Credit Card given', + 'POS' => 'Payed with payment system', + 'PayPal' => 'Payed with PayPal' + ]; + + $this->channelManagerId = 1; + $this->channelManagerName = 'Reseliva'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function requestPost($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->url . $method, + [ + 'headers' => [ + 'Content-Type' => 'text/xml; charset=UTF8', + 'Accept' => 'text/xml' + ], + 'body' => $xmlPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + + if (empty($getResponse)) { + throw new ApiErrorException('Empty XML response'); + } + + $getResponseXml = new \SimpleXMLElement($getResponse, LIBXML_NOCDATA); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + $response = ["status" => true, 'message' => '', "data" => $getResponse]; + + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage() . ' ' . $method; + Log::error($message); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage() . ' ' . $method; + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function productList($reselivaPropertyId) + { + $response = ['status' => false, 'message' => '']; + + try { + + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $reselivaPropertyId); + + $xmlPayload = $requestParam->asXML(); + + $request = $this->requestPost('product_list', $xmlPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $responseData = []; + $responseData['hotelId'] = $request['data']['@attributes']['hotel_id']; + + $roomType = singleElementXMLArray($request['data']['RoomType']); + foreach ($roomType as $room) { + + $responseData['rooms'][$room['@attributes']['id']] = [ + 'id' => $room['@attributes']['id'], + 'name' => $room['@attributes']['name'], + ]; + + $room['RatePlan'] = singleElementXMLArray($room['RatePlan']); + foreach ($room['RatePlan'] as $rate) { + + $responseData['rooms'][$room['@attributes']['id']]['rate'][$rate['@attributes']['id']] = [ + 'id' => $rate['@attributes']['id'], + 'name' => htmlspecialchars_decode($rate['@attributes']['name']), + ]; + + } + + } + + $response = [ + 'status' => true, + 'data' => $responseData + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function inventoryRoomRateUpdate($xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->requestPost('inventory', $xmlPayload); + + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + if (!isset($request['data']['success'])) { + $request['data']['error']['erroritem'] = singleElementXMLArray($request['data']['error']['erroritem']); + $errorsCollect = collect($request['data']['error']['erroritem']); + throw new ApiErrorException($request['data']['error']['@attributes']['msg'] . '. Errors: ' . implode(', ', $errorsCollect->pluck('@attributes.desc')->toArray())); + } + + $response = [ + 'status' => true, + 'data' => [ + 'confirmId' => $request['data']['rqid'] + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + /** Pattern Functions */ + + public function availabilityUpdateRequestMultiParam($propertyId, $params) + { + + $idList = []; + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $propertyId); + + $inventory = $requestParam->addChild('inventory'); + + foreach ($params as $updateDate => $rooms) { + + //foreach + $day = $inventory->addChild('day'); + $date = $day->addChild('date'); + $date->addAttribute('from', $updateDate); + $date->addAttribute('to', $updateDate); + + $roomTypes = $day->addChild('roomtypes'); + + foreach ($rooms as $roomId => $value) { + //foreach + $roomType = $roomTypes->addChild('roomtype'); + $roomType->addAttribute('reseliva_id', $roomId); + $roomType->addAttribute('availability', fillOnUndefined($value, 'availability', 0)); + $roomType->addAttribute('stopsale', fillOnUndefined($value, 'stop_sell', 0)); + + $idList = array_merge($idList, $value['idList']); + + } + + } + + return [ + 'idList' => $idList, + 'xmlPayload' => $requestParam->asXML() + ]; + } + + public function roomAvailabilityPush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = []; + + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomAvailabilityQueueForUpdate = []; + $roomAvailabilityQueueForUpdateIdList = []; + $roomAvailabilityQueue = $bulkQueueData; + + + foreach ($roomAvailabilityQueue as $roomAvailability) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomAvailability['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomAvailability, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomAvailability['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping.room_id', $roomAvailability['property_room_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomAvailability['id']; + + continue; + } + + $roomAvailabilityQueueForUpdateIdList + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomAvailability['date']][] = $roomAvailability['id']; + + + $roomAvailabilityQueueForUpdate + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomAvailability['date']] + [$channelManagerRoomRate['channel_manager_room_id']] = [ + 'id' => $roomAvailability['id'], + 'idList' => $roomAvailabilityQueueForUpdateIdList[$channelManagerPropertyMapping['channel_manager_property_id']][$roomAvailability['date']], + 'date' => $roomAvailability['date'], + 'availability' => $roomAvailability['availability'], + 'stop_sell' => $roomAvailability['stop_sell'], + ]; + + } + + foreach ($roomAvailabilityQueueForUpdate as $channelManagerPropertyId => $channelManagerProperty) { + + try { + + ksort($channelManagerProperty); + $roomAvailabilityUpdateRequestMultiParam = $this->availabilityUpdateRequestMultiParam($channelManagerPropertyId, $channelManagerProperty); + + $request = $this->inventoryRoomRateUpdate($roomAvailabilityUpdateRequestMultiParam['xmlPayload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomAvailabilityUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode[] = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateAvailabilityUpdate Error', + 'logMessage' => '
' . print_r(array_merge($request, $channelManagerProperty), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + } catch (ApiErrorException $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . implode(', ', $e->getMessageArr()); + Log::error($message); + //$response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + //$response['message'] = $e->getMessage(); + } + + } + + } else { + $channelManagerNoneMappingIds = collect($bulkQueueData)->pluck('id')->toArray(); + } + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + return $response; + } + + + public function roomRateUpdateRequestMultiParam($propertyId, $params) + { + $idList = []; + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $propertyId); + + $inventory = $requestParam->addChild('inventory'); + + foreach ($params as $updateDate => $rooms) { + + //foreach + $day = $inventory->addChild('day'); + $date = $day->addChild('date'); + $date->addAttribute('from', $updateDate); + $date->addAttribute('to', $updateDate); + + $roomTypes = $day->addChild('roomtypes'); + + foreach ($rooms as $roomId => $rates) { + + //foreach + $roomType = $roomTypes->addChild('roomtype'); + $roomType->addAttribute('reseliva_id', $roomId); + //$roomType->addAttribute('stopsale', fillOnUndefined($value, 'stop_sell')); + + foreach ($rates as $rateId => $value) { + //foreach + $ratePlan = $roomType->addChild('RatePlan'); + $ratePlan->addAttribute('reseliva_id', $rateId); + $rate = $ratePlan->addChild('Rate'); + $rate->addAttribute('price1', floatval($value['amount'])); + + $restrictions = $ratePlan->addChild('Restrictions'); + $restrictions->addAttribute('closed', fillOnUndefined($value, 'stop_sell', 0)); + + if (isset($value['min_stay']) && !in_array($value['min_stay'], [0])) { + $restrictions->addAttribute('minLOS', fillOnUndefined($value, 'min_stay', 1)); + } + + $idList = array_merge($idList, $value['idList']); + } + + } + + } + + return [ + 'idList' => $idList, + 'xmlPayload' => $requestParam->asXML() + ]; + + } + + public function roomRatePricePush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + try { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = null; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomRatePriceQueueForUpdate = []; + $roomRatePriceQueueForUpdateIdList = []; + $roomRatePriceQueue = $bulkQueueData; + + + foreach ($roomRatePriceQueue as $roomRatePrice) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomRatePrice['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomRatePrice, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomRatePrice['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping_id', $roomRatePrice['room_rate_mapping_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomRatePrice['id']; + + continue; + } + + + $roomRatePriceQueueForUpdateIdList + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']][] = $roomRatePrice['id']; + + + $roomRatePriceQueueForUpdate + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']] + [$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']] = [ + 'id' => $roomRatePrice['id'], + 'idList' => $roomRatePriceQueueForUpdateIdList[$channelManagerPropertyMapping['channel_manager_property_id']][$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']][$channelManagerRoomRate['channel_manager_room_rate_id']], + 'date' => $roomRatePrice['date'], + 'amount' => $roomRatePrice['amount'], + 'currency' => $roomRatePrice['currency'], + 'stop_sell' => $roomRatePrice['stop_sell'], + 'min_stay' => $roomRatePrice['min_stay'], + ]; + + } + + + foreach ($roomRatePriceQueueForUpdate as $channelManagerPropertyId => $channelManagerProperty) { + + + if (empty($channelManagerProperty)) { + throw new ApiErrorException('$channelManagerProperty is Empty!'); + } + + ksort($channelManagerProperty); + $roomRateUpdateRequestMultiParam = $this->roomRateUpdateRequestMultiParam($channelManagerPropertyId, $channelManagerProperty); + + $request = $this->inventoryRoomRateUpdate($roomRateUpdateRequestMultiParam['xmlPayload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomRateUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($request, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + } + + } + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + public function reservationPullFormattedData($propertyId, $channelManagerPropertyId, $param) + { + + $bookingParam = []; + + $response = ['status' => false, 'message' => '']; + + try { + + $isB2CBooking = false; + + //Check Channel Manager Mapping + $channelManagerMappingCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyChannelManager'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerMappingData = $this->channelManagerMappingService->select($channelManagerMappingCriteria); + $channelManagerMappingCollect = collect($channelManagerMappingData['data']); + $channelManagerMapping = $channelManagerMappingCollect->where('channel_manager_channel_id', $param['otaname'])->first(); + + + //Eğer kanala ait bir otel yok ise devam et + if (empty($channelManagerMapping)) { + //TODO: hata dönecek + //throw new ApiErrorException($request['message']); + } + //Check Channel Manager Mapping + + + //Check Channel Manager Property Mapping + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + //Eğer kanala ait bir otel yok ise devam et + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + ///TODO: hata dönecek + /// throw new ApiErrorException($request['message']); + } + + $channelManagerRoomRateCollect = collect($channelManagerPropertyMapping['data']['channel_manager_room_rate']); + + + if (empty(fillOnUndefined($param, 'reservno_ota'))) { + $param['reservno_ota'] = null; + } + + $roomRequest = []; + foreach ($param['room'] as $room) { + $roomRequest[] = [ + 'adults' => $room['totalpax'], + 'children' => $room['totalchd'], + 'age' => [] + ]; + } + + $paymentTypeCode = 'HTL'; + $paymentSourceCode = null; + if (isset($param['cc_token']) && !empty($param['cc_token'])) { + $paymentTypeCode = 'CRD'; + if (empty($param['prepaid'])) { + $paymentSourceCode = 'GST'; + } + if (!empty($param['prepaid'])) { + $paymentSourceCode = 'OTA'; + } + } + + //Booking + $bookingParam['booking'] = [ + 'id' => null, + 'booking_code' => null, + 'property_id' => $propertyId, + 'channel_manager_id' => $this->channelManagerId, + 'channel_id' => $channelManagerMapping['property_channel_id'], + 'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'), + 'search_key' => $param['reservno'], + 'checkin_date' => $param['checkinFormatted'], + 'checkout_date' => $param['checkoutFormatted'], + 'rooms' => json_encode($roomRequest), + 'payment_type_code' => $paymentTypeCode, + 'room_amount' => $param['paymenttotal'], + 'addon_amount' => 0, + 'discount_amount' => 0, + 'total' => $param['paymenttotal'], + 'currency_code' => $param['paymentcurr'], + 'channel_token' => null, + 'booking_engine_token' => null, + 'reservation_time' => $param['restimeUnixFormatted'], + 'status' => $param['status'] == 'A' ? 1 : 0 + ]; + + $extraParamBookingContact = []; + + //Booking Contact + $bookingParam['contact'] = [ + 'name' => $param['firstname'], + 'surname' => !empty($param['lastname']) ? $param['lastname'] : null, + 'phone_code' => null, + 'phone_number' => fillOnUndefined($param, 'tel'), + 'email' => fillOnUndefined($param, 'email'), + 'country_code' => fillOnUndefined($param, 'country'), + 'note' => !empty($param['note']) ? $param['note'] : null, + 'language_code' => fillOnUndefined($param, 'language', 'en'), + 'extra_param' => !empty($extraParamBookingContact) ? json_encode($extraParamBookingContact) : null, + 'status' => 1 + ]; + + $bookingParam['contact']['language_code'] = mb_substr($bookingParam['contact']['language_code'], 0, 2); + $bookingParam['contact']['country_code'] = mb_strtolower($bookingParam['contact']['country_code']); + + //Booking Room + $param['room'] = array_values($param['room']); + foreach ($param['room'] as $roomOrder => $room) { + + + //Check Room Rate Mapping + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->where('channel_manager_room_rate_id', $room['rateid'])->first(); + if (empty($channelManagerRoomRate)) { + $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->first(); + } + + $dailyAmount = []; + if (isset($room['price_breakdown']) && !empty($room['price_breakdown'])) { + foreach ($room['price_breakdown'] as $roomAmount) { + if (isset($roomAmount['@attributes'])) { + $dailyAmount[] = [ + 'date' => Carbon::parse($roomAmount['@attributes']['date'])->toDateString(), + 'amount' => floatval($roomAmount['@attributes']['price']), + 'currency_code' => $param['paymentcurr'] + ]; + } + } + } + + + $extraParamRoom = []; + + $bookingParam['room'][] = [ + 'room_order_number' => ($roomOrder + 1), + 'occupancy_code' => str_repeat('A', $room['totalpax']) . str_repeat('C', $room['totalchd']), + 'checkin_date' => $param['checkinFormatted'], //$room['checkin'], + 'checkout_date' => $param['checkoutFormatted'],//$room['checkout'], + 'rate_key' => null, + 'rate_key_code' => null, + 'availability_id' => 1, + 'availability_code' => 'ROM', + 'room_id' => $channelManagerRoomRate['property_room_rate_mapping']['room_id'], + 'room_name' => !empty($room['roomtype']) ? html_entity_decode($room['roomtype']) : null, + 'room_rate_mapping_id' => $channelManagerRoomRate['property_room_rate_mapping']['id'], + 'room_rate_name' => !empty($room['ratename']) ? html_entity_decode($room['ratename']) : null, + 'cancellation_policy' => null, + 'payment_type_code' => $paymentTypeCode, + 'daily_amount' => !empty($dailyAmount) ? json_encode($dailyAmount) : null, + 'extra_param' => !empty($extraParamRoom) ? json_encode($extraParamRoom) : null, + 'rate_detail' => json_encode($room), + 'total' => $room['total_amount'], + 'currency_code' => $param['paymentcurr'], + 'status' => $param['status'] == 'A' ? 1 : 0 + ]; + + + if (!$isB2CBooking && (mb_strpos(html_entity_decode($room['ratename']), 'B2C') || mb_strpos(html_entity_decode($room['ratename']), 'OPAQUE')) ) { + $isB2CBooking = true; + } + + } + + + //Booking Payment Data + $bookingParam['payment'] = [ + 'payment_code' => (isset($param['cc_token']) && !empty($param['cc_token'])) ? fillOnUndefined($param, 'cc_token') : null, + 'payment_type_code' => $paymentTypeCode, + 'payment_source_code' => $paymentSourceCode, + 'extra_param' => json_encode($param), + 'total' => $param['paymenttotal'], + 'currency_code' => $param['paymentcurr'], + 'status' => 2 + ]; + + + //Booking Channel Payment Data + $bookingParam['payment_channel'] = null; + if (isset($param['cc_token']) && !empty($param['cc_token'])) { + + $bookingParam['payment_channel'] = [ + 'type' => 'ch', + 'data' => md5($param['reservno'] . $channelManagerPropertyMapping['data']['channel_manager_property_id'] . $param['cc_token']) + ]; + + } + + //Channel Manager ETC Params + $bookingParam['channel_manager'] = [ + 'property_id' => $channelManagerPropertyId, + 'booking_id' => $param['reservno'], + 'sub_channel' => $param['otaname'], + 'sub_channel_booking_id' => $param['reservno_ota'], + 'sub_channel_source' => $param['source'], + ]; + + $statusType = null; + if ($param['status'] == 'A') { + $statusType = 'createBooking'; + } elseif ($param['status'] == 'C') { + $statusType = 'cancelBooking'; + } elseif ($param['status'] == 'M') { + $statusType = 'modifiedBooking'; + } + + //362: Barın Hotel, 34: Hotelbeds + if (in_array($propertyId, [362]) && in_array($bookingParam['booking']['channel_id'], [34])) { + if($isB2CBooking) { + //312: Hotelbeds B2C + $bookingParam['booking']['channel_id'] = 312; + } + } + + + //$statusType = 'modifiedBooking'; + + $response['status'] = true; + $response['type'] = $statusType; + $response['data'] = $bookingParam; + + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function reservationListParam($channelManagerPropertyId) + { + + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $channelManagerPropertyId); + $requestParam->addChild('include_price_breakdown', 1); + + return $requestParam->asXML(); + } + + public function reservationList($xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->requestPost('reservation_list', $xmlPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $responseData = []; + $reservationList = isset($request['data']['reservation']) ? singleElementXMLArray($request['data']['reservation']) : []; + foreach ($reservationList as $reservation) { + + if(Carbon::parse($reservation['checkin'])->toDateString() < Carbon::now()->toDateString() && $reservation['status'] == 'A') { + continue; + } + + $reservation['paymenttype'] = empty($reservation['paymenttype']) ? null : $reservation['paymenttype']; + + $responseData[$reservation['reservno']] = [ + 'reservno' => $reservation['reservno'], + 'firstname' => $reservation['firstname'], + 'lastname' => $reservation['lastname'], + 'email' => !empty($reservation['email']) ? $reservation['email'] : null, + 'tel' => !empty($reservation['tel']) ? $reservation['tel'] : null, + 'status' => $reservation['status'], + 'statusText' => fillOnUndefined($this->statusMapping, $reservation['status']), + 'resdate' => $reservation['resdate'], + 'restime' => $reservation['restime'], + 'restimeUnixFormatted' => Carbon::parse($reservation['restime'],'UTC')->timestamp, + 'resdateFormatted' => Carbon::parse($reservation['resdate'])->toDateString(), + 'checkin' => $reservation['checkin'], + 'checkinFormatted' => Carbon::parse($reservation['checkin'])->toDateString(), + 'checkout' => $reservation['checkout'], + 'checkoutFormatted' => Carbon::parse($reservation['checkout'])->toDateString(), + 'nation' => !empty($reservation['nation']) ? $reservation['nation'] : null, + 'paymentcurr' => $reservation['paymentcurr'], + 'paymenttotal' => $reservation['paymenttotal'], + 'source' => $reservation['source'], + 'otaname' => $reservation['otaname'], + 'reservno_ota' => $reservation['reservno_ota'], + 'prepaid' => $reservation['prepaid'], + 'paymenttype' => $reservation['paymenttype'], + 'paymentTypeText' => fillOnUndefined($this->paymentTypeMapping, $reservation['paymenttype']), + 'restotalpax' => $reservation['restotalpax'], + 'restotalchd' => $reservation['restotalchd'], + 'note' => $reservation['note'], + 'cc_token' => fillOnUndefined($reservation, 'cc_token'), + ]; + + $roomList = singleElementXMLArray($reservation['rooms']['room']); + foreach ($roomList as $room) { + + $room['rateid'] = !empty($room['rateid']) ? $room['rateid'] : null; + $room['ratename'] = !empty($room['ratename']) ? $room['ratename'] : null; + $room['price_breakdown'] = !empty($room['price_breakdown']) && isset($room['price_breakdown']['day']) ? singleElementXMLArray($room['price_breakdown']['day']) : null; + + $responseData[$reservation['reservno']]['room'][] = $room; + } + + } + + $response = [ + 'status' => true, + 'data' => $responseData + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + public function reservationConfirmParam($propertyId, $channelManagerBookingId, $bookingCode, $param = []) + { + + $userId = Config::get('app.channelManager.reseliva.userId'); + $userPSW = Config::get('app.channelManager.reseliva.userPassword'); + + $requestParam = new \SimpleXMLElement(''); + + $Authentication = $requestParam->addChild('Authentication'); + $Authentication->addChild('UserID', $userId); + $Authentication->addChild('UserPSW', $userPSW); + $Authentication->addChild('PropertyID', $propertyId); + + $reservations = $requestParam->addChild('reservations'); + $reservation = $reservations->addChild('reservation'); + $reservation->addAttribute('reseliva_id', $channelManagerBookingId); + $reservation->addAttribute('pms_id', $bookingCode); + + return $requestParam->asXML(); + } + + public function reservationConfirm($xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + $request = $this->requestPost('reservation_confirm', $xmlPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + if (!isset($request['data']['success'])) { + $request['data']['error']['erroritem'] = singleElementXMLArray($request['data']['error']['erroritem']); + $errorsCollect = collect($request['data']['error']['erroritem']); + throw new ApiErrorException($request['data']['error']['@attributes']['msg'] . '. Errors: ' . implode(', ', $errorsCollect->pluck('@attributes.desc')->toArray())); + } + + $response = [ + 'status' => true, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $bookingDetail = $param['booking_detail']; + + $type = $this->typeMapping[$type]; + + $serviceRequestName = 'BookingRetrieval'; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + if (in_array($bookingDetail['status'], [0, 3])) { + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + if (Carbon::createFromTimestamp($param['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) { + $Booking->addAttribute('id', $bookingDetail['id']); + } else { + $Booking->addAttribute('id', $bookingDetail['booking_code']); + } + + $Booking->addAttribute('type', 'Cancel'); + $Booking->addAttribute('cancelDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + } + + } else { + + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + if (Carbon::createFromTimestamp($param['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) { + $Booking->addAttribute('id', $bookingDetail['id']); + } else { + $Booking->addAttribute('id', $bookingDetail['booking_code']); + } + + //Book ve Modify Aynı olacak, Cancel + if ($type == 'Book') { + $Booking->addAttribute('type', 'Book'); + $Booking->addAttribute('createDateTime', Carbon::createFromTimestamp($bookingDetail['created_at'])->toISOString()); + } + + if ($type == 'Modify') { + $Booking->addAttribute('type', 'Modify'); + $Booking->addAttribute('modifyDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + } + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + + $roomPaxCollect = collect($room['room_pax']); + + $GuestCount = $RoomStay->addChild('GuestCount'); + $GuestCount->addAttribute('adult', $roomPaxCollect->where('type', 'ADT')->count()); + $GuestCount->addAttribute('child', $roomPaxCollect->where('type', 'CHD')->count()); + + if($roomPaxCollect->where('type', 'CHD')->count() > 0) { + $roomPaxChild = $roomPaxCollect->where('type', 'CHD')->toArray(); + foreach ($roomPaxChild as $child) { + $Child = $GuestCount->addChild('Child'); + $Child->addAttribute('age',Carbon::now()->diffInYears(Carbon::parse($child['birth_date'])->toDateString())); + } + } + + $diffInDays = Carbon::parse($room['checkin_date'])->diffInDays(Carbon::parse($room['checkout_date'])); + + //dd($room['total'], $diffInDays, $room); + + $PerDayRates = $RoomStay->addChild('PerDayRates'); + $PerDayRates->addAttribute('currency', $room['currency_code']); + + $baseRateDaily = moneyDoubleFormatDecimal($room['total'] / $diffInDays); + + $currentDate = $room['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $PerDayRate = $PerDayRates->addChild('PerDayRate'); + $PerDayRate->addAttribute('stayDate', $currentDate); + $PerDayRate->addAttribute('baseRate', $baseRateDaily); + $PerDayRate->addAttribute('hotelServiceFees', 0); + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + $Total = $RoomStay->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $room['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $room['currency_code']); + + $roomNotes['cancellationPolicy'] = 'Cancellation Policy: Refundable'; + $cancellationPolicy = json_decode($room['cancellation_policy'], 1); + if (!empty($cancellationPolicy) && is_array($cancellationPolicy)) { + if (isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) { + $roomNotes['cancellationPolicy'] = 'Cancellation Policy: NonRefundable'; + } + } + + $roomNotes['payment'] = 'Payment: ' . $bookingDetail['booking_payment_type']['name']; + + $RoomStay->addChild('RoomNotes', implode('. ', $roomNotes)); + + } + + + $PrimaryGuest = $Booking->addChild('PrimaryGuest'); + + $Name = $PrimaryGuest->addChild('Name'); + $Name->addAttribute('givenName', $bookingDetail['booking_contact']['name']); + $Name->addAttribute('surname', $bookingDetail['booking_contact']['surname']); + + $Phone = $PrimaryGuest->addChild('Phone'); + $Phone->addAttribute('countryCode', $bookingDetail['booking_contact']['phone_code']); + //$Phone->addAttribute('cityAreaCode'); + $Phone->addAttribute('number', $bookingDetail['booking_contact']['phone_number']); + + $PrimaryGuest->addChild('Email', $bookingDetail['booking_contact']['email']); + + if(fillOnUndefined($bookingDetail['booking_contact'],'language_code')) { + $Booking->addChild('CountryCode', $bookingDetail['booking_contact']['language_code']); + } + + $Total = $Booking->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $bookingDetail['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $bookingDetail['currency_code']); + + + $Booking->addChild('SpecialRequest'); + $Booking->addChild('BookingNotes', htmlspecialchars($bookingDetail['booking_contact']['note'])); + + } + + return $xmlResponse->asXML(); + + } + + public function requestPostReservationPush($xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + //U : uExtranetWork + //P : ExtrntWrk21!*22 + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->reservationPushUrl, + [ + 'headers' => [ + 'Content-Type' => 'text/xml; charset=UTF8', + 'Authorization' => 'Basic dUV4dHJhbmV0V29yazpFeHRybnRXcmsyMSEqMjI=', + 'Accept' => 'text/xml' + ], + 'body' => $xmlPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseXmlBase = $getResponseBody->getContents(); + + $getResponseXml = new \SimpleXMLElement($getResponseXmlBase, LIBXML_NOCDATA); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + if ($getResponse['Status'] != 'success') { + throw new ApiErrorException('requestPostReservationPush Error channelManagerName: ' . $this->channelManagerName); + } + + $response = ['status' => true, 'message' => '', 'response' => $getResponseXmlBase]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/SistemOtel.php b/app/Core/Service/ChannelManager/SistemOtel.php new file mode 100644 index 0000000..7fa6a3f --- /dev/null +++ b/app/Core/Service/ChannelManager/SistemOtel.php @@ -0,0 +1,252 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = 'https://cm.istbooking.com/push/extranetwork'; + + + $this->typeMapping = [ + 'Booking' => 'Book', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->channelManagerId = 6; + $this->channelManagerName = 'SistemOtel'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + $this->channelManagerBookingService = $channelManagerBookingService; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + + $jsonResponse = []; + $jsonResponse['hotel_id'] = $propertyId; + + + $jsonResponse['reservation']['code'] = $bookingDetail['booking_code']; + $jsonResponse['reservation']['status'] = $type; + + $jsonResponse['reservation']['time'] = Carbon::createFromTimestamp($param['booking_detail']['created_at'])->toDateTimeString(); + + $jsonResponse['reservation']['checkin_date'] = $bookingDetail['checkin_date']; + $jsonResponse['reservation']['checkout_date'] = $bookingDetail['checkout_date']; + $jsonResponse['reservation']['currency'] = $bookingDetail['currency_code']; + $jsonResponse['reservation']['total'] = $bookingDetail['total']; + + + $jsonResponse['reservation']['contact'] = [ + 'name' => $bookingDetail['booking_contact']['name'], + 'surname' => $bookingDetail['booking_contact']['surname'], + 'email' => $bookingDetail['booking_contact']['email'], + 'phone' => $bookingDetail['booking_contact']['phoneFormatted'], + 'note' => $bookingDetail['booking_contact']['note'], + ]; + + + $jsonResponse['reservation']['rooms'] = []; + + + $roomKey = 0; + $additionalNoteText = []; + foreach ($bookingDetail['booking_room'] as $roomKey => $roomDetail) { + + if ($roomDetail['status'] != 1) { + continue; + } + + $occupancy = occupancyCodeParser($roomDetail['occupancy_code']); + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + + $dailyPrices = []; + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $dailyPrices[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + $roomPax = []; + foreach ($roomDetail['room_pax'] as $pax) { + $roomPax[] = [ + 'type' => $pax['type'], + 'name' => $pax['name'], + 'surname' => $pax['surname'], + 'gender' => $pax['gender'], + 'citizen' => $pax['citizen'], + 'birth_date' => $pax['birth_date'], + ]; + } + + $cancellationPolicy = []; + $cancellationPolicyRoom = json_decode($roomDetail['cancellation_policy'], 1); + if ($cancellationPolicyRoom) { + $cancellationPolicy = [ + 'is_nonrefundable' => fillOnUndefined($cancellationPolicyRoom, 'isNonRefundable') == 1 ? true : false, + 'is_freecancellation' => fillOnUndefined($cancellationPolicyRoom, 'isFreeCancellation') == 1 ? true : false, + 'before_arrival_day' => fillOnUndefined($cancellationPolicyRoom, 'isFreeCancellation') == 1 ? fillOnUndefined($cancellationPolicyRoom, 'beforeArrivalDay') : null, + 'type' => fillOnUndefined($cancellationPolicyRoom, 'type') == 1 ? fillOnUndefined($cancellationPolicyRoom, 'type') : null, + 'value' => fillOnUndefined($cancellationPolicyRoom, 'value') == 1 ? fillOnUndefined($cancellationPolicyRoom, 'value') : null, + 'text' => null, + ]; + + $cancellationPolicyTextFormatted = cancellationPolicyTextFormatted( + fillOnUndefined($cancellationPolicyRoom, 'isNonRefundable'), + fillOnUndefined($cancellationPolicyRoom, 'isFreeCancellation'), + fillOnUndefined($cancellationPolicyRoom, 'beforeArrivalDay'), + fillOnUndefined($cancellationPolicyRoom, 'type'), + fillOnUndefined($cancellationPolicyRoom, 'value'), + $bookingDetail['currency_code'], + 'en' + ); + + if($cancellationPolicyTextFormatted) { + $cancellationPolicy['text'] = $cancellationPolicyTextFormatted; + } + } + + $jsonResponse['reservation']['rooms'][$roomKey] = [ + 'id' => $roomDetail['id'], + 'room_id' => $roomDetail['room_id'], + 'room_name' => $roomDetail['room_name'], + 'rate_id' => $roomDetail['room_rate_mapping_id'], + 'rate_name' => $roomDetail['room_rate_name'], + 'cancellation_policy' => $cancellationPolicy, + 'occupancy' => [ + 'adults' => $occupancy['ADT'], + 'children' => $occupancy['CHD'], + 'age' => $occupancy['AGE'], + ], + 'daily' => $dailyPrices, + 'pax' => $roomPax, + + ]; + + if(isset($jsonResponse['reservation']['rooms'][$roomKey]['cancellation_policy']['text'])) { + $additionalNoteText[] = ($roomKey + 1).'. '.$jsonResponse['reservation']['rooms'][$roomKey]['room_name'].' - '.$jsonResponse['reservation']['rooms'][$roomKey]['rate_name']. ' ('.$jsonResponse['reservation']['rooms'][$roomKey]['cancellation_policy']['text'].')'; + } + + } + + $additionalNoteText[] = 'Payment: '.$bookingDetail['booking_payment_type']['code'].' - '.$bookingDetail['booking_payment_type']['name']; + + $jsonResponse['reservation']['contact']['note'].=implode(', ',$additionalNoteText); + + $jsonResponse['reservation']['channel'] = [ + 'id' => $bookingDetail['booking_channel']['id'], + 'name' => $bookingDetail['booking_channel']['id'] == 1 ? 'Extranetwork' : $bookingDetail['booking_channel']['name'], + ]; + + $jsonResponse['reservation']['payment'] = [ + 'code' => $bookingDetail['booking_payment_type']['code'], + 'name' => $bookingDetail['booking_payment_type']['name'], + ]; + + return json_encode($jsonResponse); + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->reservationPushUrl, + [ + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + $getResponseBody = $res->getBody(); + $getResponseJsonBase = $getResponseBody->getContents(); + + $getResponse = json_decode($getResponseJsonBase, 1); + + if (!$getResponse['status']) { + if($getResponse['message'] == 'HOTEL_TANIMLI_DEGIL') { + + $jsonPayloadArray = json_decode($jsonPayload,1); + $bookingCriteria = [ + 'criteria' => + [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'type', 'condition' => '=', 'value' => array_search($jsonPayloadArray['reservation']['status'], $this->typeMapping)], + ['field' => 'request', 'condition' => 'LIKE', 'value' => '%'.$jsonPayloadArray['reservation']['code'].'%'], + ], + 'firstRow' => true + ]; + + $channelManagerBookingDetail = $this->channelManagerBookingService->select($bookingCriteria); + if($channelManagerBookingDetail['status'] == 'success' && !empty($channelManagerBookingDetail['status'])) { + $channelManagerBookingDetail = $channelManagerBookingDetail['data']; + $this->channelManagerBookingService->update($channelManagerBookingDetail['id'], ['status' => 2]); + } + + } + throw new ApiErrorException($getResponse['message']); + } + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/Trivago.php b/app/Core/Service/ChannelManager/Trivago.php new file mode 100644 index 0000000..d8c8c3f --- /dev/null +++ b/app/Core/Service/ChannelManager/Trivago.php @@ -0,0 +1,208 @@ +restClient = $restClient; + $this->mailer = $mailer; + $this->reservationPushUrl = 'https://secde.trivago.com/tracking/booking'; + + + $this->typeMapping = [ + 'Booking' => 'Booking', + 'Modify' => 'Modify', + 'Cancel' => 'Cancel' + ]; + + $this->channelManagerId = 11; + $this->channelManagerName = 'Trivago'; + $this->xTrvAnaKey = '1fe8a527-cbcb-4e01-9a3c-31444d47c422'; + $this->advertiserId = 3698; + + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + $this->bookingService = $bookingService; + + } + + public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = []) + { + + $type = $this->typeMapping[$type]; + $bookingDetail = $param['booking_detail']; + + $jsonResponse = []; + + $extraParam = json_decode($bookingDetail['extra_param'], 1); + if (!isset($extraParam['trv_reference'])) { + return $jsonResponse; + } + + $locale = 'TR'; + if(isset($extraParam['locale'])) { + $locale = $extraParam['locale']; + } + + if($bookingDetail['total'] > 0) { + $bookingDetail['total'] = $bookingDetail['total']; + } else { + $bookingDetail['total'] = $bookingDetail['booking_payment']['total']; + } + + $jsonResponse['trv_reference'] = $extraParam['trv_reference']; + $jsonResponse['advertiser_id'] = $this->advertiserId; + $jsonResponse['hotel'] = $bookingDetail['property_id']; + $jsonResponse['arrival'] = Carbon::parse($bookingDetail['checkin_date'])->format('Ymd'); + $jsonResponse['departure'] = Carbon::parse($bookingDetail['checkout_date'])->format('Ymd'); + $jsonResponse['date_format'] = 'Ymd'; + $jsonResponse['volume'] = $bookingDetail['total']; + $jsonResponse['currency'] = $bookingDetail['currency_code']; + $jsonResponse['locale'] = mb_strtoupper($locale); + $jsonResponse['booking_id'] = $bookingDetail['booking_code']; + //$jsonResponse['margin'] = $bookingDetail['booking_code']; + $jsonResponse['booking_date'] = Carbon::createFromTimestamp($bookingDetail['created_at'])->subHours(3)->format('YmdHisP'); + $jsonResponse['booking_date_format'] = 'YmdHisP'; + $jsonResponse['number_of_rooms'] = count($bookingDetail['booking_room']); + + if ($type == 'Modify') { + $jsonResponse['update_date'] = Carbon::createFromTimestamp($param['created_at'])->subHours(3)->format('YmdHisP'); + $jsonResponse['update_date_format'] = 'YmdHisP'; + $jsonResponse['update_origin'] = 'user'; + } + + if ($type == 'Cancel') { + $jsonResponse['refund_amount'] = $bookingDetail['total']; + $jsonResponse['cancellation_date'] = Carbon::createFromTimestamp($param['created_at'])->subHours(3)->format('YmdHisP'); + $jsonResponse['cancellation_date_format'] = 'YmdHisP'; + } + + $jsonResponse['params']['type'] = $type; + + return json_encode($jsonResponse); + + } + + public function requestPostReservationPush($jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + + $getResponse = []; + $this->restClient = new Client(['http_errors' => false]); + + try { + + + + $jsonData = json_decode($jsonPayload, 1); + $jsonDataParams = $jsonData['params']; + unset($jsonData['params']); + $jsonPayload = json_encode($jsonData); + + + switch ($jsonDataParams['type']) { + case 'Booking': + + $request = $this->restClient->post($this->reservationPushUrl, + [ + 'headers' => [ + 'X-Trv-Ana-Key' => $this->xTrvAnaKey, + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + break; + case 'Modify': + + $request = $this->restClient->put($this->reservationPushUrl, + [ + 'headers' => [ + 'X-Trv-Ana-Key' => $this->xTrvAnaKey, + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + break; + case 'Cancel': + + $request = $this->restClient->delete($this->reservationPushUrl, + [ + 'headers' => [ + 'X-Trv-Ana-Key' => $this->xTrvAnaKey, + 'Content-Type' => 'application/json' + ], + 'body' => $jsonPayload, + ] + ); + + break; + case 'default': + throw new ApiErrorException('Reservation push type not found.'); + break; + + } + + $getResponseBody = $request->getBody(); + $getResponseJsonBase = $getResponseBody->getContents(); + + $getResponse = json_decode($getResponseJsonBase, 1); + + Log::debug($jsonPayload); + Log::debug(json_encode($getResponse)); + + //dd($getResponse); + + if ($getResponse['state'] != 'OK') { + throw new ApiErrorException($getResponse['errorMessage']); + } + + $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)]; + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + +} diff --git a/app/Core/Service/ChannelManager/_Mirai.php b/app/Core/Service/ChannelManager/_Mirai.php new file mode 100644 index 0000000..69a2252 --- /dev/null +++ b/app/Core/Service/ChannelManager/_Mirai.php @@ -0,0 +1,667 @@ +restClient = $restClient; + $this->mailer = $mailer; + + if (App::environment() == 'production') { + $this->login = 'ExtranetWorktest-xml-100378347'; + $this->password = 'ifXHs3EJc-$>'; + $this->url = 'https://api.mirai.com/XMLIntegrationx/'; + } else { + $this->login = 'ExtranetWorktest-xml-100378347'; + $this->password = 'ifXHs3EJc-$>'; + $this->url = 'https://api.mirai.com/XMLIntegrationx/'; + } + + $this->channelManagerId = 7; + $this->channelManagerName = 'Mirai'; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerMappingService = $channelManagerMappingService; + + } + + public function request($type, $method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + + $formAuthParam = [ + 'login' => $this->login, + 'password' => $this->password, + ]; + + $parameter = [ + 'headers' => [], + 'query' => $formAuthParam, + ]; + + if (!empty($xmlPayload)) { + $parameter['body'] = $xmlPayload; + } + + $request = $this->restClient->request($type, $this->url . $method, $parameter); + + $getResponseBody = $request->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponseXml = new \SimpleXMLElement($getResponse); + $getResponse = json_decode(json_encode($getResponseXml), 1); + + if (isset($getResponse['error'])) { + $errorMessage = is_array($getResponse['error']['comment']) ? implode(',', $getResponse['error']['comment']) : $getResponse['error']['comment']; + throw new ApiErrorException($errorMessage); + } + + + if ($request->getStatusCode() != 200) { + $firstError = is_array($getResponse['error']['comment']) ? implode(',', $getResponse['error']['comment']) : $getResponse['error']['comment']; + + Log::debug('__REQ__'); + Log::debug($this->url); + Log::debug($type); + Log::debug($method); + Log::debug($xmlPayload); + Log::debug('__RES__'); + Log::debug($getResponse); + Log::debug(PHP_EOL); + + throw new ApiErrorException($firstError); + } + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function inventoryRoomRateUpdate($method, $xmlPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + + + $request = $this->request('POST', $method, $xmlPayload); + + if (!$request['status']) { + throw new ApiErrorException($request['message']); + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + /** Pattern Functions */ + + public function availabilityUpdateRequestMultiParam($propertyId, $propertyRoomRateMapping, $params) + { + + $idList = []; + + $requestParam['values'] = []; + + ksort($params); + + $dataByRoomDate = []; + $propertyRoomRateMappingCollect = collect($propertyRoomRateMapping); + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $value) { + $uniqueKey = $value['availability']; + + $roomIdManipulate = $roomId; + $roomIdManipulateCheck = $propertyRoomRateMappingCollect->where('channel_manager_room_id', $roomId)->where('property_room_rate_mapping.status', 1)->first(); + if (!empty($roomIdManipulateCheck)) { + $roomIdManipulate = $roomIdManipulateCheck['channel_manager_room_rate_id']; + } + + $dataByRoomDate[$roomIdManipulate][$uniqueKey][$currentDate] = $value; + } + } + + $requestParam = []; + + $valueKey = 0; + foreach ($dataByRoomDate as $roomId => $rooms) { + + foreach ($rooms as $uniqueKey => $uniqueValues) { + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + + foreach ($dateGroup as $dates) { + + if (count($dates) > 1) { + + $requestParam[$roomId]['data'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'availability' => $currentValue['availability'] + ]; + + } else { + + $requestParam[$roomId]['data'][$valueKey] = [ + 'property_id' => $propertyId, + 'room_type_id' => $roomId, + 'date_from' => reset($dates), + 'date_to' => reset($dates), + 'availability' => $currentValue['availability'] + ]; + + } + + $valueKey++; + + } + + + } + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $propertyId); + + foreach ($requestParam as $roomId => $roomData) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $roomId); + + $roomInventory = $room->addChild('inventory'); + + foreach ($roomData['data'] as $roomRate) { + $roomInventoryAvailability = $roomInventory->addChild('availability'); + + $roomInventoryAvailability->addAttribute('from', $roomRate['date_from']); + $roomInventoryAvailability->addAttribute('to', $roomRate['date_to']); + $roomInventoryAvailability->addAttribute('quantity', $roomRate['availability']); + + } + + } + + return [ + 'idList' => $idList, + 'payload' => $xmlResponse->asXML() + ]; + } + + public function roomAvailabilityPush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = []; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomAvailabilityQueueForUpdate = []; + $roomAvailabilityQueueForUpdateIdList = []; + $roomAvailabilityQueue = $bulkQueueData; + + + try { + + foreach ($roomAvailabilityQueue as $roomAvailability) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomAvailability['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomAvailability, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomAvailability['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping.room_id', $roomAvailability['property_room_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomAvailability['id']; + + continue; + } + + + $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']][] = $roomAvailability['id']; + + + $roomAvailabilityQueueForUpdate[$roomAvailability['date']] + [$channelManagerRoomRate['channel_manager_room_id']] = [ + 'id' => $roomAvailability['id'], + 'idList' => $roomAvailabilityQueueForUpdateIdList[$roomAvailability['date']], + 'date' => $roomAvailability['date'], + 'availability' => $roomAvailability['stop_sell'] == 1 ? 0 : $roomAvailability['availability'] + ]; + + } + + $roomAvailabilityUpdateRequestMultiParam = $this->availabilityUpdateRequestMultiParam($channelManagerPropertyMapping['channel_manager_property_id'], $channelManagerPropertyMapping['channel_manager_room_rate'], $roomAvailabilityQueueForUpdate); + $request = $this->inventoryRoomRateUpdate('webservice_updater.apro', $roomAvailabilityUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomAvailabilityUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode[] = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateAvailabilityUpdate Error', + 'logMessage' => '
' . print_r(array_merge($request, $roomAvailabilityUpdateRequestMultiParam), true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + + } catch (ApiErrorException $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . implode(', ', $e->getMessageArr()); + Log::error($message); + //$response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + //$response['message'] = $e->getMessage(); + } + + + } else { + $channelManagerNoneMappingIds = collect($bulkQueueData)->pluck('id')->toArray(); + } + + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + return $response; + } + + + public function roomRateUpdateRequestMultiParam($propertyId, $params) + { + + $idList = []; + ksort($params); + + $dataByRoomRate = []; + foreach ($params as $currentDate => $rooms) { + foreach ($rooms as $roomId => $rates) { + foreach ($rates as $rateId => $value) { + $uniqueKey = $value['amount'] . '|' . $value['stop_sell'] . '|' . $value['min_stay']; + $dataByRoomRate[$rateId][$uniqueKey][$currentDate] = $value; + } + } + } + + //Log::debug(json_encode($dataByRoomRate)); + + $requestParam = []; + + $valueKey = 0; + foreach ($dataByRoomRate as $rateId => $rates) { + + $valueKey = 0; + foreach ($rates as $uniqueKey => $uniqueValues) { + + + $uniqueValueDate = array_keys($uniqueValues); + + $dateKey = 0; + $dateGroup = []; + for ($i = 0; $i < count($uniqueValueDate); $i++) { + $dateGroup[$dateKey][] = $uniqueValueDate[$i]; + if ($i + 1 < count($uniqueValueDate)) { + if (Carbon::parse($uniqueValueDate[$i])->diffInDays(Carbon::parse($uniqueValueDate[$i + 1])) > 1) { + $dateKey++; + } + } + } + + foreach ($uniqueValues as $uniqueValue) { + $idList = array_merge($idList, $uniqueValue['idList']); + } + + $currentValue = reset($uniqueValues); + + foreach ($dateGroup as $dates) { + + $requestParam[$rateId][$valueKey] = [ + 'property_id' => $propertyId, + 'rate_plan_id' => $rateId, + 'date_from' => reset($dates), + 'date_to' => last($dates), + 'amount' => moneyDoubleFormatDecimal($currentValue['amount']), + 'stop_sell' => fillOnUndefined($currentValue, 'stop_sell', 0), + 'min_stay' => fillOnUndefined($currentValue, 'min_stay', 1) != 0 ? $currentValue['min_stay'] : 1, + 'currency' => $currentValue['currency'], + ]; + + if ($requestParam[$rateId][$valueKey]['amount'] == 0) { + $requestParam[$rateId][$valueKey]['stop_sell'] = 1; + } + + $valueKey++; + + } + + } + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addAttribute('hotelId', $propertyId); + + foreach ($requestParam as $roomId => $roomData) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $roomId); + + $currencyCode = reset($roomData)['currency']; + + $roomRate = $room->addChild('rate'); + $roomRate->addAttribute('currency', $currencyCode); + + foreach ($roomData as $roomRateData) { + + $roomRatePlaning = $roomRate->addChild('planning'); + + $roomRatePlaning->addAttribute('from', $roomRateData['date_from']); + $roomRatePlaning->addAttribute('to', $roomRateData['date_to']); + $roomRatePlaning->addAttribute('unitPrice', $roomRateData['stop_sell'] == 1 ? 0 : $roomRateData['amount']); + $roomRatePlaning->addAttribute('minimumStay', $roomRateData['min_stay']); + + } + + } + + return [ + 'idList' => $idList, + 'payload' => $xmlResponse->asXML() + ]; + + } + + + public function roomRatePricePush($propertyId, $bulkQueueData) + { + $response = ['status' => false, 'message' => '']; + + try { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true, + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + $channelManagerPushedIds = []; + $channelManagerNoneMappingIds = []; + $channelManagerPushConfirmCode = null; + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + $channelManagerPropertyRoomRateMappingCollect = collect($channelManagerPropertyMapping['channel_manager_room_rate']); + + + $roomRatePriceQueueForUpdate = []; + $roomRatePriceQueueForUpdateIdList = []; + $roomRatePriceQueue = $bulkQueueData; + + + foreach ($roomRatePriceQueue as $roomRatePrice) { + + + //Dates less than today cannot be updated. + if (Carbon::parse($roomRatePrice['date'])->lessThan(Carbon::now()->toDateString())) { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - Previous Date Problem', + 'logMessage' => '
' . print_r($roomRatePrice, true) . '
' + ]; + + //$this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + $channelManagerPushedIds[] = $roomRatePrice['id']; + + continue; + + } + + $channelManagerRoomRate = $channelManagerPropertyRoomRateMappingCollect->where('property_room_rate_mapping_id', $roomRatePrice['room_rate_mapping_id'])->first(); + + if (empty($channelManagerRoomRate)) { + //None Mapping! + //$channelManagerPushedIds[] = $roomAvailability['id']; + $channelManagerNoneMappingIds[] = $roomRatePrice['id']; + + //TODO: Burada oda eşleşmiyorsa süreç devam ediyor ama uyarı maili atılabilir. + + continue; + } + + + $roomRatePriceQueueForUpdateIdList + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']][] = $roomRatePrice['id']; + + + $roomRatePriceQueueForUpdate + [$channelManagerPropertyMapping['channel_manager_property_id']] + [$roomRatePrice['date']] + [$channelManagerRoomRate['channel_manager_room_id']] + [$channelManagerRoomRate['channel_manager_room_rate_id']] = [ + 'id' => $roomRatePrice['id'], + 'idList' => $roomRatePriceQueueForUpdateIdList[$channelManagerPropertyMapping['channel_manager_property_id']][$roomRatePrice['date']][$channelManagerRoomRate['channel_manager_room_id']][$channelManagerRoomRate['channel_manager_room_rate_id']], + 'date' => $roomRatePrice['date'], + 'amount' => $roomRatePrice['amount'], + 'currency' => $roomRatePrice['currency'], + 'stop_sell' => $roomRatePrice['stop_sell'], + 'min_stay' => $roomRatePrice['min_stay'], + ]; + + } + + + foreach ($roomRatePriceQueueForUpdate as $channelManagerPropertyId => $channelManagerProperty) { + + + if (empty($channelManagerProperty)) { + throw new ApiErrorException('$channelManagerProperty is Empty!'); + } + + + $roomRateUpdateRequestMultiParam = $this->roomRateUpdateRequestMultiParam($channelManagerPropertyId, $channelManagerProperty); + $request = $this->inventoryRoomRateUpdate('webservice_updater.apro', $roomRateUpdateRequestMultiParam['payload']); + + if ($request['status']) { + + $channelManagerPushedIds = array_merge($channelManagerPushedIds, $roomRateUpdateRequestMultiParam['idList']); + $channelManagerPushConfirmCode = $request['data']['confirmId']; + + } else { + + //$logMessage + $mailParams = [ + 'title' => $this->channelManagerName . ' - RoomAvailabilityPushService Error - InventoryRoomRateUpdate Error', + 'logMessage' => '
' . print_r($request, true) . '
' + ]; + + $this->mailer->onQueue('logMail', new LogMail($mailParams)); + //$logMessage + + throw new ApiErrorException($request['message']); + } + + } + + } + + $channelManagerPushedIds = array_unique($channelManagerPushedIds); + asort($channelManagerPushedIds); + $channelManagerPushedIds = array_values($channelManagerPushedIds); + + $response = [ + 'status' => true, + 'data' => [ + 'confirmCode' => $channelManagerPushConfirmCode, + 'channelManagerPushedIds' => $channelManagerPushedIds, + 'channelManagerNoneMappingIds' => $channelManagerNoneMappingIds + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $this->channelManagerName . ' - ' . implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $this->channelManagerName . ' - ' . $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + +} diff --git a/app/Core/Service/ChannelManagerBookingService.php b/app/Core/Service/ChannelManagerBookingService.php new file mode 100644 index 0000000..600ad54 --- /dev/null +++ b/app/Core/Service/ChannelManagerBookingService.php @@ -0,0 +1,145 @@ +channelManagerBookingRepository = $channelManagerBookingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerBookingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'booking_id' => fillOnUndefined($params, 'booking_id'), + 'channel_manager_id' => fillOnUndefined($params, 'channel_manager_id'), + 'type' => fillOnUndefined($params, 'type', 'Booking'), + 'status' => fillOnUndefined($params, 'status', 1) + ]; + + $createResult = $this->channelManagerBookingRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $createResult["data"], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerBookingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->channelManagerBookingRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/ChannelManagerLogService.php b/app/Core/Service/ChannelManagerLogService.php new file mode 100644 index 0000000..27a00e2 --- /dev/null +++ b/app/Core/Service/ChannelManagerLogService.php @@ -0,0 +1,119 @@ +channelManagerLogRepository = $channelManagerLogRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerLogRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_manager_id' => fillOnUndefined($params, 'channel_manager_id',1), + 'type' => fillOnUndefined($params, 'type','C2E'), + 'service' => fillOnUndefined($params, 'service'), + 'request' => fillOnUndefined($params, 'request'), + 'response' => fillOnUndefined($params, 'response'), + 'ip_address' => fillOnUndefined($params, 'ip_address'), + 'status' => fillOnUndefined($params, 'status') + ]; + + $createResult = $this->channelManagerLogRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $createResult["data"], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerLogRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/ChannelManagerMappingService.php b/app/Core/Service/ChannelManagerMappingService.php new file mode 100644 index 0000000..f963f87 --- /dev/null +++ b/app/Core/Service/ChannelManagerMappingService.php @@ -0,0 +1,134 @@ +channelManagerMappingRepository = $channelManagerMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $createResult = $this->channelManagerMappingRepository->create($params); + + if ($createResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $createData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->channelManagerMappingRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/ChannelManagerPropertyMappingService.php b/app/Core/Service/ChannelManagerPropertyMappingService.php new file mode 100644 index 0000000..2aa4371 --- /dev/null +++ b/app/Core/Service/ChannelManagerPropertyMappingService.php @@ -0,0 +1,134 @@ +channelManagerPropertyMappingRepository = $channelManagerPropertyMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerPropertyMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $createResult = $this->channelManagerPropertyMappingRepository->create($params); + + if ($createResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $createData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerPropertyMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->channelManagerPropertyMappingRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/ChannelManagerPropertyRateMappingService.php b/app/Core/Service/ChannelManagerPropertyRateMappingService.php new file mode 100644 index 0000000..964095a --- /dev/null +++ b/app/Core/Service/ChannelManagerPropertyRateMappingService.php @@ -0,0 +1,134 @@ +channelManagerPropertyRateMappingRepository = $channelManagerPropertyRateMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerPropertyRateMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $createResult = $this->channelManagerPropertyRateMappingRepository->create($params); + + if ($createResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $createData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerPropertyRateMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->channelManagerPropertyRateMappingRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/ChannelManagerService.php b/app/Core/Service/ChannelManagerService.php new file mode 100644 index 0000000..e7f31d2 --- /dev/null +++ b/app/Core/Service/ChannelManagerService.php @@ -0,0 +1,134 @@ +channelManagerRepository = $channelManagerRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->channelManagerRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $createResult = $this->channelManagerRepository->create($params); + + if ($createResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $createData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $createData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->channelManagerRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->channelManagerRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/CompetitorPriceAnalysisService.php b/app/Core/Service/CompetitorPriceAnalysisService.php new file mode 100644 index 0000000..76cd26f --- /dev/null +++ b/app/Core/Service/CompetitorPriceAnalysisService.php @@ -0,0 +1,130 @@ +propertyCompetitorMappingRepository = $propertyCompetitorMappingRepository; + } + + public function createPropertyCompetitorMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $insertData = [ + "property_id" => fillOnUndefined($param, "property_id"), + "competitor_property_name" => fillOnUndefined($param, "competitor_property_name"), + "competitor_property_source" => fillOnUndefined($param, "competitor_property_source", 'tripadvisor'), + "competitor_property_key" => fillOnUndefined($param, "competitor_property_key"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertDataResult = $this->propertyCompetitorMappingRepository->create($insertData); + if ($insertDataResult['status'] != 'success') { + throw new Exception($insertDataResult['message']); + } + + $insertDataResult = $insertDataResult["data"]; + + $response = [ + 'status' => true, + 'data' => $insertDataResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function selectPropertyCompetitorMapping($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyCompetitorMappingRepository->findByCriteria($param, $column); + + $propertyList = []; + foreach ($data as $property) { + $propertyList[] = [ + 'id' => $property['id'], + 'property_id' => $property['property_id'], + 'name' => $property['competitor_property_name'], + 'key' => $property['competitor_property_key'], + 'competitor_property_source' => $property['competitor_property_source'], + + ]; + } + + $response = [ + 'status' => true, + 'data' => $propertyList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyCompetitorMapping($deleteThisId) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteThisId = is_array($deleteThisId) ? $deleteThisId : [$deleteThisId]; + $deleteThisArray = $this->propertyCompetitorMappingRepository->destroy($deleteThisId); + + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/CountryService.php b/app/Core/Service/CountryService.php new file mode 100644 index 0000000..ebf7e53 --- /dev/null +++ b/app/Core/Service/CountryService.php @@ -0,0 +1,43 @@ +countryRepository = $countryRepository; + } + + + public function getCountryList ( array $criteria = [],$columns = ["*"] ) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $data = $this->countryRepository->findByCriteria($criteria, $columns); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/CurrencyService.php b/app/Core/Service/CurrencyService.php new file mode 100644 index 0000000..84adeb1 --- /dev/null +++ b/app/Core/Service/CurrencyService.php @@ -0,0 +1,145 @@ +currencyRepository = $currencyRepository; + $this->currencyRatesRepository = $currencyRatesRepository; + } + + + public function getCurrencyList(array $params = [], $columns = ["*"]) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => CurrencyService::STATUS], + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + if(isset($params['justBasicCurrencies']) && $params['justBasicCurrencies']) { + $criteria['criteria'][] = ['field' => 'is_basic', 'condition' => '=', 'value' => 1]; + } + + $data = $this->currencyRepository->findByCriteria($criteria, $columns); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function lastExchangeRate($currency, $exchangeCurrency) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'currency_code', 'condition' => '=', 'value' => $currency], + ['field' => 'exc_currency_code', 'condition' => '=', 'value' => $exchangeCurrency], + ], + "orderBy" => [ + ["field" => "date", "value" => "DESC"] + ] + , + 'firstRow' => true, + ]; + + $data = $this->currencyRatesRepository->findByCriteria($criteria); + + $rate = fillOnUndefined($data, 'rate', 1); + + $response = [ + 'status' => true, + 'data' => $rate, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function exchangeCurrencyRates($currency) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'currency_code', 'condition' => '=', 'value' => $currency], + ], + "orderBy" => [ + ["field" => "date", "value" => "DESC"] + ], + 'firstRow' => true, + ]; + + $lastDate = $this->currencyRatesRepository->findByCriteria($criteria); + + + $criteria = [ + 'criteria' => [ + ['field' => 'currency_code', 'condition' => '=', 'value' => $currency], + ['field' => 'date', 'condition' => '=', 'value' => $lastDate['date']], + ], + "orderBy" => [ + ["field" => "currency_code", "value" => "ASC"], + ["field" => "exc_currency_code", "value" => "ASC"] + ] + ]; + + $currencyRates = $this->currencyRatesRepository->findByCriteria($criteria); + + $response = [ + 'status' => true, + 'data' => $currencyRates, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/DashboardPlusService.php b/app/Core/Service/DashboardPlusService.php new file mode 100644 index 0000000..1cb3318 --- /dev/null +++ b/app/Core/Service/DashboardPlusService.php @@ -0,0 +1,878 @@ +currencyService = $currencyService; + $this->propertyWebRepository = $propertyWebRepository; + } + + + public function webVisitor(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + + $propertyWeb = $this->propertyWebRepository->findByCriteria($criteria, $columns); + if (empty($propertyWeb)) { + throw new ApiErrorException('No record found.'); + } + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->timestamp; + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->timestamp; + $propertyWebLogRaw = PropertyWebLog::whereBetween('created_at', [$startDate, $finishDate]) + ->where('web_id', $propertyWeb) + ->groupBy('country_code') + ->select('country_code', DB::raw('count(id) count')) + ->get()->toArray(); + + $propertyWebLogCountryIds = pickItemFromArray('country_code', $propertyWebLogRaw); + $propertyWebLogCountry = Country::whereIn('country_code', $propertyWebLogCountryIds)->get()->toArray(); + $propertyWebLogCountry = collect($propertyWebLogCountry); + + $propertyWebLog = []; + $propertyWebLogTotal = 0; + foreach ($propertyWebLogRaw as $propertyWebLogKey => $propertyWebLogValue) { + + $countryCodeDetail = $propertyWebLogCountry->where('country_code', mb_strtoupper($propertyWebLogValue['country_code']))->first(); + if (empty($countryCodeDetail)) { + continue; + } + + $propertyWebLog[] = [ + 'country' => $countryCodeDetail['name'], + 'language_key' => $countryCodeDetail['language_key'], + 'country_code' => $propertyWebLogValue['country_code'], + 'count' => $propertyWebLogValue['count'], + 'formatted' => [ + 'value' => $propertyWebLogValue['count'], + 'country' => $propertyWebLogValue['country_code'], + 'country_name' => $countryCodeDetail['name'], + ] + ]; + + } + + $propertyWebLog = collect($propertyWebLog)->sortByDesc('count')->toArray(); + $propertyWebLog = array_values($propertyWebLog); + + $propertyWebLogTotal = collect($propertyWebLog)->sum('count'); + + $response = [ + 'status' => true, + 'data' => [ + 'total' => $propertyWebLogTotal, + 'country' => $propertyWebLog + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function guestDemographic(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $propertyChannel = PropertyChannel::whereIn('channel_category_id', [2, 3])->get(['id'])->sortBy('id')->toArray(); + $propertyChannelIds = pickItemFromArray('id', $propertyChannel); + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->timestamp; + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->timestamp; + $propertyBooking = Booking::whereBetween('created_at', [$startDate, $finishDate]) + ->where('status', 1) + ->whereIn('channel_id', $propertyChannelIds) + ->where('property_id', $params['property_id']) + ->get(['id'])->sortBy('id')->toArray(); + $propertyBookingIds = pickItemFromArray('id', $propertyBooking); + + + $bookingRoomPax = BookingRoomPax:: + whereIn('booking_id', $propertyBookingIds) + ->get()->toArray(); + $bookingRoomPax = collect($bookingRoomPax); + + $guestDemographic = []; + + + $totalPax = $bookingRoomPax->count(); + + $guestDemographic['all'] = $totalPax; + + //Gender + $guestDemographic['gender'] = []; + if (!empty($totalPax)) { + $guestDemographic['gender'] = [ + 'male' => [ + 'title' => 'Male', + 'count' => $bookingRoomPax->where('gender', 'M')->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPax->where('gender', 'M')->count() / $totalPax * 100), + ], + 'female' => [ + 'title' => 'Female', + 'count' => $bookingRoomPax->where('gender', 'F')->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPax->where('gender', 'F')->count() / $totalPax * 100), + ] + ]; + } + + + //Type + $guestDemographic['type'] = []; + if (!empty($totalPax)) { + $guestDemographic['type'] = [ + 'adult' => [ + 'title' => 'Adult', + 'count' => $bookingRoomPax->where('type', 'ADT')->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPax->where('type', 'ADT')->count() / $totalPax * 100), + ], + 'child' => [ + 'title' => 'Child', + 'count' => $bookingRoomPax->where('type', 'CHD')->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPax->where('type', 'CHD')->count() / $totalPax * 100), + ] + ]; + } + + + //Citizen + $guestDemographic['citizen'] = []; + if (!empty($totalPax)) { + $bookingRoomPaxGroupedCitizen = $bookingRoomPax->groupBy('citizen')->map->count()->toArray(); + arsort($bookingRoomPaxGroupedCitizen); + + $paxGroupedCitizenCountry = Country::whereIn('country_code', array_keys($bookingRoomPaxGroupedCitizen))->get()->toArray(); + $paxGroupedCitizenCountry = collect($paxGroupedCitizenCountry); + + foreach ($bookingRoomPaxGroupedCitizen as $bookingRoomPaxGroupedCitizenCode => $bookingRoomPaxGroupedCitizenCount) { + + $countryCodeDetail = $paxGroupedCitizenCountry->where('country_code', mb_strtoupper($bookingRoomPaxGroupedCitizenCode))->first(); + + $guestDemographic['citizen'][mb_strtolower($bookingRoomPaxGroupedCitizenCode)] = [ + 'country' => fillOnUndefined($countryCodeDetail, 'name', $bookingRoomPaxGroupedCitizenCode), + 'language_key' => fillOnUndefined($countryCodeDetail, 'language_key', $bookingRoomPaxGroupedCitizenCode), + 'country_code' => mb_strtolower($bookingRoomPaxGroupedCitizenCode), + 'count' => $bookingRoomPaxGroupedCitizenCount, + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxGroupedCitizenCount / $totalPax * 100), + ]; + } + } + + //Age + $guestDemographic['age'] = []; + if (!empty($totalPax)) { + $bookingRoomPaxAges = $bookingRoomPax->map(function ($value, $key) { + $value['age'] = Carbon::parse($value['birth_date'])->diffInYears(Carbon::createFromTimestamp($value['created_at'])); + return $value; + }); + + + $guestDemographic['age'] = [ + '0-12' => [ + 'title' => '0-12 Age', + 'count' => $bookingRoomPaxAges->where('age', '>=', 0)->where('age', '<', 12)->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxAges->where('age', '>=', 0)->where('age', '<', 12)->count() / $totalPax * 100), + ], + '12-18' => [ + 'title' => '12-18 Age', + 'count' => $bookingRoomPaxAges->where('age', '>=', 12)->where('age', '<', 18)->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxAges->where('age', '>=', 12)->where('age', '<', 18)->count() / $totalPax * 100), + ], + '18-36' => [ + 'title' => '18-36 Age', + 'count' => $bookingRoomPaxAges->where('age', '>=', 18)->where('age', '<', 36)->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxAges->where('age', '>=', 18)->where('age', '<', 36)->count() / $totalPax * 100), + ], + '36-60' => [ + 'title' => '36-60 Age', + 'count' => $bookingRoomPaxAges->where('age', '>=', 36)->where('age', '<', 60)->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxAges->where('age', '>=', 36)->where('age', '<', 60)->count() / $totalPax * 100), + ], + '60+' => [ + 'title' => '60+ Age', + 'count' => $bookingRoomPaxAges->where('age', '>=', 60)->count(), + 'percentage' => moneyDoubleFormatDecimal($bookingRoomPaxAges->where('age', '>=', 60)->count() / $totalPax * 100), + ], + ]; + } + + $response = [ + 'status' => true, + 'data' => $guestDemographic + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function topChannel(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $defaultCurrency = 'TRY'; + $bookingEngineBaseCurrency = PropertyChannelMapping::where('status', 1) + ->where('channel_id', 1) + ->where('property_id', $params['property_id']) + ->first()->toArray(); + + if (!empty($bookingEngineBaseCurrency)) { + $defaultCurrency = $bookingEngineBaseCurrency['currency_code']; + } + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->timestamp; + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->timestamp; + /*$propertyBooking = Booking::whereBetween('created_at', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->get(['id', 'property_id', 'channel_id', 'total', 'currency_code', 'status']) + ->sortByDesc('id')->toArray();*/ + + $propertyBooking = Booking::whereBetween('created_at', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->where('status', 1) + ->groupBy('channel_id') + ->groupBy('currency_code') + ->select('channel_id', 'currency_code', DB::raw('count(id) count, sum(total) total')) + ->get()->toArray(); + + //Channel Id List + $channelIds = pickItemFromArray('channel_id', $propertyBooking); + $channelIds = !empty($channelIds) ? array_values(array_unique($channelIds)) : []; + $propertyChannel = PropertyChannel::whereIn('id', $channelIds)->get(['id', 'name'])->toArray(); + $propertyChannelCollect = collect($propertyChannel); + + //Currency Code List + $currencyCodes = pickItemFromArray('currency_code', $propertyBooking); + $currencyCodes = !empty($currencyCodes) ? array_values(array_unique($currencyCodes)) : []; + + + $topChannel = []; + foreach ($propertyBooking as $booking) { + + if ($booking['total'] <= 0) { + continue; + } + + $commonCurrencyCodeRate = $this->currencyService->lastExchangeRate($booking['currency_code'], $defaultCurrency); + + $channelName = $propertyChannelCollect->where('id', $booking['channel_id'])->first(); + if (!empty($channelName)) { + $channelName = $channelName['name']; + } + + $topChannel[$booking['channel_id']] = [ + 'name' => $channelName, + 'count' => $booking['count'], + 'total' => $booking['total'], + 'currency_code' => $booking['currency_code'], + 'commonCurrencyTotal' => ($booking['total'] * $commonCurrencyCodeRate['data']), + 'commonCurrencyCode' => $defaultCurrency + ]; + + } + + $totalChannelOverall = collect($topChannel)->sum('commonCurrencyTotal'); + foreach ($topChannel as $channelId => $channel) { + $topChannel[$channelId]['total'] = moneyDoubleFormatDecimal($channel['total']); + $topChannel[$channelId]['commonCurrencyTotal'] = moneyDoubleFormatDecimal($channel['commonCurrencyTotal']); + $topChannel[$channelId]['percentage'] = moneyDoubleFormatDecimal($channel['commonCurrencyTotal'] / $totalChannelOverall * 100); + } + + + $topChannel = collect($topChannel)->sortByDesc('commonCurrencyTotal')->toArray(); + $topChannel = array_values($topChannel); + + $response = [ + 'status' => true, + 'data' => $topChannel + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function todayCheckin(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $todayCheckin = 0; + $today = Carbon::now()->startOfDay()->toDateString(); + $todayCheckin = Booking::where('checkin_date', $today)->where('property_id', $params['property_id'])->count(); + + $response = [ + 'status' => true, + 'data' => $todayCheckin + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function todayCheckout(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $todayCheckOut = 0; + $today = Carbon::now()->startOfDay()->toDateString(); + $todayCheckOut = Booking::where('checkout_date', $today)->where('property_id', $params['property_id'])->count(); + + $response = [ + 'status' => true, + 'data' => $todayCheckOut + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function lengthOfStay(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $lengthOfStay = 0; + $lengthOfStay = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->pluck('length_of_stay')->avg(); + + $lengthOfStay = moneyDoubleFormatDecimal($lengthOfStay); + + $response = [ + 'status' => true, + 'data' => $lengthOfStay + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function lengthOfBooking(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $lengthOfBooking = 0; + $lengthOfBooking = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->pluck('length_of_booking')->avg(); + + $lengthOfBooking = moneyDoubleFormatDecimal($lengthOfBooking); + + $response = [ + 'status' => true, + 'data' => $lengthOfBooking + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function totalBooking(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $defaultCurrency = 'TRY'; + $bookingEngineBaseCurrency = PropertyChannelMapping::where('status', 1) + ->where('channel_id', 1) + ->where('property_id', $params['property_id']) + ->first()->toArray(); + + if (!empty($bookingEngineBaseCurrency)) { + $defaultCurrency = $bookingEngineBaseCurrency['currency_code']; + } + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $propertyBooking = 0; + $propertyBooking = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->groupBy('currency_code') + ->select('currency_code', DB::raw('count(id) count, sum(total) total')) + ->get()->toArray(); + + + $totalBooking = [ + 'totalCount' => 0, + 'totalRevenue' => 0, + 'currencyCode' => $defaultCurrency + ]; + + foreach ($propertyBooking as $booking) { + + if ($booking['total'] <= 0) { + continue; + } + + $commonCurrencyCodeRate = $this->currencyService->lastExchangeRate($booking['currency_code'], $defaultCurrency); + $totalBooking['totalRevenue'] += ($booking['total'] * $commonCurrencyCodeRate['data']); + $totalBooking['totalCount'] += $booking['count']; + + } + + $totalBooking['totalRevenue'] = moneyDoubleFormatDecimal($totalBooking['totalRevenue']); + + + $response = [ + 'status' => true, + 'data' => $totalBooking + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function averageDailyRate(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $defaultCurrency = 'TRY'; + $bookingEngineBaseCurrency = PropertyChannelMapping::where('status', 1) + ->where('channel_id', 1) + ->where('property_id', $params['property_id']) + ->first()->toArray(); + + if (!empty($bookingEngineBaseCurrency)) { + $defaultCurrency = $bookingEngineBaseCurrency['currency_code']; + } + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $averageDailyRate = [ + 'averageDailyRate' => 0, + 'currencyCode' => $defaultCurrency + ]; + + $propertyBooking = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->select('id') + ->get()->toArray(); + $propertyBookingIds = pickItemFromArray('id', $propertyBooking); + + $bookingRoom = BookingRoom::whereIn('booking_id', $propertyBookingIds) + ->select('id', 'booking_id', 'checkin_date', 'checkout_date', 'total', 'currency_code') + ->get()->toArray(); + + $exchangeCurrencyList = collect($bookingRoom)->unique('currency_code')->pluck('currency_code')->toArray(); + + foreach ($exchangeCurrencyList as $currencyCode) { + if ($currencyCode == $defaultCurrency) { + $commonCurrencyCodeRate[$currencyCode] = 1; + } else { + $lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, $defaultCurrency); + $commonCurrencyCodeRate[$currencyCode] = $lastExchangeRate['data']; + } + } + + $averageDailyRateList = []; + foreach ($bookingRoom as $perRoom) { + $diffInDays = Carbon::parse($perRoom['checkout_date'])->diffInDays(Carbon::parse($perRoom['checkin_date'])); + $totalExchangeAmount = ($perRoom['total'] * $commonCurrencyCodeRate[$perRoom['currency_code']]); + $averageDailyRateList[] = $totalExchangeAmount / $diffInDays; + } + + + $averageDailyRate['averageDailyRate'] = moneyDoubleFormatDecimal(collect($averageDailyRateList)->average()); + + $response = [ + 'status' => true, + 'data' => $averageDailyRate + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function totalPax(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $defaultCurrency = 'TRY'; + $bookingEngineBaseCurrency = PropertyChannelMapping::where('status', 1) + ->where('channel_id', 1) + ->where('property_id', $params['property_id']) + ->first()->toArray(); + + if (!empty($bookingEngineBaseCurrency)) { + $defaultCurrency = $bookingEngineBaseCurrency['currency_code']; + } + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $propertyBooking = 0; + $propertyBooking = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->groupBy('currency_code') + ->select('currency_code', DB::raw('count(id) count, sum(total) total')) + ->get()->toArray(); + + + $totalPax = [ + 'totalPaxCount' => 0, + 'totalPaxRevenue' => 0, + 'averageRevenuePerPax' => 0, + 'currencyCode' => $defaultCurrency + ]; + + foreach ($propertyBooking as $booking) { + + if ($booking['total'] <= 0) { + continue; + } + + $commonCurrencyCodeRate = $this->currencyService->lastExchangeRate($booking['currency_code'], $defaultCurrency); + $totalPax['totalPaxRevenue'] += ($booking['total'] * $commonCurrencyCodeRate['data']); + + } + + $totalPax['totalPaxRevenue'] = moneyDoubleFormatDecimal($totalPax['totalPaxRevenue']); + + $bookingIds = vwBookingSummaryAll::whereBetween('time', [$startDate, $finishDate]) + ->where('property_id', $params['property_id']) + ->pluck('id')->toArray(); + + $bookingRoom = BookingRoom::whereIn('booking_id', $bookingIds) + ->groupBy('occupancy_code') + ->select('occupancy_code', DB::raw('count(id) count')) + ->get()->toArray(); + + foreach ($bookingRoom as $bookingRoomPax) { + + $adultCount = substr_count($bookingRoomPax['occupancy_code'], 'A'); + $childCount = substr_count($bookingRoomPax['occupancy_code'], 'C'); + + $totalPax['totalPaxCount'] += (($adultCount + $childCount) * $bookingRoomPax['count']); + + } + + if($totalPax['totalPaxCount'] > 0) { + $totalPax['averageRevenuePerPax'] = moneyDoubleFormatDecimal($totalPax['totalPaxRevenue'] / $totalPax['totalPaxCount']); + } + + + $response = [ + 'status' => true, + 'data' => $totalPax + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function channelForecast(array $params = [], $columns = ["*"]) + { + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateString(); + + //Burada mutlaka 2 kontrol eklenecke, + // 1. bitiş, başlangıçtan büyük olamazi + // 2. max 6 aylık yani 180 günlük veri çekilebilir + + + $relatingDates = []; + $dateDiff = Carbon::parse($startDate)->diffInDays(Carbon::parse($finishDate)); + for ($i = 0; $i < ($dateDiff + 1); $i++) { + $currentDate = Carbon::parse($startDate)->addDays($i)->toDateString(); + $relatingDates[] = $currentDate; + } + + $period = []; + $periodModel = 'daily'; + if (Carbon::parse($startDate)->month != Carbon::parse($finishDate)->month) { + $periodModel = 'monthly'; + } elseif (Carbon::parse($startDate)->diffInDays(Carbon::parse($finishDate)) > 30) { + $periodModel = 'monthly'; + } + + $propertyBooking = Booking::where('status', 1) + ->where('checkin_date', '<=', $finishDate) + ->where('checkout_date', '>=', $startDate) + ->where('property_id', $params['property_id']) + //->where('id',11825) + ->with('bookingRoomSummary') + ->select('id', 'channel_id', 'checkin_date', 'checkout_date', 'total', 'status') + ->get()->toArray(); + + //dd($propertyBooking); + + //Channel Id List + $channelIds = pickItemFromArray('channel_id', $propertyBooking); + $channelIds = !empty($channelIds) ? array_values(array_unique($channelIds)) : []; + $propertyChannel = PropertyChannel::whereIn('id', $channelIds)->get(['id', 'name'])->toArray(); + $propertyChannelCollect = collect($propertyChannel); + + $bookingChannelForecast = []; + $bookingChannelForecastTotal = []; + foreach ($propertyBooking as $booking) { + + if ($booking['total'] <= 0) { + continue; + } + + $channelName = $propertyChannelCollect->where('id', $booking['channel_id'])->first(); + if (!empty($channelName)) { + $channelName = $channelName['name']; + } + + foreach ($booking['booking_room_summary'] as $bookingRoom) { + + $checkInDate = $bookingRoom['checkin_date']; + $checkOutDate = $bookingRoom['checkout_date']; + $dateDiff = Carbon::parse($checkOutDate)->diffInDays(Carbon::parse($checkInDate)); + + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($checkInDate)->addDays($i)->toDateString(); + + if(!in_array($date,$relatingDates)) { + continue; + } + + + if (!isset($bookingChannelForecast[$booking['channel_id']]['total'])) { + $bookingChannelForecast[$booking['channel_id']]['id'] = $booking['channel_id']; + $bookingChannelForecast[$booking['channel_id']]['title'] = $channelName; + $bookingChannelForecast[$booking['channel_id']]['total'] = 0; + $bookingChannelForecast[$booking['channel_id']]['percentage'] = 0; + } + + if (!isset($bookingChannelForecast[$booking['channel_id']]['data'][$date])) { + $bookingChannelForecast[$booking['channel_id']]['data'][$date] = 0; + } + + if (!isset($bookingChannelForecastTotal[$date])) { + $bookingChannelForecastTotal[$date] = 0; + } + + + $bookingChannelForecast[$booking['channel_id']]['data'][$date]++; + $bookingChannelForecast[$booking['channel_id']]['total']++; + $bookingChannelForecastTotal[$date]++; + + } + } + + } + + + $totalRoom = collect($bookingChannelForecast)->sum('total'); + + $dateDiff = Carbon::parse($startDate)->diffInDays(Carbon::parse($finishDate)); + for ($i = 0; $i < ($dateDiff + 1); $i++) { + $currentDate = Carbon::parse($startDate)->addDays($i)->toDateString(); + foreach ($bookingChannelForecast as $channelId => $channel) { + foreach ($channel['data'] as $date => $count) { + + if (!isset($bookingChannelForecast[$channelId]['data'][$currentDate])) { + $bookingChannelForecast[$channelId]['data'][$currentDate] = 0; + } + + if (!isset($bookingChannelForecastTotal[$currentDate])) { + $bookingChannelForecastTotal[$currentDate] = 0; + } + + + $period[$currentDate] = $currentDate; + $bookingChannelForecast[$channelId]['percentage'] = moneyDoubleFormatDecimal($bookingChannelForecast[$channelId]['total'] / $totalRoom * 100); + + ksort($bookingChannelForecast[$channelId]['data']); + ksort($period); + + } + } + } + + + if ($periodModel == 'monthly') { + + $period = []; + foreach ($bookingChannelForecast as $channelId => $channel) { + foreach ($channel['data'] as $date => $count) { + + $currentMonth = Carbon::parse($date)->format('Y-m'); + $period[$currentMonth] = $currentMonth; + + if (!isset($bookingChannelForecast[$channelId]['data'][$currentMonth])) { + $bookingChannelForecast[$channelId]['data'][$currentMonth] = 0; + } + + + if (!isset($bookingChannelForecastTotal[$currentMonth])) { + $bookingChannelForecastTotal[$currentMonth] = 0; + } + + + $bookingChannelForecast[$channelId]['data'][$currentMonth] += $bookingChannelForecast[$channelId]['data'][$date]; + $bookingChannelForecastTotal[$currentMonth] += $bookingChannelForecast[$channelId]['data'][$date]; + + unset($bookingChannelForecast[$channelId]['data'][$date]); + unset($bookingChannelForecastTotal[$date]); + ksort($bookingChannelForecast[$channelId]['data']); + ksort($bookingChannelForecast); + ksort($period); + } + } + + } + + $bookingChannelForecast = collect($bookingChannelForecast)->sortBy('title')->toArray(); + $bookingChannelForecast = array_values($bookingChannelForecast); + + $propertyChannel = collect($propertyChannel)->sortBy('name')->pluck('name')->toArray(); + + $period = is_array($period) ? array_values($period) : []; + + ksort($bookingChannelForecastTotal); + + $response = [ + 'status' => true, + 'data' => [ + 'title' => 'Forecast - '.$startDate . ' / ' . $finishDate . ' (' . ucfirst($periodModel) . ')', + 'period' => $period, + 'channel' => $propertyChannel, + 'forecast' => $bookingChannelForecast, + 'forecastTotal' => $bookingChannelForecastTotal + ] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + +} diff --git a/app/Core/Service/DestinationService.php b/app/Core/Service/DestinationService.php new file mode 100644 index 0000000..72d1b10 --- /dev/null +++ b/app/Core/Service/DestinationService.php @@ -0,0 +1,107 @@ +VWDestinationRepository = $VWDestinationRepository; + $this->destinationSearchValidator = $destinationSearchValidator ; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->VWDestinationRepository->findByCriteria($param, $column); + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function searchDestination($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $validationResult = $this->destinationSearchValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $searchCriteria = [ + 'criteria' => [ + ['field' => 'long_name', 'condition' => 'like', 'value' => '%'.$params['search_term'].'%'], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ["field" => "priority", "value" => "DESC"], + ["field" => "level", "value" => "ASC"], + ["field" => "name", "value" => "ASC"] + ], + 'take' => 5 + ]; + + $searchResult = $this->select($searchCriteria, ['id', 'long_name']); + + if(!$searchResult['data']){ + throw new ApiErrorException(lang('Search data not found')); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['destination' =>$searchResult['data'] ] ]; + } catch(ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} \ No newline at end of file diff --git a/app/Core/Service/EnwContactFormService.php b/app/Core/Service/EnwContactFormService.php new file mode 100644 index 0000000..9c5d61c --- /dev/null +++ b/app/Core/Service/EnwContactFormService.php @@ -0,0 +1,85 @@ +mailer = $mailer; + $this->enwContactFormCreateValidator = $enwContactFormCreateValidator; + } + + public function sendEmail($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->enwContactFormCreateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $bcc[] = "bd@extranetwork.com"; + $mailData = [ + 'to' => [ + 'name' => Config::get('app.name'), + 'email' => Config::get('app.enwContactFormMailTo') + ], + 'bcc' => $bcc + ]; + + $mailViewParams = $params ; + $mailViewParams['logo'] = 'https://www.extranetwork.com/assets/img/logo/logo.png'; + + $mailParams = [ + 'mailData' => $mailData, + 'mailViewParams' => $mailViewParams + ]; + + + $this->mailer->onQueue( + 'enwContactFormMail', + new EnwContactFormMail($mailParams) + ); + + $response = [ + 'status' => true, + 'data' => null, + 'message' => 'myweb-contact_form-success_message', + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/FindCountryCodeService.php b/app/Core/Service/FindCountryCodeService.php new file mode 100644 index 0000000..59ec097 --- /dev/null +++ b/app/Core/Service/FindCountryCodeService.php @@ -0,0 +1,122 @@ +restClient = $restClient; + $this->ipNationRepository = $ipNationRepository; + } + + public function findCountryWithIpAddress($ip) + { + + $response = ['status' => false, 'message' => '']; + + $ipPoolCache = []; + $ipPoolCacheKey = 'ipPoolCacheKey'; + + if(Cache::has($ipPoolCacheKey)) { + $ipPoolCache = Cache::get($ipPoolCacheKey); + } + + if(isset($ipPoolCache[$ip])) { + $response = [ + 'status' => true, + 'data' => [ + 'code' => mb_strtolower($ipPoolCache[$ip]), + 'source' => 'cache' + ] + ]; + + return output($response); + } + + try { + + $request = $this->restClient->get('http://ip-api.com/json/' . $ip, ['timeout' => 2]); + + $getResponseBody = $request->getBody(); + $getResponse = $getResponseBody->getContents(); + + if (empty($getResponse)) { + throw new ApiErrorException('Empty JSON response'); + } + + $getResponse = json_decode($getResponse, 1); + + if ($getResponse['status'] != 'success') { + throw new ApiErrorException('Error'); + } + + if (isset($getResponse['message'])) { + throw new ApiErrorException($getResponse['message']); + } + + + if(in_array($getResponse['countryCode'],['GB'])) { + $getResponse['countryCode'] = 'UK'; + } + + $response = [ + 'status' => true, + 'data' => [ + 'code' => mb_strtolower($getResponse['countryCode']), + 'source' => 'ip-api.com' + ] + ]; + + } catch (ApiErrorException $e) { + + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + + $ip = ip2long($ip); + + $requestData = [ + 'criteria' => [ + ['field' => 'ip', 'condition' => '<', 'value' => $ip] + ], + 'orderBy' => [["field" => "ip", "value" => "DESC"]], + 'with' => ['country'], + 'firstRow' => true + ]; + + $ipResult = $this->ipNationRepository->findByCriteria($requestData); + + $response = [ + 'status' => true, + 'data' => !empty($ipResult['country']) ? $ipResult['country'] : [] + ]; + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if($response['status'] && isset($response['data']['code']) && !empty($response['data']['code'])) { + $ipPoolCache[$ip] = $response['data']['code']; + Cache::put($ipPoolCacheKey, $ipPoolCache, 24 * 60 * 60);//10 Min, 60 * 10 = 600 TTL + } + + return output($response); + } + +} diff --git a/app/Core/Service/GeneralTimezoneService.php b/app/Core/Service/GeneralTimezoneService.php new file mode 100644 index 0000000..f6d4c10 --- /dev/null +++ b/app/Core/Service/GeneralTimezoneService.php @@ -0,0 +1,109 @@ +generalTimezoneRepository = $generalTimezoneRepository; + + } + + + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->generalTimezoneRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getAllaGeneralTimezone($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $generalTimezoneRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + + ]; + + $generalTimezoneData = $this->select($generalTimezoneRequest); + if($generalTimezoneData['status'] != "success"){ + throw new Exception('api-unknown_error'); + } + + $generalTimezones = collect($generalTimezoneData['data'])->map(function ($timezone){ + return [ + "id" => $timezone["id"], + "location" => $timezone["location"], + "description" => $timezone["description"], + "action_type" => $timezone["action_type"], + "hour" => $timezone["hour"], + "minute" => $timezone["minute"], + + ]; + + }); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $generalTimezones]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/Google/GoogleVisionLabelService.php b/app/Core/Service/Google/GoogleVisionLabelService.php new file mode 100644 index 0000000..dd0100a --- /dev/null +++ b/app/Core/Service/Google/GoogleVisionLabelService.php @@ -0,0 +1,72 @@ +googleVisionAuthentication = base_path().'/resources/data/google-vision-authentication.json'; + putenv('GOOGLE_APPLICATION_CREDENTIALS='.$this->googleVisionAuthentication ); + } + + public function getImageGoogleVisionLabels($params) + { + $photoLabelList = []; + try + { + $imagePath = $params['image_paths']; + $image = file_get_contents($imagePath); + $imageAnnotator = new ImageAnnotatorClient(); + $responseImageAnnotator = $imageAnnotator->labelDetection($image); + $getLabelAnnotations = $responseImageAnnotator->getLabelAnnotations(); + $getLabelAnnotations = $getLabelAnnotations ? $getLabelAnnotations : null; + + if( empty($getLabelAnnotations) ) + { + throw new ApiErrorException(lang('Not tags found!')); + } + + if ($getLabelAnnotations) { + $i = 1; + foreach ($getLabelAnnotations as $labelAnnotation) + { + $photoLabelList[] = + [ + 'description' => $labelAnnotation->getDescription(), + 'score' => $labelAnnotation->getScore(), + 'topicality' => $labelAnnotation->getTopicality(), + ]; + if($i == 3){ + break; + } + $i++; + } + + Log:info($photoLabelList); + } + + + + $imageAnnotator->close(); + + }catch (Exception $e) + { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + return $photoLabelList; + } + + +} diff --git a/app/Core/Service/JobsService.php b/app/Core/Service/JobsService.php new file mode 100644 index 0000000..acbfdef --- /dev/null +++ b/app/Core/Service/JobsService.php @@ -0,0 +1,20 @@ +jobsRepository = $jobsRepository; + } + + public function getJobsList ( array $params,$columns = ["*"] ) + { + return $this->jobsRepository->findByCriteria($params,$columns); + } + +} \ No newline at end of file diff --git a/app/Core/Service/JwtService.php b/app/Core/Service/JwtService.php new file mode 100644 index 0000000..f67aafa --- /dev/null +++ b/app/Core/Service/JwtService.php @@ -0,0 +1,79 @@ +jwt = $jwt ; + } + + + protected function jwt($params) + { + $payload = [ + 'iss' => $params['iss'], // Issuer of the token + 'sub' => $params['sub'], // Subject of the token + 'user_id' => $params['user_id'], + 'remember_me' => $params['remember_me'], + 'iat' => $params['iat'], // Time when JWT was issued. + 'exp' => $params['exp'] // Expiration time 5 Hours + ]; + + // As you can see we are passing `JWT_SECRET` as the second parameter that will + // be used to decode the token in the future. + return JWT::encode($payload, Config::get('app.jwt.secret')); + } + + public function jwtCreate($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $dayCounter = isset( $params['day_counter'] ) ? $params['day_counter'] : 5 ; + $rememberMe = isset( $params['remember_me'] ) && $params['remember_me'] === true ? true : false ; + $jwtParams = [ + 'iss' => $this->jwtISS, // Issuer of the token + 'sub' => 'UserLoginToken', // Subject of the token + 'user_id' => $params['user_id'], + 'iat' => time(), // Time when JWT was issued. + 'exp' => $rememberMe ? time() + (60 * 60 * 24 * 30) : time() + (60 * 60 * 24 * $dayCounter), + 'remember_me' => $rememberMe ? true : false , + ]; + $response = [ + 'status ' => 1, + 'data' => [ + 'token' => $this->jwt($jwtParams), + 'iat' => $jwtParams['iat'], + 'remember_me' => $rememberMe , + 'exp' => $jwtParams['exp'] + ], + + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + + } + +} diff --git a/app/Core/Service/LanguageBaseService.php b/app/Core/Service/LanguageBaseService.php new file mode 100644 index 0000000..935869a --- /dev/null +++ b/app/Core/Service/LanguageBaseService.php @@ -0,0 +1,581 @@ +request = $request; + $this->languageBaseRepository = $languageBaseRepository; + $this->languageTranslateRepository = $languageTranslateRepository; + $this->languageRepository = $languageRepository; + + $this->tableVariables = [ + +/* 'currency' => [ + 'repository' => 'App\Core\Repository\Currency\CurrencyRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'language' => [ + 'repository' => 'App\Core\Repository\Language\LanguageRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_channel_category' => [ + 'repository' => 'App\Core\Repository\PropertyChannelCategory\PropertyChannelCategoryRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_content_category' => [ + 'repository' => 'App\Core\Repository\PropertyContentCategory\PropertyContentCategoryRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_executive_type' => [ + 'repository' => 'App\Core\Repository\PropertyExecutiveType\PropertyExecutiveTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_fact' => [ + 'repository' => 'App\Core\Repository\PropertyFact\PropertyFactRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => true, + 'parent_column_name' => 'parent_id' + ], + + 'property_photo_category' => [ + 'repository' => 'App\Core\Repository\PropertyPhotoCategory\PropertyPhotoCategoryRepository', + 'source_column' => 'category_name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => 'null' + ], + + 'property_room_bed_type' => [ + 'repository' => 'App\Core\Repository\PropertyRoomBedType\PropertyRoomBedTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => 'null' + ], + + 'property_room_type' => [ + 'repository' => 'App\Core\Repository\PropertyRoomType\PropertyRoomTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => 'null' + ], + + 'property_type' => [ + 'repository' => 'App\Core\Repository\PropertyType\PropertyTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => 'null' + ], + + 'country' => [ + 'repository' => 'App\Core\Repository\Country\CountryRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_room_view_type' => [ + 'repository' => 'App\Core\Repository\PropertyRoomViewType\PropertyRoomViewTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_booking_type' => [ + 'repository' => 'App\Core\Repository\PropertyBookingType\PropertyBookingTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_booking_payment_type' => [ + 'repository' => 'App\Core\Repository\PropertyBookingPaymentType\PropertyBookingPaymentTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_availability_type' => [ + 'repository' => 'App\Core\Repository\PropertyAvailabilityType\PropertyAvailabilityTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_place_category' => [ + 'repository' => 'App\Core\Repository\PropertyPlaceCategory\PropertyPlaceCategoryRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => true, + 'parent_column_name' => 'parent_id' + ], + 'property_place_working_hour' => [ + 'repository' => 'App\Core\Repository\PropertyPlaceWorkingHour\PropertyPlaceWorkingHourRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => 'parent_id' + ], + + + 'property_place_fact_title' => [ + 'repository' => 'App\Core\Repository\PropertyPlaceFactTitle\PropertyPlaceFactTitleRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'property_place_fact' => [ + 'repository' => 'App\Core\Repository\PropertyPlaceFact\PropertyPlaceFactRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'place_category_field' => [ + 'repository' => 'App\Core\Repository\PlaceCategoryField\PlaceCategoryFieldRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'place_category_field_option' => [ + 'repository' => 'App\Core\Repository\PlaceCategoryFieldOption\PlaceCategoryFieldOptionRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => false, + 'parent_column_name' => null + ], + + 'promotion_type' => [ + 'repository' => 'App\Core\Repository\PromotionType\PromotionTypeRepository', + 'source_column' => 'name', + 'key_column' => 'language_key', + 'parent_structure' => true, + 'parent_column_name' => 'parent_id' + ] +*/ + + ]; + + } + + + public function createApplicationLanguageData() + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + $languages = $this->languageRepository->findByCriteria($languageCriteria, ['id', 'code', 'name', 'status']); + if (!$languages) { + throw new ApiErrorException('Language data not found'); + } + + $languagesBase = $this->languageBaseRepository->findByCriteria([], ['id', 'code', 'key', 'text']); + $languagesBase = $languagesBase ? $languagesBase : []; + + $languagesBaseArray = []; + foreach ($languagesBase as $base) { + $languagesBaseArray[$base['key']] = $base['text']; + } + + $languagesTranslate = $this->languageTranslateRepository->findByCriteria([], ['id', 'code', 'key', 'text']); + $languagesTranslate = $languagesTranslate ? $languagesTranslate : []; + + $languagesTranslateArray = []; + foreach ($languagesTranslate as $translate) { + $languagesTranslateArray[$translate['code']][$translate['key']] = $translate['text']; + + } + + $languageExportData = []; + + foreach ($languages as $language) { + $languageContent = null; + if ($language['code'] == 'en') { + $languageContent = $languagesBaseArray; + } elseif (isset($languagesTranslateArray[$language['code']])) { + $languageContent = $languagesTranslateArray[$language['code']]; + } + + $languageExportData[$language['code']] = $languageContent; + } + + $response = [ + 'status' => 1, + 'data' => $languageExportData + ]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function createApplicationLanguageFiles() + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + $languages = $this->languageRepository->findByCriteria($languageCriteria, ['id', 'code', 'name', 'status']); + if (!$languages) { + throw new ApiErrorException('Language data not found'); + } + + $languagesBase = $this->languageBaseRepository->findByCriteria([], ['id', 'code', 'key', 'text']); + $languagesBase = $languagesBase ? $languagesBase : []; + + $languagesBaseArray = []; + foreach ($languagesBase as $base) { + $languagesBaseArray[$base['key']] = trim($base['text']); + } + + $languagesTranslate = $this->languageTranslateRepository->findByCriteria([], ['id', 'code', 'key', 'text']); + $languagesTranslate = $languagesTranslate ? $languagesTranslate : []; + + $languagesTranslateArray = []; + foreach ($languagesTranslate as $translate) { + $clearSpaceData = trim($translate['text']); + if($clearSpaceData){ + $languagesTranslateArray[$translate['code']][$translate['key']] = $clearSpaceData; + } + } + + $applicationLanguageFolder = Config::get('app.appLanguageJsonStoredFolder'); + $myWebLanguageFolder = Config::get('app.myWebLanguageJsonStoredFolder'); + //$wwwLanguageFolder = Config::get('app.wwwLanguageJsonStoredFolder'); + $bookingEngineLanguageFolder = Config::get('app.bookingEngineLanguageJsonStoredFolder'); + $apiLanguageFolder = resource_path() . '/lang/' ; + + foreach ($languages as $language) { + $languageContent = null; + if ($language['code'] == 'en') { + $languageContent = $languagesBaseArray; + } elseif (isset($languagesTranslateArray[$language['code']])) { + $languageContent = $languagesTranslateArray[$language['code']]; + } + $filePath = $applicationLanguageFolder . '/language/' . $language['code']; + if ($languageContent) { + // App Language Create + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + File::put($filePath . '/common.json', json_encode($languageContent, JSON_UNESCAPED_UNICODE)); + + // Api Language Create + if (!File::exists($apiLanguageFolder)) { + File::makeDirectory($apiLanguageFolder, 0777, true); + } + File::put($apiLanguageFolder . $language['code'] . '.json', json_encode($languageContent, JSON_UNESCAPED_UNICODE)); + + // MyWeb Language Create + if (!File::exists($myWebLanguageFolder)) { + File::makeDirectory($myWebLanguageFolder, 0777, true); + } + File::put($myWebLanguageFolder . $language['code'] . '.json', json_encode($languageContent, JSON_UNESCAPED_UNICODE)); + + // www Language Create + /*if (!File::exists($wwwLanguageFolder)) { + File::makeDirectory($wwwLanguageFolder, 0777, true); + } + File::put($wwwLanguageFolder . $language['code'] . '.json', json_encode($languageContent, JSON_UNESCAPED_UNICODE));*/ + + // bookingEngine Language Create + if (!File::exists($bookingEngineLanguageFolder)) { + File::makeDirectory($bookingEngineLanguageFolder, 0777, true); + } + File::put($bookingEngineLanguageFolder . $language['code'] . '.json', json_encode($languageContent, JSON_UNESCAPED_UNICODE)); + + } + } + + try { + Artisan::call('queue:restart'); + } catch (Exception $error) { + Log::error($error->getMessage()); + } + + $response['status'] = 1; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function createApplicationLanguageBaseData() + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $languagesBase = $this->languageBaseRepository->findByCriteria([], ['id', 'code', 'key', 'text']); + $languagesBase = $languagesBase ? $languagesBase : []; + + $languagesBaseArray = []; + foreach ($languagesBase as $base) { + $languagesBaseArray[$base['key']] = $base['text']; + } + + $insertBaseData = []; + foreach ($this->tableVariables as $key => $value) { + $repository = App::make($value['repository']); + $tableVariables = $repository->findByCriteria([]); + $tableVariables = $tableVariables ? $tableVariables : []; + foreach ($tableVariables as $tableVariable) { + if (!isset($languagesBaseArray[$tableVariable[$value['key_column']]])) { + + $insertBaseData[] = [ + 'key' => $tableVariable[$value['key_column']], + 'code' => 'en', + 'text' => $tableVariable[$value['source_column']], + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ]; + } + } + } + $insertBaseDataStatus = $this->languageBaseRepository->createAll($insertBaseData); + if ($insertBaseDataStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + + } + + $response['status'] = 1; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function fillApplicationLanguageKeys() + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + foreach ($this->tableVariables as $key => $value) { + print("for table => $key \n"); + $repository = App::make($value['repository']); + $oldVariables = $repository->findByCriteria([]); + $oldVariables = $oldVariables ? $oldVariables : []; + $oldVariablesCollect = collect($oldVariables); + $oldVariables = $oldVariablesCollect->keyBy('id'); + if ($value['parent_structure'] == true) { + + $mainFacts = $oldVariablesCollect->where('parent_id', '=', null); + + foreach ($mainFacts as $mainFact) { + + // main fact keys, + $mainFactSlug = language_key($mainFact[$value['source_column']]); + $mainFactLanguageKey = $key . '-' . $mainFactSlug; + $mainFactLanguageKey = $this->keyGenerator($mainFactLanguageKey, $value['key_column'], $oldVariables, 0); + + if ($mainFact[$value['key_column']] == null) { + $mainFact[$value['key_column']] = $mainFactLanguageKey; + $oldVariables[$mainFact['id']] = $mainFact; + $repository->update($mainFact['id'], [$value['key_column'] => $mainFactLanguageKey]); + } + + + $subFacts = $oldVariablesCollect->where('parent_id', '=', $mainFact['id']); + foreach ($subFacts as $subFact) { + + // sub fact keys + $subFactSlug = language_key($subFact[$value['source_column']]); + $subFactLanguageKey = $mainFactLanguageKey . '-' . $subFactSlug; + $subFactLanguageKey = $this->keyGenerator($subFactLanguageKey, $value['key_column'], $oldVariables, 0); + + if ($subFact[$value['key_column']] == null) { + $subFact[$value['key_column']] = $subFactLanguageKey; + $oldVariables[$subFact['id']] = $subFact; + $repository->update($subFact['id'], [$value['key_column'] => $subFactLanguageKey]); + } + + $facts = $oldVariablesCollect->where('parent_id', '=', $subFact['id']); + foreach ($facts as $fact) { + + if ($fact[$value['key_column']] == null) { + // sub fact keys + $factSlug = language_key($fact[$value['source_column']]); + $factLanguageKey = $subFactLanguageKey . '-' . $factSlug; + $factLanguageKey = $this->keyGenerator($factLanguageKey, $value['key_column'], $oldVariables, 0); + + $fact[$value['key_column']] = $factLanguageKey; + $oldVariables[$fact['id']] = $fact; + $repository->update($fact['id'], [$value['key_column'] => $factLanguageKey]); + } + + } + + } + + } + } else { + foreach ($oldVariables as $oldVariable) { + if ($oldVariable[$value['key_column']] == null) { + $slug = language_key($oldVariable[$value['source_column']]); + $languageKey = $key . '-' . $slug; + $languageKey = $this->keyGenerator($languageKey, $value['key_column'], $oldVariables, 0); + $oldVariable[$value['key_column']] = $languageKey; + $oldVariables[$oldVariable['id']] = $oldVariable; + $repository->update($oldVariable['id'], [$value['key_column'] => $languageKey]); + } + } + } + } + + $response['status'] = 1; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + protected function keyGenerator($key, $keyColumn, $oldData, $index) + { + + $checkKey = collect($oldData)->where($keyColumn, '=', $key)->first(); + + + if ($checkKey != null) { + + $keyArray1 = explode('-', $key); + $lastArray1Item = end($keyArray1); + + $keyArray2 = explode('_', $lastArray1Item); + $lastArray2Item = end($keyArray2); + $index++; + + + if (is_numeric($lastArray2Item)) { + + array_pop($keyArray2); + array_push($keyArray2, $index); + $array2ToStr = implode($keyArray2, "_"); + + + array_pop($keyArray1); + array_push($keyArray1, $array2ToStr); + $array1ToStr = implode($keyArray1, "-"); + + + $newKey = $array1ToStr; + } else { + + $newKey = $key . '_' . $index; + } + + $key = $this->keyGenerator($newKey, $keyColumn, $oldData, $index); + } + return $key; + + } +} diff --git a/app/Core/Service/LanguageService.php b/app/Core/Service/LanguageService.php new file mode 100644 index 0000000..2702c4d --- /dev/null +++ b/app/Core/Service/LanguageService.php @@ -0,0 +1,196 @@ +request = $request; + $this->languageRepository = $languageRepository; + } + + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->languageRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $languageData = + [ + "name" => fillOnUndefined($param, "name"), + "rating" => fillOnUndefined($param, "rating"), + "longitude" => fillOnUndefined($param, "longitude"), + "latitude" => fillOnUndefined($param, "latitude"), + "status" => fillOnUndefined($param, "status", 0), + "currency_type" => fillOnUndefined($param, "currency_type"), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => null, + "created_at" => time(), + "updated_at" => time(), + + ]; + + $validationResult = $this->languageCreateValidator->validate($languageData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $languageCreateResult = $this->languageRepository->create($languageData); + + if ($languageCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response['status'] = 1; + $response['data'] = $languageCreateResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getAllLanguages($languageCriteria, $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $languages =$this->languageRepository->findByCriteria($languageCriteria,$column); + + if(!$languages){ + throw new ApiErrorException(lang('Language data not found')); + } + + $response['status'] = 1; + $response['data'] = $languages; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function getApplicationLanguages() + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status' , 'condition' => '=', 'value' => 1 ], + ['field' => 'is_application' , 'condition' => '=', 'value' => 1 ], + ['field' => 'is_published' , 'condition' => '=', 'value' => 1 ] + ] , + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + $languageData = $this->select($languageCriteria, ['id','code','name','status', 'language_key']); + $response['status'] = 1; + $response['data'] = $languageData['data']; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function propertyLanguageSpoken($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status' , 'condition' => '=', 'value' => 1 ], + ] , + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + $languageData = $this->select($languageCriteria, ['id','code','name','status', 'language_key']); + $spokenLanguages = $params['selected_languages']; + $responseLanguage = [] ; + + foreach ($languageData['data'] as $language) { + $responseItem = $language ; + $responseItem['is_selected'] = array_search($language['code'], $spokenLanguages) > -1 ? true : false ; + $responseLanguage[] = $responseItem ; + + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseLanguage]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/ManualPaymentMailService.php b/app/Core/Service/ManualPaymentMailService.php new file mode 100644 index 0000000..6288673 --- /dev/null +++ b/app/Core/Service/ManualPaymentMailService.php @@ -0,0 +1,148 @@ +mailer = $mailer ; + $this->propertyService = $propertyService ; + $this->propertyPaymentService = $propertyPaymentService; + + } + + public function process ($params = []) + { + try + { + + + $paymentDetailParam = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $params['orderCode']], + ['field' => 'transaction_type', 'condition' => '=', 'value' => 'LNK'], + ['field' => 'status', 'condition' => '=', 'value' => 5], + ], + 'with' => ['relatedTransactions', 'paymentUser'], + 'firstRow' => true + ]; + + $paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam); + + + if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) { + throw new ApiErrorException(lang('Payment not found')); + } + + $payment = $paymentDetail['data'] ; + $transactions = collect($payment['related_transactions']) ; + $successTransaction = $transactions->where('status' , '=', 1)->first() ; + $paymentParams = $payment['paramsArray']; + + if($paymentParams['email']){ + + $propertyParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $payment['property_id']], + ], + 'with' => ['propertyBrand', 'propertyContact','propertyExecutive'], + 'firstRow' => true + ]; + + $getProperty = $this->propertyService->select($propertyParam) ; + if ($getProperty['status'] != "success") { + throw new ApiErrorException($getProperty['message']); + } + $property = $getProperty['data']; + + + $bcc[] = "bd@extranetwork.com"; + if(isset($payment['payment_user']['email'])){ + $bcc[] = $payment['payment_user']['email']; + } + + $accountExecutives = collect($property['property_executive'])->where('status',1)->where('executive_type_id',1)->pluck('email')->toArray(); + if(!empty($accountExecutives)) { + $bcc = array_merge($bcc,$accountExecutives); + } + + $mailData = [ + 'to' => [ + 'email' => $paymentParams['email'], + ], + 'bcc' => $bcc + + ]; + + $hostAddress = Config::get('app.bookingEngineUrl').'/link/'.$payment['order_id'].'/'.$params['language_code'].'/receipt' ; + $logo = 'https://www.extranetwork.com/assets/img/logo/logo.png'; + if(isset($property['property_brand']['logo_name'])){ + $logo = Config::get('app.imageUrl'). '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'].'_250x250.'. $property['property_brand']['logo_file_ext']; + } + + $mailViewParams = [ + 'property' => $property, + 'payment_params' => $paymentParams, + 'success_transaction' => $successTransaction, + 'amount' => $successTransaction['amount'], + 'currency' => $successTransaction['currency'], + 'date_time' => date('d.m.Y H:i', $successTransaction['created_at'] ), + 'name_surname' => $successTransaction['paramsArray']['creditCard']['name'], + 'email' => $paymentParams['email'], + 'process_title' => $paymentParams['title'], + 'property_name' => $property['name'], + 'url' => $hostAddress, + 'logo' => $logo, + 'language_code' => $params['language_code'], + ] ; + + $mailParams = [ + 'mailData' => $mailData, + 'mailViewParams' => $mailViewParams + ]; + + $this->mailer->onQueue( + 'manualPaymentMail', + new ManualPaymentMail($mailParams) + ); + + } + + + + + } + catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + return output( ['status' => -1, 'message' => $e->getMessage()] ); + } + } + +} diff --git a/app/Core/Service/MyWebContentService.php b/app/Core/Service/MyWebContentService.php new file mode 100644 index 0000000..b0ba5db --- /dev/null +++ b/app/Core/Service/MyWebContentService.php @@ -0,0 +1,2596 @@ +propertyRepository = $propertyRepository; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + $this->propertyContactService = $propertyContactService; + $this->propertyFactService = $propertyFactService; + $this->propertyPhotoService = $propertyPhotoService; + $this->propertyRoomService = $propertyRoomService; + $this->propertyExecutiveService = $propertyExecutiveService; + $this->propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository; + $this->propertyWebColorMappingService = $propertyWebColorMappingService; + $this->propertyWebAboutUsService = $propertyWebAboutUsService; + $this->mailer = $mailer; + $this->propertyWebContactFormValidator = $propertyWebContactFormValidator; + $this->propertyPlaceService = $propertyPlaceService; + $this->propertyWebRoomMappingService = $propertyWebRoomMappingService; + $this->propertyFactMappingService = $propertyFactMappingService; + $this->propertyWebContentRepository = $propertyWebContentRepository; + $this->propertyWebReviewRepository = $propertyWebReviewRepository; + $this->propertyRoomRatePriceRepository = $propertyRoomRatePriceRepository; + + } + + public function home($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyRooms.propertyRoomViewMapping.propertyRoomViewType', + 'propertyChain', 'propertyRooms.propertyRoomPhotoMapping.propertyRoomPhoto', + 'propertyWeb', 'propertyRooms.propertyRoomType', 'propertyAwardsCertificates.awardsCertificateCategory', + 'propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceCategory', + 'propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlacePhotoMapping.propertyPlacePhoto', + 'propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', + 'propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle', + 'propertyWebComponent' + ], + 'firstRow' => true + ]; + + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + + if (!$property) { + throw new ApiErrorException('property not found'); + } + + $propertyWebRoomCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $propertyWebRoom = $this->propertyWebRoomMappingService->select($propertyWebRoomCriteria, ['property_room_id']); + if ($propertyWebRoom['status'] != 'success') { + throw new ApiErrorException($propertyWebRoom['message']); + } + $propertyWebRoomIds = collect($propertyWebRoom['data'])->pluck('property_room_id')->toArray(); + + + $rooms = []; + foreach ($propertyWebRoom['data'] as $roomMappingData) { + $roomCheck = collect($property['property_rooms'])->where('id', $roomMappingData['property_room_id'])->first(); + if ($roomCheck) { + + + $rooms[$roomMappingData['property_room_id']] = $roomCheck; + $rooms[$roomMappingData['property_room_id']]['slug'] = Str::slug($roomCheck['name'], $separator = '-', $language = 'en'); + + unset($rooms[$roomMappingData['property_room_id']]['property_room_photo_mapping']); + $roomThumbnailPhoto = NULL; + + $rooms[$roomMappingData['property_room_id']]['property_room_photos'] = collect($roomCheck['property_room_photo_mapping'])->map(function ($value, $key) use ($property, &$roomThumbnailPhoto) { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_medium.' . $value['property_room_photo']['file_ext']; + } + if ($key === 0) { + $photoThumbUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + if (File::exists($photoThumbUrlFilePath)) { + $roomThumbnailPhoto = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + } else { + $roomThumbnailPhoto = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_thumbnail.' . $value['property_room_photo']['file_ext']; + } + } + return $photoUrlFilePath; + + })->all(); + + $rooms[$roomMappingData['property_room_id']]['cover_photo'] = $rooms[$roomMappingData['property_room_id']]['property_room_photos'] != null ? $rooms[$roomMappingData['property_room_id']]['property_room_photos'][0] : null; + $rooms[$roomMappingData['property_room_id']]['room_thumbnail_photo'] = $roomThumbnailPhoto; + + + } + } + + $rooms = array_values($rooms); + + /* + $rooms = collect($property['property_rooms']) + ->filter(function ($value) use ($propertyWebRoomIds) { + if (!empty($propertyWebRoomIds)) { + if (in_array($value['id'], $propertyWebRoomIds)) { + return $value; + } + } else { + return $value; + } + }) + ->map(function ($value, $valueKey) use ($property, $propertyWebRoomIds) { + + $room = $value; + unset($room['property_room_photo_mapping']); + $roomThumbnailPhoto = NULL; + $room['property_room_photos'] = collect($value['property_room_photo_mapping'])->map(function ($value, $key) use ($property, &$roomThumbnailPhoto) { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_medium.' . $value['property_room_photo']['file_ext']; + } + if ($key === 0) { + $photoThumbUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + if (File::exists($photoThumbUrlFilePath)) { + $roomThumbnailPhoto = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + } else { + $roomThumbnailPhoto = Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . '/' . $value['property_room_photo']['photo_name'] . '_thumbnail.' . $value['property_room_photo']['file_ext']; + } + } + return $photoUrlFilePath; + + })->all(); + $room['cover_photo'] = $room['property_room_photos'] != null ? $room['property_room_photos'][0] : null; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + $room['room_thumbnail_photo'] = $roomThumbnailPhoto; + + return $room; + })->values()->all(); + */ + + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $coverPhotos = $this->coverPhotos($params); + + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $propertyAwardsCertificates = collect($property['property_awards_certificates']) + ->where('status', '=', 1) + ->where('awards_certificate_category.type', '!=', 'PLC') + //->where('awards_certificate_category.type', '!=', 'MNU') + ->map(function ($value) { + + $return = $value; + unset($return['awards_certificate_category']); + $image = null; + + if ($value['file_path']) { + $urlPath = '/property-photos/' . $value['property_id'] . "/awards-certificates/"; + $image = Config::get('app.imageUrl') . $urlPath . $value['file_path']; + } + + + $catLogo = null; + if ($value['awards_certificate_category']['id']) { + $urlPath = '/assets/img/awards/'; + $catLogo = Config::get('app.client_server') . $urlPath . $value['awards_certificate_category']['id'] . '.png'; + } + + $return['file_path'] = $image ? $image : null; + + $category = [ + 'category_name' => $value['awards_certificate_category']['name'], + 'category_language_key' => $value['awards_certificate_category']['language_key'], + 'category_country_code' => $value['awards_certificate_category']['country_code'], + 'category_logo' => $catLogo, + 'category_type' => $value['awards_certificate_category']['type'], + 'category_status' => $value['awards_certificate_category']['status'], + ]; + return array_merge($return, $category); + })->values()->all(); + + array_multisort( + array_column($propertyAwardsCertificates, 'date'), SORT_DESC, + array_column($propertyAwardsCertificates, 'name'), SORT_ASC, + $propertyAwardsCertificates + ); + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_language_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'landing_photo' => $coverPhotos, + 'description' => $property['name'], + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'awards_certificate_category' => $propertyAwardsCertificates, + 'property_contact' => $property['property_contact'] + ]; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = $propertyAdditionalInfo['data']; + } + + + $propertyPlace = []; + /** Property Place **/ + foreach ($property['property_web']['property_web_place_mapping'] as $place) { + + $place = $place['place_detail']; + + if ($place['status'] != 1) { + continue; + } + + $propertyPlace[$place['id']]['id'] = $place['id']; + $propertyPlace[$place['id']]['name'] = $place['name']; + $propertyPlace[$place['id']]['slug'] = Str::slug($place['name'], $separator = '-', $language = 'en'); + + $propertyPlace[$place['id']]['category']['name'] = $place['property_place_category']['name']; + $propertyPlace[$place['id']]['category']['language_key'] = $place['property_place_category']['language_key']; + + $propertyPlace[$place['id']]['photo'] = [ + 'thumb' => '/assets/img/placeholder.webp', + 'fixed' => '/assets/img/placeholder.webp' + ]; + + if (isset($place['property_place_photo_mapping'])) { + $propertyPlacePhotoMapping = collect($place['property_place_photo_mapping'])->sortBy('id')->first(); + if ($propertyPlacePhotoMapping) { + $propertyPlace[$place['id']]['photo'] = [ + 'thumb' => $propertyPlacePhotoMapping['property_place_photo']['photoUrl']['thumb'], + 'fixed' => $propertyPlacePhotoMapping['property_place_photo']['photoUrl']['fixed'], + ]; + } + } + + + $propertyPlaceFact = []; + foreach ($place['property_place_fact_mapping'] as $fact) { + + $factId = $fact['property_place_fact_title_fact_mapping']['place_fact_id']; + $factCategoryId = $fact['property_place_fact_title_fact_mapping']['place_fact_title_id']; + $propertyPlaceFact[$factCategoryId]['category'] = [ + 'name' => $fact['property_place_fact_title_fact_mapping']['place_fact_title']['name'], + 'language_key' => $fact['property_place_fact_title_fact_mapping']['place_fact_title']['language_key'], + ]; + + $propertyPlaceFact[$factCategoryId]['fact'][] = [ + 'name' => $fact['property_place_fact_title_fact_mapping']['place_fact']['name'], + 'language_key' => $fact['property_place_fact_title_fact_mapping']['place_fact']['language_key'], + 'icon' => $fact['property_place_fact_title_fact_mapping']['place_fact']['icon'], + ]; + + } + + $propertyPlace[$place['id']]['feature'] = !empty($propertyPlaceFact) ? array_values($propertyPlaceFact) : []; + + if (count($propertyPlace) == 2) { + //break; + } + + } + + /** Property Place **/ + $responseData['property_place'] = !empty($propertyPlace) ? array_values($propertyPlace) : []; + + + /** Property Facts **/ + $getPropertyFact = $this->propertyFactService->getPropertyFact($params); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $getPropertyFact = $this->getPropertyFactForHtml($getPropertyFact['data']); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $responseData['property_facts'] = $getPropertyFact['data']; + /** Property Facts **/ + + + /** Property Review **/ + $propertyWebReviewData = []; + + + $propertyWebComponentCheck = collect($property['property_web_component'])->where('component_id', 3)->count(); + if ($propertyWebComponentCheck) { + $propertyWebReviewRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'time', 'value' => 'DESC'] + ] + ]; + + $propertyWebReview = $this->propertyWebReviewRepository->findByCriteria($propertyWebReviewRequest); + + + $currentLanguageCheck = []; + if (fillOnUndefined($params, 'currentLanguage')) { + $currentLanguageCheck = collect($propertyWebReview)->where('language_code', $params['currentLanguage'])->toArray(); + } + + if (count($currentLanguageCheck) > 4) { + $propertyWebReviewData = collect($currentLanguageCheck)->take(10)->toArray(); + } else { + $propertyWebReviewData = collect($propertyWebReview)->take(10)->toArray(); + } + + $propertyWebReviewData = $propertyWebReviewData ? array_values($propertyWebReviewData) : []; + } + + $responseData['property_review'] = $propertyWebReviewData; + /** Property Review **/ + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function aboutUs($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $responseData = []; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates.awardsCertificateCategory', + 'propertyLanguageSpoken.languageCode', + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $coverPhotos = $this->coverPhotos($params); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + + $propertyWebAboutUsParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'mode' => $params['mode'] === "preview" ? 2 : 1, // live : 1 preview : 2 + ]; + $propertyWebAboutUs = $this->propertyWebAboutUsService->getPropertyWebAboutUs($propertyWebAboutUsParams); + + if ($propertyWebAboutUs['status'] != 'success') { + throw new ApiErrorException($propertyWebAboutUs['message']); + } + + $aboutUs = isset($propertyWebAboutUs['data']) && !empty($propertyWebAboutUs['data']) ? $propertyWebAboutUs['data'] : []; + + $aboutUsFiltred = collect($aboutUs)->first(function ($value, $key) use ($params) { + if ($value['language_code'] == $params['currentLanguage']) { + return $value['value']; + } + }); + + $propertyAwardsCertificates = collect($property['property_awards_certificates']) + ->where('awards_certificate_category.type', '!=', 'PLC') + ->where('status', '=', 1) + ->map(function ($value) { + + $return = $value; + unset($return['awards_certificate_category']); + $image = null; + + if ($value['file_path']) { + $urlPath = '/property-photos/' . $value['property_id'] . "/awards-certificates/"; + $image = Config::get('app.imageUrl') . $urlPath . $value['file_path']; + } + + + $catLogo = null; + if ($value['awards_certificate_category']['id']) { + $urlPath = '/assets/img/awards/'; + $catLogo = Config::get('app.client_server') . $urlPath . $value['awards_certificate_category']['id'] . '.png'; + } + + $return['file_path'] = $image ? $image : null; + + $category = [ + 'category_name' => $value['awards_certificate_category']['name'], + 'category_language_key' => $value['awards_certificate_category']['language_key'], + 'category_country_code' => $value['awards_certificate_category']['country_code'], + 'category_logo' => $catLogo, + 'category_type' => $value['awards_certificate_category']['type'], + 'category_status' => $value['awards_certificate_category']['status'], + ]; + return array_merge($return, $category); + })->values()->all(); + + array_multisort( + array_column($propertyAwardsCertificates, 'date'), SORT_DESC, + array_column($propertyAwardsCertificates, 'name'), SORT_ASC, + $propertyAwardsCertificates + ); + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + + $propertyLanguageSpoken = null; + $propertyLanguageSpoken = collect($property['property_language_spoken'])->map(function ($spokenLanguage) { + return [ + 'code' => $spokenLanguage['language_code']['code'], + 'name' => $spokenLanguage['language_code']['name'], + 'language_key' => $spokenLanguage['language_code']['language_key'] + ]; + }); + + + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => isset($aboutUsFiltred['value']) ? $aboutUsFiltred['value'] : "", + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'property_contact' => $property['property_contact'], + 'landing_photo' => $coverPhotos, + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'awards_certificate_category' => $propertyAwardsCertificates, + 'property_language_spoken' => $propertyLanguageSpoken, + ]; + + $getPropertyFact = $this->propertyFactService->getPropertyFact($params); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $getPropertyFact = $this->getPropertyFactForHtml($getPropertyFact['data']); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $responseData['property_facts'] = $getPropertyFact['data']; + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = $propertyAdditionalInfo['data']; + } + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyFactForHtml($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $categories = $params; + $responseArray = []; + foreach ($categories as $category) { + $categoryArray = []; + $categoryItem = $category; + foreach ($category['fact_subcategory'] as $subCategory) { + $subCategoryItem = $subCategory; + $facts = collect($subCategory['fact']) + ->where('is_selected', '=', true) + ->map(function ($value) { + return $value; + })->values()->all(); + $subCategoryItem['fact'] = $facts ? $facts : []; + if ($facts) { + $categoryArray[$subCategory['id']] = $subCategoryItem; + } + } + $categoryItem['fact_subcategory'] = $categoryArray; + $responseArray[$category['id']] = $categoryItem; + } + + $response = [ + 'status' => true, + 'data' => $responseArray, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function gallery($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + + $responseData['photos'] = $this->photos($params);; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function rooms($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + + $propertyWebRoomCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $propertyWebRoom = $this->propertyWebRoomMappingService->select($propertyWebRoomCriteria, ['property_room_id']); + if ($propertyWebRoom['status'] != 'success') { + throw new ApiErrorException($propertyWebRoom['message']); + } + $propertyWebRoomIds = collect($propertyWebRoom['data'])->pluck('property_room_id')->toArray(); + + $rooms = []; + foreach ($propertyWebRoom['data'] as $roomMappingData) { + $roomCheck = collect($property['property_rooms'])->where('id', $roomMappingData['property_room_id'])->first(); + if ($roomCheck) { + $rooms[$roomMappingData['property_room_id']] = $roomCheck; + $rooms[$roomMappingData['property_room_id']]['slug'] = Str::slug($roomCheck['name'], $separator = '-', $language = 'en'); + } + } + + $rooms = array_values($rooms); + + /*$rooms = collect($property['property_rooms']) + ->filter(function ($value) use ($propertyWebRoomIds) { + if (!empty($propertyWebRoomIds)) { + if (in_array($value['id'], $propertyWebRoomIds)) { + return $value; + } + } else { + return $value; + } + }) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all();*/ + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomDefaultPhoto.propertyRoomPhoto', 'propertyRoomFactMapping.propertyFact', 'propertyRoomViewMapping.propertyRoomViewType'] + ]; + $propertyRooms = $this->propertyRoomService->select($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + if ($propertyRooms['status'] != 'success') { + throw new ApiErrorException($propertyRooms['message']); + } + + if (!$propertyRooms['data']) { + throw new ApiErrorException('room data not found'); + } + + $rooms = []; + foreach ($propertyWebRoom['data'] as $roomMappingData) { + $roomCheck = collect($propertyRooms['data'])->where('id', $roomMappingData['property_room_id'])->first(); + if ($roomCheck) { + $rooms[$roomMappingData['property_room_id']] = $roomCheck; + $rooms[$roomMappingData['property_room_id']]['slug'] = Str::slug($roomCheck['name'], $separator = '-', $language = 'en'); + } + } + + $newRoomMapping = []; + foreach ($rooms as $room) { + + $roomPhoto = $room['property_room_default_photo']; + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_1024x768.' . $roomPhoto['property_room_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_200x200.' . $roomPhoto['property_room_photo']['file_ext']; + + $photoItem['photo_original'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '.' . $roomPhoto['property_room_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoItem['photo_large'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_1024x768.' . $roomPhoto['property_room_photo']['file_ext']; + } else { + $photoItem['photo_large'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_medium.' . $roomPhoto['property_room_photo']['file_ext']; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoItem['photo_thumbnail'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_200x200.' . $roomPhoto['property_room_photo']['file_ext']; + } else { + $photoItem['photo_thumbnail'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_thumbnail.' . $roomPhoto['property_room_photo']['file_ext']; + } + + $room['default_photo'] = $photoItem; + unset($room['property_room_default_photo']); + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + + $roomFacts = $room['property_room_fact_mapping']; + $newFacts = []; + + foreach ($roomFacts as $fact) { + + $factItem['id'] = $fact['id']; + $factItem['fact_id'] = $fact['fact_id']; + $factItem['name'] = $fact['property_fact']['name']; + $factItem['language_key'] = $fact['property_fact']['language_key']; + $factItem['type'] = $fact['property_fact']['type']; + $factItem['order_number'] = $fact['property_fact']['order_number']; + $factItem['icon'] = $fact['property_fact']['icon']; + $factItem['is_feature'] = $fact['is_feature']; + $newFacts[] = $factItem; + } + + unset($room['property_room_fact_mapping']); + + $room['facts'] = $newFacts; + + // Room Views + $roomViews = $room['property_room_view_mapping']; + $newViews = []; + foreach ($roomViews as $view) { + $viewItem['id'] = $view['property_room_view_type']['id']; + $viewItem['name'] = $view['property_room_view_type']['name']; + $viewItem['language_key'] = $view['property_room_view_type']['language_key']; + $newViews[] = $viewItem; + } + unset($room['property_room_view_mapping']); + $room['views'] = $newViews; + + $newRoomMapping[] = $room; + } + + $responseData['room_detailed_list'] = $newRoomMapping; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function roomDetail($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + //'propertyRooms.propertyRoomDefaultPhoto.propertyRoomPhoto', + //'propertyRooms.propertyRoomType', + //'propertyRooms.propertyRoomFactMapping.propertyFact', + 'propertyWebRooms.roomDetail.propertyRoomDefaultPhoto.propertyRoomPhoto', + 'propertyWebRooms.roomDetail.propertyRoomType', + 'propertyWeb', 'propertyAwardsCertificates' + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + + $rooms = collect($property['property_web_rooms']) + ->map(function ($value) use ($property) { + $room = $value['room_detail']; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + $room['property_room_default_photo'] = $room['property_room_default_photo']['property_room_photo']['photoUrl']; + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['room_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomBedGroup.propertyRoomBedType', 'propertyRoomPhotoMapping.propertyRoomPhoto', 'propertyRoomFactMapping.propertyFact', 'propertyRoomViewMapping.propertyRoomViewType'], + 'firstRow' => 1 + ]; + + $propertyRooms = $this->propertyRoomService->select($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number', 'description']); + + if ($propertyRooms['status'] != 'success') { + throw new ApiErrorException($propertyRooms['message']); + } + + if (!$propertyRooms['data']) { + throw new ApiErrorException('room data not found'); + } + $room = $propertyRooms['data']; + + $bedGroups = collect($room['property_room_bed_group'])->keyBy('bed_group')->keys(); + $group = []; + foreach ($bedGroups as $bedGroup) { + $thisGroup = collect($room['property_room_bed_group'])->where('bed_group', '=', $bedGroup)->map(function ($bedItem) use ($bedGroup) { + $responseMapping = $bedItem; + $responseMapping['bed_type_name'] = $bedItem['property_room_bed_type']['name']; + unset($responseMapping['property_room_bed_type']); + return $responseMapping; + })->toArray(); + $newItem = []; + foreach ($thisGroup as $item) { + $newItem[] = $item; + } + $group[] = $newItem; + } + $room['property_room_bed_group'] = $group; + + $roomDescriptions = json_decode($room['description'], true); + $roomDescription = null; + $currentLanguage = isset($params['currentLanguage']) ? $params['currentLanguage'] : 'en'; + + if (isset($roomDescriptions[$currentLanguage]) && $roomDescriptions[$currentLanguage]) { + $roomDescription = $roomDescriptions[$currentLanguage]; + } + $room['description'] = $roomDescription; + + $roomPhotos = $room['property_room_photo_mapping']; + $newRoomPhotos = []; + + foreach ($roomPhotos as $roomPhoto) { + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_1024x768.' . $roomPhoto['property_room_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_200x200.' . $roomPhoto['property_room_photo']['file_ext']; + $photoItem['photo_original'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '.' . $roomPhoto['property_room_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoItem['photo_large'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_1024x768.' . $roomPhoto['property_room_photo']['file_ext']; + } else { + $photoItem['photo_large'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_medium.' . $roomPhoto['property_room_photo']['file_ext']; + } + if (File::exists($photoUrlThumbFilePath)) { + $photoItem['photo_thumbnail'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_200x200.' . $roomPhoto['property_room_photo']['file_ext']; + } else { + $photoItem['photo_thumbnail'] = Config::get('app.imageUrl') . '/property-photos/' . $roomPhoto['property_id'] . '/' . $roomPhoto['property_room_photo']['photo_name'] . '_thumbnail.' . $roomPhoto['property_room_photo']['file_ext']; + } + $newRoomPhotos[] = $photoItem; + } + $room['default_photo'] = $newRoomPhotos ? $newRoomPhotos[0] : []; + unset($room['property_room_photo_mapping']); + $room['photos'] = $newRoomPhotos; + + $roomFacts = $room['property_room_fact_mapping']; + $newFacts = []; + foreach ($roomFacts as $fact) { + + $factItem['id'] = $fact['id']; + $factItem['fact_id'] = $fact['fact_id']; + $factItem['name'] = $fact['property_fact']['name']; + $factItem['language_key'] = $fact['property_fact']['language_key']; + $factItem['type'] = $fact['property_fact']['type']; + $factItem['order_number'] = $fact['property_fact']['order_number']; + $factItem['icon'] = $fact['property_fact']['icon']; + $newFacts[] = $factItem; + } + unset($room['property_room_photo_mapping']); + unset($room['property_room_fact_mapping']); + $room['photos'] = $newRoomPhotos; + $room['facts'] = $newFacts; + + // Room Views + $roomViews = $room['property_room_view_mapping']; + $newViews = []; + foreach ($roomViews as $view) { + $viewItem['id'] = $view['property_room_view_type']['id']; + $viewItem['name'] = $view['property_room_view_type']['name']; + $viewItem['language_key'] = $view['property_room_view_type']['language_key']; + $newViews[] = $viewItem; + } + unset($room['property_room_view_mapping']); + $room['views'] = $newViews; + + + + $room['minPrice'] = null; + $room['priceRange'] = null; + $roomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $params['room_id']], + ['field' => 'amount', 'condition' => '>', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => Carbon::now()->format('Y-m-d')], + ['field' => 'date', 'condition' => '<=', 'value' => Carbon::now()->addMonth()->format('Y-m-d')], + ], + 'orderBy' => [ + ['field' => 'amount', 'value' => 'ASC'] + ] + ]; + + $minRoomRatePrice = $this->propertyRoomRatePriceRepository->findbyCriteria($roomRatesCriteria, ['id', 'property_id', 'property_room_id', 'date', 'amount', 'currency']); + + $lowPrice = collect($minRoomRatePrice)->sortBy('amount')->first(); + $highPrice = collect($minRoomRatePrice)->sortByDesc('amount')->first(); + + if($lowPrice && $highPrice) { + + $room['lowPrice'] = [ + 'amount' => $lowPrice['amount'], + 'currency' => $lowPrice['currency'], + ]; + + $room['highPrice'] = [ + 'amount' => $highPrice['amount'], + 'currency' => $highPrice['currency'], + ]; + + } + + + $responseData['room_detail'] = $room; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function contact($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyType', 'propertyChain', 'propertyExecutive.executiveType', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + + + $newExecutiveArray = []; + foreach ($property['property_executive'] as $propertyExecutive) { + + $executiveItem = [ + 'id' => $propertyExecutive['id'], + 'executive_type_name' => $propertyExecutive['executive_type']['name'], + 'executive_type_locale_key' => $propertyExecutive['executive_type']['language_key'], + 'executive_type_icon' => $propertyExecutive['executive_type']['icon'], + 'name_surname' => $propertyExecutive['name_surname'], + 'email' => $propertyExecutive['email'], + 'phone_code' => $propertyExecutive['phone_code'], + 'phone' => $propertyExecutive['phone'], + 'extension' => $propertyExecutive['extension'], + 'mobile_code' => $propertyExecutive['mobile_code'], + 'mobile' => $propertyExecutive['mobile'], + 'fax_code' => $propertyExecutive['fax_code'], + 'fax' => $propertyExecutive['fax'], + 'view_full_phone' => $propertyExecutive['view_full_phone'], + 'view_full_mobile' => $propertyExecutive['view_full_mobile'], + 'view_full_fax' => $propertyExecutive['view_full_fax'], + ]; + + if ($propertyExecutive['status'] == 1) { + $newExecutiveArray[] = $executiveItem; + } + + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $additionalInfoRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'additional_info_key_id', 'condition' => '=', 'value' => 10] + ], + 'firstRow' => true + ]; + + $myWebContactEmail = $this->propertyAdditionalInfoService->select($additionalInfoRequest); + + if ($myWebContactEmail['status'] != 'success') { + throw new ApiErrorException($myWebContactEmail['message']); + } + + $myWebContactEmail = isset($myWebContactEmail['data']['value']) && !empty($myWebContactEmail['data']['value']) ? $myWebContactEmail['data']['value'] : null; + + $property['property_contact']['myweb_contact_email'] = $myWebContactEmail; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + + + $distances = []; + $factDistancesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['fact'] + ]; + + $factDistances = $this->propertyFactMappingService->select($factDistancesCriteria); + if ($factDistances['status'] == 'success') { + $factDistances = collect($factDistances['data'])->where('fact.parent_id', 735)->toArray(); + foreach ($factDistances as $factDistance) { + $distances[] = [ + 'name' => $factDistance['fact']['name'], + 'icon' => $factDistance['fact']['icon'], + 'language_key' => $factDistance['fact']['language_key'], + 'description' => $factDistance['descriptionArray'], + ]; + } + } + + $coverPhotos = $this->coverPhotos($params); + + + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'property_executive' => $newExecutiveArray, + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'landing_photo' => $coverPhotos, + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + 'distances' => $distances + + ]; + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function executiveDetail($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $executiveRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['executive_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + 'with' => ['executiveType'] + ]; + + $getExecutiveFields = ['id', 'property_id', 'executive_type_id', 'name_surname', 'email', 'phone_code', 'phone', 'extension', 'mobile_code', 'mobile', 'fax_code', 'fax']; + $executive = $this->propertyExecutiveService->select($executiveRequest, $getExecutiveFields); + if ($executive['status'] != 'success' || !$executive['data']) { + throw new ApiErrorException($executive['message']); + } + + $propertyExecutive = $executive['data']; + $executiveItem = [ + 'id' => $propertyExecutive['id'], + 'executive_type_name' => $propertyExecutive['executive_type']['name'], + 'executive_type_locale_key' => $propertyExecutive['executive_type']['language_key'], + 'executive_type_icon' => $propertyExecutive['executive_type']['icon'], + 'name_surname' => $propertyExecutive['name_surname'], + 'email' => $propertyExecutive['email'], + 'phone_code' => $propertyExecutive['phone_code'], + 'phone' => $propertyExecutive['phone'], + 'extension' => $propertyExecutive['extension'], + 'mobile_code' => $propertyExecutive['mobile_code'], + 'mobile' => $propertyExecutive['mobile'], + 'fax_code' => $propertyExecutive['fax_code'], + 'fax' => $propertyExecutive['fax'], + 'view_full_phone' => $propertyExecutive['view_full_phone'], + 'view_full_mobile' => $propertyExecutive['view_full_mobile'], + 'view_full_fax' => $propertyExecutive['view_full_fax'], + ]; + + $response = [ + 'status' => true, + 'data' => $executiveItem, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function coverPhotos($params = []) + { + + $propertyWebPhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ['field' => 'is_cover', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => $params['mode'] == 'preview' ? 2 : 1], + ], + 'with' => ['propertyPhoto'] + ]; + $propertyWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($propertyWebPhotoMappingRequest); + $propertyWebMappingPhotos = $propertyWebMappingPhotos ? $propertyWebMappingPhotos : []; + $coverPhotos = []; + + foreach ($propertyWebMappingPhotos as $key => $photo) { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_medium.' . $photo['property_photo']['file_ext']; + } + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_thumbnail.' . $photo['property_photo']['file_ext']; + } + $coverPhotos[$key]['default'] = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '.' . $photo['property_photo']['file_ext']; + $coverPhotos[$key]['fixed'] = $photoUrlFilePath; + $coverPhotos[$key]['thumb'] = $photoUrlThumbFilePath; + } + + return $coverPhotos; + + } + + public function photos($params = []) + { + + $propertyWebPhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + //['field' => 'is_cover', 'condition' => '=', 'value' => 0], + ['field' => 'status', 'condition' => '=', 'value' => $params['mode'] == 'preview' ? 2 : 1], + ], + 'with' => ['propertyPhoto'] + ]; + $propertyWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($propertyWebPhotoMappingRequest); + $propertyWebMappingPhotos = $propertyWebMappingPhotos ? $propertyWebMappingPhotos : []; + $responsePhotos = []; + + foreach ($propertyWebMappingPhotos as $photo) { + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_medium.' . $photo['property_photo']['file_ext']; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_thumbnail.' . $photo['property_photo']['file_ext']; + } + + + $responsePhotos[] = [ + 'id' => $photo['id'], + 'photo_url_thump' => $photoUrlThumbFilePath, + 'photo_url' => $photoUrlFilePath, + 'is_cover' => $photo['is_cover'], + /*'medium_photo_size' => [ + 'width' => Image::make($photoUrlFilePath)->width(), + 'height' => Image::make($photoUrlFilePath)->height() + ] ,*/ + ]; + + } + return $responsePhotos; + + } + + private function checkWebColorMapping($params, $status) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $webColorRequestData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'status' => $status + ]; + $webColorDatas = $this->propertyWebColorMappingService->getPropertyWebColorMappingWithStatus($webColorRequestData, ['id', 'color_code', 'order_number', 'status']); + + if ($webColorDatas['status'] != 'success') { + throw new ApiErrorException($webColorDatas['message']); + } + + $data = []; + if (!empty($webColorDatas['data']['property_web_color_mapping'])) { + foreach ($webColorDatas['data']['property_web_color_mapping'] as $key => $webColorMappingData) { + $data[$key]['color_number'] = $webColorMappingData['order_number']; + $data[$key]['color_code'] = $webColorMappingData['color_code']; + } + } + + $response = [ + 'status' => true, + 'data' => $data + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function contactForm($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->propertyWebContactFormValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyExecutive.executiveType', 'propertyWeb'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if ($propertyAdditionalInfo['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + $myWebContactEmail = $propertyAdditionalInfo['data']['myweb_contact_email']; + + if (!$myWebContactEmail) { + throw new ApiErrorException('api-unknown-error'); + } + + $bcc = []; + $mailData = [ + 'to' => [ + 'name' => $property['name'], + 'email' => $myWebContactEmail, + ], + 'bcc' => $bcc + + ]; + + $mailViewParams = $params; + $mailViewParams['logo'] = 'https://www.extranetwork.com/assets/img/logo/logo.png'; + + + $mailParams = [ + 'mailData' => $mailData, + 'mailViewParams' => $mailViewParams + ]; + + $this->mailer->onQueue( + 'contactFormMail', + new ContactFormMail($mailParams) + ); + + $response = [ + 'status' => true, + 'data' => null, + 'message' => 'myweb-contact_form-success_message', + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function placeCategoryPlaces($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'property_contact' => $property['property_contact'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + + ]; + + $categoryMapping = $this->propertyPlaceService->getCategoriesInList($params); + if ($categoryMapping['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + + $responseData['places'] = $categoryMapping['data']['places']; + $responseData['category'] = $categoryMapping['data']['category']; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPlace($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + + $getPlace = $this->propertyPlaceService->getPlace($params); + if ($getPlace['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + + if (isset($getPlace['data']['description']) && !is_null($getPlace['data']['description'])) { + $description = json_decode($getPlace['data']['description'], 1); + $getPlace['data']['description'] = null; + if (isset($description[$params['currentLanguage']])) { + $getPlace['data']['description'] = $description[$params['currentLanguage']]; + } + } + + $responseData['place'] = $getPlace['data']; + + //Category's Other Places + $categoryPlaces = $this->propertyPlaceService->getCategoriesInList(['property_id' => $params['property_id'], 'place_category_id' => $getPlace['data']['category']['id']]); + $responseData['categoryPlace'] = $categoryPlaces['status'] == 'success' && !empty($categoryPlaces['data']) && isset($categoryPlaces['data']['places']) ? $categoryPlaces['data']['places'] : []; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function kvkk($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = collect($propertyAdditionalInfo['data'])->only(['kvkk_mersis_no', 'kvkk_data_controller', 'kvkk_contact_person', 'kvkk_addres', 'kvkk_phone', 'kvkk_tax_office', 'kvkk_tax_number', 'kvkk_email', 'kvkk_web_site', 'kvkk_contact_email', 'kvkk_contact_address'])->toArray(); + } + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function multimedia($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyType', 'propertyChain', 'propertyExecutive.executiveType', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country', 'content_code']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + + + $newExecutiveArray = []; + foreach ($property['property_executive'] as $propertyExecutive) { + + $executiveItem = [ + 'id' => $propertyExecutive['id'], + 'executive_type_name' => $propertyExecutive['executive_type']['name'], + 'executive_type_locale_key' => $propertyExecutive['executive_type']['language_key'], + 'executive_type_icon' => $propertyExecutive['executive_type']['icon'], + 'name_surname' => $propertyExecutive['name_surname'], + 'email' => $propertyExecutive['email'], + 'phone_code' => $propertyExecutive['phone_code'], + 'phone' => $propertyExecutive['phone'], + 'extension' => $propertyExecutive['extension'], + 'mobile_code' => $propertyExecutive['mobile_code'], + 'mobile' => $propertyExecutive['mobile'], + 'fax_code' => $propertyExecutive['fax_code'], + 'fax' => $propertyExecutive['fax'], + 'view_full_phone' => $propertyExecutive['view_full_phone'], + 'view_full_mobile' => $propertyExecutive['view_full_mobile'], + 'view_full_fax' => $propertyExecutive['view_full_fax'], + ]; + + if ($propertyExecutive['status'] == 1) { + $newExecutiveArray[] = $executiveItem; + } + + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $additionalInfoRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'additional_info_key_id', 'condition' => '=', 'value' => 10] + ], + 'firstRow' => true + ]; + + $myWebContactEmail = $this->propertyAdditionalInfoService->select($additionalInfoRequest); + + if ($myWebContactEmail['status'] != 'success') { + throw new ApiErrorException($myWebContactEmail['message']); + } + + $myWebContactEmail = isset($myWebContactEmail['data']['value']) && !empty($myWebContactEmail['data']['value']) ? $myWebContactEmail['data']['value'] : null; + + $property['property_contact']['myweb_contact_email'] = $myWebContactEmail; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + + + $distances = []; + $factDistancesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['fact'] + ]; + + $factDistances = $this->propertyFactMappingService->select($factDistancesCriteria); + if ($factDistances['status'] == 'success') { + $factDistances = collect($factDistances['data'])->where('fact.parent_id', 735)->toArray(); + foreach ($factDistances as $factDistance) { + $distances[] = [ + 'name' => $factDistance['fact']['name'], + 'icon' => $factDistance['fact']['icon'], + 'language_key' => $factDistance['fact']['language_key'], + 'description' => $factDistance['descriptionArray'], + ]; + } + } + + + $responseData = [ + 'id' => $property['id'], + 'name' => $property['name'], + 'content_code' => $property['content_code'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'property_executive' => $newExecutiveArray, + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + 'distances' => $distances + + ]; + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function content($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = collect($propertyAdditionalInfo['data'])->only(['kvkk_mersis_no', 'kvkk_data_controller', 'kvkk_contact_person', 'kvkk_addres', 'kvkk_phone', 'kvkk_tax_office', 'kvkk_tax_number', 'kvkk_email', 'kvkk_web_site', 'kvkk_contact_email', 'kvkk_contact_address'])->toArray(); + } + + $columns = ['id', 'property_id', 'content_category_id', 'title', 'slug', 'image', 'language_code', 'status', 'created_at']; + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'content_category_id', 'condition' => '=', 'value' => $params['content_category_id']], + ['field' => 'language_code', 'condition' => '=', 'value' => $params['language_code']], + ], + 'with' => ['ContentCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + $propertyWebContent = $this->propertyWebContentRepository->findByCriteria($propertyWebContentCriteria, $columns); + + $responseData['property_content'] = $propertyWebContent; + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function contentDetail($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => '', + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'property_contact' => $property['property_contact'], + + ]; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = collect($propertyAdditionalInfo['data'])->only(['kvkk_mersis_no', 'kvkk_data_controller', 'kvkk_contact_person', 'kvkk_addres', 'kvkk_phone', 'kvkk_tax_office', 'kvkk_tax_number', 'kvkk_email', 'kvkk_web_site', 'kvkk_contact_email', 'kvkk_contact_address'])->toArray(); + } + + $columns = ['id', 'property_id', 'content_category_id', 'title', 'slug', 'image', 'language_code', 'content', 'status', 'created_at']; + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'slug', 'condition' => '=', 'value' => $params['slug']] + ], + 'with' => ['ContentCategory'], + 'firstRow' => true + ]; + + $propertyWebContent = $this->propertyWebContentRepository->findByCriteria($propertyWebContentCriteria, $columns); + + $responseData['property_content'] = $propertyWebContent; + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function policy($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $responseData = []; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates.awardsCertificateCategory'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + + $rooms = collect($property['property_rooms']) + ->map(function ($value) use ($property) { + $room = $value; + $room['slug'] = Str::slug($room['name'], $separator = '-', $language = 'en'); + return $room; + })->values()->all(); + + $coverPhotos = $this->coverPhotos($params); + + $myWebServiceMode = fillOnUndefined($params, 'mode', 'live'); // preview or live + $myWebServiceModeStatus = $myWebServiceMode === "live" ? 1 : 2; + + $webColormappingRequestData = [ + 'property_id' => $property['id'], + 'property_web_id' => $property['property_web']['id'] + ]; + $webColormappingDatas = $this->checkWebColorMapping($webColormappingRequestData, $myWebServiceModeStatus); + + if (empty($webColormappingDatas['data'])) { + $property['property_brand']['color_codes'] = isset($property['property_brand']['color_codes']) ? json_decode($property['property_brand']['color_codes'], true) : json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } else { + $property['property_brand']['color_codes'] = $webColormappingDatas['data']; + } + + $property['property_brand']['title'] = isset($property['property_brand']['title']) ? $property['property_brand']['title'] : '{"en":null,"de":null,"es":null,"tr":null}'; + $property['property_brand']['logo_name'] = isset($property['property_brand']['logo_name']) ? $property['property_brand']['logo_name'] : null; + + + $propertyWebAboutUsParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'mode' => $params['mode'] === "preview" ? 2 : 1, // live : 1 preview : 2 + ]; + $propertyWebAboutUs = $this->propertyWebAboutUsService->getPropertyWebAboutUs($propertyWebAboutUsParams); + + if ($propertyWebAboutUs['status'] != 'success') { + throw new ApiErrorException($propertyWebAboutUs['message']); + } + + $aboutUs = isset($propertyWebAboutUs['data']) && !empty($propertyWebAboutUs['data']) ? $propertyWebAboutUs['data'] : []; + + $aboutUsFiltred = collect($aboutUs)->first(function ($value, $key) use ($params) { + if ($value['language_code'] == $params['currentLanguage']) { + return $value['value']; + } + }); + + $propertyAwardsCertificates = collect($property['property_awards_certificates']) + ->where('awards_certificate_category.type', '=', 'PLC') + ->where('status', '=', 1) + ->map(function ($value) { + + $return = $value; + unset($return['awards_certificate_category']); + $image = null; + + if ($value['file_path']) { + $urlPath = '/property-photos/' . $value['property_id'] . "/awards-certificates/"; + $image = Config::get('app.imageUrl') . $urlPath . $value['file_path']; + } + + + $catLogo = null; + if ($value['awards_certificate_category']['id']) { + $urlPath = '/assets/img/awards/'; + $catLogo = Config::get('app.client_server') . $urlPath . $value['awards_certificate_category']['id'] . '.png'; + } + + $return['file_path'] = $image ? $image : null; + + $category = [ + 'category_name' => $value['awards_certificate_category']['name'], + 'category_language_key' => $value['awards_certificate_category']['language_key'], + 'category_country_code' => $value['awards_certificate_category']['country_code'], + 'category_logo' => $catLogo, + 'category_type' => $value['awards_certificate_category']['type'], + 'category_status' => $value['awards_certificate_category']['status'], + ]; + return array_merge($return, $category); + })->values()->all(); + + array_multisort( + array_column($propertyAwardsCertificates, 'date'), SORT_DESC, + array_column($propertyAwardsCertificates, 'name'), SORT_ASC, + $propertyAwardsCertificates + ); + + $haveSafeCertificate = collect($property['property_awards_certificates'])->where('category_id', '=', 2)->where('status', '=', 1)->first(); + + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'about_us' => isset($aboutUsFiltred['value']) ? $aboutUsFiltred['value'] : "", + 'rooms' => $rooms, + 'property_brand' => $property['property_brand'], + 'property_contact' => $property['property_contact'], + 'landing_photo' => $coverPhotos, + 'have_safe_tourism_cert' => isset($haveSafeCertificate), + 'policy' => $propertyAwardsCertificates + + ]; + + $getPropertyFact = $this->propertyFactService->getPropertyFact($params); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $getPropertyFact = $this->getPropertyFactForHtml($getPropertyFact['data']); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $responseData['property_facts'] = $getPropertyFact['data']; + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = $propertyAdditionalInfo['data']; + } + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function promotion($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $responseData = []; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyPromotionMapping.propertyPromotion.promotionType', + 'propertyPromotionMapping.propertyRoomRateChannelMapping.propertyRoomRateMapping.propertyRoom', + 'propertyPromotionMapping.propertyRoomRateChannelMapping.propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation' + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + + + $promotionList = []; + $responseData['promotion'] = []; + + if (!empty($property['property_promotion_mapping'])) { + + //Web Channel + $propertyPromotionMapping = collect($property['property_promotion_mapping'])->where('property_room_rate_channel_mapping.channel_id', 1)->toArray(); + + foreach ($propertyPromotionMapping as $promotion) { + + + $promotionList[$promotion['property_promotion_id']]['id'] = $promotion['property_promotion']['id']; + $promotionList[$promotion['property_promotion_id']]['title'] = __($promotion['property_promotion']['promotion_type']['language_key'], [], $params['language']); + $promotionList[$promotion['property_promotion_id']]['type_code'] = $promotion['property_promotion']['promotion_type']['type_code']; + $promotionList[$promotion['property_promotion_id']]['order_number'] = $promotion['property_promotion']['promotion_type']['order_number']; + $promotionList[$promotion['property_promotion_id']]['detail'] = [ + 'start_date' => $promotion['property_promotion']['start_date'], + 'end_date' => $promotion['property_promotion']['end_date'], + 'reservation_start_date' => $promotion['property_promotion']['reservation_start_date'], + 'reservation_end_date' => $promotion['property_promotion']['reservation_end_date'], + 'is_time' => $promotion['property_promotion']['is_time'], + 'start_time' => $promotion['property_promotion']['start_time'], + 'end_time' => $promotion['property_promotion']['end_time'], + 'day_before' => $promotion['property_promotion']['day_before'], + 'amount' => $promotion['property_promotion']['amount'], + 'min_stay' => $promotion['property_promotion']['min_stay'], + 'is_mobile' => $promotion['property_promotion']['is_mobile'], + 'days' => $promotion['property_promotion']['daysArray'], + ]; + + $propertyRoomRateMapping = $promotion['property_room_rate_channel_mapping']['property_room_rate_mapping']; + + $promotionList[$promotion['property_promotion_id']]['room'][$propertyRoomRateMapping['property_room']['id']]['id'] = $propertyRoomRateMapping['property_room']['id']; + $promotionList[$promotion['property_promotion_id']]['room'][$propertyRoomRateMapping['property_room']['id']]['title'] = $propertyRoomRateMapping['property_room']['name']; + + $promotionList[$promotion['property_promotion_id']]['room'][$propertyRoomRateMapping['property_room']['id']]['rate'][$propertyRoomRateMapping['property_room_rate']['id']]['id'] = $propertyRoomRateMapping['property_room_rate']['id']; + $promotionList[$promotion['property_promotion_id']]['room'][$propertyRoomRateMapping['property_room']['id']]['rate'][$propertyRoomRateMapping['property_room_rate']['id']]['title'] = $propertyRoomRateMapping['property_room_rate']['name']; + $promotionList[$promotion['property_promotion_id']]['room'][$propertyRoomRateMapping['property_room']['id']]['rate'][$propertyRoomRateMapping['property_room_rate']['id']]['accommodation'] = __($propertyRoomRateMapping['property_room_rate']['property_room_rate_accommodation']['language_key'], [], $params['language']); + + //dd($promotionList, $promotion); + + } + + + foreach ($promotionList as $promotionKey => $promotion) { + foreach ($promotion['room'] as $promotionRoomKey => $promotionRoom) { + $promotionList[$promotionKey]['room'][$promotionRoomKey]['rate'] = array_values($promotionList[$promotionKey]['room'][$promotionRoomKey]['rate']); + } + $promotionList[$promotionKey]['room'] = array_values($promotionList[$promotionKey]['room']); + } + + $promotionList = array_values($promotionList); + + $responseData['promotion'] = $promotionList; + + } + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function affiliateRequestMail($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact', 'propertyExecutive.executiveType', 'propertyWeb'], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + if (!$property) { + throw new ApiErrorException('property not found'); + } + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if ($propertyAdditionalInfo['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + $myWebContactEmail = $propertyAdditionalInfo['data']['myweb_contact_email']; + + if (!$myWebContactEmail) { + throw new ApiErrorException('api-unknown-error'); + } + + $propertyExecutives = collect($property['property_executive'])->where('status', 1)->where('executive_type_id', 8)->pluck('email')->toArray(); + + + $bcc = []; + $mailData = [ + 'to' => [ + 'name' => $property['name'], + 'email' => $myWebContactEmail, + ], + 'bcc' => $propertyExecutives + + ]; + + $mailViewParams = $params; + $mailViewParams['logo'] = 'https://www.extranetwork.com/assets/img/logo/logo.png'; + + $mailParams = [ + 'mailData' => $mailData, + 'mailViewParams' => $mailViewParams + ]; + + + $this->mailer->onQueue( + 'affiliateRequestMail', + new AffiliateRequestMail($mailParams) + ); + + + $response = [ + 'status' => true, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/NewBookingMailService.php b/app/Core/Service/NewBookingMailService.php new file mode 100644 index 0000000..b1e24bc --- /dev/null +++ b/app/Core/Service/NewBookingMailService.php @@ -0,0 +1,364 @@ +mailer = $mailer; + $this->bookingRepository = $bookingRepository; + $this->userPropertyMappingRepository = $userPropertyMappingRepository; + $this->propertyBrandService = $propertyBrandService; + + } + + public function process($params = []) + { + try { + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => [ + 'bookingPayment', 'bookingRoom.roomRateMapping.propertyRoom', 'bookingRoom.roomRateMapping.propertyRoomRate', + 'bookingContact', 'bookingProperty.propertyBrand', 'bookingProperty.propertyExecutive', + 'bookingPropertyWeb', 'propertyBookingEngine', 'propertyBookingChannel', 'bookingAddon.propertyChannelAddon.propertyAddon.fact', + 'propertyChannelMapping.channelBookingPaymentType' + ], + 'firstRow' => true + ]; + + $bookingData = $this->bookingRepository->findByCriteria($bookingDetailParam); + if (!$bookingData) { + throw new Exception('api-unknown_error'); + } + + $reservationExecutives = []; + if (isset($bookingData['booking_property']['property_executive'])) { + $reservationExecutives = collect($bookingData['booking_property']['property_executive']) + ->where('executive_type_id', '=', '7') // sadece rezervasyon yetkisi olanlar ... + ->values()->all(); + } + + $userPropertyMappingParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingData['property_id']] + ], + 'with' => ['user'] + ]; + $userData = $this->userPropertyMappingRepository->findByCriteria($userPropertyMappingParam); + + $bcc = []; + foreach ($userData as $user) { + if (!empty($user['user'])) { + $bcc[] = $user['user']['email']; + } + } + + + foreach ($reservationExecutives as $reservationExecutive) { + $bcc[] = $reservationExecutive['email']; + } + + if (in_array($bookingData['property_booking_channel']['channel_category_id'], [3])) { + $bcc[] = "sales@extranetwork.com"; + } else { + $bcc[] = "channel@extranetwork.com"; + } + + + //ENW kanalı harici tüm işlemlerde giden kısmı otel kullanıcısı olacak. + if (in_array($bookingData['property_booking_channel']['channel_category_id'], [4, 7])) { + $firstUserData = reset($userData); + $mailData['to'] = [ + 'name' => $bookingData['booking_property']['name'], + 'email' => $firstUserData['user']['email'] + ]; + } else { + $mailData['to'] = [ + 'name' => $bookingData['booking_contact']['nameSurname'], + 'email' => $bookingData['booking_contact']['email'] + ]; + } + + $mailData['bcc'] = $bcc; + + $hostAddress = Config::get('app.bookingEngineUrl') . '/' . $bookingData['property_booking_engine']['token'] . '/' . $bookingData['booking_contact']['language_code'] . '/booking-detail/' . $bookingData['booking_code']; + + $brandRequestData = ['property_id' => $bookingData['property_id']]; + $getPropertyBrand = $this->propertyBrandService->getPropertyBrand($brandRequestData); + if ($getPropertyBrand['status'] != "success") { + throw new Exception($getPropertyBrand['message']); + } + + $propertyBrand = $getPropertyBrand['data']; + $propertyBrandLogo = isset($propertyBrand['name']) + ? Config::get('app.fileSystemDriver') . '/property-photos/' . $propertyBrand['property_id'] . "/logo/" . $propertyBrand['name'] . '_250x250.' . $propertyBrand['logo_file_ext'] + : null; + + $roomOrder = 1; + $bookingChannelRoom = []; + foreach ($bookingData['booking_room'] as $bookingRoom) { + + if (!empty($bookingRoom['room_rate_mapping']['property_room'])) { + $bookingRoom['room_name'] = $bookingRoom['room_rate_mapping']['property_room']['name']; + } + if (!empty($bookingRoom['room_rate_mapping']['property_room_rate'])) { + $bookingRoom['room_rate_name'] = $bookingRoom['room_rate_mapping']['property_room_rate']['name']; + } + + $extraParam = null; + if (!empty($bookingRoom['extra_param'])) { + $extraParamDecode = json_decode($bookingRoom['extra_param'], 1); + + foreach ($extraParamDecode as $extraParamKey => $extraParamValue) { + + $extraParamTitle = explode('_', $extraParamKey); + foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) { + $extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue); + } + $extraParamTitle = implode(' ', $extraParamTitle); + + $extraParam[$extraParamKey] = [ + 'title' => $extraParamTitle, + 'value' => $extraParamValue, + ]; + } + + } + + $additionalFee = null; + if (!empty($bookingRoom['rate_detail'])) { + $rateDetail = json_decode($bookingRoom['rate_detail'], 1); + if (isset($rateDetail['taxes']) && $bookingData['channel_manager_id'] == 2) { + $additionalFee = $rateDetail['taxes']; + } + } + + //$cancellationPolicy + $cancellationPolicy = null; + $cancellationPolicyRoom = json_decode($bookingRoom['cancellation_policy'], 1); + if ($cancellationPolicyRoom) { + $cancellationPolicyTextFormatted = cancellationPolicyTextFormatted( + fillOnUndefined($cancellationPolicyRoom, 'isNonRefundable'), + fillOnUndefined($cancellationPolicyRoom, 'isFreeCancellation'), + fillOnUndefined($cancellationPolicyRoom, 'beforeArrivalDay'), + fillOnUndefined($cancellationPolicyRoom, 'type'), + fillOnUndefined($cancellationPolicyRoom, 'value'), + $bookingData['currency_code'], + $bookingData['booking_contact']['language_code'] + ); + + if ($cancellationPolicyTextFormatted) { + $cancellationPolicy = $cancellationPolicyTextFormatted; + } + } + //$cancellationPolicy + + $bookingChannelRoom[] = [ + 'roomOrder' => $roomOrder, + 'roomName' => $bookingRoom['room_name'], + 'roomRateName' => $bookingRoom['room_rate_name'], + 'occupancyCode' => $bookingRoom['occupancy_code'], + 'occupancyText' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'amount' => $bookingRoom['amount'], + 'discount_amount' => $bookingRoom['discount_amount'], + 'total' => $bookingRoom['total'], + 'currencyCode' => $bookingRoom['currency_code'], + 'dailyAmount' => !empty($bookingRoom['daily_amount']) ? json_decode($bookingRoom['daily_amount'], 1) : null, + 'extraParam' => $extraParam, + 'occupancyFormatted' => occupancyCodeFormatted($bookingRoom['occupancy_code']), + 'additionalFee' => $additionalFee, + 'cancellationPolicy' => $cancellationPolicy + ]; + + //dd($bookingChannelRoom); + + //$bookingChannelRoom[] = $roomOrder . '. ' . $bookingRoom['room_name'] . ' - ' . $bookingRoom['room_rate_name'] . ' - ' . occupancyCodeFormatted($bookingRoom['occupancy_code']); + $roomOrder++; + } + + //$bookingChannelRoom = implode('
', $bookingChannelRoom); + + $bookingLanguageCode = isset($bookingData['booking_contact']['language_code']) ? $bookingData['booking_contact']['language_code'] : 'en'; + $bookingChannelPaymentType = __('property_booking_payment_type-pay_at_hotel', [], $bookingLanguageCode); + $bookingChannelPaymentSource = null; + if ($bookingData['booking_payment']['payment_type_code'] == 'CRD') { + $bookingChannelPaymentType = __('property_booking_payment_type-credit_card', [], $bookingLanguageCode); + if ($bookingData['booking_payment']['payment_source_code'] == 'OTA') { + $bookingChannelPaymentSource = __('enw-ota-credit_card', [], $bookingLanguageCode); + } + if ($bookingData['booking_payment']['payment_source_code'] == 'GST') { + $bookingChannelPaymentSource = __('enw-guest-credit_card', [], $bookingLanguageCode); + } + } + + $creditCardInformation = null; + if (!is_null($bookingData['booking_payment']['extra_param'])) { + $paymentData = json_decode($bookingData['booking_payment']['extra_param'], 1); + + if (isset($paymentData['attributes']['guarantee'])) { + $creditCardInformation['cardNumber'] = isset($paymentData['attributes']['guarantee']['card_number']) ? $paymentData['attributes']['guarantee']['card_number'] : null; + $creditCardInformation['cardHolderName'] = isset($paymentData['attributes']['guarantee']['cardholder_name']) ? $paymentData['attributes']['guarantee']['cardholder_name'] : null; + $creditCardInformation['expirationDate'] = isset($paymentData['attributes']['guarantee']['expiration_date']) ? $paymentData['attributes']['guarantee']['expiration_date'] : null; + $creditCardInformation['cvv'] = isset($paymentData['attributes']['guarantee']['cvv']) ? $paymentData['attributes']['guarantee']['cvv'] : null; + } + } + + //Genius Member + $bookingContactExtraParam = null; + if (!empty($bookingData['booking_contact']['extra_param'])) { + $bookingContactExtraParam = json_decode($bookingData['booking_contact']['extra_param'], 1); + } + $isBookingGenius = false; + if (isset($bookingContactExtraParam['is_genius']) && $bookingContactExtraParam['is_genius']) { + $isBookingGenius = true; + } + + + //BOOKING ADDON + $bookingAddonList = []; + $bookingAddons = $bookingData['booking_addon']; + foreach ($bookingAddons as $bookingAddon) { + + $bookingAddonAttributeList = []; + $isHasAttribute = false; + $attributeArray = []; + + if (!empty($bookingAddon['property_channel_addon']['property_addon']['attributeArray'])) { + $isHasAttribute = true; + $attributeArray = $bookingAddon['property_channel_addon']['property_addon']['attributeArray']; + $bookingAddonAttributes = json_decode($bookingAddon['attribute'], 1); + if (!is_null($bookingAddonAttributes)) { + foreach ($bookingAddonAttributes as $key => $bookingAddonAttribute) { + foreach ($bookingAddonAttribute as $bookingAddonAttributeKey => $bookingAddonAttributeValue) { + + if (isset($bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey])) { + $bookingAddonAttributeList[] = [ + 'key' => $bookingAddonAttributeKey, + 'name' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['name'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['language_key'], + 'value' => $bookingAddonAttributeValue, + ]; + } + + } + } + } + } + + $bookingAddonList[] = [ + 'id' => $bookingAddon['id'], + 'booking_id' => $bookingAddon['booking_id'], + 'property_channel_addon_id' => $bookingAddon['property_channel_addon_id'], + 'count' => $bookingAddon['count'], + 'amount' => $bookingAddon['amount'], + 'total' => $bookingAddon['total'], + 'currency_code' => $bookingAddon['currency_code'], + 'name' => $bookingAddon['property_channel_addon']['property_addon']['fact']['name'], + 'title' => $bookingAddon['property_channel_addon']['title'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['fact']['language_key'], + 'icon' => $bookingAddon['property_channel_addon']['property_addon']['fact']['icon'], + 'isHasAttribute' => $isHasAttribute, + 'attributeArray' => $attributeArray, + 'attribute' => $bookingAddonAttributeList + ]; + + } + + $payAtHotelCreditCardCheck = false; + if(isset($bookingData['property_channel_mapping']) && !empty($bookingData['property_channel_mapping'])) { + $payAtHotelCreditCardCheck = collect($bookingData['property_channel_mapping']['channel_booking_payment_type'])->where('payment_type_id',2)->where('is_get_payment_data',1)->isNotEmpty(); + } + + $mailViewParams = [ + 'bookingId' => $bookingData['id'], + 'bookingCode' => $bookingData['booking_code'], + 'propertyId' => $bookingData['booking_property']['id'], + 'booking_code' => $bookingData['booking_code'], + 'search_key' => $bookingData['search_key'], + 'channel_token' => $bookingData['channel_token'], + 'booking_engine_token' => $bookingData['booking_engine_token'], + 'checkin_date' => Carbon::parse($bookingData['checkin_date'])->format('d.m.Y'), + 'checkout_date' => Carbon::parse($bookingData['checkout_date'])->format('d.m.Y'), + 'payment_type_code' => $bookingData['booking_payment']['payment_type_code'], + 'payment_source_code' => $bookingData['booking_payment']['payment_source_code'], + 'room_amount' => $bookingData['room_amount'], + 'addon_amount' => $bookingData['addon_amount'], + 'discount_amount' => $bookingData['discount_amount'], + 'total' => $bookingData['total'], + 'currency_code' => $bookingData['currency_code'], + 'name_surname' => $bookingData['booking_contact']['nameSurname'], + 'countryCode' => upperCase($bookingData['booking_contact']['country_code']), + 'email' => $bookingData['booking_contact']['email'], + 'property_name' => $bookingData['booking_property']['name'], + 'url' => $hostAddress, + 'logo' => $bookingData['booking_property']['property_brand']['logoUrl'], + 'language_code' => $bookingData['booking_contact']['language_code'], + 'bookingChannelId' => $bookingData['channel_id'], + 'bookingChannelName' => fillOnUndefined($bookingData['property_booking_channel'], 'name'), + 'bookingChannelCategoryId' => $bookingData['property_booking_channel']['channel_category_id'], + 'bookingChannelCode' => $bookingData['channel_booking_code'], + 'bookingChannelContactNameSurname' => $bookingData['booking_contact']['nameSurname'], + 'bookingChannelContactEmail' => $bookingData['booking_contact']['email'], + 'bookingChannelContactPhone' => $bookingData['booking_contact']['phone_number'], + 'bookingChannelNote' => $bookingData['booking_contact']['note'], + 'bookingChannelRoom' => $bookingChannelRoom, + 'bookingAddon' => $bookingAddonList, + 'bookingChannelPaymentType' => $bookingChannelPaymentType, + 'bookingChannelPaymentSource' => $bookingChannelPaymentSource, + 'creditCardInformation' => $creditCardInformation, + 'payAtHotelCreditCardCheck' => $payAtHotelCreditCardCheck, + 'isBookingGenius' => $isBookingGenius, + 'web' => isset($bookingData['booking_property_web']['webProtocolUrl']) ? $bookingData['booking_property_web']['webProtocolUrl'] : null + ]; + + $mailViewParams['showCreditCardUrl'] = null; + if (!empty($mailViewParams['creditCardInformation'])) { + $mailViewParams['showCreditCardUrl'] = Config::get('app.client_server') . '/app/network/reservation/' . $mailViewParams['bookingId'] . '?propertyid=' . $mailViewParams['propertyId']; + } + + $mailParams = [ + 'mailData' => $mailData, + 'mailViewParams' => $mailViewParams + + ]; + + $this->mailer->onQueue('newBookingMail', new NewBookingMail($mailParams)); + + + } catch + (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + return output(['status' => -1, 'message' => $e->getMessage()]); + } + } + +} diff --git a/app/Core/Service/NotificationService.php b/app/Core/Service/NotificationService.php new file mode 100644 index 0000000..82a332a --- /dev/null +++ b/app/Core/Service/NotificationService.php @@ -0,0 +1,162 @@ +bookingRepository = $bookingRepository; + $this->propertyRepository = $propertyRepository; + $this->language = $languageService::getDefaultLang(); + $this->validLanguages = $languageService::getValidLanguages(); + } + + public function sendLogNotification($params = []) + { + + $response = ['status' => false, 'message' => '']; + try { + + + $propertyDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'firstRow' => true + ]; + + $propertyData = $this->propertyRepository->findByCriteria($propertyDetailParam); + + if (!$propertyData) { + throw new Exception('api-unknown_error'); + } + + $param = [ + 'property_id' => $params['property_id'], + 'subject' => 'Otel Bilgileri Güncelleme', + 'message' => $propertyData['name'] . ', Otel Bilgileri Güncellendi.' + ]; + + Notification::route('OneSignal', null)->notify(new PushNotificationPropertyUser($param)); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function sendNewBookingNotification($params = []) + { + + $response = ['status' => false, 'message' => '']; + try { + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => ['bookingPayment', 'bookingProperty'], + 'firstRow' => true + ]; + + $bookingData = $this->bookingRepository->findByCriteria($bookingDetailParam); + + if (!$bookingData) { + throw new Exception('api-unknown_error'); + } + + if (in_array(strtolower($bookingData['booking_property']['country']), $this->validLanguages)) { + $this->language = strtolower($bookingData['booking_property']['country']); + } + + $param = [ + 'property_id' => $bookingData['booking_property']['id'], + 'subject' => '🛎️ '.__('notification-new_booking', [], $this->language), + 'message' => __('notification-new_booking_desc', ['hotel_name' => $bookingData['booking_property']['name'], 'amount' => $bookingData['total'], 'currency' => $bookingData['currency_code']], $this->language), + ]; + + Notification::route('OneSignal', null)->notify(new PushNotificationPropertyUser($param)); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function sendTicketNotification($params = []) + { + + $response = ['status' => false, 'message' => '']; + try { + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']] + ], + 'with' => ['bookingPayment', 'bookingProperty'], + 'firstRow' => true + ]; + + $bookingData = $this->bookingRepository->findByCriteria($bookingDetailParam); + + if (!$bookingData) { + throw new Exception('api-unknown_error'); + } + + if (in_array(strtolower($bookingData['booking_property']['country']), $this->validLanguages)) { + $this->language = strtolower($bookingData['booking_property']['country']); + } + + $param = [ + 'property_id' => $bookingData['booking_property']['id'], + 'subject' => '📥 '.__('notification-new_ticket', [], $this->language), + 'message' => __('notification-new_ticket_desc', [ + 'hotel' => $bookingData['booking_property']['name'], + 'bookingCode' => $bookingData['booking_code'] + ], $this->language), + ]; + + Notification::route('OneSignal', null)->notify(new PushNotificationPropertyUser($param)); + + $response['status'] = true; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + +} diff --git a/app/Core/Service/OfferAccommodationMappingService.php b/app/Core/Service/OfferAccommodationMappingService.php new file mode 100644 index 0000000..0e07725 --- /dev/null +++ b/app/Core/Service/OfferAccommodationMappingService.php @@ -0,0 +1,282 @@ +offerAccommodationMappingRepository = $offerAccommodationMappingRepository; + $this->offerAccommodationMappingCreateValidator = $offerAccommodationMappingCreateValidator; + $this->offerAccommodationMappingAddValidator = $offerAccommodationMappingAddValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerAccommodationMappingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_accommodation_id" => fillOnUndefined($param, "property_accommodation_id"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerAccommodationMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerAccommodationMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerAccommodationMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerAccommodationMappingRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + + public function insertAccommodationMapping($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerAccommodationMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $insertDataArray = [] ; + foreach ($param['accommodation_mapping'] as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_accommodation_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerContactInsertResult = $this->offerAccommodationMappingRepository->createAll($insertDataArray); + if ($offerContactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $offerContactInsertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateAccommodationMapping($param = [], $offerAccommodationMapping) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerAccommodationMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertThisIds = array_diff($param['accommodation_mapping'], $offerAccommodationMapping); + $deleteThisIds = array_diff($offerAccommodationMapping, $param['accommodation_mapping']); + $responseDeleteIds = $deleteThisIds; + + + + $insertDataArray = [] ; + foreach ($insertThisIds as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_accommodation_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerContactInsertResult = $this->offerAccommodationMappingRepository->createAll($insertDataArray); + if ($offerContactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_accommodation_id", "value" => $deleteThisIds] + ] + ]; + $eraseMappingData = $this->offerAccommodationMappingRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $deleteThisIds = collect($eraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerAccommodationMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $response = [ + 'status' => true, + 'data' => $responseDeleteIds, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/OfferCancellationPolicyService.php b/app/Core/Service/OfferCancellationPolicyService.php new file mode 100644 index 0000000..96b5f1e --- /dev/null +++ b/app/Core/Service/OfferCancellationPolicyService.php @@ -0,0 +1,175 @@ +offerCancellationPolicyRepository = $offerCancellationPolicyRepository; + $this->offerCancellationPolicyCreateValidator = $offerCancellationPolicyCreateValidator; + } + + public function insertCancellationPolicy($param = [], $oldOfferCancellationPolicy) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->offerCancellationPolicyCreateValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $cancellationPolicies = $param['cancellation_policy']; + $cancellationPolicyData = []; + $userData = [] ; + + if($param['has_cancellation_policy'] == true){ + foreach ($cancellationPolicies as $cancellationPolicy){ + + $cancellationPolicyData[] = [ + + "offer_id" => $param['offer_id'], + "days_before" => fillOnUndefined($cancellationPolicy, "days_before"), + "type" => fillOnUndefined($cancellationPolicy, "type"), + "value" => fillOnUndefined($cancellationPolicy, "value"), + "status" => fillOnUndefined($cancellationPolicy, "status",1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time() + ]; + } + + $userCreateResult = $this->offerCancellationPolicyRepository->createAll($cancellationPolicyData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + + } + + + if($oldOfferCancellationPolicy){ + $deleteThisArray = $this->offerCancellationPolicyRepository->destroy($oldOfferCancellationPolicy); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerCancellationPolicyRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerCancellationPolicyRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerCancellationPolicyRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + +} diff --git a/app/Core/Service/OfferContactMappingService.php b/app/Core/Service/OfferContactMappingService.php new file mode 100644 index 0000000..21de590 --- /dev/null +++ b/app/Core/Service/OfferContactMappingService.php @@ -0,0 +1,279 @@ +offerContactMappingRepository = $offerContactMappingRepository; + $this->offerContactMappingCreateValidator = $offerContactMappingCreateValidator; + $this->offerContactMappingAddValidator = $offerContactMappingAddValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerContactMappingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_executive_id" => fillOnUndefined($param, "property_executive_id"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerContactMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerContactMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerContactMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerContactMappingRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insertContactMapping($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerContactMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $insertDataArray = [] ; + foreach ($param['contact_mapping'] as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_executive_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerContactInsertResult = $this->offerContactMappingRepository->createAll($insertDataArray); + if ($offerContactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $offerContactInsertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateContactMapping($param = [], $offerContactMapping) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerContactMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertThisIds = array_diff($param['contact_mapping'], $offerContactMapping); + $deleteThisIds = array_diff($offerContactMapping, $param['contact_mapping']); + + $insertDataArray = [] ; + foreach ($insertThisIds as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_executive_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerContactInsertResult = $this->offerContactMappingRepository->createAll($insertDataArray); + if ($offerContactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_executive_id", "value" => $deleteThisIds] + ] + ]; + $eraseMappingData = $this->offerContactMappingRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $deleteThisIds = collect($eraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerContactMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $userData = $offerContactInsertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/OfferFactMappingService.php b/app/Core/Service/OfferFactMappingService.php new file mode 100644 index 0000000..a25bf88 --- /dev/null +++ b/app/Core/Service/OfferFactMappingService.php @@ -0,0 +1,338 @@ +offerFactMappingRepository = $offerFactMappingRepository; + $this->offerFactMappingCreateValidator = $offerFactMappingCreateValidator; + $this->offerFactMappingAddValidator = $offerFactMappingAddValidator; + $this->propertyFactService = $propertyFactService; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerFactMappingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "category_id" => fillOnUndefined($param, "category_id"), + "property_fact_parent_id" => fillOnUndefined($param, "property_fact_parent_id"), + "property_fact_id" => fillOnUndefined($param, "property_fact_id"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerFactMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerFactMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerFactMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerFactMappingRepository->updateOrCreate($criteria, $saveData); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insertNewOfferFacts($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerFactMappingAddValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyFactsCheckParam = [ + 'fact_ids' => $param['fact_mapping'], + 'property_id' => $param['property_id'] + ]; + $propertyFactsCheck = $this->propertyFactService->checkPropertyFactMapping($propertyFactsCheckParam); + if($propertyFactsCheck['status'] != 'success'){ + throw new ApiErrorException($propertyFactsCheck['message']); + } + + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $factData = $this->propertyFactService->select($requestData); + + if ($factData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $facts = collect($factData['data'])->keyBy('id'); + $insertDataArray = [] ; + + if(!empty($param['hotel_features_mapping'])){ + $param['fact_mapping'] = array_merge($param['fact_mapping'], $param['hotel_features_mapping']); + } + + foreach ($param['fact_mapping'] as $fact) { + $theFact = $facts[$fact]; + $parentFact = $facts[$theFact['parent_id']]; + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "category_id" => $parentFact['parent_id'], + "property_fact_parent_id" => $theFact['parent_id'], + "property_fact_id" =>$fact, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerFactInsertResult = $this->offerFactMappingRepository->createAll($insertDataArray); + if ($offerFactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $offerFactInsertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateOfferFacts($param = [], $offerAllFactIds = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerFactMappingAddValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + if(!empty($param['hotel_features_mapping'])){ + $param['fact_mapping'] = array_merge($param['fact_mapping'], $param['hotel_features_mapping']); + } + + $insertThisIds = array_diff($param['fact_mapping'], $offerAllFactIds); + $deleteThisIds = array_diff($offerAllFactIds, $param['fact_mapping']); + + + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $factData = $this->propertyFactService->select($requestData); + + if ($factData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $facts = collect($factData['data'])->keyBy('id'); + $insertDataArray = [] ; + + + foreach ($insertThisIds as $fact) { + $theFact = $facts[$fact]; + $parentFact = $facts[$theFact['parent_id']]; + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "category_id" => $parentFact['parent_id'], + "property_fact_parent_id" => $theFact['parent_id'], + "property_fact_id" =>$fact, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $offerFactInsertResult = $this->offerFactMappingRepository->createAll($insertDataArray); + if ($offerFactInsertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_fact_id", "value" => $deleteThisIds] + ] + ]; + $factEraseMappingData = $this->offerFactMappingRepository->findByCriteria($requestData, ['id']); + $factEraseMappingData = $factEraseMappingData ? $factEraseMappingData : [] ; + $deleteThisIds = collect($factEraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerFactMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $userData = $offerFactInsertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/OfferImportantNotesService.php b/app/Core/Service/OfferImportantNotesService.php new file mode 100644 index 0000000..dbc1207 --- /dev/null +++ b/app/Core/Service/OfferImportantNotesService.php @@ -0,0 +1,219 @@ +offerImportantNotesRepository = $offerImportantNotesRepository; + $this->offerImportantNotesCreateValidator = $offerImportantNotesCreateValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerImportantNotesCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "note" => fillOnUndefined($param, "note"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerImportantNotesRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerImportantNotesRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerImportantNotesRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerImportantNotesRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + + public function insertImportantNotes($param = [], $oldOfferImportantNotes) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerImportantNotesCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertDataArray = [] ; + foreach ($param['important_notes'] as $item) { + if(!$item){ + continue; + } + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "note" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $insertResult = $this->offerImportantNotesRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + if($oldOfferImportantNotes){ + $deleteThisArray = $this->offerImportantNotesRepository->destroy($oldOfferImportantNotes); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + + +} diff --git a/app/Core/Service/OfferPaymentTypeService.php b/app/Core/Service/OfferPaymentTypeService.php new file mode 100644 index 0000000..e445d92 --- /dev/null +++ b/app/Core/Service/OfferPaymentTypeService.php @@ -0,0 +1,155 @@ +offerPaymentTypeRepository = $offerPaymentTypeRepository; + $this->offerPaymentTypeCreateValidator = $offerPaymentTypeCreateValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerPaymentTypeCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerPaymentTypeRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPaymentTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerPaymentTypeRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPaymentTypeRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + +} diff --git a/app/Core/Service/OfferPhotoMappingService.php b/app/Core/Service/OfferPhotoMappingService.php new file mode 100644 index 0000000..edb0180 --- /dev/null +++ b/app/Core/Service/OfferPhotoMappingService.php @@ -0,0 +1,449 @@ +offerPhotoMappingRepository = $offerPhotoMappingRepository; + $this->offerPhotoMappingCreateValidator = $offerPhotoMappingCreateValidator; + $this->offerPhotoMappingAddValidator = $offerPhotoMappingAddValidator; + $this->offerCoverPhotoAddValidator = $offerCoverPhotoAddValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerPhotoMappingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_photo_id" => fillOnUndefined($param, "property_photo_id"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerPhotoMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPhotoMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerPhotoMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPhotoMappingRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insertPhotoMapping($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerPhotoMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $insertDataArray = [] ; + foreach ($param['photo_mapping'] as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_photo_id" => $item, + "is_cover" => 0, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + $insertResult = $this->offerPhotoMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function insertCoverPhotoMapping($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerCoverPhotoAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $insertDataArray = [] ; + foreach ($param['cover_photos'] as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_photo_id" => $item, + "is_cover" => 1, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + $insertResult = $this->offerPhotoMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updatePhotoMapping($param = [], $offerPhotoMapping) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerPhotoMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertThisIds = array_diff($param['photo_mapping'], $offerPhotoMapping); + $deleteThisIds = array_diff($offerPhotoMapping, $param['photo_mapping']); + + $insertDataArray = [] ; + foreach ($insertThisIds as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_photo_id" => $item, + "is_cover" => 0, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + $insertResult = $this->offerPhotoMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_photo_id", "value" => $deleteThisIds] + ] + ]; + $eraseMappingData = $this->offerPhotoMappingRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $deleteThisIds = collect($eraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerPhotoMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateCoverPhotoMapping($param = [], $offerCoverPhotoMapping) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->offerCoverPhotoAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $insertThisIds = array_diff($param['cover_photos'], $offerCoverPhotoMapping); + $deleteThisIds = array_diff($offerCoverPhotoMapping, $param['cover_photos']); + + + $insertDataArray = [] ; + foreach ($insertThisIds as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_photo_id" => $item, + "is_cover" => 1, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + $insertResult = $this->offerPhotoMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_photo_id", "value" => $deleteThisIds] + ] + ]; + $eraseMappingData = $this->offerPhotoMappingRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $deleteThisIds = collect($eraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerPhotoMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function destroy($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'property_photo_id', 'condition' => '=', 'value' => $params['photo_id']], + ] + ]; + + $deleteData = $this->offerPhotoMappingRepository->findByCriteria($deleteCriteria, ['id']); + $deleteData = $deleteData ? $deleteData : [] ; + if($deleteData){ + $deleteIds = array_column($deleteData, 'id') ; + $destroyResult = $this->offerPhotoMappingRepository->destroy($deleteIds); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + +} diff --git a/app/Core/Service/OfferPriceService.php b/app/Core/Service/OfferPriceService.php new file mode 100644 index 0000000..749b21c --- /dev/null +++ b/app/Core/Service/OfferPriceService.php @@ -0,0 +1,232 @@ +offerPriceRepository = $offerPriceRepository; + $this->offerPriceCreateValidator = $offerPriceCreateValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerPriceCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + + + "offer_id" => fillOnUndefined($param, "offer_id"), + "date" => fillOnUndefined($param, "date"), + "property_room_id" => fillOnUndefined($param, "property_room_id"), + "property_accommodation_id" => fillOnUndefined($param, "property_accommodation_id"), + "number_of_rooms" => fillOnUndefined($param, "number_of_rooms"), + "currency" => fillOnUndefined($param, "currency"), + "amount" => fillOnUndefined($param, "amount"), + "total_amount" => fillOnUndefined($param, "total_amount"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerPriceRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPriceRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerPriceRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerPriceRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insert($params){ + + return $this->offerPriceRepository->insert($params); + } + + public function destroy($params){ + + return $this->offerPriceRepository->destroy($params); + } + + public function deleteThisOfferPrices($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteThisIds = [] ; + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($params, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_room_id", "value" => fillOnUndefined($params, "property_room_id", [])] + ] + ]; + $eraseMappingData = $this->offerPriceRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $delete = collect($eraseMappingData)->keyBy('id')->keys()->all(); + $deleteThisIds = array_merge($deleteThisIds, $delete) ; + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($params, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_accommodation_id", "value" => fillOnUndefined($params, "property_accommodation_id", [])] + ] + ]; + $eraseMappingData = $this->offerPriceRepository->findByCriteria($requestData, ['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $delete = collect($eraseMappingData)->keyBy('id')->keys()->all(); + $deleteThisIds = array_merge($deleteThisIds, $delete) ; + + if($deleteThisIds){ + $deleteThisArray = $this->offerPriceRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/OfferRoomMappingService.php b/app/Core/Service/OfferRoomMappingService.php new file mode 100644 index 0000000..a938b1c --- /dev/null +++ b/app/Core/Service/OfferRoomMappingService.php @@ -0,0 +1,296 @@ +offerRoomMappingRepository = $offerRoomMappingRepository; + $this->offerRoomMappingCreateValidator = $offerRoomMappingCreateValidator; + $this->roomMappingAddValidator = $roomMappingAddValidator; + $this->propertyRoomService = $propertyRoomService; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerRoomMappingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + + + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_room_id" => fillOnUndefined($param, "property_room_id"), + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerRoomMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerRoomMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerRoomMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerRoomMappingRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insertRoomMapping($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->roomMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyRoomCheckParam = [ + 'room_ids' => $param['room_mapping'], + 'property_id' => $param['property_id'] + ]; + $propertyRoomCheck = $this->propertyRoomService->checkPropertyRoomMapping($propertyRoomCheckParam) ; + if($propertyRoomCheck['status'] != 'success'){ + throw new ApiErrorException($propertyRoomCheck['message']); + } + + $insertDataArray = [] ; + foreach ($param['room_mapping'] as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_room_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $insertResult = $this->offerRoomMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateRoomMapping($param = [], $offerRoomMapping) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->roomMappingAddValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertThisIds = array_diff($param['room_mapping'], $offerRoomMapping); + $deleteThisIds = array_diff($offerRoomMapping, $param['room_mapping']); + $responseDeleteIds = $deleteThisIds; + + $insertDataArray = [] ; + foreach ($insertThisIds as $item) { + $insertDataArray[] = + [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_room_id" => $item, + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $insertResult = $this->offerRoomMappingRepository->createAll($insertDataArray); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $requestData = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + "whereIn" => + [ + ["field" => "property_room_id", "value" => $deleteThisIds] + ] + ]; + $eraseMappingData = $this->offerRoomMappingRepository->findByCriteria($requestData,['id']); + $eraseMappingData = $eraseMappingData ? $eraseMappingData : [] ; + $deleteThisIds = collect($eraseMappingData)->keyBy('id')->keys()->all(); + + if($deleteThisIds){ + $deleteThisArray = $this->offerRoomMappingRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $response = [ + 'status' => true, + 'data' => $responseDeleteIds, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/OfferService.php b/app/Core/Service/OfferService.php new file mode 100644 index 0000000..9b0c284 --- /dev/null +++ b/app/Core/Service/OfferService.php @@ -0,0 +1,1484 @@ +offerRepository = $offerRepository; + $this->offerConfirmTypeRepository = $offerConfirmTypeRepository; + $this->offerCreateValidator = $offerCreateValidator; + $this->offerFactMappingService = $offerFactMappingService; + $this->offerContactMappingService = $offerContactMappingService; + $this->offerRoomMappingService = $offerRoomMappingService; + $this->offerImportantNotesService = $offerImportantNotesService; + $this->offerPhotoMappingService = $offerPhotoMappingService; + $this->offerCancellationPolicyService = $offerCancellationPolicyService; + $this->offerAccommodationMappingService = $offerAccommodationMappingService; + $this->offerPriceService = $offerPriceService; + $this->offerUpdateValidator = $offerUpdateValidator; + $this->offerStatusValidator = $offerStatusValidator; + $this->propertyRoomService = $propertyRoomService; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "ticket_code" => $this->generateTicket(6), + "offer_code" => generateRandomString(16), + "title" => fillOnUndefined($param, "title"), + "email" => fillOnUndefined($param, "email"), + "expire_date" => fillOnUndefined($param, "expire_date"), + "confirm_type" => fillOnUndefined($param, "confirm_type", 'INS'), + "language" => fillOnUndefined($param, "language"), + "currency" => fillOnUndefined($param, "currency"), + "total" => fillOnUndefined($param, "total", 0), + "payment_type_id" => fillOnUndefined($param, "payment_type_id"), + "payment_type_mapping_id" => fillOnUndefined($param, "payment_type_mapping_id"), + "status" => fillOnUndefined($param, "status", 1), + "accept_status" => fillOnUndefined($param, "accept_status", 2), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->offerRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectOfferConfirmType($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerConfirmTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->offerRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->offerRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + + public function addNewOffer($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + DB::beginTransaction(); + + $offerData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "title" => fillOnUndefined($param, "title"), + "email" => fillOnUndefined($param, "email"), + "expire_date" => fillOnUndefined($param, "expire_date"), + "confirm_type" => fillOnUndefined($param, "confirm_type"), + "language" => fillOnUndefined($param, "language"), + "currency" => fillOnUndefined($param, "currency"), + "total" => fillOnUndefined($param, "total"), + "payment_type_id" => fillOnUndefined($param, "payment_type_id"), + "payment_type_mapping_id" => fillOnUndefined($param, "payment_type_mapping_id"), + "status" => fillOnUndefined($param, "status", 1), + "accept_status" => 3, //Pending Customer Confirm + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + + ]; + + $offerCreateResult = $this->create($offerData); + + if ($offerCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $offerData = $offerCreateResult["data"]; + + $offerData = [ + 'offer_id' => $offerData['id'], + 'property_id' => fillOnUndefined($param, "property_id"), + 'user_id' => fillOnUndefined($param, "user_id"), + 'fact_mapping' => fillOnUndefined($param, 'fact_mapping', []), + 'contact_mapping' => fillOnUndefined($param, 'contact_mapping', []), + 'room_mapping' => fillOnUndefined($param, 'room_mapping', []), + 'important_notes' => fillOnUndefined($param, 'important_notes', []), + 'photo_mapping' => fillOnUndefined($param, 'photo_mapping', []), + 'cover_photos' => fillOnUndefined($param, 'cover_photos', []), + 'has_cancellation_policy' => fillOnUndefined($param, 'has_cancellation_policy', false), + 'cancellation_policy' => fillOnUndefined($param, 'cancellation_policy', []), + 'accommodation_mapping' => fillOnUndefined($param, 'accommodation_mapping', []), + 'hotel_features_mapping' => fillOnUndefined($param, 'hotel_features_mapping', []), + ]; + $addOfferFactResponse = $this->offerFactMappingService->insertNewOfferFacts($offerData); + if ($addOfferFactResponse['status'] != 'success') { + throw new ApiErrorException($addOfferFactResponse['message']); + } + + $offerContactResponse = $this->offerContactMappingService->insertContactMapping($offerData); + if ($offerContactResponse['status'] != 'success') { + throw new ApiErrorException($offerContactResponse['message']); + } + + $offerRoomResponse = $this->offerRoomMappingService->insertRoomMapping($offerData); + if ($offerRoomResponse['status'] != 'success') { + throw new ApiErrorException($offerRoomResponse['message']); + } + + $offerRoomResponse = $this->offerAccommodationMappingService->insertAccommodationMapping($offerData); + if ($offerRoomResponse['status'] != 'success') { + throw new ApiErrorException($offerRoomResponse['message']); + } + + + $offerImportantNotesResponse = $this->offerImportantNotesService->insertImportantNotes($offerData, []); + if ($offerImportantNotesResponse['status'] != 'success') { + throw new ApiErrorException($offerImportantNotesResponse['message']); + } + + $offerPhotoMapping = $this->offerPhotoMappingService->insertPhotoMapping($offerData); + if ($offerPhotoMapping['status'] != 'success') { + throw new ApiErrorException($offerPhotoMapping['message']); + } + + $offerCoverPhotoMapping = $this->offerPhotoMappingService->insertCoverPhotoMapping($offerData); + if ($offerCoverPhotoMapping['status'] != 'success') { + throw new ApiErrorException($offerCoverPhotoMapping['message']); + } + + $offerCancellationPolicy = $this->offerCancellationPolicyService->insertCancellationPolicy($offerData, []); + if ($offerCancellationPolicy['status'] != 'success') { + throw new ApiErrorException($offerCancellationPolicy['message']); + } + + + $response = [ + 'status' => true, + 'data' => $offerCreateResult["data"], + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPriceList($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $offerRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $param['offer_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'with' => ['offerAccommodationMapping.propertyAccommodation', 'offerPrice', 'offerRoomMapping.propertyRoom'], + 'firstRow' => 1 + ]; + $columns = [ + "id", + "property_id", + "ticket_code", + "offer_code", + "title", + "description", + "expire_date", + "language", + "currency", + "total", + "payment_type_id", + "accept_status", + "status" + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest, $columns); + if (!$offerData) { + throw new ApiErrorException('Offer data not found'); + } + + + $offerAccommodationMapping = collect($offerData['offer_accommodation_mapping'])->map(function ($value) { + return $value['property_accommodation']; + })->values()->all(); + + $offerPrice = $offerData['offer_price']; + $offerRoomMapping = collect($offerData['offer_room_mapping'])->map(function ($value) { + return $value['property_room']; + })->values()->all(); + + $responseOfferData = [ + + "id" => $offerData['id'], + "property_id" => $offerData['property_id'], + "ticket_code" => $offerData['ticket_code'], + "offer_code" => $offerData['offer_code'], + "title" => $offerData['title'], + "expire_date" => $offerData['expire_date'], + "language" => $offerData['language'], + "currency" => $offerData['currency'], + "total" => $offerData['total'], + "accept_status" => $offerData['accept_status'], + "status" => $offerData['status'], + + ]; + + + $priceDataStartDate = collect($offerPrice)->keyBy('date')->keys()->min(); + $startDate = Carbon::parse($priceDataStartDate); + $endDate = collect($offerPrice)->keyBy('date')->keys()->max(); + + $diffInDays = collect($offerPrice)->count() > 0 ? $startDate->diffInDays(Carbon::parse($endDate)) : -1; + + $roomArray = []; + $priceArray = []; + foreach ($offerPrice as $price) { + + $priceArray[$offerData['id'] . "|" . $price['property_room_id'] . "|" . $price['property_accommodation_id'] . "|" . $price['date']] = $price; + } + + foreach ($offerRoomMapping as $room) { + $roomItem = [ + 'room_id' => $room['id'], + 'room_name' => $room['name'], + ]; + $accommodationArray = []; + foreach ($offerAccommodationMapping as $offerAccommodation) { + + $accommodationItem = [ + 'id' => $offerAccommodation['id'], + 'name' => $offerAccommodation['name'], + 'language_key' => $offerAccommodation['language_key'], + ]; + $roomPrice = []; + $startDate = Carbon::parse($priceDataStartDate); + $numberOfRooms = null; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $offerData['id'] . "|" . $room['id'] . "|" . $offerAccommodation['id'] . "|" . $startDate->format('Y-m-d'); + if (isset($priceArray[$checkKey])) { + $roomPrice[$startDate->format('Y-m-d')] = $priceArray[$checkKey]['amount']; + $numberOfRooms = $priceArray[$checkKey]['number_of_rooms']; + } else { + $roomPrice[$startDate->format('Y-m-d')] = null; + } + $startDate = $startDate->addDay(); + } + $accommodationItem['number_of_rooms'] = $numberOfRooms; + $accommodationItem['price'] = $roomPrice; + $accommodationArray[] = $accommodationItem; + } + $roomItem['accommodation'] = $accommodationArray; + $roomArray[] = $roomItem; + } + + $responseOfferData['room_price'] = $roomArray; + $responseOfferData['start_date'] = $priceDataStartDate; + $responseOfferData['end_Date'] = $endDate; + + $response = [ + 'status' => true, + 'data' => $responseOfferData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPrice($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $offerRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $param['offer_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'with' => [ + 'offerAccommodationMapping.propertyAccommodation', + 'offerPrice', + 'offerRoomMapping.propertyRoom.propertyRoomType', + 'offerRoomMapping.propertyRoom.propertyRoomFactMapping.propertyFact', + 'offerRoomMapping.propertyRoom.PropertyRoomPhotoMapping.propertyRoomPhoto', + 'offerRoomMapping.propertyRoom.propertyRoomViewMapping.PropertyRoomViewType' + ], + 'firstRow' => 1 + ]; + $columns = [ + "id", + "property_id", + "title", + "description", + "expire_date", + "language", + "currency", + "total", + "payment_type_id", + "accept_status", + "status" + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest, $columns); + if (!$offerData) { + throw new ApiErrorException('Offer data not found'); + } + + if(empty($offerData['offer_price'])) { + throw new ApiErrorException('Offer prices not include'); + } + + $offerAccommodationMapping = collect($offerData['offer_accommodation_mapping'])->map(function ($value) { + return $value['property_accommodation']; + })->values()->all(); + + $offerPrice = $offerData['offer_price']; + $offerRoomMapping = collect($offerData['offer_room_mapping'])->map(function ($value) { + return $value['property_room']; + })->values()->all(); + + + $roomArray = []; + + $offerPrice = collect($offerPrice); + + $sumAmount = 0; + $sumTotalAmount = 0; + foreach ($offerRoomMapping as $room) { + $accommodationArray = []; + + $room['property_room_type'] = collect($room['property_room_type'])->first(); + $room['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + + + $occupancyParams = [ + 'max_adult' => $room['max_adult'], + 'max_child' => $room['max_child'], + 'max_occupancy' => $room['max_occupancy'], + 'exclude_occupancy' => $room['exclude_occupancy'], + ]; + $room['include_occupancy'] = $this->propertyRoomService->roomIncludeOccupancies($occupancyParams); + + + $roomFact = collect($room['property_room_fact_mapping'])->map(function ($value) use ($param) { + return collect($value['property_fact']); + })->values()->all(); + + $room['room_fact'] = $roomFact; + + $roomViews = collect($room['property_room_view_mapping'])->map(function ($value) use ($param) { + return collect($value['property_room_view_type']); + })->values()->all(); + + $room['room_views'] = $roomViews; + + $offerRoomMapping = collect($room['property_room_photo_mapping'])->map(function ($value) use ($param) { + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_1024x768.' . $value['property_room_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_medium.' . $value['property_room_photo']['file_ext']; + } + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_200x200.' . $value['property_room_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '_thumbnail.' . $value['property_room_photo']['file_ext']; + } + + $original = Config::get('app.imageUrl') . '/property-photos/' . $param['property_id'] . '/' . $value['property_room_photo']['photo_name'] . '.' . $value['property_room_photo']['file_ext']; + return [ + 'default' => $original, + 'fixed' => $photoUrlFilePath, + 'thumb' => $photoUrlThumbFilePath + ]; + })->values()->all(); + $room['room_photos'] = $offerRoomMapping; + + + unset($room['property_room_fact_mapping']); + unset($room['property_room_photo_mapping']); + unset($room['property_room_view_mapping']); + + + $roomItem = $room; + + foreach ($offerAccommodationMapping as $offerAccommodation) { + + $accommodationItem = $offerAccommodation; + + $amount = $offerPrice->where('property_room_id', '=', $room['id']) + ->where('property_accommodation_id', '=', $offerAccommodation['id']) + ->sum('amount'); + + $totalAmount = $offerPrice->where('property_room_id', '=', $room['id']) + ->where('property_accommodation_id', '=', $offerAccommodation['id']) + ->sum('total_amount'); + + $numberOfRooms = $offerPrice->where('property_room_id', '=', $room['id']) + ->where('property_accommodation_id', '=', $offerAccommodation['id'])->sortBy('date') + ->pluck('number_of_rooms')->first(); + + $roomAccommodationPrices = $offerPrice->where('property_room_id', '=', $room['id']) + ->where('property_accommodation_id', '=', $offerAccommodation['id'])->sortBy('date') + ->toArray(); + + + $accommodationItem['price_daily'] = []; + + if ($roomAccommodationPrices) { + + foreach ($roomAccommodationPrices as $dailyPrice) { + $accommodationItem['price_daily'][] = [ + 'date' => $dailyPrice['date'], + 'date_formatted' => Carbon::parse($dailyPrice['date'])->format('d/m/Y'), + 'amount' => moneyDoubleFormat($dailyPrice['amount']), + 'number_of_rooms' => $dailyPrice['number_of_rooms'], + 'total' => moneyDoubleFormat($dailyPrice['total_amount']), + //'currency' => $dailyPrice['currency'], + ]; + } + + + $sumAmount += $amount; + $sumTotalAmount += $totalAmount; + $accommodationItem['price'] = [ + 'amount' => moneyDoubleFormat($amount), + 'total_amount' => moneyDoubleFormat($totalAmount), + 'number_of_rooms' => $numberOfRooms + ]; + + $accommodationArray[] = $accommodationItem; + } + } + if ($accommodationArray) { + $roomItem['accommodation'] = $accommodationArray; + $roomArray[] = $roomItem; + } + } + + $response = [ + 'status' => true, + 'data' => [ + 'room_list' => $roomArray, + 'amount' => moneyDoubleFormat($sumAmount), + 'total_amount' => moneyDoubleFormat($sumTotalAmount) + + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function storePriceList($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $offerData = + [ + "check_in" => fillOnUndefined($param, "start_date"), + "check_out" => fillOnUndefined($param, "end_date") + ]; + + $offerCheckInCheckOutUpdate = $this->update($param["offer_id"], $offerData); + + if ($offerCheckInCheckOutUpdate['status'] != 'success') { + throw new ApiErrorException($offerCheckInCheckOutUpdate['message']); + } + + $checkOfferApprovedParam = [ + 'offer_id' => $param['offer_id'] + ]; + $checkOfferApprovedStatus = $this->checkOfferApprovedStatus($checkOfferApprovedParam); + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $offerRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $param['offer_id']], + ], + 'with' => ['offerPrice'], + 'firstRow' => 1 + ]; + $columns = [ + "id", + "property_id", + "title", + "description", + "expire_date", + "language", + "currency", + "total", + "payment_type_id", + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest, $columns); + if (!$offerData) { + throw new ApiErrorException('Offer data not found'); + } + + + $oldOfferPrices = $offerData['offer_price']; + $newRoomPrices = $param['room_price']; + $checkTotalAmount = 0; + + $insertPrices = []; + foreach ($newRoomPrices as $room) { + foreach ($room['accommodation'] as $accommodation) { + if ( + isset($accommodation['number_of_rooms']) && + !empty($accommodation['number_of_rooms']) && + $accommodation['number_of_rooms'] !== "" && + is_numeric($accommodation['number_of_rooms']) + ) { + foreach ($accommodation['price'] as $date => $price) { + if (is_numeric($price)) { + $totalAmount = $price * $accommodation['number_of_rooms']; + $insertItem = [ + 'offer_id' => $offerData['id'], + 'date' => $date, + 'property_room_id' => $room['room_id'], + 'property_accommodation_id' => $accommodation['id'], + 'number_of_rooms' => $accommodation['number_of_rooms'], + 'currency' => $offerData['currency'], + 'amount' => $price, + 'total_amount' => $totalAmount, + 'status' => fillOnUndefined($param, "status", 1), + 'created_by' => fillOnUndefined($param, "user_id", 0), + 'updated_by' => fillOnUndefined($param, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + $checkTotalAmount += $price; + $insertPrices[] = $insertItem; + } + } + } else { + throw new ApiErrorException(lang('Room (' . $room['room_name'] . '-' . $accommodation['name'] . ') number of rooms data not valid', [])); + } + } + } + + $deleteThis = collect($oldOfferPrices)->keyBy('id')->keys()->toArray(); + + if ($deleteThis) { + $deleteRoomRatePrices = $this->offerPriceService->destroy($deleteThis); + if ($deleteRoomRatePrices['status'] != 'success') { + throw new ApiErrorException($deleteRoomRatePrices['message']); + } + } + + $insertRoomRatePrices = $this->offerPriceService->insert($insertPrices); + if ($insertRoomRatePrices['status'] != 'success') { + throw new ApiErrorException($insertRoomRatePrices['message']); + } + + if ($checkTotalAmount <= 0) { + throw new ApiErrorException('Total amount cannot be zero. Please check your number of rooms and rates.'); + } + + + $offerPriceParams = [ + "offer_id" => fillOnUndefined($param, "offer_id"), + "property_id" => fillOnUndefined($param, "property_id"), + "user_id" => fillOnUndefined($param, "user_id"), + ]; + + $offerPriceTotal = $this->offerPriceTotalUpdate($offerPriceParams); + if ($offerPriceTotal['status'] != 'success') { + throw new ApiErrorException($offerPriceTotal['message']); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + private function offerPriceTotalUpdate($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $checkOfferApprovedParam = [ + 'offer_id' => $params['offer_id'] + ]; + $checkOfferApprovedStatus = $this->checkOfferApprovedStatus($checkOfferApprovedParam); + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $offerPriceTotalRequest = [ + 'criteria' => [ + ['field' => 'offer_id', 'condition' => '=', 'value' => $params['offer_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + + ]; + $offerPriceTotal = $this->offerPriceService->select($offerPriceTotalRequest); + if ($offerPriceTotal['status'] != 'success') { + throw new ApiErrorException($offerPriceTotal['message']); + } + + $totalPrice = collect($offerPriceTotal['data'])->sum(['total_amount']); + + $offerStatusData = + [ + "total" => $totalPrice, + "updated_by" => fillOnUndefined($params, "user_id") + + ]; + + $offerStatusResult = $this->update($params, $offerStatusData); + + if ($offerStatusResult['status'] != 'success') { + throw new ApiErrorException(lang('Offer Price Total data is not updated.')); + } + + $response = [ + 'status' => true, + 'data' => $offerStatusResult["data"], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + + public function findOffer($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $offerRequest = [ + 'criteria' => [ + // ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['offer_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => [ + 'offerAccommodationMapping.propertyAccommodation', + 'offerCancellationPolicy', 'offerContactMapping.propertyExecutive.executiveType', + 'offerFactMapping.propertyFact', 'offerImportantNotes', 'offerPhotoMapping.propertyPhoto', + 'offerPrice', 'offerRoomMapping.propertyRoom', 'offerAcceptStatus', + 'offerLanguage', 'createUser', 'property.propertyBrand'], + 'firstRow' => 1 + ]; + $columns = [ + "id", + "email", + "property_id", + "ticket_code", + "offer_code", + "title", + "description", + "expire_date", + "language", + "currency", + "total", + "status", + "payment_type_id", + "payment_type_mapping_id", + "status", + "accept_status", + "confirm_type", + "check_in", + "check_out", + "created_by" + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest, $columns); + if (!$offerData) { + throw new ApiErrorException('Offer data not found'); + } + + $offerAccommodationMapping = collect($offerData['offer_accommodation_mapping'])->map(function ($value) { + return $value['property_accommodation']; + })->values()->all(); + + $offerCancellationPolicy = collect($offerData['offer_cancellation_policy'])->map(function ($value) { + return $value; + })->values()->all(); + + $offerContactMapping = collect($offerData['offer_contact_mapping'])->map(function ($value) use ($offerData) { + $response = $value['property_executive']; + + $response['executive_type'] = $response['executive_type']['language_key']; + return $response; + })->values()->all(); + + $offerFactMapping = collect($offerData['offer_fact_mapping'])->map(function ($value) { + return $value['property_fact']; + })->values()->all(); + + $offerImportantNotes = $offerData['offer_important_notes']; + $offerPhotoMapping = collect($offerData['offer_photo_mapping']) + ->where('is_cover', '=', 0) + ->map(function ($value) use ($params) { + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_1024x768.' . $value['property_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_200x200.' . $value['property_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_1024x768.' . $value['property_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_medium.' . $value['property_photo']['file_ext']; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_200x200.' . $value['property_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_thumbnail.' . $value['property_photo']['file_ext']; + } + $value['property_photo']['image_url'] = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '.' . $value['property_photo']['file_ext']; + $value['property_photo']['thumb_image_url'] = $photoUrlThumbFilePath; + $value['property_photo']['medium_image_url'] = $photoUrlFilePath; + return $value['property_photo']; + })->values()->all(); + + + $offerCoverPhotoMapping = collect($offerData['offer_photo_mapping']) + ->where('is_cover', '=', 1) + ->map(function ($value) use ($params) { + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_1024x768.' . $value['property_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_200x200.' . $value['property_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_1024x768.' . $value['property_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_medium.' . $value['property_photo']['file_ext']; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_200x200.' . $value['property_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '_thumbnail.' . $value['property_photo']['file_ext']; + } + $value['property_photo']['image_url'] = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $value['property_photo']['photo_name'] . '.' . $value['property_photo']['file_ext']; + $value['property_photo']['thumb_image_url'] = $photoUrlThumbFilePath; + $value['property_photo']['medium_image_url'] = $photoUrlFilePath; + return $value['property_photo']; + })->values()->all(); + + + $offerPrice = $offerData['offer_price']; + $offerRoomMapping = collect($offerData['offer_room_mapping'])->map(function ($value) { + return $value['property_room']; + })->values()->all(); + + $responseOfferData = [ + + "id" => $offerData['id'], + "email" => $offerData['email'], + "property_id" => $offerData['property_id'], + "ticket_code" => $offerData['ticket_code'], + "offer_code" => $offerData['offer_code'], + "title" => $offerData['title'], + "description" => $offerData['description'], + "expire_date" => $offerData['expire_date'], + "check_in" => $offerData['check_in'], + "check_out" => $offerData['check_out'], + "language" => $offerData['language'], + "currency" => $offerData['currency'], + "total" => $offerData['total'], + "status" => $offerData['status'], + "payment_type_id" => $offerData['payment_type_id'], + "payment_type_mapping_id" => $offerData['payment_type_mapping_id'], + "accept_status" => $offerData['accept_status'], + "confirm_type" => $offerData['confirm_type'], + 'offer_accommodation_mapping' => $offerAccommodationMapping, + 'offer_has_cancellation_policy' => count($offerCancellationPolicy) > 0 ? true : false, + 'offer_cancellation_policy' => $offerCancellationPolicy, + 'offer_contact_mapping' => $offerContactMapping, + 'offer_fact_mapping' => $offerFactMapping, + 'offer_important_notes' => $offerImportantNotes, + 'offer_photo_mapping' => $offerPhotoMapping, + 'offer_cover_photos' => $offerCoverPhotoMapping, + 'offer_price' => $offerPrice, + 'offer_room_mapping' => $offerRoomMapping, + 'offer_language' => $offerData['offer_language'], + 'offer_accept_status' => $offerData['offer_accept_status'], + 'create_user' => $offerData['create_user'], + 'property' => $offerData['property'], + 'property_brand' => $offerData['property']['property_brand'], + ]; + + $response = [ + 'status' => true, + 'data' => $responseOfferData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function editFormCheckValues($params) + { + + $responseData = $params; + $offer = fillOnUndefined($params, 'get_offer', []); + + $offerContactMapping = collect($offer['offer_contact_mapping'])->keyBy('id')->keys()->all(); + $offerPhotoMapping = collect($offer['offer_photo_mapping'])->keyBy('id')->keys()->all(); + $offerCoverPhotoMapping = collect($offer['offer_cover_photos'])->keyBy('id')->keys()->all(); + $offerRoomMapping = collect($offer['offer_room_mapping'])->keyBy('id')->keys()->all(); + + $responseData['executives'] = collect($params['executives'])->map(function ($value) use ($offerContactMapping) { + $value['is_selected'] = array_search($value['id'], $offerContactMapping) > -1 ? true : false; + return $value; + })->values()->all(); + + $responseData['photos'] = collect($params['photos'])->map(function ($value) use ($offerPhotoMapping, $offerCoverPhotoMapping) { + $value['is_selected'] = array_search($value['id'], $offerPhotoMapping) > -1 ? true : false; + $value['is_cover'] = array_search($value['id'], $offerCoverPhotoMapping) > -1 ? true : false; + + return $value; + })->values()->all(); + + $responseData['property_rooms'] = collect($params['property_rooms'])->map(function ($value) use ($offerRoomMapping) { + $value['is_selected'] = array_search($value['id'], $offerRoomMapping) > -1 ? true : false; + return $value; + })->values()->all(); + unset($offer['offer_accommodation_mapping']); + unset($offer['offer_contact_mapping']); + unset($offer['offer_fact_mapping']); + unset($offer['offer_photo_mapping']); + unset($offer['offer_cover_photos']); + unset($offer['offer_room_mapping']); + unset($offer['offer_price']); + $responseData['get_offer'] = $offer; + return $responseData; + } + + public function updateOffer($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + DB::beginTransaction(); + + $checkOfferApprovedParam = [ + 'offer_id' => $param['offer_id'] + ]; + $checkOfferApprovedStatus = $this->checkOfferApprovedStatus($checkOfferApprovedParam); + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $offerId = fillOnUndefined($param, "offer_id"); + $offerData = [ + "title" => fillOnUndefined($param, "title"), + "email" => fillOnUndefined($param, "email"), + "expire_date" => fillOnUndefined($param, "expire_date"), + "language" => fillOnUndefined($param, "language"), + "currency" => fillOnUndefined($param, "currency"), + "payment_type_id" => fillOnUndefined($param, "payment_type_id"), + "payment_type_mapping_id" => fillOnUndefined($param, "payment_type_mapping_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + ]; + + if ($checkOfferApprovedStatus['data']['confirm_type'] != $param['confirm_type']) { + if ($checkOfferApprovedStatus['data']['accept_status'] == 3) { + $offerData['confirm_type'] = fillOnUndefined($param, "confirm_type"); + } else { + throw new ApiErrorException('Offer information cannot be updated due to approval phase.'); + } + } + + if ($checkOfferApprovedStatus['data']['payment_type_mapping_id'] != $param['payment_type_mapping_id']) { + if ($checkOfferApprovedStatus['data']['accept_status'] == 3) { + $offerData['payment_type_mapping_id'] = fillOnUndefined($param, "payment_type_mapping_id"); + } else { + throw new ApiErrorException('Offer information cannot be updated due to approval phase.'); + } + } + + $validationResult = $this->offerUpdateValidator->validate($offerData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $offerCreateResult = $this->update($offerId, $offerData); + + if ($offerCreateResult['status'] != 'success') { + throw new ApiErrorException(lang('Offer data is not updated.')); + } + $offerData = $offerCreateResult["data"]; + + + $offerData = [ + 'offer_id' => $offerData['id'], + 'user_id' => fillOnUndefined($param, "user_id"), + 'fact_mapping' => fillOnUndefined($param, 'fact_mapping', []), + 'contact_mapping' => fillOnUndefined($param, 'contact_mapping', []), + 'room_mapping' => fillOnUndefined($param, 'room_mapping', []), + 'important_notes' => fillOnUndefined($param, 'important_notes', []), + 'photo_mapping' => fillOnUndefined($param, 'photo_mapping', []), + 'cover_photos' => fillOnUndefined($param, 'cover_photos', []), + 'cancellation_policy' => fillOnUndefined($param, 'cancellation_policy', []), + 'has_cancellation_policy' => fillOnUndefined($param, 'has_cancellation_policy', false), + 'accommodation_mapping' => fillOnUndefined($param, 'accommodation_mapping', []), + 'hotel_features_mapping' => fillOnUndefined($param, 'hotel_features_mapping', []), + ]; + + $getOffer = $this->findOffer($param); + + if ($getOffer['status'] != 'success') { + throw new ApiErrorException($getOffer['message']); + } + + $offer = $getOffer['data']; + + + $offerFactMapping = collect($offer['offer_fact_mapping'])->keyBy('id')->keys()->all(); + $offerContactMapping = collect($offer['offer_contact_mapping'])->keyBy('id')->keys()->all(); + $offerPhotoMapping = collect($offer['offer_photo_mapping'])->keyBy('id')->keys()->all(); + $offerCoverPhotoMapping = collect($offer['offer_cover_photos'])->keyBy('id')->keys()->all(); + $offerRoomMapping = collect($offer['offer_room_mapping'])->keyBy('id')->keys()->all(); + $offerAccommodationMapping = collect($offer['offer_accommodation_mapping'])->keyBy('id')->keys()->all(); + $offerCancellationPolicy = collect($offer['offer_cancellation_policy'])->keyBy('id')->keys()->all(); + $offerImportantNotes = collect($offer['offer_important_notes'])->keyBy('id')->keys()->all(); + + + $addOfferFactResponse = $this->offerFactMappingService->updateOfferFacts($offerData, $offerFactMapping); + if ($addOfferFactResponse['status'] != 'success') { + throw new ApiErrorException($addOfferFactResponse['message']); + } + + $offerContactResponse = $this->offerContactMappingService->updateContactMapping($offerData, $offerContactMapping); + if ($offerContactResponse['status'] != 'success') { + throw new ApiErrorException($offerContactResponse['message']); + } + + $offerPhotoMapping = $this->offerPhotoMappingService->updatePhotoMapping($offerData, $offerPhotoMapping); + if ($offerPhotoMapping['status'] != 'success') { + throw new ApiErrorException($offerPhotoMapping['message']); + } + + $offerCoverPhotoMapping = $this->offerPhotoMappingService->updateCoverPhotoMapping($offerData, $offerCoverPhotoMapping); + if ($offerCoverPhotoMapping['status'] != 'success') { + throw new ApiErrorException($offerCoverPhotoMapping['message']); + } + + $offerRoomResponse = $this->offerRoomMappingService->updateRoomMapping($offerData, $offerRoomMapping); + if ($offerRoomResponse['status'] != 'success') { + throw new ApiErrorException($offerRoomResponse['message']); + } + + $offerAccommodationResponse = $this->offerAccommodationMappingService->updateAccommodationMapping($offerData, $offerAccommodationMapping); + if ($offerAccommodationResponse['status'] != 'success') { + throw new ApiErrorException($offerAccommodationResponse['message']); + } + + $offerImportantNotesResponse = $this->offerImportantNotesService->insertImportantNotes($offerData, $offerImportantNotes); + if ($offerImportantNotesResponse['status'] != 'success') { + throw new ApiErrorException($offerImportantNotesResponse['message']); + } + + $offerCancellationPolicy = $this->offerCancellationPolicyService->insertCancellationPolicy($offerData, $offerCancellationPolicy); + if ($offerCancellationPolicy['status'] != 'success') { + throw new ApiErrorException($offerCancellationPolicy['message']); + } + + $deleteThisPrices = [ + 'offer_id' => $offer['id'], + 'property_room_id' => fillOnUndefined($offerRoomResponse, 'data', []), + 'property_accommodation_id' => fillOnUndefined($offerAccommodationResponse, 'data', []), + + ]; + + $deleteThisOfferPrices = $this->offerPriceService->deleteThisOfferPrices($deleteThisPrices); + if ($deleteThisOfferPrices['status'] != 'success') { + throw new ApiErrorException($deleteThisOfferPrices['message']); + } + + + $response = [ + 'status' => true, + 'data' => $offerCreateResult["data"], + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function updateStatus($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->offerStatusValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $offerId = fillOnUndefined($param, "offer_id"); + + $checkOfferApprovedParam = [ + 'offer_id' => $offerId + ]; + $checkOfferApprovedStatus = $this->checkOfferApprovedStatus($checkOfferApprovedParam); + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $offerStatusData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "status" => fillOnUndefined($param, "status"), + "updated_by" => fillOnUndefined($param, "user_id") + + ]; + $offerStatusResult = $this->update($offerId, $offerStatusData); + + if ($offerStatusResult['status'] != 'success') { + throw new ApiErrorException(lang('Offer Status data is not updated.')); + } + + $response = [ + 'status' => true, + 'data' => $offerStatusResult["data"], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateAcceptStatus($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $offerId = fillOnUndefined($param, "offer_id"); + $offerCode = fillOnUndefined($param, "offer_code"); + $acceptStatus = fillOnUndefined($param, "accept_status", 1); + + $checkOfferApprovedParam = [ + 'offer_id' => $offerId + ]; + $checkOfferApprovedStatus = $this->checkOfferApprovedStatus($checkOfferApprovedParam); + + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $offerRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $offerId], + ['field' => 'offer_code', 'condition' => '=', 'value' => $offerCode] + ], + 'firstRow' => 1 + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest); + if (!$offerData) { + throw new ApiErrorException('Offer data not found'); + } + + $offerAcceptStatusData = [ + "accept_status" => $acceptStatus, + "updated_at" => Carbon::now()->timestamp + ]; + + $offerAcceptStatusResult = $this->update($offerData['id'], $offerAcceptStatusData); + + if ($offerAcceptStatusResult['status'] != 'success') { + throw new ApiErrorException(lang('Offer Accept Status data is not updated.')); + } + + $response = [ + 'status' => true, + 'data' => $offerAcceptStatusResult["data"], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function checkOfferApprovedStatus($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $offerRequest = [ + 'criteria' => [ + // ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ], + 'firstRow' => 1 + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest); + if (!$offerData) { + throw new ApiErrorException('Update failed. Offer data not found'); + } + + if (!in_array($offerData['accept_status'], [1, 2, 3])) { + throw new ApiErrorException('Update failed. Offer update is locked.'); + } + + $response = [ + 'status' => true, + 'data' => $offerData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + private function generateTicket($length = 6) + { + $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + $checkTicketCriteria = [ + 'criteria' => [ + ['field' => 'ticket_code', 'condition' => '=', 'value' => $randomString], + ], + 'firstRow' => 1 + ]; + $checkTicket = $this->offerRepository->findByCriteria($checkTicketCriteria); + if ($checkTicket) { + $this->generateTicket($length); + } + return $randomString; + } + + public function checkPropertyOfferPermissionAccess($param) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $offerRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, "offer_id")], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, "property_id")], + ], + 'firstRow' => 1 + ]; + + $offerData = $this->offerRepository->findByCriteria($offerRequest, + [ + 'id', 'property_id', 'offer_code', 'status', 'confirm_type', 'accept_status', + 'payment_type_mapping_id', 'title', 'ticket_code', 'offer_code', 'email', 'currency', 'total', + 'language', 'created_by' + ] + ); + + if (!$offerData) { + throw new ApiErrorException('Offer permission error'); + } + $response = [ + 'status' => true, + 'data' => $offerData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/OneSignalService.php b/app/Core/Service/OneSignalService.php new file mode 100644 index 0000000..252dcdd --- /dev/null +++ b/app/Core/Service/OneSignalService.php @@ -0,0 +1,68 @@ +restClient = new Client(); + } + + public function sendOneSignalPushNotification($restUrl , $payloadJson) + { + + $oneSignalAppId = '1d4372b2-4f8f-47c3-aab0-a9e38f2ad4c3'; + + $payloadJson['app_id'] = $oneSignalAppId; + + $response = ['status' => false, 'message' => '']; + try { + + $result = $this->restClient->post( + $restUrl, + [ + 'headers' => [ + 'Authorization' => 'Basic ODQ2NGEzMTUtM2Y2OS00MzczLWE2MmEtMjNkN2ZiYzg0ZTY5', + 'Content-Type' => 'application/json', + ], + 'body' => json_encode($payloadJson) + ] + ); + + $getResponseBody = $result->getBody()->getContents(); + $getResponseData = $getResponseBody ? json_decode($getResponseBody,1) : []; + + if(isset($getResponseData['errors']) && !empty($getResponseData['errors'])) { + $response['message'] = isset($getResponseData['errors']) ? implode(',', $getResponseData['errors']) : 'Servis Hatası!'; + } else { + $response = [ + 'status' => true, + 'data' => $getResponseData, + ]; + } + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + +} diff --git a/app/Core/Service/PdfContentService.php b/app/Core/Service/PdfContentService.php new file mode 100644 index 0000000..6797ec5 --- /dev/null +++ b/app/Core/Service/PdfContentService.php @@ -0,0 +1,635 @@ +propertyRepository = $propertyRepository; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + $this->propertyContactService = $propertyContactService; + $this->propertyFactService = $propertyFactService; + $this->propertyPhotoService = $propertyPhotoService; + $this->propertyRoomService = $propertyRoomService; + $this->propertyExecutiveService = $propertyExecutiveService; + $this->propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository; + $this->propertyWebColorMappingService = $propertyWebColorMappingService; + $this->propertyPlaceService = $propertyPlaceService; + + } + + + public function pdfData($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + 'propertyRooms.propertyRoomType', 'propertyExecutive.executiveType', + 'propertyLanguageSpoken.languageCode', 'propertyAwardsCertificates.awardsCertificateCategory' + ], + 'firstRow' => true + ]; + + + $getPropertyFields = [ + 'id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country' + ]; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + + //dd($property['property_rooms']); + + if (!$property) { + throw new ApiErrorException('property not found'); + } + + $newExecutiveArray = []; + foreach ($property['property_executive'] as $propertyExecutive) { + + $executiveItem = [ + 'id' => $propertyExecutive['id'], + 'executive_type_name' => $propertyExecutive['executive_type']['name'], + 'executive_type_locale_key' => $propertyExecutive['executive_type']['language_key'], + 'executive_type_icon' => $propertyExecutive['executive_type']['icon'], + 'name_surname' => $propertyExecutive['name_surname'], + 'email' => $propertyExecutive['email'], + 'phone_code' => $propertyExecutive['phone_code'], + 'phone' => $propertyExecutive['phone'], + 'extension' => $propertyExecutive['extension'], + 'mobile_code' => $propertyExecutive['mobile_code'], + 'mobile' => $propertyExecutive['mobile'], + 'fax_code' => $propertyExecutive['fax_code'], + 'fax' => $propertyExecutive['fax'], + 'view_full_phone' => $propertyExecutive['view_full_phone'], + 'view_full_mobile' => $propertyExecutive['view_full_mobile'], + 'view_full_fax' => $propertyExecutive['view_full_fax'], + ]; + + if ($propertyExecutive['status'] == 1) { + $newExecutiveArray[] = $executiveItem; + } + + } + + $getPropertyFact = $this->propertyFactService->getPropertyFact($params); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $getPropertyFact = $this->getPropertyFactForHtml($getPropertyFact['data']); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $responseData = [ + 'name' => $property['name'], + 'property_type' => fillOnUndefined($property['property_type'], 'name'), + 'property_type_language_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_type_key' => fillOnUndefined($property['property_type'], 'language_key'), + 'property_chain' => fillOnUndefined($property['property_chain'], 'name'), + 'official_name' => $property['official_name'], + 'tax_office' => $property['tax_office'], + 'tax_number' => $property['tax_number'], + 'currency_type' => $property['currency_type'], + 'country' => $property['country'], + 'description' => $property['name'], + 'rooms' => $property['property_rooms'], + 'property_brand' => $property['property_brand'], + 'property_contact' => $property['property_contact'], + 'property_facts' => $getPropertyFact['data'], + 'property_executive' => $newExecutiveArray, + ]; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if (isset($propertyAdditionalInfo['data'])) { + $responseData['additional_info'] = $propertyAdditionalInfo['data']; + } + + + $responseData['property_language_spoken'] = null; + if ($property['property_language_spoken']) { + foreach ($property['property_language_spoken'] as $language) { + $responseData['property_language_spoken'][] = __($language['language_code']['language_key']); + } + if ($responseData['property_language_spoken']) { + $responseData['property_language_spoken'] = implode(', ', $responseData['property_language_spoken']); + } + } + + + $responseData['property_awards_certificates'] = null; + if ($property['property_awards_certificates']) { + foreach ($property['property_awards_certificates'] as $certificate) { + if ($certificate['status'] == 1) { + $responseData['property_awards_certificates'][] = $certificate['awards_certificate_category']['name'] . (!empty($certificate['date']) ? ' (' . $certificate['date'] . ')' : ''); + } + } + if ($responseData['property_awards_certificates']) { + $responseData['property_awards_certificates'] = implode(', ', $responseData['property_awards_certificates']); + } + } + + $propertyPlaceCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '!=', 'value' => 0], + //['field' => 'id', 'condition' => '=', 'value' => 5],//TODO: Del + ], + 'with' => [ + 'propertyPlaceCategory', 'propertyPlaceWorkingHour', + 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', + 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle', + 'propertyPlaceCategoryFieldValue.placeCategoryField', + 'propertyPlaceCategoryFieldValue.unitValue', + 'propertyPlaceCategoryFieldValue.optionValue' + ], + 'orderBy' => [["field" => "order_number", "value" => "ASC"]], + ]; + $propertyPlaces = $this->propertyPlaceService->select($propertyPlaceCriteria); + $propertyPlaces = $propertyPlaces['data'] ? $propertyPlaces['data'] : []; + + + foreach ($propertyPlaces as $placeKey => $propertyPlace) { + + $propertyPlaceFactGroups = collect($propertyPlace['property_place_fact_mapping'])->groupBy('property_place_fact_title_fact_mapping.place_fact_title.id'); + $propertyPlaceFactGroups = $propertyPlaceFactGroups->toArray(); + + $propertyPlaceFactMapping = []; + foreach ($propertyPlaceFactGroups as $propertyPlaceFactGroupKey => $propertyPlaceFactGroup) { + foreach ($propertyPlaceFactGroup as $propertyPlaceFact) { + $propertyPlaceFactMapping[$propertyPlaceFactGroupKey]['title'] = $propertyPlaceFact['property_place_fact_title_fact_mapping']['place_fact_title']['language_key']; + $propertyPlaceFactMapping[$propertyPlaceFactGroupKey]['fact'][] = $propertyPlaceFact['property_place_fact_title_fact_mapping']['place_fact']['language_key']; + } + } + + unset($propertyPlaces[$placeKey]['property_place_fact_mapping']); + + $propertyPlaces[$placeKey]['property_place_fact_mapping'] = $propertyPlaceFactMapping; + + } + + $responseData['propertyPlaces'] = $propertyPlaces; + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyFactForHtml($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $categories = $params; + $responseArray = []; + foreach ($categories as $category) { + $categoryArray = []; + $categoryItem = $category; + foreach ($category['fact_subcategory'] as $subCategory) { + $subCategoryItem = $subCategory; + $facts = collect($subCategory['fact']) + ->where('is_selected', '=', true) + ->map(function ($value) { + return $value; + })->values()->all(); + $subCategoryItem['fact'] = $facts ? $facts : []; + if ($facts) { + $categoryArray[$subCategory['id']] = $subCategoryItem; + } + } + $categoryItem['fact_subcategory'] = $categoryArray; + $responseArray[$category['id']] = $categoryItem; + } + + $response = [ + 'status' => true, + 'data' => $responseArray, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function propertyBaseData($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBrand', 'propertyContact'], + 'firstRow' => true + ]; + + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + + if (!$property) { + throw new ApiErrorException('property not found'); + } + + $response = [ + 'status' => true, + 'data' => $property, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function factSheetData($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + $factSheetData = []; + + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + 'propertyExecutive.executiveType', 'propertyLanguageSpoken.languageCode', 'propertyAwardsCertificates.awardsCertificateCategory', + 'propertyRooms.propertyRoomType', 'propertyRooms.propertyRoomFactMapping.propertyFact', + 'propertyRooms.propertyRoomPhotoMapping.propertyRoomPhoto', + 'propertyRooms.propertyRoomViewMapping.propertyRoomViewType', + 'propertyFactMapping.fact.propertyFactParent.propertyFactParent', 'propertyBookingEngineToken', + 'propertyPlace.propertyPlaceCategory', 'propertyPlace.propertyPlaceWorkingHour', + 'propertyPlace.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', + 'propertyPlace.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle', + 'propertyPlace.propertyPlaceCategoryFieldValue.placeCategoryField', + 'propertyPlace.propertyPlaceCategoryFieldValue.unitValue', + 'propertyPlace.propertyPlaceCategoryFieldValue.optionValue', + 'propertyPlace.propertyPlacePhotoMapping.propertyPlacePhoto', + 'propertyAdditionalInfos.propertyAdditionalInfoKey' + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $property = $this->propertyRepository->findByCriteria($propertyRequest, $getPropertyFields); + + if (!$property) { + throw new ApiErrorException('Property not found'); + } + + + //colorCodes + $colorCodes = null; + $colorCodesArray = json_decode($property['property_brand']['color_codes'], 1); + $colorCodes = array_values($colorCodesArray); + + //summary + $summary = null; + $summaryArray = json_decode($property['property_brand']['title'], 1); + $summary = isset($summaryArray[$params['locale']]) ? $summaryArray[$params['locale']] : null; + + + //propertyFact + $propertyFact = null; + $amenities = collect($property['property_fact_mapping'])->where('fact.property_fact_parent.property_fact_parent.id',1)->toArray(); + $propertyFact['amenities']['name'] = __('property_fact-amenities',[],$params['locale']); + foreach ($amenities as $propertyFactMapping) { + + $propertyFact['amenities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['name'] = __($propertyFactMapping['fact']['property_fact_parent']['language_key'],[],$params['locale']); + $propertyFact['amenities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['order_number'] = $propertyFactMapping['fact']['property_fact_parent']['order_number']; + $propertyFact['amenities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact'][$propertyFactMapping['fact']['id']] = [ + 'name' => __($propertyFactMapping['fact']['language_key'],[],$params['locale']), + 'icon' => $propertyFactMapping['fact']['icon'], + ]; + $propertyFact['amenities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact'] = array_values($propertyFact['amenities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact']); + } + $propertyFact['amenities']['fact'] = collect($propertyFact['amenities']['fact'])->sortBy('order_number')->toArray(); + $propertyFact['amenities']['fact'] = array_values($propertyFact['amenities']['fact']); + + $facilities = collect($property['property_fact_mapping'])->where('fact.property_fact_parent.property_fact_parent.id',44)->toArray(); + $propertyFact['facilities']['name'] = __('property_fact-facilities',[],$params['locale']); + foreach ($facilities as $propertyFactMapping) { + + $propertyFact['facilities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['name'] = __($propertyFactMapping['fact']['property_fact_parent']['language_key'],[],$params['locale']); + $propertyFact['facilities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['order_number'] = $propertyFactMapping['fact']['property_fact_parent']['order_number']; + $propertyFact['facilities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact'][$propertyFactMapping['fact']['id']] = [ + 'name' => __($propertyFactMapping['fact']['language_key'],[],$params['locale']), + 'icon' => $propertyFactMapping['fact']['icon'], + ]; + $propertyFact['facilities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact'] = array_values($propertyFact['facilities']['fact'][$propertyFactMapping['fact']['property_fact_parent']['id']]['fact']); + } + $propertyFact['facilities']['fact'] = collect($propertyFact['facilities']['fact'])->sortBy('order_number')->toArray(); + $propertyFact['facilities']['fact'] = array_values($propertyFact['facilities']['fact']); + + + //propertyPhoto + $propertyPhoto = []; + foreach ($property['property_photos'] as $propertyPhotos) { + $propertyPhoto[] = [ + 'photo_order' => $propertyPhotos['photo_order'], + 'is_default' => $propertyPhotos['is_default'], + 'is_compatible_slider' => $propertyPhotos['is_compatible_with_myweb_slider'], + 'photoUrl' => $propertyPhotos['photoUrl'], + ]; + } + $propertyPhoto = collect($propertyPhoto)->sortBy('photo_order')->toArray(); + $propertyPhoto = array_values($propertyPhoto); + + + //propertyAwardsCertificate + $propertyAwardsCertificate = []; + foreach ($property['property_awards_certificates'] as $propertyAwardsCertificateMapping) { + $propertyAwardsCertificate[] = [ + 'name' => $propertyAwardsCertificateMapping['awards_certificate_category']['name'], + 'type' => $propertyAwardsCertificateMapping['awards_certificate_category']['type'], + ]; + } + + //propertyExecutive + $propertyExecutive = []; + foreach ($property['property_executive'] as $propertyExecutives) { + $propertyExecutive[] = [ + 'name' => $propertyExecutives['name_surname'], + 'type' => __($propertyExecutives['executive_type']['language_key'],[],$params['locale']), + 'email' => $propertyExecutives['email'], + 'phone' => $propertyExecutives['view_full_phone'], + 'mobile' => $propertyExecutives['view_full_mobile'], + 'fax' => $propertyExecutives['view_full_fax'], + ]; + } + + + //propertyAwardsCertificate + $propertyAdditionalInfo = []; + foreach ($property['property_additional_infos'] as $propertyAdditionalInfos) { + $propertyAdditionalInfo[] = [ + 'id' => $propertyAdditionalInfos['additional_info_key_id'], + 'name' => __($propertyAdditionalInfos['property_additional_info_key']['language_key'],[],$params['locale']), + 'key' => $propertyAdditionalInfos['property_additional_info_key']['additional_info_key'], + 'language_key' => $propertyAdditionalInfos['property_additional_info_key']['language_key'], + 'value' => $propertyAdditionalInfos['value'], + ]; + } + + //propertyRoom + $propertyRoom = []; + foreach ($property['property_rooms'] as $propertyRooms) { + + $propertyRoom[$propertyRooms['id']] = [ + 'name' => $propertyRooms['name'], + 'type' => __($propertyRooms['property_room_type']['language_key'],[],$params['locale']), + 'max_occupancy' => $propertyRooms['max_occupancy'], + 'max_adult' => $propertyRooms['max_adult'], + 'max_child' => $propertyRooms['max_child'], + 'max_child_number' => $propertyRooms['max_child_number'], + 'room_size' => $propertyRooms['room_size'], + 'room_size_type' => $propertyRooms['roomSizeTypeFormatted'], + 'room_count' => $propertyRooms['room_count'] + ]; + + //propertyRoomFact + $propertyRoomFact = null; + foreach ($propertyRooms['property_room_fact_mapping'] as $propertyRoomFactMapping) { + $propertyRoomFact[$propertyRoomFactMapping['property_fact']['id']] = [ + 'name' => __($propertyRoomFactMapping['property_fact']['language_key'],[],$params['locale']), + 'icon' => $propertyRoomFactMapping['property_fact']['icon'], + ]; + $propertyRoomFact = array_values($propertyRoomFact); + } + + $propertyRoomFact = collect($propertyRoomFact)->sortBy('order_number')->toArray(); + $propertyRoomFact = array_values($propertyRoomFact); + $propertyRoom[$propertyRooms['id']]['fact'] = $propertyRoomFact; + + //propertyRoomPhoto + $propertyRoomPhoto = null; + foreach ($propertyRooms['property_room_photo_mapping'] as $propertyRoomPhotoMapping) { + $propertyRoomPhoto[] = [ + 'photo_order' => $propertyRoomPhotoMapping['property_room_photo']['photo_order'], + 'is_default' => $propertyRoomPhotoMapping['property_room_photo']['is_default'], + 'photoUrl' => $propertyRoomPhotoMapping['property_room_photo']['photoUrl'], + ]; + } + $propertyRoomPhoto = collect($propertyRoomPhoto)->sortBy('photo_order')->toArray(); + + //dd($propertyRoomPhoto); + $propertyRoomPhoto = array_values($propertyRoomPhoto); + $propertyRoom[$propertyRooms['id']]['photo'] = $propertyRoomPhoto; + + //propertyRoomView + $propertyRoomView = null; + foreach ($propertyRooms['property_room_view_mapping'] as $propertyRoomViewMapping) { + $propertyRoomView[] = [ + 'name' => __($propertyRoomViewMapping['property_room_view_type']['language_key'],[],$params['locale']), + ]; + } + $propertyRoom[$propertyRooms['id']]['view'] = $propertyRoomView; + + } + + $propertyRoom = array_values($propertyRoom); + + + //propertyPlace + $propertyPlace = []; + foreach ($property['property_place'] as $propertyPlaces) { + + + //$description + $description = null; + $descriptionArray = json_decode($propertyPlaces['description'], 1); + $description = isset($descriptionArray[$params['locale']]) ? $descriptionArray[$params['locale']] : null; + + + //propertyPlaceFact + $propertyPlaceFact = null; + foreach ($propertyPlaces['property_place_fact_mapping'] as $propertyPlaceFactMapping) { + $propertyPlaceFact[$propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact_title']['id']]['name'] = __($propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact_title']['language_key']); + $propertyPlaceFact[$propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact_title']['id']]['fact'][$propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact']['id']] = [ + 'name' => __($propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact']['language_key'],[],$params['locale']), + 'icon' => $propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact']['icon'], + ]; + $propertyPlaceFact[$propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact_title']['id']]['fact'] = array_values($propertyPlaceFact[$propertyPlaceFactMapping['property_place_fact_title_fact_mapping']['place_fact_title']['id']]['fact']); + } + $propertyPlaceFact = collect($propertyPlaceFact)->sortBy('order_number')->toArray(); + $propertyPlaceFact = array_values($propertyPlaceFact); + + + //propertyPlaceFact + $propertyPlaceField = null; + foreach ($propertyPlaces['property_place_category_field_value'] as $propertyPlaceCategoryField) { + $propertyPlaceField[] = [ + 'id' => $propertyPlaceCategoryField['place_category_field']['id'], + 'name' => __($propertyPlaceCategoryField['place_category_field']['language_key'],[],$params['locale']), + 'element' => $propertyPlaceCategoryField['place_category_field']['element'], + 'input_value' => $propertyPlaceCategoryField['input_value'], + 'option_value' => $propertyPlaceCategoryField['option_value'], + 'unit' => isset($propertyPlaceCategoryField['unit_value']) ? __($propertyPlaceCategoryField['unit_value']['language_key'],[],$params['locale']) : null, + 'unit_short_name' => isset($propertyPlaceCategoryField['unit_value']) ? $propertyPlaceCategoryField['unit_value']['short_name'] : null, + ]; + } + + //propertyPlacePhoto + $propertyPlacePhoto= null; + foreach ($propertyPlaces['property_place_photo_mapping'] as $propertyPlacePhotoMapping) { + $propertyPlacePhoto[] = [ + 'photo_order' => $propertyPlacePhotoMapping['property_place_photo']['photo_order'], + 'is_default' => $propertyPlacePhotoMapping['property_place_photo']['is_default'], + 'photoUrl' => $propertyPlacePhotoMapping['property_place_photo']['photoUrl'], + ]; + } + $propertyPlacePhoto = collect($propertyPlacePhoto)->sortBy('photo_order')->toArray(); + $propertyPlacePhoto = array_values($propertyPlacePhoto); + + + + $propertyPlace[$propertyPlaces['id']] = [ + 'name' => $propertyPlaces['name'], + 'category' => __($propertyPlaces['property_place_category']['language_key'],[],$params['locale']), + 'description' => $description, + 'field' => $propertyPlaceField, + 'fact' => $propertyPlaceFact, + 'photo' => $propertyPlacePhoto + ]; + + + } + + $propertyPlace = array_values($propertyPlace); + + + $factSheetData = [ + 'id' => $property['id'], + 'name' => $property['name'], + 'booking_engine_token' => isset($property['property_booking_engine_token']['token']) ? $property['property_booking_engine_token']['token'] : null, + 'property_type' => __(fillOnUndefined($property['property_type'], 'language_key'),[],$params['locale']), + 'property_chain' => __(fillOnUndefined($property['property_chain'], 'name'),[],$params['locale']), + 'property_brand' => [ + 'logoUrl' => $property['property_brand']['logoUrl'], + 'colorCodes' => $colorCodes, + 'summary' => $summary + ], + 'property_contact' => [ + 'country' => $property['country'], + 'address' => $property['property_contact']['address'], + 'zip_code' => $property['property_contact']['zip_code'], + 'latitude' => $property['property_contact']['latitude'], + 'longitude' => $property['property_contact']['longitude'], + 'phone' => $property['property_contact']['view_full_phone'], + 'mobile' => $property['property_contact']['view_full_mobile'], + 'fax' => $property['property_contact']['view_full_fax'], + 'email' => $property['property_contact']['email'], + 'web' => $property['property_contact']['web'], + ], + 'property_executive' => $propertyExecutive, + 'property_awards_certificates' => $propertyAwardsCertificate, + 'property_fact' => $propertyFact, + 'property_photo' => $propertyPhoto, + 'property_room' => $propertyRoom, + 'property_place' => $propertyPlace, + 'additional_info' => $propertyAdditionalInfo + + ]; + + $response = [ + 'status' => true, + 'data' => $factSheetData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PermissionGroupService.php b/app/Core/Service/PermissionGroupService.php new file mode 100644 index 0000000..54b19c1 --- /dev/null +++ b/app/Core/Service/PermissionGroupService.php @@ -0,0 +1,28 @@ +permissionGroupRepository = $permissionGroupRepository; + } + + public function findByCriteria($param) + { + return $this->permissionGroupRepository->findByCriteria($param); + } + + public function findAll() + { + return $this->permissionGroupRepository->all(); + } +} diff --git a/app/Core/Service/PermissionGroupUserMappingService.php b/app/Core/Service/PermissionGroupUserMappingService.php new file mode 100644 index 0000000..1ad733e --- /dev/null +++ b/app/Core/Service/PermissionGroupUserMappingService.php @@ -0,0 +1,49 @@ +permissionGroupUserMappingRepository = $permissionGroupUserMappingRepository; + } + + public function findByCriteria ( array $params ) + { + return $this->permissionGroupUserMappingRepository->findByCriteria($params); + } + + public function updateOrCreate(array $criteria,array $saveData) + { + return $this->permissionGroupUserMappingRepository->updateOrCreate($criteria, $saveData); + } + + public function delete($param) + { + return $this->permissionGroupUserMappingRepository->delete($param); + } + + public function create ( array $param ) + { + return $this->permissionGroupUserMappingRepository->create($param); + } + + public function createAll ( array $param ) + { + return $this->permissionGroupUserMappingRepository->createAll ( $param ); + } + + public function update ( $id, $saveData ) + { + return $this->permissionGroupUserMappingRepository->update($id,$saveData); + + } + +} diff --git a/app/Core/Service/PermissionService.php b/app/Core/Service/PermissionService.php new file mode 100644 index 0000000..3fdbc07 --- /dev/null +++ b/app/Core/Service/PermissionService.php @@ -0,0 +1,181 @@ +permissionRepository = $permissionRepository; + $this->permissionGroupUserMappingRepository = $permissionGroupUserMappingRepository; + $this->permissionGroupMappingRepository = $permissionGroupMappingRepository; + $this->userService = $userService; + } + + public function findByCriteria ( array $params ) + { + return $this->permissionRepository->findByCriteria ( $params ); + } + + public function getPermissionMenuModelWithCriteria ( array $params ) + { + return $this->permissionRepository->permissionMenuModelFindByCriteria ( $params ); + } + + public function getMenuTreeForUser ( $params) + { + try + { + + $user_id = fillOnUndefined($params, 'user_id'); + $property_id = fillOnUndefined($params, 'property_id'); + $locale = fillOnUndefined($params,'locale', 'en'); + + $isAdmin = false; + $groupUserMappingCriteria = + [ + "criteria" => + [ + [ "field" => "user_id", "condition" => "=", "value" => $user_id ], + [ "field" => "property_id", "condition" => "=", "value" => $property_id ], + [ "field" => "status", "condition" => "=", "value" => 1 ] + ], + "with" => [ "permissionGroup" ] + ]; + $groupUserMapping = $this->permissionGroupUserMappingRepository->findByCriteria ( $groupUserMappingCriteria ); + $groupIds = pickItemFromArray ( "permission_group_id", $groupUserMapping ); + + + foreach ($groupUserMapping as $perMapping) + { + if ($perMapping[ "permission_group" ][ "is_admin" ]) + { + $isAdmin = true; + $groupIds = [ ]; + } + } + + $permissionIds = [ ]; + if ($groupIds) + { + $groupMappingCriteria = + [ + "whereIn" => + [ + [ "field" => "permission_group_id", "value" => $groupIds ] + ], + ]; + $groupMapping = $this->permissionGroupMappingRepository->findByCriteria ( $groupMappingCriteria ); + $permissionIds = pickItemFromArray ( "permission_id", $groupMapping ); + } + + $permissionMenuCriteria = + [ + "criteria" => + [ + [ "field" => "parent_id", "condition" => "=", "value" => null ] + ], + "orderBy" => [ [ "field" => "menu_order", "value" => "ASC" ] ], + "withCriteria" => + [ + [ + "method" => "children", + "whereIn" => + [ + [ "field" => "id", "value" => $permissionIds ] + ], + "orderBy" => + [ + [ "field" => "menu_order", "value" => "ASC" ] + ] + ] + ] + ]; + + + if ($permissionIds) + { + $permissionMenuCriteria[ "whereIn" ] = + [ + [ "field" => "id", "condition" => "=", "value" => $permissionIds ] + ]; + } + else + { + $userInfo = $this->userService->findUser($user_id); + if(!$userInfo["isSuperUser"] && !$isAdmin) + { + return []; + } + $permissionMenuCriteria['withCriteria'][] = + [ + "method" => "children", + "orderBy" => + [ + [ "field" => "menu_order", "value" => "ASC" ] + ] + ]; + } + + $permissionMenu = $this->getPermissionMenuModelWithCriteria ( $permissionMenuCriteria ); + $reDesignMenu = [ + 'permission_menu' => $permissionMenu, + 'locale' => $locale + ]; + + return $this->designPermissionMenu($reDesignMenu); + + } catch ( Exception $e ) + { + return [ ]; + } + } + + public function designPermissionMenu($params){ + try{ + $return = []; + $permissionMenu = fillOnUndefined($params , 'permission_menu', []); + $locale = fillOnUndefined($params , 'locale'); + foreach ($permissionMenu as $param){ + $menu = collect($param); + $filtered = $menu->only('id', 'name', 'code', 'children', 'component', 'menu_order','url')->toArray(); + if(!empty($filtered['children'])){ + $reDesignMenu = [ + 'permission_menu' => $filtered['children'], + 'locale' => $locale, + ]; + $filtered['children'] = $this->designPermissionMenu($reDesignMenu); + } + + + $return[] = $filtered ; + } + return $return ; + + }catch ( Exception $e ) + { + return [ ]; + } + } + +} diff --git a/app/Core/Service/ProductParameterMappingService.php b/app/Core/Service/ProductParameterMappingService.php new file mode 100644 index 0000000..fa15b39 --- /dev/null +++ b/app/Core/Service/ProductParameterMappingService.php @@ -0,0 +1,43 @@ +productParameterMappingRepository = $productParameterMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->productParameterMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/ProductService.php b/app/Core/Service/ProductService.php new file mode 100644 index 0000000..168112f --- /dev/null +++ b/app/Core/Service/ProductService.php @@ -0,0 +1,263 @@ +productRepository = $productRepository; + $this->propertyProductMappingService = $propertyProductMappingService; + $this->productParameterMappingService = $productParameterMappingService; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->productRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyProducts($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $productCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [] + ]; + + $products = $this->select($productCriteria); + + + if ($products['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $productsCollection = collect($products['data']); + + $propertyProductMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyProductMappingData = $this->propertyProductMappingService->select($propertyProductMappingCriteria); + if ($propertyProductMappingData['status'] != 'success') { + throw new ApiErrorException(lang('Property Product data not loaded')); + } + + $propertyProductMappingData = $propertyProductMappingData['data'] ? $propertyProductMappingData['data'] : []; + + $propertyProductMappingDataCollection = collect($propertyProductMappingData); + + $productParameterMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parameterDetail'] + ]; + + $productParameterMappingData = $this->productParameterMappingService->select($productParameterMappingCriteria); + $productParameterMappingDataCollection = collect($productParameterMappingData['data'] ?? []); + + $propertyProducts = []; + foreach ($products['data'] as $product) { + + $productParameterArray = null; + $productMappingDetail = $propertyProductMappingDataCollection->where('product_id', $product['id'])->first(); + if (isset($productMappingDetail['parameterArray']) && !empty($productMappingDetail['parameterArray'])) { + $productParameterArray = $productMappingDetail['parameterArray']; + } + + $propertyProducts[$product['id']] = $product; + $propertyProducts[$product['id']]['property_has_product'] = count($propertyProductMappingDataCollection->where('product_id', $product['id'])->toArray()) ? true : false; + $propertyProducts[$product['id']]['parameterArray'] = $productParameterArray; + $propertyProducts[$product['id']]['parameters'] = $productParameterMappingDataCollection + ->where('product_id', $product['id']) + ->values() + ->map(function ($item) { + return [ + 'product_parameter_id' => $item['product_parameter_id'] ?? null, + 'is_selected' => $item['is_selected'] ?? null, + 'value' => $item['value'] ?? null, + 'unit' => $item['unit'] ?? null, + 'parameter_detail' => isset($item['parameterDetail']) ? [ + 'id' => $item['parameterDetail']['id'] ?? null, + 'name' => $item['parameterDetail']['name'] ?? null, + ] : (isset($item['parameter_detail']) ? [ + 'id' => $item['parameter_detail']['id'] ?? null, + 'name' => $item['parameter_detail']['name'] ?? null, + ] : null) + ]; + })->all(); + } + + $response = [ + 'status' => true, + 'data' => $propertyProducts, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function setDefaultPropertyProducts($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $productCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'id', 'value' => [1, 4, 5]] + //['field' => 'id', 'value' => [1, 2, 3, 4, 5, 6]] + ], + 'with' => [] + ]; + + $products = $this->select($productCriteria); + if ($products['status'] != 'success') { + throw new ApiErrorException(lang('Products data not loaded')); + } + + + $createParam['property_id'] = fillOnUndefined($params, 'property_id'); + foreach ($products['data'] as $product) { + $createParam['products'][] = [ + 'product_id' => fillOnUndefined($product, 'id') + ]; + + } + + $setProducts = $this->propertyProductMappingService->create($createParam); + if ($setProducts['status'] != 'success') { + throw new ApiErrorException($setProducts['message']); + } + + $response = [ + 'status' => true, + 'data' => $products['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function propertyProductActivate($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $productCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['product_id']], + ], + 'firstRow' => true + ]; + + $productCheck = $this->select($productCriteria); + if ($productCheck['status'] != 'success') { + throw new ApiErrorException(lang('Products data not loaded')); + } + + + $createParam['property_id'] = fillOnUndefined($params, 'property_id'); + + $createParam['products'][] = [ + 'product_id' => fillOnUndefined($params, 'product_id'), + 'expiration_date' => Carbon::now()->addMonth()->toDateString(), + 'amount' => fillOnUndefined($params, 'amount'), + 'currency' => fillOnUndefined($params, 'currency'), + ]; + + $setProducts = $this->propertyProductMappingService->create($createParam); + if ($setProducts['status'] != 'success') { + throw new ApiErrorException($setProducts['message']); + } + + $response = [ + 'status' => true, + 'data' => $setProducts['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyAdditionalInfo/PropertyAdditionalInfoService.php b/app/Core/Service/PropertyAdditionalInfo/PropertyAdditionalInfoService.php new file mode 100644 index 0000000..6062f1f --- /dev/null +++ b/app/Core/Service/PropertyAdditionalInfo/PropertyAdditionalInfoService.php @@ -0,0 +1,470 @@ +propertyAdditionalInfoRepository = $additionalInfoRepository; + $this->propertyAdditionalInfoKeyRepository = $additionalInfoKeyRepository; + $this->generalTimezoneRepository = $generalTimezoneRepository; + } + + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyAdditionalInfoRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "additional_info_key_id" => fillOnUndefined($param, "additional_info_key_id"), + "value" => fillOnUndefined($param, "value"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + + ]; + + + /* + $validationResult = $this->propertyExecutiveCreateValidator->validate($insertData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + */ + + + $userCreateResult = $this->propertyAdditionalInfoRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyAdditionalInfoRepository->update($id, $param); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + + + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + /** + * @param array $params property_id and locale code + * + */ + public function getPropertyAdditionalInfo($params) + { + try { + $locale = $params['locale']; + $propertyId = $params['property_id']; + + $getPropertyAdditionalInfoKeyCriteria = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + $getPropertyAdditionalInfoKey = $this->propertyAdditionalInfoKeyRepository->findByCriteria($getPropertyAdditionalInfoKeyCriteria, ['id', 'additional_info_key']); + $getPropertyAdditionalInfoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + $getPropertyAdditionalInfo = $this->propertyAdditionalInfoRepository->findByCriteria($getPropertyAdditionalInfoCriteria); + $getPropertyAdditionalInfoHasInfoKey = collect($getPropertyAdditionalInfo)->keyBy('additional_info_key_id')->toArray(); + + $filteredPropertyAdditionalInfo = []; + foreach ($getPropertyAdditionalInfoKey as $key => $propertyAdditionalInfoKeys) { + $value = null; + $additionalId = null; + + $additionalId = $propertyAdditionalInfoKeys['id']; + if (array_key_exists($additionalId, $getPropertyAdditionalInfoHasInfoKey)) { + $value = $getPropertyAdditionalInfoHasInfoKey[$additionalId]['value']; + } + + $filteredPropertyAdditionalInfo[$additionalId] = + [ + 'id' => $additionalId, + 'name' => $propertyAdditionalInfoKeys['additional_info_key'], + 'value' => $value, + ]; + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $filteredPropertyAdditionalInfo; + return output($response); + } + + /** + * @param array $params + * @param string $locale 'en','tr', etc.. + * @return array + */ + + public function insertPropertyAdditionalInfo($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + $responseData = $params['data']; + $insertPropertyAdditionalInfoData = []; + + foreach ($responseData as $perData) { + $insertPropertyAdditionalInfoData[] = + [ + 'property_id' => $params['property_id'], + 'additional_info_key_id' => $perData['additional_info_key_id'], + 'value' => $perData['value'], + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + } + + $response = $this->propertyAdditionalInfoRepository->createAll($insertPropertyAdditionalInfoData); + + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => '']; + + + } catch (ApiErrorException $e) { + $response = ['status' => 0, 'statusCode' => 500, 'message' => $e->getMessage(), 'data' => null]; + } catch (Exception $e) { + + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return output($response); + + } + + public function updatePropertyAdditionalInfo($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + $responseData = $params['data']; + $updatePropertyAdditionalInfoData = []; + $responseDataCount = count($responseData); + $countOfUpdatedData = 0; + //TODO : update'i gerçekleştirilmeyen datanında bildirilmesi gerekiyor. + foreach ($responseData as $perData) { + $id = $perData['id']; + + $updatePropertyAdditionalInfoData = + [ + 'property_id' => $params['property_id'], + 'additional_info_key_id' => $perData['additional_info_key_id'], + 'value' => $perData['value'], + 'updated_by' => $params['user_id'], + ]; + + $update = $this->propertyAdditionalInfoRepository->update($id, $updatePropertyAdditionalInfoData); + if ($update['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + if ($update['status'] === "success" && !empty($update['data'])) { + $countOfUpdatedData++; + } + } + + + if ($countOfUpdatedData != $responseDataCount) { + throw new ApiErrorException(lang('Your update did not take place!')); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => '']; + + + } catch (ApiErrorException $e) { + $response = ['status' => 0, 'statusCode' => 500, 'message' => $e->getMessage(), 'data' => null]; + } catch (Exception $e) { + + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return output($response); + } + + public function updateOrCreatePropertyAdditionalInfo($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + + + // Get All Keys + $getPropertyAdditionalKeyCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $getPropertyAdditionalKeyResponse = $this->propertyAdditionalInfoKeyRepository->findByCriteria($getPropertyAdditionalKeyCriteria, ['id', 'additional_info_key']); + $getPropertyAdditionalKeyResponse = $getPropertyAdditionalKeyResponse ? $getPropertyAdditionalKeyResponse : []; + $keyArray = collect($getPropertyAdditionalKeyResponse)->keyBy('additional_info_key')->all(); + + // get all property additional info + $propertyAdditionalInfoRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $propertyAdditionalInfoResponse = $this->select($propertyAdditionalInfoRequest); + if ($propertyAdditionalInfoResponse['status'] != 'success') { + throw new ApiErrorException(lang('Additional Data Not Loaded')); + } + $propertyAdditionalInfoCollection = collect($propertyAdditionalInfoResponse['data']); + foreach ($params['additional_info'] as $key => $value) { + + if (!isset($keyArray[$key])) { + continue; + } + + if (!isset($keyArray[$key])) { + throw new ApiErrorException($key . ' not found'); + } + + $value = $value != null ? $value : ""; + + + $additionalInfoCheck = $propertyAdditionalInfoCollection + ->where('additional_info_key_id', '=', $keyArray[$key]['id']) + ->first(); + /* + $kvkkKeys = ['kvkk_mersis_no', 'kvkk_data_controller', 'kvkk_contact_person']; + if(in_array($key, $kvkkKeys)){ + if($value === "" || $value === NULL){ + continue; + } + } + */ + if ($additionalInfoCheck) { + $updateData = [ + 'value' => $value, + 'updated_by' => $params['user_id'], + 'status' => 1, + ]; + $updateStatus = $this->update($additionalInfoCheck['id'], $updateData); + + if ($updateStatus['status'] != 'success') { + throw new Exception($updateStatus['message']); + } + + } else { + $createData = [ + 'property_id' => $params['property_id'], + 'additional_info_key_id' => $keyArray[$key]['id'], + 'value' => $value, + 'updated_by' => $params['user_id'], + 'created_by' => $params['user_id'], + ]; + $createStatus = $this->create($createData); + if ($createStatus['status'] != 'success') { + throw new Exception($createStatus['message']); + } + } + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => '']; + + + } catch (ApiErrorException $e) { + $response = ['status' => 0, 'statusCode' => 500, 'message' => $e->getMessage(), 'data' => null]; + } catch (Exception $e) { + + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return output($response); + } + + public function getPropertyAdditionalInfo2KeyBy($params) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + $getPropertyAdditionalKeyCriteria = [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $getPropertyAdditionalKeyResponse = $this->propertyAdditionalInfoKeyRepository->findByCriteria($getPropertyAdditionalKeyCriteria, ['id', 'additional_info_key']); + $getPropertyAdditionalKeyResponse = $getPropertyAdditionalKeyResponse ? $getPropertyAdditionalKeyResponse : []; + + $getPropertyAdditionalInfoCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $getPropertyAdditionalInfoResponse = $this->propertyAdditionalInfoRepository->findByCriteria($getPropertyAdditionalInfoCriteria, ['id', 'additional_info_key_id', 'value']); + $getPropertyAdditionalInfoResponse = $getPropertyAdditionalInfoResponse ? $getPropertyAdditionalInfoResponse : []; + $getPropertyAdditionalInfoResponse = collect($getPropertyAdditionalInfoResponse)->keyBy('additional_info_key_id')->all(); + + $newMap = []; + foreach ($getPropertyAdditionalKeyResponse as $keyItem) { + $newMap[$keyItem['additional_info_key']] = isset($getPropertyAdditionalInfoResponse[$keyItem['id']]) ? $getPropertyAdditionalInfoResponse[$keyItem['id']]['value'] : null; + + //property_timezone + if ($keyItem['additional_info_key'] == 'property_timezone') { + $generalTimezoneRepositoryCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $getPropertyAdditionalInfoResponse[$keyItem['id']]['value']], + ], + 'firstRow' => true + ]; + $propertyTimeZoneDetail = $this->generalTimezoneRepository->findByCriteria($generalTimezoneRepositoryCriteria, ['location', 'action_type', 'hour', 'minute']); + $newMap['property_timezone_detail'] = $propertyTimeZoneDetail ?? null; + } + } + + $response = ['status' => true, 'data' => $newMap]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function deletePropertyAdditionalInfos($params) + { + + $keyIdCriteria = [ + 'whereIn' => + [ + ['field' => 'additional_info_key', 'value' => $params['key_array']], + ], + ]; + $keyData = $this->propertyAdditionalInfoKeyRepository->findByCriteria($keyIdCriteria); + $keyIds = collect($keyData)->keyBy('id')->keys(); + + $propertyExecutiveDeleteRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'whereIn' => [ + ['field' => 'additional_info_key_id', 'value' => $keyIds], + ] + ]; + + $this->propertyAdditionalInfoRepository->delete($propertyExecutiveDeleteRequest); + + } + +} diff --git a/app/Core/Service/PropertyAddonService.php b/app/Core/Service/PropertyAddonService.php new file mode 100644 index 0000000..0fe3178 --- /dev/null +++ b/app/Core/Service/PropertyAddonService.php @@ -0,0 +1,205 @@ +propertyAddonRepository = $propertyAddonRepository; + $this->propertyChannelAddonRepository = $propertyChannelAddonRepository; + $this->propertyAddonValidator = $propertyAddonValidator; + } + + public function selectPropertyChannelAddon($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelAddonRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyChannelAddon($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyAddonValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = [ + "title" => fillOnUndefined($param, "title"), + 'description' => fillOnUndefined($param, 'description'), + "property_id" => fillOnUndefined($param, "property_id"), + "channel_id" => fillOnUndefined($param, "channel_id"), + "property_addon_id" => fillOnUndefined($param, "property_addon_id"), + "amount" => fillOnUndefined($param, "amount"), + "type" => fillOnUndefined($param, "type", 'PRP'), + "min_stay" => fillOnUndefined($param, "min_stay"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertDataResult = $this->propertyChannelAddonRepository->create($insertData); + if ($insertDataResult['status'] != 'success') { + throw new Exception($insertDataResult['message']); + } + + $insertDataResult = $insertDataResult["data"]; + + $response = [ + 'status' => true, + 'data' => $insertDataResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function updatePropertyChannelAddon($id, $params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyAddonValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $updateParamAvailable = ['title','description','amount','type','min_stay','status','updated_by']; + foreach ($params as $key => $value) { + if(!in_array($key, $updateParamAvailable)) { + unset($params[$key]); + } + } + + $result = $this->propertyChannelAddonRepository->update($id, $params); + if ($result['status'] != 'success') { + throw new Exception($result['message']); + } + + $result = $result["data"]; + + $response = [ + 'status' => true, + 'data' => $result, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function deletePropertyChannelAddon($deleteThisId) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteThisId = is_array($deleteThisId) ? $deleteThisId : [$deleteThisId]; + $deleteThisArray = $this->propertyChannelAddonRepository->destroy($deleteThisId); + + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function selectPropertyAddon($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyAddonRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyAwardsCertificateService.php b/app/Core/Service/PropertyAwardsCertificateService.php new file mode 100644 index 0000000..e72faeb --- /dev/null +++ b/app/Core/Service/PropertyAwardsCertificateService.php @@ -0,0 +1,531 @@ +propertyAwardsCertificateRepository = $propertyAwardsCertificateRepository; + $this->awardsCertificateCategoryRepository = $awardsCertificateCategoryRepository; + $this->propertyAwardsCertificateCreateValidator = $propertyAwardsCertificateCreateValidator ; + $this->propertyAwardsCertificateUpdateValidator = $propertyAwardsCertificateUpdateValidator; + $this->propertyAwardCertificateUploadValidator = $propertyAwardCertificateUploadValidator; + $this->propertyRepository = $propertyRepository ; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyAwardsCertificateCreateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $filePath = null ; + $fileType = null ; + + if($params['file']){ + + // upload new image ... + $uploadFile = $this->uploadCertificate($params); + if ($uploadFile['status'] != 'success') { + throw new Exception($uploadFile['message']); + } + + $filePath = $uploadFile['data']['file_path'] ; + $fileType = $uploadFile['data']['file_type'] ; + + } + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'category_id' => fillOnUndefined($params, 'category_id'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'name' => fillOnUndefined($params, 'name'), + 'date' => fillOnUndefined($params, 'date'), + 'url' => fillOnUndefined($params, 'url'), + 'file_path' => $filePath, + 'file_type' => $fileType, + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $createResult = $this->propertyAwardsCertificateRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($params= [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyAwardsCertificateRepository->findByCriteria($params, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyAwardsCertificateUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $id = fillOnUndefined($params, 'award_certificate_id') ; + $filePath = null ; + $fileType = null ; + $deleteThisImage = null ; + + $requestCriteria = [ + 'criteria' => [ + // ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['award_certificate_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => 1, + ]; + $columns = ['id', 'property_id', 'category_id', 'name', 'date', 'url', 'file_path', 'file_type', 'status']; + $awardCertificate = $this->propertyAwardsCertificateRepository->findByCriteria($requestCriteria,$columns); + if (!$awardCertificate) { + throw new Exception('api-unknown_error'); + } + $fileUpdateData = []; + + if($params['file']){ + + // upload new image ... + $uploadFile = $this->uploadCertificate($params); + if ($uploadFile['status'] != 'success') { + throw new Exception($uploadFile['message']); + } + + $filePath = $uploadFile['data']['file_path'] ; + $fileType = $uploadFile['data']['file_type'] ; + + // set delete old image+++++++ + if($awardCertificate['file_path']){ + $urlPath = '/property-photos/' . $awardCertificate['property_id'] . "/awards-certificates/"; + $deleteThisImage = Config::get('app.fileSystemDriver') . $urlPath . $awardCertificate['file_path']; + } + $fileUpdateData = [ + 'file_path' => $filePath, + 'file_type' => $fileType, + ]; + } + + $updateData = [ + 'category_id' => fillOnUndefined($params, 'category_id'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'name' => fillOnUndefined($params, 'name'), + 'date' => fillOnUndefined($params, 'date'), + 'url' => fillOnUndefined($params, 'url'), + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time(), + ]; + $updateData = array_merge($updateData, $fileUpdateData) ; + + $updateResult = $this->propertyAwardsCertificateRepository->update($id, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + + if($deleteThisImage) { + if (File::exists($deleteThisImage)) { + File::delete($deleteThisImage); + } + } + + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getCategoryList($params= [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $requestCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'firstRow' => 1 + ]; + $columns = ['id', 'name', 'country']; + $property = $this->propertyRepository->findByCriteria($requestCriteria, $columns); + + $requestCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereOr' => [ + ['field' => 'country_code', 'condition' => '=', 'value' => $property['country']], + ['field' => 'country_code', 'condition' => '=', 'value' => null], + ], + 'orderBy' => [ + ["field" => "name", "value" => "ASC"], + ] + + ]; + $columns = ['id', 'name', 'language_key', 'country_code', 'logo', 'type', 'status']; + + $data = $this->awardsCertificateCategoryRepository->findByCriteria($requestCriteria,$columns); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function listAwardsCertificates($params= [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $requestCriteria = [ + 'criteria' => [ + // ['field' => 'status', 'condition' => '=', 'value' => 1] + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'with' => ['awardsCertificateCategory'] + ]; + $columns = ['id', 'property_id', 'category_id', 'name', 'language_code', 'date', 'url', 'file_path', 'file_type', 'status']; + $data = $this->propertyAwardsCertificateRepository->findByCriteria($requestCriteria,$columns); + + $responseData = collect($data)->map(function ($value){ + $return = $value ; + unset($return['awards_certificate_category']) ; + $image = null ; + + if($value['file_path']){ + $urlPath = '/property-photos/' . $value['property_id'] . "/awards-certificates/"; + $image = Config::get('app.imageUrl') . $urlPath . $value['file_path']; + } + + $return['file_path'] = $image ? $image : null ; + + $category = [ + 'category_name' => $value['awards_certificate_category']['name'], + 'category_language_key' => $value['awards_certificate_category']['language_key'], + 'category_country_code' => $value['awards_certificate_category']['country_code'], + 'category_logo' => $value['awards_certificate_category']['logo'], + 'category_type' => $value['awards_certificate_category']['type'], + 'category_status' => $value['awards_certificate_category']['status'], + ]; + return array_merge($return, $category) ; + })->values()->all() ; + + array_multisort( + array_column($responseData, 'category_name'), SORT_ASC, + array_column($responseData, 'id'), SORT_DESC, + $responseData + ); + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function uploadCertificate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + $fileParam = [] ; + $validateParams = [ + 'file' => $params['file'] + ]; + + $validationResult = $this->propertyAwardCertificateUploadValidator->validate($validateParams); + if ($validationResult->errors()->first()) { + throw new ApiErrorException($validationResult->errors()->all()); + } + + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . "/awards-certificates/"; + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + $uploadedFile = $params['file']; + $fileExt = $uploadedFile->getClientOriginalExtension(); + $fileName = time() . '_'. generateRandomString(10) . '.' . $fileExt; + $quality = 80 ; + + if(strtolower($fileExt) == 'pdf'){ + $move = $params['file']->move($filePath, $fileName); + if ($move) { + $fileParam = + [ + 'file_path' => $fileName, + 'file_type' => 'PDF', + ]; + } + }else{ + + $uploadedOriginalImage = Image::make($uploadedFile); + $imageWidth = $uploadedOriginalImage->width() ; + $imageHeight = $uploadedOriginalImage->height(); + + if ($imageHeight > $imageWidth) { + + if($imageHeight > 768){ + + $imageHRatio = $imageHeight / 768 ; + $imageResizedOriginalWidth = intval($imageWidth / $imageHRatio); + $image = $uploadedOriginalImage->fit($imageResizedOriginalWidth, 768)->save($filePath . $fileName , $quality) ; + }else{ + $image = $uploadedOriginalImage->save($filePath . $fileName , $quality) ; + } + + } else { + + if($imageWidth > 1024) { + $imageWRatio = $imageWidth / 1024 ; + $imageResizedOriginalHeight = intval($imageHeight / $imageWRatio); + $image = $uploadedOriginalImage->fit(1024, $imageResizedOriginalHeight)->save($filePath . $fileName , $quality) ; + }else{ + $image = $uploadedOriginalImage->save($filePath . $fileName , $quality) ; + } + } + + $fileParam = + [ + 'file_path' => $fileName, + 'file_type' => 'IMG', + ]; + $uploadedOriginalImage->destroy(); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $fileParam]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function deletePhotoAwardsCertificates($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $requestCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['award_certificate_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => 1, + ]; + $columns = ['id', 'property_id', 'category_id', 'name', 'date', 'url', 'file_path', 'file_type', 'status']; + $awardCertificate = $this->propertyAwardsCertificateRepository->findByCriteria($requestCriteria,$columns); + if (!$awardCertificate) { + throw new Exception('api-unknown_error'); + } + + $urlPath = '/property-photos/' . $awardCertificate['property_id'] . "/awards-certificates/"; + $deleteThisImage = Config::get('app.fileSystemDriver') . $urlPath . $awardCertificate['file_path']; + + if($deleteThisImage) { + if (File::exists($deleteThisImage)) { + File::delete($deleteThisImage); + } + } + + $id = $awardCertificate['id'] ; + $updateData = [ + 'file_path' => null, + 'file_type' => null, + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyAwardsCertificateRepository->update($id, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateStatus($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $updateId = fillOnUndefined($param, "award_certificate_id") ; + $placeRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => $updateId], + ] + ]; + $propertyWebData = $this->propertyAwardsCertificateRepository->findByCriteria($placeRequest, ['id', 'name']); + + if (!$propertyWebData) { + throw new Exception('api-unknown_error'); + } + + $updateData = + [ + "status" => fillOnUndefined($param, "set_status", 0), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyAwardsCertificateRepository->update($updateId, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyBookingEngineSearchService.php b/app/Core/Service/PropertyBookingEngineSearchService.php new file mode 100644 index 0000000..f8d6d41 --- /dev/null +++ b/app/Core/Service/PropertyBookingEngineSearchService.php @@ -0,0 +1,163 @@ +propertyBookingEngineSearchRepository = $propertyBookingEngineSearchRepository; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'search_key' => fillOnUndefined($params, 'search_key'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'checkin_date' => fillOnUndefined($params, 'checkin_date'), + 'checkout_date' => fillOnUndefined($params, 'checkout_date'), + 'pax' => fillOnUndefined($params, 'pax'), + 'rooms' => fillOnUndefined($params, 'rooms'), + 'booking_code' => fillOnUndefined($params, 'booking_code'), + 'amount' => fillOnUndefined($params, 'best_amount'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'ip_address' => fillOnUndefined($params, 'ip_address'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'language_code' => fillOnUndefined($params, 'language_code', 'en'), + 'detail' => fillOnUndefined($params, 'detail'), + 'referrer' => fillOnUndefined($params, 'referrer'), + 'status' => fillOnUndefined($params, 'status', 3), + ]; + + $createResult = $this->propertyBookingEngineSearchRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $createResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyBookingEngineSearchRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyBookingEngineSearchRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->propertyBookingEngineSearchRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyBookingEngineService.php b/app/Core/Service/PropertyBookingEngineService.php new file mode 100644 index 0000000..679665b --- /dev/null +++ b/app/Core/Service/PropertyBookingEngineService.php @@ -0,0 +1,288 @@ +propertyBookingEngineRepository = $propertyBookingEngineRepository; + $this->propertyChannelRepository = $propertyChannelRepository; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->contractUploadValidator = $contractUploadValidator; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyBookingEngineRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + + public function createBookingEngineToken($params = []){ + + $response = ['status' => "success", 'message' => '', 'data' => null]; + + try { + if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) { + + $data = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "token" => getGuid(), + "status" => 1, + "created_by" => $params['created_by'], + "updated_by" => $params['updated_by'], + "created_at" => time(), + "updated_at" => time(), + ]; + + $create = $this->propertyBookingEngineRepository->create($data); + if ($create['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + log:info("createBookingEngineToken",[$response]); + return output($response); + + } + + public function reactivateBookingEngineToken($params = []){ + + log:info("reactivateBookingEngineToken",[]); + $response = ['status' => "success", 'message' => '', 'data' => null]; + + try { + + if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) { + $updateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ] + ]; + + $updateData = [ + "status" => 1, + 'updated_by' => $params["updated_by"], + 'updated_at' => time(), + ]; + + $update = $this->propertyBookingEngineRepository->updateWhere($updateCriteria, $updateData); + if ($update['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deactivateBookingEngineToken($params = []){ + + log:info("reactivateBookingEngineToken",[]); + $response = ['status' => "success", 'message' => '', 'data' => null]; + + try { + + if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) { + $updateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ] + ]; + + $updateData = [ + "status" => 0, + 'updated_by' => $params["updated_by"], + 'updated_at' => time(), + ]; + + $update = $this->propertyBookingEngineRepository->updateWhere($updateCriteria, $updateData); + if ($update['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function bookEngineDashboard($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property.propertyBookingEngineGroupMapping.propertyGroup.propertyGroupMapping.property.propertyBookingEngineToken', 'propertyWeb'], + 'firstRow' => 1 + ] ; + $propertyBookingEngine = $this->select($propertyRequest, ['id', 'property_id', 'channel_id', 'token']); + if ($propertyBookingEngine['status'] != 'success') { + throw new ApiErrorException($propertyBookingEngine['message']); + } + + $propertyBookingEngine = $propertyBookingEngine['data'] ; + + $channelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ] ; + $propertyChannelMapping = $this->propertyChannelMappingRepository->findByCriteria($channelMappingRequest, ['id', 'property_id', 'channel_id']); + + $response = [ + 'is_booking_engine_active' => isset($propertyBookingEngine['token'] ) && $propertyChannelMapping , + 'booking_engine_url' => isset($propertyBookingEngine['token'] ) ? Config::get('app.bookingEngineUrl').'/'.$propertyBookingEngine['token'] : null, + 'token' => isset($propertyBookingEngine['token']) ? $propertyBookingEngine['token'] : null, + + ]; + + + + + + $response = [ + 'status' => true, + 'data' => $response, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function contractFileUpload($params = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->contractUploadValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $uploadResponse = [] ; + if($params['contract_file']){ + + $public_dir = Config::get('app.fileSystemDriver'); + $filePath = $public_dir . '/property-files/'.$params['property_id'].'/be'; + $filePathResponse = $params['property_id'].'/be/'; + + $contractFile = $params['contract_file']; + $newFileName = $params['property_id'] . '_'.$params['channel_id'].'_contract.pdf'; + + $propertyFilesUrl = Config::get('app.propertyFilesUrl'); + + $createFile = $contractFile->move($filePath, $newFileName); + if($createFile){ + $uploadResponse['contract_file_url'] = $propertyFilesUrl.$filePathResponse.$newFileName; + $uploadResponse['contract_file_path'] = $filePathResponse.$newFileName; + } + } + + $response = ['status' => 1, 'data' => $uploadResponse]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyBookingPaymentTypeService.php b/app/Core/Service/PropertyBookingPaymentTypeService.php new file mode 100644 index 0000000..3552f76 --- /dev/null +++ b/app/Core/Service/PropertyBookingPaymentTypeService.php @@ -0,0 +1,88 @@ +request = $request; + $this->propertyBookingPaymentTypeRepository = $propertyBookingPaymentTypeRepository; + + } + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyBookingPaymentTypeRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyBookingPaymentTypeList(){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $propertyBookingPaymentTypeListRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ] + ]; + + $propertyBookingPaymentTypeList = $this->select($propertyBookingPaymentTypeListRequest, ['id', 'name', 'language_key', 'code']); + + if(isset($propertyBookingPaymentTypeList['data'])){ + $return['booking_payment_types'] = $propertyBookingPaymentTypeList['data'] ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyBrandService.php b/app/Core/Service/PropertyBrandService.php new file mode 100644 index 0000000..6dab603 --- /dev/null +++ b/app/Core/Service/PropertyBrandService.php @@ -0,0 +1,500 @@ +propertyBrandRepository = $propertyBrandRepository; + $this->propertyPhotoRepository = $propertyPhotoRepository; + $this->propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository; + $this->propertyBrandAddValidator = $propertyBrandAddValidator; + $this->propertyBrandPhotoValidator = $propertyBrandPhotoValidator; + $this->languageService = $languageService; + } + + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyBrandRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyBrandRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyBrand($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyBrandAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $photoArray = []; + if ($params['photo']) { + $photoArray = $this->uploadBrandPhoto($params); + if ($photoArray['status'] != 'success') { + throw new ApiErrorException($photoArray['message']); + } + $photoArray = $photoArray['data']; + } + + $brandCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'firstRow' => 1 + + ]; + + $oldBrandData = $this->propertyBrandRepository->findByCriteria($brandCriteria); + + $checkPropertyBrand = [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + + ]; + + $brandColor = json_decode($params['color_codes'], true); + $colorCodes = trim($brandColor[0]['color_code']) === '' && trim($brandColor[1]['color_code']) === '' ? null : json_encode($brandColor, true); + + + $titles = []; + $titleArray = json_decode(fillOnUndefined($params, "title", []), 1); + + if (!empty($oldBrandData['title'])) { + $brandLanguages = (array)json_decode($oldBrandData['title'], 1); + + $arrDiffs = array_diff_key($brandLanguages, $titles); + + foreach ($arrDiffs as $key => $arrDiff) { + $titles[$key] = $arrDiff; + } + } + + foreach ($titleArray as $key => $arr) { + $titles[$arr['language_code']] = $arr['description']; + } + + + $insertData = + [ + "property_id" => fillOnUndefined($params, "property_id"), + "title" => json_encode($titles), + "color_codes" => $colorCodes, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + if ($photoArray) { + $insertData['logo_path'] = $photoArray['path']; + $insertData['logo_name'] = $photoArray['photo']; + $insertData['logo_file_ext'] = $photoArray['extension']; + } + + $propertyBrandResponse = $this->propertyBrandRepository->updateOrCreate($checkPropertyBrand, $insertData); + + + if ($propertyBrandResponse['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + if ($oldBrandData && $params['photo'] && $photoArray) { + $urlPath = '/property-photos/' . $oldBrandData['property_id'] . "/logo/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath; + $oldImage250px = $filePath . $oldBrandData['logo_name'] . '_250x250' . '.' . $oldBrandData['logo_file_ext']; + $oldImage750px = $filePath . $oldBrandData['logo_name'] . '_750x750' . '.' . $oldBrandData['logo_file_ext']; + if (File::exists($oldImage750px)) { + File::delete($oldImage750px); + } + if (File::exists($oldImage250px)) { + File::delete($oldImage250px); + } + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyBrandResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function uploadBrandPhoto($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $fileParam = []; + $validateParams = [ + 'photo' => $params['photo'] + ]; + + $validationResult = $this->propertyBrandPhotoValidator->validate($validateParams); + if ($validationResult->errors()->first()) { + throw new ApiErrorException($validationResult->errors()->all()); + } + + + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . "/logo/"; + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + + $uploadedFile = $params['photo']; + $imageResize = Image::make($uploadedFile); + $imageWidth = $imageResize->width(); + $imageHeight = $imageResize->height(); + if ($imageWidth < 200 && $imageHeight < 150) { + throw new ApiErrorException('image size error'); + } + + $fileExt = $uploadedFile->getClientOriginalExtension(); + $urlPath = '/property-photos/' . $params['property_id'] . "/logo/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath; + $fileName = time(); + + if ($imageWidth >= 750 || $imageHeight >= 750) { + if ($imageWidth >= $imageHeight) { + $imageResize->resize(750, null, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_750x750' . '.' . $fileExt); + + $imageResize->resize(250, null, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_250x250' . '.' . $fileExt); + } else { + $imageResize->resize(null, 750, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_750x750' . '.' . $fileExt); + $imageResize->resize(null, 250, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_250x250' . '.' . $fileExt); + + } + } else { + if ($imageWidth >= $imageHeight) { + $imageResize->save($filePath . $fileName . '_750x750' . '.' . $fileExt); + $imageResize->resize(250, null, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_250x250' . '.' . $fileExt); + } else { + $imageResize->save($filePath . $fileName . '_750x750' . '.' . $fileExt); + $imageResize->resize(null, 250, function ($constraint) { + $constraint->aspectRatio(); + })->save($filePath . $fileName . '_250x250' . '.' . $fileExt); + } + } + $imageResize->destroy(); + $fileParam = + [ + 'photo' => $fileName, + 'path' => $urlPath, + 'extension' => $fileExt, + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $fileParam]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function getPropertyBrand($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $requestBrand = [ + + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + + ], + 'firstRow' => 1 + ]; + + $getPropertyBrand = $this->select($requestBrand); + if ($getPropertyBrand['status'] != "success") { + throw new ApiErrorException($getPropertyBrand['message']); + } + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + $responseLangTitle = []; + + $brandLanguages = []; + if (!empty($getPropertyBrand['data']['title'])) { + $brandLanguages = (array)json_decode($getPropertyBrand['data']['title'], 1); + } + + if (!empty($getPropertyBrand['data'])) { + $brandColors = $getPropertyBrand['data']['color_codes']; + $getPropertyBrand = $getPropertyBrand['data']; + $getPropertyBrand['color_codes'] = json_decode($brandColors, true); + $getPropertyBrand['name'] = $getPropertyBrand['logo_name']; + $getPropertyBrand['logo_name'] = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . "/logo/" . $getPropertyBrand['logo_name'] . '_250x250.' . $getPropertyBrand['logo_file_ext']; + $brandTitle = fillOnUndefinedAndEmpty($getPropertyBrand, 'title', "[]"); + + $titleLangContents = json_decode($brandTitle, 1); + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangTitle[] = [ + 'language_code' => $langKey, + 'description' => isset($titleLangContents[$langKey]) ? $titleLangContents[$langKey] : null + ]; + } + $appLanguages = []; + foreach ($applicationLanguages as $applicationLanguage) { + $appLanguages[] = $applicationLanguage['code']; + } + + foreach ($appLanguages as $key => $appLanguage) { + if (in_array($appLanguage, array_keys($brandLanguages))) { + + $getPropertyBrand['title'] = $responseLangTitle; + } + } + + $getPropertyBrand['title'] = $responseLangTitle; + + } else { + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangTitle[] = [ + 'language_code' => $langKey, + 'description' => null + ]; + } + $getPropertyBrand = null; + $getPropertyBrand['title'] = $responseLangTitle; + $getPropertyBrand['color_codes'] = json_decode('[{"color_number":1,"color_code":"#000"},{"color_number":2,"color_code":"#000"}]'); + } + + + //Cover Photo + $coverPhoto = null; + $propertyWebPhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'is_cover', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyPhoto'], + 'orderBy' => [["field" => "updated_at", "value" => "ASC"]], + 'firstRow' => true + ]; + $propertyWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($propertyWebPhotoMappingRequest); + $propertyWebMappingPhotos = $propertyWebMappingPhotos ? $propertyWebMappingPhotos : []; + + if (!empty($propertyWebMappingPhotos)) { + $coverPhoto = $propertyWebMappingPhotos['property_photo']['photoUrl']['default']; + } else { + + $propertyDefaultPhotoRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'is_default', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + $propertyDefaultPhoto = $this->propertyPhotoRepository->findByCriteria($propertyDefaultPhotoRequest); + $propertyDefaultPhoto = $propertyDefaultPhoto ? $propertyDefaultPhoto : []; + + + if (!empty($propertyDefaultPhoto)) { + $coverPhoto = $propertyDefaultPhoto['photoUrl']['default']; + } + } + + $getPropertyBrand['cover_photo'] = empty($coverPhoto) ? 'https://api.extranetwork.com/assets/img/main-image.png' : $coverPhoto; + //Cover Photo + + $response = [ + 'status' => true, + 'data' => $getPropertyBrand, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function clearBrandLogo($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $requestBrand = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + + ], + 'firstRow' => 1 + ]; + + $getPropertyBrand = $this->select($requestBrand); + + if ($getPropertyBrand['status'] != "success") { + throw new ApiErrorException($getPropertyBrand['message']); + } + + if (empty($getPropertyBrand['data'])) { + throw new ApiErrorException("Property Not Found"); + } + + $brandId = $getPropertyBrand['data']['id']; + + $brandUpdateData = [ + "logo_path" => null, + "logo_name" => null, + "logo_file_ext" => null, + "updated_by" => fillOnUndefined($params, 'user_id'), + "updated_at" => time(), + ]; + + $updatedBrand = $this->update($brandId, $brandUpdateData); + + if (!empty($updatedBrand['data'])) { + $brandLogoPath = Config::get('app.fileSystemDriver') . $getPropertyBrand['data']['logo_path']; + $brandLogoName = $getPropertyBrand['data']['logo_name']; + $brandLogoExtension = $getPropertyBrand['data']['logo_file_ext']; + + $filename1 = $brandLogoPath . $brandLogoName . '_250x250' . '.' . $brandLogoExtension; + $filename2 = $brandLogoPath . $brandLogoName . '_750x750' . '.' . $brandLogoExtension; + + if (File::exists($filename1) && File::exists($filename2)) { + File::delete([$filename1, $filename2]); + } + } + + $response = [ + 'status' => true, + 'data' => $updatedBrand, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/PropertyCancellationPolicyService.php b/app/Core/Service/PropertyCancellationPolicyService.php new file mode 100644 index 0000000..8a22af9 --- /dev/null +++ b/app/Core/Service/PropertyCancellationPolicyService.php @@ -0,0 +1,572 @@ +request = $request; + $this->propertyCancellationPolicyRepository = $propertyCancellationPolicyRepository; + $this->propertyRoomRepository = $propertyRoomRepository; + $this->propertyChannelRoomRateCancellationPolicyMappingRepository = $propertyChannelRoomRateCancellationPolicyMappingRepository ; + $this->updateRoomRateChannelCancellationPolicyValidator = $updateRoomRateChannelCancellationPolicyValidator ; + $this->propertyCancellationPolicyAddValidator = $propertyCancellationPolicyAddValidator ; + $this->propertyCancellationPolicyUpdateValidator = $propertyCancellationPolicyUpdateValidator ; + + } + + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyCancellationPolicyRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "name" => fillOnUndefined($param, "name"), + 'before_arrival' => fillOnUndefined($param, "before_arrival"), + 'is_nonrefundable' => fillOnUndefined($param, "is_nonrefundable"), + 'is_free_cancellation' => fillOnUndefined($param, "is_free_cancellation"), + 'type' => fillOnUndefined($param, "type"), + 'value' => fillOnUndefined($param, "value"), + 'is_affected_price' => fillOnUndefined($param, "is_affected_price"), + 'affect_price_action_type' => fillOnUndefined($param, "affect_price_action_type"), + 'affect_price_type' => fillOnUndefined($param, "affect_price_type"), + 'affect_price_value' => fillOnUndefined($param, "affect_price_value"), + 'is_date_range' => fillOnUndefined($param, "is_date_range"), + 'start_date' => fillOnUndefined($param, "start_date"), + 'finish_date' => fillOnUndefined($param, "finish_date"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $propertyCreateResult = $this->propertyCancellationPolicyRepository->create($propertyData); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $data = Arr::except($propertyCreateResult["data"],['status','created_by','updated_by','created_at','updated_at']); + $response = [ + 'status' => true, + 'data' => $data + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyCancellationPolicyRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $data = Arr::except($updateData,['status','created_by','updated_by','created_at','updated_at']); + $response = [ + 'status' => true, + 'data' => $data + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyCancellationPolicyList($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyId = fillOnUndefined($params, 'property_id'); + $propertyCancellationPolicyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + + ], + ]; + $propertyCancellationPolicy = $this->propertyCancellationPolicyRepository->findByCriteria($propertyCancellationPolicyRequest, ['id', 'property_id', 'name', 'before_arrival', 'is_nonrefundable', 'is_free_cancellation', 'type','value', 'is_affected_price', 'affect_price_action_type', 'affect_price_type', 'affect_price_value', 'is_date_range', 'start_date', 'finish_date', 'status']); + + $propertyCancellationPolicy = $propertyCancellationPolicy ? $propertyCancellationPolicy : [] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyCancellationPolicy]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function createPropertyCancellationPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + DB::beginTransaction(); + + $validationResult = $this->propertyCancellationPolicyAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + if($params['is_nonrefundable']){ + $type = 'PER'; + $value = 100 ; + }elseif ($params['is_free_cancellation']){ + $type = 'PER'; + $value = 0 ; + }else{ + $type = $params['type'] ; + $value = $params['value'] ; + } + $createData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => isset($params['name']) && $params['name'] ? $params['name'] : null, + 'before_arrival' => $params['before_arrival'], + 'is_nonrefundable' => $params['is_nonrefundable'], + 'is_free_cancellation' => $params['is_free_cancellation'], + 'type' => $type, + 'value' => $value, + 'is_affected_price' => $params['affects_price'], + 'affect_price_action_type' => $params['affects_price_action_type'], + 'affect_price_type' => $params['affects_price_type'], + 'affect_price_value' => $params['affects_price_value'], + 'is_date_range' => $params['is_date_range'], + 'start_date' => fillOnUndefined($params, 'start_date'), + 'finish_date' => fillOnUndefined($params, 'finish_date'), + 'user_id' => fillOnUndefined($params, 'user_id'), + 'status' => 1, + ]; + + + $createResult = $this->create($createData); + + if($createResult['status'] != 'success'){ + throw new ApiErrorException($createResult['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResult['data']]; + + DB::commit(); + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyCancellationPolicy($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $validationResult = $this->propertyCancellationPolicyUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + if($params['is_nonrefundable']){ + $type = 'PER'; + $value = 100 ; + }elseif ($params['is_free_cancellation']){ + $type = 'PER'; + $value = 0 ; + }else{ + $type = $params['type'] ; + $value = $params['value'] ; + } + + $cancellationPolicyUpdateData = + [ + 'name' => isset($params['name']) && $params['name'] ? $params['name'] : null, + 'before_arrival' => $params['before_arrival'], + 'is_nonrefundable' => $params['is_nonrefundable'], + 'is_free_cancellation' => $params['is_free_cancellation'], + 'type' => $type, + 'value' => $value, + 'is_affected_price' => $params['affects_price'], + 'affect_price_action_type' => $params['affects_price_action_type'], + 'affect_price_type' => $params['affects_price_type'], + 'affect_price_value' => $params['affects_price_value'], + 'is_date_range' => $params['is_date_range'], + 'start_date' => fillOnUndefined($params, 'start_date'), + 'finish_date' => fillOnUndefined($params, 'finish_date'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'updated_at' => time() + ]; + + $cancellationPolicyId = fillOnUndefined($params, 'cancellation_policy_id'); + + $cancellationPolicyResult = $this->update($cancellationPolicyId, $cancellationPolicyUpdateData); + + if ($cancellationPolicyResult['status'] != 'success') { + throw new ApiErrorException(lang('Property Cancellation Policy data is not updated.')); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $cancellationPolicyResult['data']]; + + } catch(ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function getRoomRateChannelCancellationPolicy($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomRateMapping.propertyRoomRateChannel.propertyRoomRateChannelCancellationPolicy', 'propertyRoomRateMapping.propertyRoomRate'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'exclude_occupancy', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + $propertyCancellationPolicyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyCancellationPolicy = $this->propertyCancellationPolicyRepository->findByCriteria($propertyCancellationPolicyRequest, ['id', 'property_id', 'name', 'before_arrival', 'is_nonrefundable', 'is_free_cancellation', 'type','value', 'is_affected_price', 'affect_price_action_type', 'affect_price_type', 'affect_price_value', 'is_date_range', 'start_date', 'finish_date', 'status']); + + $return = []; + + foreach ($roomData as $room){ + + if($room['property_room_rate_mapping']){ + $item = $room; + $item['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + $roomRateMappings = $room['property_room_rate_mapping'] ; + $mapping = []; + $addedMapping = 0 ; + foreach ($roomRateMappings as $roomRateMapping){ + $propertyRoomRateChannel = null; + if(isset($roomRateMapping['property_room_rate_channel'])){ + $propertyRoomRateChannel = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('room_rate_mapping_id', '=', $roomRateMapping['id']) + ->first(); + } + + $mappingStatus = false ; + $propertyCancellationPolicyArray = [] ; + if($propertyRoomRateChannel){ + if ($propertyRoomRateChannel['status'] == 1) { + $mappingStatus = true; + foreach ($propertyCancellationPolicy as $cancellationPolicy) { + + $propertyRoomRateChannelCancellationPolicy = [] ; + if (isset($propertyRoomRateChannel['property_room_rate_channel_cancellation_policy'])) { + $propertyRoomRateChannelCancellationPolicy = collect($propertyRoomRateChannel['property_room_rate_channel_cancellation_policy']) + ->where('cancellation_policy_id', '=', $cancellationPolicy['id']) + ->where('room_rate_channel_mapping_id', '=', $propertyRoomRateChannel['id']) + ->values()->toArray(); + } + + $propertyCancellationPolicyArray[] = [ + 'id' => $cancellationPolicy['id'], + 'property_id' => $cancellationPolicy['property_id'], + 'name' => $cancellationPolicy['name'], + 'before_arrival' => $cancellationPolicy['before_arrival'], + 'is_nonrefundable' => $cancellationPolicy['is_nonrefundable'], + 'is_free_cancellation' => $cancellationPolicy['is_free_cancellation'], + 'type' => $cancellationPolicy['type'], + 'value' => $cancellationPolicy['value'], + 'is_affected_price' => $cancellationPolicy['is_affected_price'], + 'affect_price_action_type' => $cancellationPolicy['affect_price_action_type'], + 'affect_price_type' => $cancellationPolicy['affect_price_type'], + 'affect_price_value' => $cancellationPolicy['affect_price_value'], + 'is_date_range' => $cancellationPolicy['is_date_range'], + 'start_date' => $cancellationPolicy['start_date'], + 'finish_date' => $cancellationPolicy['finish_date'], + 'is_selected' => $propertyRoomRateChannelCancellationPolicy ? true : false , + ]; + } + + } + } + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['is_selected'] = $mappingStatus; + $roomRateMapping['has_date'] = $propertyRoomRateChannel['has_date'] == 0 ? false : true; + $roomRateMapping['end_date'] = $propertyRoomRateChannel['end_date']; + $roomRateMapping['start_date'] = $propertyRoomRateChannel['start_date']; + $roomRateMapping['room_rate_channel_mapping_id'] = $propertyRoomRateChannel['id']; + $roomRateMapping['room_rate_channel_cancellation_policy'] = $propertyCancellationPolicyArray; + + unset($roomRateMapping['property_room_rate']); + unset($roomRateMapping['property_room_rate_channel']); + if($mappingStatus){ + $addedMapping++; + $mapping[] = $roomRateMapping; + } + } + $item['property_room_rate_mapping'] = $mapping; + if($addedMapping > 0){ + $return[] = $item ; + } + } + + } + + $collection = collect($return); + $sorted = $collection->sortBy('id')->values()->all(); + + $response = [ + 'status' => true, + 'data' => $sorted, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateRoomRateChannelCancellationPolicy($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->updateRoomRateChannelCancellationPolicyValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyCancellationPolicy'] + ]; + + $propertyChannelRoomRateCancellationPolicyMapping = $this->propertyChannelRoomRateCancellationPolicyMappingRepository->findByCriteria($criteria); + $oldMappingData = collect($propertyChannelRoomRateCancellationPolicyMapping); + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['cancellation_policy_id']], + ], + 'firstRow' => 1 + ]; + + $mappedCancellationPolicy = $this->propertyCancellationPolicyRepository->findByCriteria($criteria); + if(!$mappedCancellationPolicy) { + throw new ApiErrorException('This Cancellation Policy not found'); + } + if ($params['is_selected'] == true) { + + $oldDataMappingCollect = collect($oldMappingData)->map(function ($value){ + return [ + 'id' => $value['id'] , + 'property_id' => $value['property_id'], + 'cancellation_policy_id' => $value['cancellation_policy_id'], + 'room_rate_channel_mapping_id' => $value['room_rate_channel_mapping_id'], + 'name' => $value['property_cancellation_policy']['name'] , + 'before_arrival' => $value['property_cancellation_policy']['before_arrival'], + 'is_nonrefundable' => $value['property_cancellation_policy']['is_nonrefundable'], + 'is_free_cancellation' => $value['property_cancellation_policy']['is_free_cancellation'], + 'type' => $value['property_cancellation_policy']['value'], + 'value' => $value['property_cancellation_policy']['type'], + 'is_affected_price' => $value['property_cancellation_policy']['is_affected_price'], + 'affect_price_action_type' => $value['property_cancellation_policy']['affect_price_action_type'], + 'affect_price_type' => $value['property_cancellation_policy']['affect_price_type'], + 'affect_price_value' => $value['property_cancellation_policy']['affect_price_value'], + ] ; + }); + + $checkHasMapping = $oldDataMappingCollect->where('cancellation_policy_id', '=', $params['cancellation_policy_id']) + ->where('room_rate_channel_mapping_id' ,'=', $params['room_rate_channel_mapping_id']) + ->where('property_id', '=', $params['property_id']) + ->first() ; + + $checkHasDay = $oldDataMappingCollect + ->where('before_arrival', '=', $mappedCancellationPolicy['before_arrival']) + ->where('start_date', '=', $mappedCancellationPolicy['start_date']) + ->where('finish_date', '=', $mappedCancellationPolicy['finish_date']) + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('property_id', '=', $params['property_id']) + ->first() ; + + if($checkHasMapping || $checkHasDay) { + throw new ApiErrorException('This mapping added before'); + }else{ + + $insertData = [] ; + $insertData[] = [ + 'property_id' => $params['property_id'], + 'cancellation_policy_id' => $params['cancellation_policy_id'], + 'room_rate_channel_mapping_id' => $params['room_rate_channel_mapping_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, 'user_id'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + if($insertData){ + $createResult = $this->propertyChannelRoomRateCancellationPolicyMappingRepository->insert($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + } + + + if($params['is_selected'] == false){ + $deleteThis = collect($propertyChannelRoomRateCancellationPolicyMapping) + ->where('cancellation_policy_id', '=', $params['cancellation_policy_id']) + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('property_id', '=', $params['property_id']) + ->keyBy('id')->keys()->toArray(); + + if($deleteThis){ + $deleteThisArray = $this->propertyChannelRoomRateCancellationPolicyMappingRepository->destroy($deleteThis); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + } + + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyChainService.php b/app/Core/Service/PropertyChainService.php new file mode 100644 index 0000000..41ceab3 --- /dev/null +++ b/app/Core/Service/PropertyChainService.php @@ -0,0 +1,95 @@ +propertyChainRepository = $propertyChainRepository; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChainRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChains($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ['field' => 'priority','value' => 'ASC'] + ] + ]; + + $searchResult = $this->select($searchCriteria, ['id', 'name', 'loyalty' ]); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_chains' =>$return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyChannelBookingPaymentSetupService.php b/app/Core/Service/PropertyChannelBookingPaymentSetupService.php new file mode 100644 index 0000000..bf8b392 --- /dev/null +++ b/app/Core/Service/PropertyChannelBookingPaymentSetupService.php @@ -0,0 +1,397 @@ +request = $request; + $this->propertyChannelBookingPaymentSetupRepository = $propertyChannelBookingPaymentSetupRepository; + $this->propertyBookingPaymentTypeService = $propertyBookingPaymentTypeService; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyChannelBookingPaymentSetupAddValidator = $propertyChannelBookingPaymentSetupAddValidator; + $this->propertyChannelTaxRepository = $propertyChannelTaxRepository; + + } + + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyChannelBookingPaymentSetupRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyCreateResult = $this->propertyChannelBookingPaymentSetupRepository->createAll($param); + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $propertyCreateResult["data"] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyChannelBookingPaymentSetupRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getChannelBookingPaymentSetup($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyBookingPaymentTypeList = $this->propertyBookingPaymentTypeService->getPropertyBookingPaymentTypeList(); + + $propertyChannelBookingPaymentSetupRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']] + ] + ]; + + $propertyChannelBookingPaymentSetup = $this->select($propertyChannelBookingPaymentSetupRequest, ['id','property_id', 'channel_id','cancellation_policy', 'property_channel_mapping_id', 'payment_type_id', 'is_affected_price', 'action_type', 'value_type', 'value','is_get_payment_data', 'is_selected']); + + if($propertyChannelBookingPaymentSetup['status'] != 'success'){ + throw new ApiErrorException('Property Channel Booking Payment Setup data not found'); + } + + $dataList = []; + $dataList['channel_id'] = $params['channel_id']; + foreach ($propertyBookingPaymentTypeList['data']['booking_payment_types'] as $propertyBookingPaymentType){ + + if($propertyBookingPaymentType['code'] == 'CHN') { + //continue; + } + + $setup = collect($propertyChannelBookingPaymentSetup['data']) + ->where('payment_type_id', '=', $propertyBookingPaymentType['id'])->first(); + + $paymentCancellationPolicy = []; + if(!empty($setup['cancellationPolicyArray'])) { + $paymentCancellationPolicy = $setup['cancellationPolicyArray']; + } + + $dataList['payments'][] = [ + "payment_type_id" => $propertyBookingPaymentType['id'], + "name" => $propertyBookingPaymentType['name'], + "code" => $propertyBookingPaymentType['code'], + "language_key" => $propertyBookingPaymentType['language_key'], + "is_affected_price" => isset($setup['is_affected_price']) ? $setup['is_affected_price'] : null, + "action_type" => isset($setup['action_type']) ? $setup['action_type'] : null, + "value_type" => isset($setup['value_type']) ? $setup['value_type'] : null, + "value" => isset($setup['value']) ? $setup['value'] : null, + "is_get_payment_data" => isset($setup['is_get_payment_data']) ? $setup['is_get_payment_data'] : null, + "is_selected" => $setup['is_selected'] ? true : false, + "cancellation_policy" => $paymentCancellationPolicy + ]; + } + + $propertyChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']] + ], + 'firstRow' => true + ]; + + $propertyCurrencyCode = $this->propertyChannelMappingService->select($propertyChannelMappingRequest, ['currency_code']); + + if($propertyCurrencyCode['status'] != 'success'){ + throw new ApiErrorException($propertyCurrencyCode['message']); + } + + + $getChannelRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel'], + 'firstRow' => 1 + ]; + $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'name','default_currency', 'currency_code']) ; + if($getChannelResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelResponse['message']); + } + $channelData['channel'] = $getChannelResponse['data'] ; + + + $dataList['currency_code'] = isset($propertyCurrencyCode['data']) && !empty($propertyCurrencyCode['data']['currency_code']) + ? $propertyCurrencyCode['data']['currency_code'] : $channelData['channel']['default_currency']; + + + + $getChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest) ; + + if($getChannelMappingResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponse['message']); + } + + + $channelTaxCriteria = ["criteria" => [["field" => "status", "condition" => "=", "value" => 1]]]; + $channelTaxes = $this->propertyChannelTaxRepository->findByCriteria($channelTaxCriteria, ['id', 'name', 'language_key', 'code']); + $channelTaxes = $channelTaxes ? $channelTaxes : []; + + $channelTaxList = []; + foreach ($channelTaxes as $channelTax) { + $channelTaxList[] = [ + "id" => $channelTax['id'], + "name" => $channelTax['name'], + "language_key" => $channelTax['language_key'], + "code" => $channelTax['code'], + "is_selected" => $channelTax['id'] == $getChannelMappingResponse['data']['channel_tax_id'] ? true : false, + ]; + } + + $dataList['channel_tax'] = $channelTaxList; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $dataList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + return output($response); + } + + public function addChannelBookingPaymentSetup($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->propertyChannelBookingPaymentSetupAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']], + ["field" => "channel_id", "condition" => "=", "value" => $params['channel_id']], + ] + ]; + + $oldMappingList = $this->propertyChannelBookingPaymentSetupRepository->findByCriteria($criteria); + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']], + ["field" => "channel_id", "condition" => "=", "value" => $params['channel_id']], + ], + "firstRow" => 1 + ]; + + $channelMapping = $this->propertyChannelMappingService->select($criteria); + + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']) ; + } + $channelMapping = $channelMapping['data'] ; + + if(empty($oldMappingList)){ + $setupData = []; + foreach ($params['payments'] as $channelSetup) { + $setupData[] = + [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "property_channel_mapping_id" => $channelMapping['id'], + "payment_type_id" => fillOnUndefinedAndEmpty($channelSetup, 'payment_type_id', null), + "cancellation_policy" => !empty($channelSetup['cancellation_policy']) ? json_encode($channelSetup['cancellation_policy']) : null, + "is_affected_price" => fillOnUndefinedAndEmpty($channelSetup, 'is_affected_price', 0), + "is_get_payment_data" => fillOnUndefinedAndEmpty($channelSetup, 'is_get_payment_data', 0), + "action_type" => fillOnUndefinedAndEmpty($channelSetup, 'action_type', null), + "value_type" => fillOnUndefinedAndEmpty($channelSetup, 'value_type', null), + "value" => fillOnUndefinedAndEmpty($channelSetup, 'value', null), + "is_selected" => $channelSetup['is_selected'], + "status" => 1, + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $createStatus = $this->create($setupData); + + if($createStatus['status'] != 'success'){ + throw new ApiErrorException($createStatus['message']); + } + + }else{ + + foreach ($params['payments'] as $channelSetup) { + + $updateData = collect($oldMappingList)->firstWhere('payment_type_id',$channelSetup['payment_type_id']); + if(!empty($updateData)){ + $setupData = + [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "payment_type_id" => fillOnUndefinedAndEmpty($channelSetup, 'payment_type_id', null), + "cancellation_policy" => !empty($channelSetup['cancellation_policy']) ? json_encode($channelSetup['cancellation_policy']) : null, + "action_type" => fillOnUndefinedAndEmpty($channelSetup, 'action_type', null), + "value_type" => fillOnUndefinedAndEmpty($channelSetup, 'value_type', null), + "value" => fillOnUndefinedAndEmpty($channelSetup, 'value', null), + "is_affected_price" => fillOnUndefinedAndEmpty($channelSetup, 'is_affected_price', 0), + "is_get_payment_data" => fillOnUndefinedAndEmpty($channelSetup, 'is_get_payment_data', 0), + "is_selected" => $channelSetup['is_selected'], + "status" => 1, + "updated_by" => $params['user_id'], + "updated_at" => time() + ]; + + $updateStatus = $this->update($updateData['id'], $setupData); + + if($updateStatus['status'] != 'success'){ + throw new ApiErrorException($updateStatus['message']); + } + } + } + + } + + + $getChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest); + $getChannelMappingResponse = $getChannelMappingResponse['status'] ? $getChannelMappingResponse['data'] : []; + + $channelTaxCriteria = ["criteria" => [["field" => "status", "condition" => "=", "value" => 1]]]; + $channelTaxes = $this->propertyChannelTaxRepository->findByCriteria($channelTaxCriteria, ['id', 'name', 'language_key', 'code']); + $channelTaxes = $channelTaxes ? $channelTaxes : []; + + if(isset($params['channel_tax']) || is_null($params['channel_tax'])) { + $this->propertyChannelMappingService->update($getChannelMappingResponse['id'], ['channel_tax_id' => $params['channel_tax']]); + } + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + +} diff --git a/app/Core/Service/PropertyChannelCategoryService.php b/app/Core/Service/PropertyChannelCategoryService.php new file mode 100644 index 0000000..13a8448 --- /dev/null +++ b/app/Core/Service/PropertyChannelCategoryService.php @@ -0,0 +1,122 @@ +propertyChannelCategoryRepository = $propertyChannelCategoryRepository; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyChannelCategoryRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelCategoryRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChannelCategories($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + ]; + + $data = $this->propertyChannelCategoryRepository->findByCriteria($criteria, ['id', 'name', 'language_key']); + + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyChannelContactService.php b/app/Core/Service/PropertyChannelContactService.php new file mode 100644 index 0000000..048cd92 --- /dev/null +++ b/app/Core/Service/PropertyChannelContactService.php @@ -0,0 +1,256 @@ +propertyChannelContactRepository = $propertyChannelContactRepository; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = + [ + 'property_channel_mapping_id' => fillOnUndefined($params, 'property_channel_mapping_id'), + 'name' => fillOnUndefined($params, 'name'), + 'email' => fillOnUndefined($params, 'email'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + + ]; + + $userCreateResult = $this->propertyChannelContactRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('This e-mail address already in list'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelContactRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyChannelContactRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function add($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = + [ + 'property_channel_mapping_id' => fillOnUndefined($params, 'property_channel_mapping_id'), + 'name' => fillOnUndefined($params, 'name'), + 'email' => fillOnUndefined($params, 'email'), + "status" => fillOnUndefined($params, "status", 1), + "user_id" => fillOnUndefined($params, "user_id"), + ]; + + + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getContact($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + if(!isset($params['id'])){ + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_channel_mapping_id', 'condition' => '=', 'value' => $params['property_channel_mapping_id']] + ], + 'orderBy' => [ + ['field' => 'name', 'value' => 'ASC'] + ] + ]; + + $contactData = $this->propertyChannelContactRepository->findByCriteria($criteria); + $contactData = $contactData ? $contactData : [] ; + } + else{ + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['id']], + ['field' => 'property_channel_mapping_id', 'condition' => '=', 'value' => $params['property_channel_mapping_id']] + ], + 'firstRow' => true + ]; + + $contactData = $this->propertyChannelContactRepository->findByCriteria($criteria); + if (!$contactData) { + throw new ApiErrorException('Unvalid Contact'); + } + } + + + $response = [ + 'status' => true, + 'data' => $contactData, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + $request = [ + 'criteria' => [ + ['field' => 'property_channel_mapping_id', 'condition' => '=', 'value' => $params['property_channel_mapping_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['id']], + ] + ]; + + + $response = $this->propertyChannelContactRepository->delete($request); + if(!$response){ + throw new ApiErrorException('No record to delete'); + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $response['data']]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyChannelCouponService.php b/app/Core/Service/PropertyChannelCouponService.php new file mode 100644 index 0000000..c728ee1 --- /dev/null +++ b/app/Core/Service/PropertyChannelCouponService.php @@ -0,0 +1,179 @@ +propertyChannelCouponRepository = $propertyChannelCouponRepository; + $this->propertyChannelCouponValidator = $propertyChannelCouponValidator; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelCouponRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyChannelCouponValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = [ + "title" => fillOnUndefined($param, "title"), + "property_id" => fillOnUndefined($param, "property_id"), + "channel_id" => fillOnUndefined($param, "channel_id"), + "code" => fillOnUndefined($param, "code"), + "start_date" => fillOnUndefined($param, "start_date"), + "end_date" => fillOnUndefined($param, "end_date"), + "reservation_start_date" => fillOnUndefined($param, "reservation_start_date"), + "reservation_end_date" => fillOnUndefined($param, "reservation_end_date"), + 'is_notify' => fillOnUndefined($param, 'is_notify'), + 'email' => fillOnUndefined($param, 'email'), + "status" => fillOnUndefined($param, "status", 1), + "type" => fillOnUndefined($param, "type"), + "value" => fillOnUndefined($param, "value"), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertDataResult = $this->propertyChannelCouponRepository->create($insertData); + if ($insertDataResult['status'] != 'success') { + throw new Exception($insertDataResult['message']); + } + + $insertDataResult = $insertDataResult["data"]; + + $response = [ + 'status' => true, + 'data' => $insertDataResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function update($id, $params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /*$validationResult = $this->propertyAddonValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + + $updateParamAvailable = ['title', 'code', 'start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', 'checked', 'used', 'type', 'value', 'is_notify', 'email' , 'status']; + foreach ($params as $key => $value) { + if (!in_array($key, $updateParamAvailable)) { + unset($params[$key]); + } + } + + $result = $this->propertyChannelCouponRepository->update($id, $params); + if ($result['status'] != 'success') { + throw new Exception($result['message']); + } + + $result = $result["data"]; + + $response = [ + 'status' => true, + 'data' => $result, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function delete($deleteThisId) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteThisId = is_array($deleteThisId) ? $deleteThisId : [$deleteThisId]; + $deleteThisArray = $this->propertyChannelCouponRepository->destroy($deleteThisId); + + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyChannelGroupChannelMappingService.php b/app/Core/Service/PropertyChannelGroupChannelMappingService.php new file mode 100644 index 0000000..6f01f1c --- /dev/null +++ b/app/Core/Service/PropertyChannelGroupChannelMappingService.php @@ -0,0 +1,131 @@ +propertyChannelGroupChannelMappingRepository = $propertyChannelGroupChannelMappingRepository; + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /* Todo: validator + $validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + */ + + $insertData = + [ + 'channel_group_id' => fillOnUndefined($params, 'channel_group_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by", 0), + "updated_by" => fillOnUndefined($params, "updated_by", 0), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertResponse = $this->propertyChannelGroupChannelMappingRepository->create($insertData); + + if ($insertResponse['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $insertResponse["data"] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelGroupChannelMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyChannelGroupChannelMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyChannelGroupService.php b/app/Core/Service/PropertyChannelGroupService.php new file mode 100644 index 0000000..0222a66 --- /dev/null +++ b/app/Core/Service/PropertyChannelGroupService.php @@ -0,0 +1,278 @@ +propertyChannelGroupRepository = $propertyChannelGroupRepository; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + /* Todo: validator + $validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + */ + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by", 0), + "updated_by" => fillOnUndefined($params, "updated_by", 0), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertResponse = $this->propertyChannelGroupRepository->create($insertData); + + if ($insertResponse['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $insertResponse["data"] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelGroupRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyChannelGroupRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChannelGroup($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + if(fillOnUndefined($params, 'property_id', null) == null){ + throw new ApiErrorException(lang('property_id is required')); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + ]; + + if(isset($params['id'])){ + $criteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['channelGroupActiveChannels'], + 'firstRow' => true + ]; + } + + + $groups = $this->propertyChannelGroupRepository->findByCriteria($criteria, ['id', 'name','status']); + $groups = $groups ? $groups : [] ; + + if(isset($params['id'])){ + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + + $propertyChannel = $this->propertyChannelService->getPropertyChannels($requestParams); + if($propertyChannel['status'] != 'success'){ + throw new ApiErrorException($propertyChannel['message']); + } + + + $propertyChannelCollection = collect($propertyChannel['data']); + $filterPropertyChannels = $propertyChannelCollection->where('is_selected', true); + $filterPropertyChannels = $filterPropertyChannels->where('is_pending', false); + $selectedPropertyChannels = $filterPropertyChannels->all(); + + $groupChannelCollection = collect($groups["channel_group_active_channels"]); + + + foreach ($selectedPropertyChannels as $k=>$v){ + + $filtergroupChannel = $groupChannelCollection->where('channel_id', $v['id']); + $isChannelMatched = $filtergroupChannel->all(); + + $selectedPropertyChannels[$k]["in_group"] = false; + if(count($isChannelMatched)){ + $selectedPropertyChannels[$k]["in_group"] = true; + } + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $v['id']], + ['field' => 'property_availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $availabilityTypeCheck = $this->propertyChannelMappingRepository->findByCriteria($criteria); + if(!count($availabilityTypeCheck)){ + unset($selectedPropertyChannels[$k]); + } + + } + + $groups["channel_group_active_channels"] = $selectedPropertyChannels; + + } + + + $response = [ + 'status' => true, + 'data' => $groups, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChannelGroupActiveChannels($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + if(fillOnUndefined($params, 'property_id', null) == null){ + throw new ApiErrorException(lang('property_id is required')); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_group_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['channelGroupActiveChannels','channelGroupActiveChannels.channel'], + 'firstRow' => true + ]; + + + $group = $this->propertyChannelGroupRepository->findByCriteria($criteria, ['id', 'name','status']); + $group = $group ? $group : [] ; + + $response = [ + 'status' => true, + 'data' => $group, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + + +} diff --git a/app/Core/Service/PropertyChannelMappingService.php b/app/Core/Service/PropertyChannelMappingService.php new file mode 100644 index 0000000..639d0b4 --- /dev/null +++ b/app/Core/Service/PropertyChannelMappingService.php @@ -0,0 +1,1214 @@ +request = $request; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->propertyChannelMappingAddValidator = $propertyChannelMappingAddValidator; + $this->propertyChannelMappingRemoveValidator = $propertyChannelMappingRemoveValidator; + $this->propertyChannelMappingUpdateValidator = $propertyChannelMappingUpdateValidator; + $this->propertyChannelSetupValidator = $propertyChannelSetupValidator ; + $this->propertyBookingTypeRepository = $propertyBookingTypeRepository; + $this->propertyBookingPaymentTypeRepository = $propertyBookingPaymentTypeRepository; + $this->propertyAvailabilityTypeRepository = $propertyAvailabilityTypeRepository ; + $this->propertyRoomPricingTypeRepository = $propertyRoomPricingTypeRepository ; + $this->propertyRoomRepository = $propertyRoomRepository ; + $this->propertyRoomRateChannelMappingRepository = $propertyRoomRateChannelMappingRepository ; + $this->propertyChannelSetupAddValidator = $propertyChannelSetupAddValidator ; + $this->propertyChannelSetupUpdateValidator = $propertyChannelSetupUpdateValidator ; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService ; + $this->propertyBookingEngineService = $propertyBookingEngineService; + $this->propertyChannelSetupWithMissingParametersAddValidator = $propertyChannelSetupWithMissingParametersAddValidator; + $this->propertyRoomService = $propertyRoomService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomRatePriceRepository = $propertyRoomRatePriceRepository; + $this->propertyChannelTaxRepository = $propertyChannelTaxRepository; + + } + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyChannelMappingRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyChannelMappingData = + [ + "channel_id" => fillOnUndefined($param, "user_id"), + "property_id" => fillOnUndefined($param, "property_id"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "created_by"), + + ]; + + + $propertyCreateResult = $this->propertyChannelMappingRepository->create($propertyChannelMappingData); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $propertyCreateResult["data"]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyChannelMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyChannelMapping($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->propertyChannelMappingAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']] + ] + ]; + $oldMappingList = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id', 'status']); + + + foreach ($params['channels'] as $addChannel) { + + $checkData = collect($oldMappingList) + ->where('property_id' , '=', $params['property_id']) + ->where('channel_id', '=', $addChannel) + ->first(); + + if(!$checkData){ + $addPropertyChannelMappingData = [ + "property_id" => $params['property_id'], + "channel_id" => $addChannel, + "status" => 1, + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + ]; + $createStatus = $this->propertyChannelMappingRepository->create($addPropertyChannelMappingData); + if($createStatus['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + }else{ + + $updatePropertyChannelMappingData = [ + "status" => 1, + "updated_by" => $params['user_id'] + ]; + $updateResult = $this->propertyChannelMappingRepository->update($checkData['id'], $updatePropertyChannelMappingData) ; + if($updateResult['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + + } + } + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChannelMapping($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $getPropertyCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel.propertyChannelCategory', 'property'] + + ]; + + $getChannels = $this->propertyChannelMappingRepository->findByCriteria($getPropertyCriteria, ['id', 'property_id', 'channel_id']) ; + + $response = ['status' => 1 , 'message' => '', 'data' => ['property_channel_mapping' => $getChannels]]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function removePropertyChannelMapping($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->propertyChannelMappingRemoveValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + foreach ($params['channels'] as $removeChannel) { + + + $updatePropertyCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id'] ], + ['field' => 'channel_id', 'condition' => '=', 'value' => $removeChannel], + ] + + ]; + + $updatePropertyChannelMappingData = [ + "status" => 0, + "updated_by" => $params['user_id'], + "updated_at" => time() + ]; + + $updateResult = $this->propertyChannelMappingRepository->updateWhere($updatePropertyCriteria, $updatePropertyChannelMappingData) ; + if($updateResult['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + } + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyChannelMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + $validationResult = $this->propertyChannelMappingUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $addPropertyChannelMapping = []; + $addChannelList = collect($params['property_channel']) + ->where('is_selected' ,'=', true); + $addChannelIds = $addChannelList->keyBy("id")->keys()->toArray(); + + $removeChannelList = collect($params['property_channel']) + ->where('is_selected' ,'=', false); + + $removeChannelIds = $removeChannelList->keyBy("id")->keys()->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + "whereIn" => [ + ["field" => "channel_id", "value" => $addChannelIds] + ] + ]; + $checkPropertyMappingResponse = $this->propertyChannelMappingRepository->findByCriteria($checkPropertyMappingRequest,['id', 'property_id', 'channel_id']); + + $checkPropertyMappingResponse = $checkPropertyMappingResponse ? $checkPropertyMappingResponse : [] ; + + + $checkPropertyMappingCollect = collect($checkPropertyMappingResponse); + + foreach ($addChannelList->toArray() as $key => $param) + { + $checkPropertyMapping = $checkPropertyMappingCollect->where('property_id', '=', $params['property_id']) + ->where('channel_id', '=', $param['id']) + ->first() ; + if(!$checkPropertyMapping){ + $addPropertyChannelMapping[] = + [ + 'property_id' => $params['property_id'], + 'channel_id' => fillOnUndefined($param, 'id'), + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + }else{ + $updatePropertyChannelMapping = + [ + 'status' => 1, + 'updated_by' => $params['user_id'], + ]; + + $response = $this->propertyChannelMappingRepository->update($checkPropertyMapping['id'], $updatePropertyChannelMapping); + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + $response = $this->propertyChannelMappingRepository->insert($addPropertyChannelMapping); + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + if($removeChannelIds){ + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + "whereIn" => + [ + ["field" => "channel_id", "value" => $removeChannelIds] + ] + ]; + $deletePropertyChannelMapping = $this->propertyChannelMappingRepository->findByCriteria($findCriteria); + $deleteThisIds = []; + foreach ($deletePropertyChannelMapping as $deleteThisItem){ + + $updatePropertyChannelMapping = + [ + 'status' => 0, + 'updated_by' => $params['user_id'], + ]; + $response = $this->propertyChannelMappingRepository->update($deleteThisItem['id'], $updatePropertyChannelMapping); + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + if ($response['status'] != 'success') { + throw new ApiErrorException(lang('Data is not added')) ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function addPropertyChannelSetup($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']], + ["field" => "channel_id", "condition" => "=", "value" => $params['channel_id']], + ], + 'firstRow' => true + ]; + $oldMappingList = $this->propertyChannelMappingRepository->findByCriteria($criteria); + + $roomCriteria = [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']] + ], + 'with' => ['propertyRoomRateMapping.propertyRoomRate'] + ]; + + $rooms = $this->propertyRoomRepository->findByCriteria($roomCriteria) ; + $rooms = $rooms ? $rooms : [] ; + + $roomRateMappingIds = [] ; + foreach ($rooms as $room) { + foreach ($room['property_room_rate_mapping'] as $item) { + if(!in_array($params['channel_id'],[5]) && $item['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + $roomRateMappingIds[] = $item['id'] ; + } + } + + if(!$oldMappingList){ + + $addPropertyChannelMappingData = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "currency_code" => $params['currency_code'], + "property_booking_type_id" => $params['booking_type_id'], + "property_availability_type_id" => $params['availability_type_id'], + "property_room_pricing_type_id" => $params['room_pricing_type_id'], + "connected_channel_id" => fillOnUndefined($params,'connected_channel_id'), + "connected_channel_action" => fillOnUndefined($params,'connected_channel_action'), + "contract_file" => null, + 'token' => getGuid(), + "status" => 1, + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + ]; + + + if($params['contract_file'] != null) { + + $contractFileUploadParams = [ + 'property_id' => $params['property_id'], + 'contract_file' => $params['contract_file'], + 'channel_id' => $params['channel_id'], + ]; + + $contractFileUpload = $this->propertyBookingEngineService->contractFileUpload($contractFileUploadParams); + if ($contractFileUpload['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $addPropertyChannelMappingData["contract_file"] = $contractFileUpload["data"]["contract_file_path"]; + + } + + + + $validationResult = $this->propertyChannelSetupAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $createStatus = $this->propertyChannelMappingRepository->create($addPropertyChannelMappingData); + + if($createStatus['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + + $roomRateChannelMappingData = [] ; + + foreach ($roomRateMappingIds as $roomRateMappingId) { + $roomRateChannelMappingData[] = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "room_rate_mapping_id" => $roomRateMappingId, + "has_date" => 0, + "status" => 1, + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + "created_at" => time(), + "updated_at" => time(), + ]; + } + + if($roomRateChannelMappingData){ + $insertRoomRateChannelMappingResult = $this->propertyRoomRateChannelMappingRepository->insert($roomRateChannelMappingData); + if ($insertRoomRateChannelMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $channelTokenParam = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + ]; + + $createBookingEngineToken = $this->propertyBookingEngineService->createBookingEngineToken($channelTokenParam); + if ($createBookingEngineToken['status'] != 'success') { + throw new ApiErrorException($createBookingEngineToken['message']); + } + + + }else{ + + $updatePropertyChannelMappingData = [ + "currency_code" => $params['currency_code'], + "property_booking_type_id" => $params['booking_type_id'], + "property_availability_type_id" => $params['availability_type_id'], + "property_room_pricing_type_id" => $params['room_pricing_type_id'], + "connected_channel_id" => fillOnUndefined($params,'connected_channel_id'), + "connected_channel_action" => fillOnUndefined($params,'connected_channel_action'), + "updated_by" => $params['user_id'], + "status" => 1, + "updated_at" => time(), + ]; + + $validationResult = $this->propertyChannelSetupUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + if($params['contract_file'] != null){ + $contractFileUploadParams = [ + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'contract_file' => $params['contract_file'], + ]; + + $contractFileUpload = $this->propertyBookingEngineService->contractFileUpload($contractFileUploadParams); + if ($contractFileUpload['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $updatePropertyChannelMappingData["contract_file"] = $contractFileUpload["data"]["contract_file_path"]; + } + + + + $updateStatus = $this->update($oldMappingList['id'], $updatePropertyChannelMappingData); + + if($updateStatus['status'] != 'success'){ + throw new ApiErrorException($updateStatus['message']); + } + + if ($oldMappingList['property_availability_type_id'] != $params['availability_type_id']) { + $dropParams = [ + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + ]; + $deleteOldAvailability = $this->propertyRoomAvailabilityService->dropPropertyChannelGuaranteedAndLimitedAvailability($dropParams); + if ($deleteOldAvailability['status'] != 'success') { + throw new ApiErrorException($deleteOldAvailability['message']); + } + } + + $channelTokenParam = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "updated_by" => $params['user_id'], + ]; + + $reactivateBookingEngineToken = $this->propertyBookingEngineService->reactivateBookingEngineToken($channelTokenParam); + if ($reactivateBookingEngineToken['status'] != 'success') { + throw new ApiErrorException($reactivateBookingEngineToken['message']); + } + } + + //Booking Engine Channel - Channel Manager Replication + if($params['channel_id'] == 1 && !empty($params['connected_channel_id']) && $params['connected_channel_id'] == 5) { + + + //Delete Old Prices + $oldRoomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ] + ]; + + $oldRoomRates = $this->propertyRoomRatePriceRepository->findbyCriteria($oldRoomRatesCriteria, ['id']); + if(!empty($oldRoomRates)) { + $oldRoomRatePriceIds = collect($oldRoomRates)->pluck('id')->toArray(); + $deleteRoomRatePrices = $this->propertyRoomRatePriceRepository->destroy($oldRoomRatePriceIds); + if($deleteRoomRatePrices['status'] != 'success') { + throw new ApiErrorException($deleteRoomRatePrices['message']); + } + } + //Delete Old Prices + + $getPropertyRoomInventoryParam = [ + 'property_id' => $params['property_id'], + 'channel_id' => 5, + 'start_date' => Carbon::now()->toDateString(), + 'end_date' => Carbon::now()->addYear()->subDay()->toDateString(), + ]; + + $getPropertyRoomInventory = $this->propertyRoomService->getPropertyRoomInventory($getPropertyRoomInventoryParam); + if($getPropertyRoomInventory['status'] != 'success'){ + throw new ApiErrorException($getPropertyRoomInventory['message']); + } + + $getPropertyRoomInventory = $getPropertyRoomInventory['data']; + + $roomRateReplicationParam = [ + 'property_id' => $params['property_id'], + 'channel_id' => 1, + 'user_id' => $params['user_id'], + 'availability' => [], + 'rates' => [] + ]; + + foreach ($getPropertyRoomInventory as $roomInventory) { + foreach ($roomInventory['property_room_rate_mapping'] as $propertyRoomRate) { + if(isset($propertyRoomRate['prices'][1])) { + foreach ($propertyRoomRate['prices'][1]['price'] as $date => $price) { + $roomRateKey = '1|'.$roomInventory['id'].'|'.$propertyRoomRate['id'].'|'.$date; + //availability_type_id|property_room_id|room_rate_mapping_id|2022-06-22 + if(!is_null($price['value'])) { + $roomRateReplicationParam['rates'][$roomRateKey] = [ + 'setup_type_id' => '1', + 'room_id' => $roomInventory['id'], + 'room_rate_mapping_id' => $propertyRoomRate['id'], + 'date' => $date, + 'amount' => fillOnUndefined($price,'value', ''), + ]; + } + } + } + } + } + + $roomRateReplication = $this->propertyRoomRatePriceService->roomRateUpdate($roomRateReplicationParam); + if ($roomRateReplication['status'] != 'success') { + throw new ApiErrorException($roomRateReplication['message']); + } + + } + + //Booking Engine Channel - Channel Manager Replication + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyChannelSetup($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $bookingTypeCriteria = + [ + "criteria" => + [ + ["field" => "status", "condition" => "=", "value" => 1], + ], + + ]; + $bookingTypes = $this->propertyBookingTypeRepository->findByCriteria($bookingTypeCriteria, ['id', 'name', 'language_key', 'code', 'icon']); + $bookingTypes = $bookingTypes ? $bookingTypes : []; + + + $availabilityTypeCriteria = + [ + "criteria" => + [ + ["field" => "status", "condition" => "=", "value" => 1], + ], + + ]; + $availabilityTypes = $this->propertyAvailabilityTypeRepository->findByCriteria($availabilityTypeCriteria, ['id', 'name', 'language_key', 'code', 'icon']); + $availabilityTypes = $availabilityTypes ? $availabilityTypes : []; + + + $criteria = + [ + "criteria" => + [ + ["field" => "status", "condition" => "=", "value" => 1] + ] + ]; + $propertyRoomPricingTypes = $this->propertyRoomPricingTypeRepository->findByCriteria($criteria); + $propertyRoomPricingTypes = $propertyRoomPricingTypes ? $propertyRoomPricingTypes : []; + + + + $getChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + $getChannelMappingResponse = $this->select($getChannelMappingRequest) ; + + if($getChannelMappingResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponse['message']); + } + + $propertyBookingTypeId = NULL; + $propertyAvailabilityTypeId = NULL; + $propertyRoomPricingTypeId = NULL; + $propertyContractFile = NULL; + if(!empty($getChannelMappingResponse['data'])){ + $propertyBookingTypeId = $getChannelMappingResponse['data']['property_booking_type_id']; + $propertyAvailabilityTypeId = $getChannelMappingResponse['data']['property_availability_type_id']; + $propertyRoomPricingTypeId = $getChannelMappingResponse['data']['property_room_pricing_type_id']; + + if(!empty($getChannelMappingResponse['data']['contract_file'])){ + $propertyContractFile = Config::get('app.propertyFilesUrl').$propertyContractFile.$getChannelMappingResponse['data']['contract_file']; + } + } + + $bookingList = [] ; + $propertyRoomPricingTypeList = [] ; + $availabilityList = [] ; + $bulkUpdateOptions = []; + + foreach ($bookingTypes as $bookingType) { + $bookingList[] = [ + "booking_type_id" => $bookingType['id'], + "name" => $bookingType['name'], + "language_key" => $bookingType['language_key'], + "icon" => $bookingType['icon'], + "is_selected" => $bookingType['id'] === $propertyBookingTypeId ? true : false, + ]; + } + + + + foreach ($availabilityTypes as $availabilityType) { + $availabilityList[] = [ + "availability_type_id" => $availabilityType['id'], + "name" => $availabilityType['name'], + "language_key" => $availabilityType['language_key'], + "icon" => $availabilityType['icon'], + "is_selected" => $availabilityType['id'] === $propertyAvailabilityTypeId ? true : false, + ]; + + } + + $roomAvailability = collect($availabilityList)->where('availability_type_id',1)->first(); + $limitedAvailability = collect($availabilityList)->where('availability_type_id',2)->first(); + $guaranteedAvailability = collect($availabilityList)->where('availability_type_id',3)->first(); + + foreach ($availabilityList as $index => $availabilityListItem){ + if($propertyAvailabilityTypeId === 1){ + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "availability", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "rate", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "room_stop_sell", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "rate_stop_sell", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "min_stay", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => 'enw-input-quick_pricing', + "type" => "quick_pricing", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + break; + }else if($propertyAvailabilityTypeId === 2){ + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "availability", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $limitedAvailability['name'], + "language_key" => $limitedAvailability['language_key'], + "type" => "availability", + "availability_type_id" => $limitedAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $limitedAvailability['name'], + "language_key" => $limitedAvailability['language_key'], + "type" => "rate", + "availability_type_id" => $limitedAvailability['availability_type_id'] + ]; + break; + }else if($propertyAvailabilityTypeId === 3){ + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "availability", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $roomAvailability['name'], + "language_key" => $roomAvailability['language_key'], + "type" => "rate", + "availability_type_id" => $roomAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $guaranteedAvailability['name'], + "language_key" => $guaranteedAvailability['language_key'], + "type" => "availability", + "availability_type_id" => $guaranteedAvailability['availability_type_id'] + ]; + + $bulkUpdateOptions[] = [ + "name" => $guaranteedAvailability['name'], + "language_key" => $guaranteedAvailability['language_key'], + "type" => "rate", + "availability_type_id" => $guaranteedAvailability['availability_type_id'] + ]; + break; + } + + } + + foreach ($propertyRoomPricingTypes as $propertyRoomPricingType) { + $propertyRoomPricingTypeList[] = [ + "room_pricing_type_id" => $propertyRoomPricingType['id'], + "name" => $propertyRoomPricingType['name'], + "language_key" => $propertyRoomPricingType['language_key'], + "icon" => $propertyRoomPricingType['icon'], + "is_selected" => $propertyRoomPricingType['id'] === $propertyRoomPricingTypeId ? true : false, + ]; + } + + $responseData = [ + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'booking' => $bookingList, + 'room_price_type' => $propertyRoomPricingTypeList, + 'availability' => $availabilityList, + 'bulk_update_options' => $bulkUpdateOptions, + 'contract_file_url' => $propertyContractFile + ]; + + $response = ['status' => 1 , 'message' => '', 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function checkPropertyChannelMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $getMapping = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $data = $this->propertyChannelMappingRepository->findByCriteria($getMapping); + if(!$data){ + throw new ApiErrorException('api-unknown_error'); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyChannelSetupWithMissingParameters($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']], + ["field" => "channel_id", "condition" => "=", "value" => $params['channel_id']], + ], + 'firstRow' => true + ]; + $oldMappingList = $this->propertyChannelMappingRepository->findByCriteria($criteria); + + if($oldMappingList){ + + //UPDATE + $updatePropertyChannelMappingData = [ + "updated_by" => $params['user_id'], + "status" => self::STATUS_PENDING, + "updated_at" => time(), + ]; + + $createdOrUpdatedResponse = $this->update($oldMappingList['id'], $updatePropertyChannelMappingData); + if($createdOrUpdatedResponse['status'] != 'success'){ + throw new ApiErrorException($createdOrUpdatedResponse['message']); + } + + }else{ + + //CREATE + $addPropertyChannelMappingData = [ + "property_id" => $params['property_id'], + "channel_id" => $params['channel_id'], + "currency_code" => null, + "property_booking_type_id" => null, + "property_availability_type_id" => null, + "property_room_pricing_type_id" => null, + "status" => self::STATUS_PENDING, + "created_by" => $params['user_id'], + "updated_by" => $params['user_id'], + ]; + + $validationResult = $this->propertyChannelSetupWithMissingParametersAddValidator->validate($addPropertyChannelMappingData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $createdOrUpdatedResponse = $this->propertyChannelMappingRepository->create($addPropertyChannelMappingData); + if($createdOrUpdatedResponse['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + + } + + if(!empty($createdOrUpdatedResponse['data'])){ + $response['data'] = [ + "property_id" => $createdOrUpdatedResponse['data']['property_id'], + "channel_id" => $createdOrUpdatedResponse['data']['channel_id'], + "currency_code" => $createdOrUpdatedResponse['data']['currency_code'], + "property_booking_type_id" => $createdOrUpdatedResponse['data']['property_booking_type_id'], + "property_availability_type_id" => $createdOrUpdatedResponse['data']['property_availability_type_id'], + "property_room_pricing_type_id" => $createdOrUpdatedResponse['data']['property_room_pricing_type_id'], + "status" => $createdOrUpdatedResponse['data']['status'] + ]; + } + + $response = ['status' => 1 , 'message' => '', 'data' => $response['data'] ]; + + }catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPropertyChildChannel($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $getPropertyCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + + ]; + $getChannels = $this->propertyChannelMappingRepository->findByCriteria($getPropertyCriteria) ; + + $childDatas = collect($getChannels)->where('channel.channel_category_id', 4) + ->where('channel.parent_id', '!=', null)->toArray(); + + $responseData = []; + + if(!empty($childDatas)){ + + foreach ($childDatas as $childData){ + $responseData[] = [ + 'channel_mapping_id' => $childData['id'], + 'property_id' => $childData['property_id'], + 'channel_id' => $childData['channel_id'], + 'status' => $childData['status'], + 'channel_name' => $childData['channel']['name'], + 'channel_logo' => $childData['channel']['logo'] + + ]; + } + + } + + $response = ['status' => 1 , 'message' => '', 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPropertyChannelMappingForChannelGroup($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $getChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_availability_type_id', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channel_ids']] + ] + ]; + + $getChannels = $this->propertyChannelMappingRepository->findByCriteria($getChannelMappingCriteria) ; + if(!$getChannels){ + throw new ApiErrorException('api-unknown_error'); + } + $response = ['status' => 1 , 'message' => '', 'data' => $getChannels]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getOnlyPropertyChannelMapping($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $getChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + + $getChannels = $this->propertyChannelMappingRepository->findByCriteria($getChannelMappingCriteria) ; + if(!$getChannels){ + throw new ApiErrorException('api-unknown_error'); + } + $response = ['status' => 1 , 'message' => '', 'data' => $getChannels]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyChannelService.php b/app/Core/Service/PropertyChannelService.php new file mode 100644 index 0000000..6f879d8 --- /dev/null +++ b/app/Core/Service/PropertyChannelService.php @@ -0,0 +1,367 @@ +propertyChannelRepository = $propertyChannelRepository; + $this->propertyChannelAddValidator = $propertyChannelAddValidator; + $this->propertyChannelUpdateValidator = $propertyChannelUpdateValidator; + $this->propertyChannelDeleteValidator = $propertyChannelDeleteValidator; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyChannelAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'name' => fillOnUndefined($params, 'name'), + 'official_name' => fillOnUndefined($params, 'official_name'), + 'description' => fillOnUndefined($params, 'description'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'currency_code' => fillOnUndefined($params, 'currency_code'), + 'logo' => fillOnUndefined($params, 'logo'), + 'address' => fillOnUndefined($params, 'address'), + 'zip_code' => fillOnUndefined($params, 'zip_code'), + 'email' => fillOnUndefined($params, 'email'), + 'phone' => fillOnUndefined($params, 'phone'), + 'phone2' => fillOnUndefined($params, 'phone2'), + 'fax' => fillOnUndefined($params, 'fax'), + 'score' => fillOnUndefined($params, 'score'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by", 0), + "updated_by" => fillOnUndefined($params, "updated_by", 0) + + ]; + + $userCreateResult = $this->propertyChannelRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyChannelRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyChannelRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyChannel($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = + [ + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'name' => fillOnUndefined($params, 'name'), + 'official_name' => fillOnUndefined($params, 'official_name'), + 'description' => fillOnUndefined($params, 'description'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'currency_code' => json_encode(fillOnUndefined($params, 'currency_code', [])), + 'logo' => fillOnUndefined($params, 'logo'), + 'address' => fillOnUndefined($params, 'address'), + 'zip_code' => fillOnUndefined($params, 'zip_code'), + 'email' => fillOnUndefined($params, 'email'), + 'phone' => fillOnUndefined($params, 'phone'), + 'phone2' => fillOnUndefined($params, 'phone2'), + 'fax' => fillOnUndefined($params, 'fax'), + 'score' => fillOnUndefined($params, 'score'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyChannels($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $mappingData = [] ; + + if(isset($params['property_id'])){ + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $mappingData = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id','connected_channel_id', 'status']); + $mappingData = $mappingData ? $mappingData : [] ; + $mappingData = collect($mappingData)->keyBy('channel_id')->all() ; + } + + $mappingDataPending = [] ; + + if(isset($params['property_id'])){ + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $mappingDataPending = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id','connected_channel_id', 'status']); + $mappingDataPending = $mappingDataPending ? $mappingDataPending : [] ; + $mappingDataPending = collect($mappingDataPending)->keyBy('channel_id')->all() ; + } + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1 ] + ], + 'with' => ['propertyChannelCategory', 'parentChannel'], + 'orderBy' => [ + ['field' => 'name', 'value' => 'ASC'] + ] + ]; + + + if(isset($params['parent_id'])){ + $params['parent_id'] = $params['parent_id'] == "null" ? null : $params['parent_id']; + $criteria['criteria'][] = ['field' => 'parent_id', 'condition' => '=', 'value' => $params['parent_id'] ] ; + } + if(isset($params['type'])){ + $criteria['criteria'][] = ['field' => 'type', 'condition' => '=', 'value' => $params['type'] ] ; + } + if(isset($params['channel_category_id'])){ + $criteria['criteria'][] = ['field' => 'channel_category_id', 'condition' => '=', 'value' => $params['channel_category_id'] ] ; + } + if(isset($params['country_code'])){ + $criteria['criteria'][] = ['field' => 'country_code', 'condition' => '=', 'value' => $params['country_code'] ] ; + } + + + $data = $this->propertyChannelRepository->findByCriteria($criteria,['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'country_code', 'restriction','currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']); + + + $data = collect($data)->map(function ($channels) use ($params, $mappingData, $mappingDataPending){ + + if($params['property_id']){ + $channels['is_selected'] = isset($mappingData[$channels['id']]) ; + $channels['is_pending'] = isset($mappingDataPending[$channels['id']]) && $mappingDataPending[$channels['id']]['status'] == 2 ? true : false ; + $channels['connected_channel_id'] = isset($mappingData[$channels['id']]) ? $mappingData[$channels['id']]['connected_channel_id'] : null; + } + + $channels["currency_code"] = json_decode($channels["currency_code"], 1); + + $channels['has_children'] = in_array($channels['channel_category_id'], [3,4]) ? true : false; + + return $channels; + }); + + $data = $data->keyBy('id')->toArray(); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyChannel($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyChannelUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'name' => fillOnUndefined($params, 'name'), + 'official_name' => fillOnUndefined($params, 'official_name'), + 'description' => fillOnUndefined($params, 'description'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'currency_code' => json_encode(fillOnUndefined($params, 'currency_code', [])), + 'logo' => fillOnUndefined($params, 'logo'), + 'address' => fillOnUndefined($params, 'address'), + 'zip_code' => fillOnUndefined($params, 'zip_code'), + 'email' => fillOnUndefined($params, 'email'), + 'phone' => fillOnUndefined($params, 'phone'), + 'phone2' => fillOnUndefined($params, 'phone2'), + 'fax' => fillOnUndefined($params, 'fax'), + 'score' => fillOnUndefined($params, 'score'), + "updated_by" => fillOnUndefined($params, "user_id", 0) + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function checkChannelCategory($channel_id=0, $category_id=0){ + + $response = false; + + $channel = $this->propertyChannelRepository->find($channel_id); + if(isset($channel["channel_category_id"]) && $channel["channel_category_id"] == $category_id){ + $response = true; + } + + return $response; + } + + +} diff --git a/app/Core/Service/PropertyCompetitorGroupService.php b/app/Core/Service/PropertyCompetitorGroupService.php new file mode 100644 index 0000000..e5f6809 --- /dev/null +++ b/app/Core/Service/PropertyCompetitorGroupService.php @@ -0,0 +1,371 @@ +propertyCompetitorGroupRepository = $propertyCompetitorGroupRepository; + $this->propertyCompetitorGroupMappingRepository = $propertyCompetitorGroupMappingRepository; + } + + public function createPropertyCompetitorGroup($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + "property_id" => fillOnUndefined($param, "property_id"), + "name" => fillOnUndefined($param, "name"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertDataResult = $this->propertyCompetitorGroupRepository->create($insertData); + if ($insertDataResult['status'] != 'success') { + throw new Exception($insertDataResult['message']); + } + + $insertDataResult = $insertDataResult["data"]; + + $response = [ + 'status' => true, + 'data' => $insertDataResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function selectPropertyCompetitorGroup($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyCompetitorGroupRepository->findByCriteria($param, $column); + + $propertyList = []; + foreach ($data as $property) { + $propertyList[] = [ + 'id' => $property['id'], + 'property_id' => $property['property_id'], + 'name' => $property['name'], + 'status' => $property['status'], + ]; + } + + $response = [ + 'status' => true, + 'data' => $propertyList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function syncPropertyCompetitorGroup($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $id = fillOnUndefined($param, "id"); + $propertyId = fillOnUndefined($param, "property_id"); + $name = fillOnUndefined($param, "name"); + $status = fillOnUndefined($param, "status", 1); + $userId = fillOnUndefined($param, "user_id"); + + if ($id) { + // Güncelleme öncesi: kayıt ve yetki kontrolü + $existingRow = $this->propertyCompetitorGroupRepository->findByCriteria([ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id], + ], + 'firstRow' => 1 + ], ['id','property_id']); + + if (!$existingRow) { + throw new ApiErrorException('Record not found'); + } + + // Eğer dışarıdan property_id gönderildiyse, kayıtla eşleşmesini zorunlu tutalım + if (!is_null($propertyId) && (int)$propertyId !== (int)$existingRow['property_id']) { + // Bu durum, kullanıcının farklı bir property_id ile kayıt güncellemeye çalıştığını gösterir + throw new ApiErrorException('Permission denied for this property'); + } + + // Güvenlik: update sırasında property_id değiştirilmesin + $updateData = [ + "name" => $name, + "status" => $status, + "updated_by" => $userId, + "updated_at" => time(), + ]; + + // Repository update signature: update($id, $data) + $updateResult = $this->propertyCompetitorGroupRepository->update($id, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception($updateResult['message']); + } + $data = $updateResult["data"]; + } else { + // Ekleme + $insertData = [ + "property_id" => $propertyId, + "name" => $name, + "status" => $status, + "created_by" => $userId, + "updated_by" => $userId, + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertResult = $this->propertyCompetitorGroupRepository->create($insertData); + if ($insertResult['status'] != 'success') { + throw new Exception($insertResult['message']); + } + $data = $insertResult["data"]; + } + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function deletePropertyCompetitorGroup($deleteThisId) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteThisId = is_array($deleteThisId) ? $deleteThisId : [$deleteThisId]; + $deleteThisArray = $this->propertyCompetitorGroupRepository->destroy($deleteThisId); + + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + /** + * Mapping GET + * GET isteklerinde meta alanlar (created_by, updated_by, created_at, updated_at) gizlenir. + */ + public function getPropertyCompetitorGroupMapping($param = [], $columns = [ + 'id', + 'competitor_group_id', + 'property_id', + 'competitor_property_source', + 'competitor_property_key', + 'status', + ]) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $propertyId = fillOnUndefined($param, 'property_id'); + $competitorGroupId = fillOnUndefined($param, 'competitor_group_id'); + + if (!$propertyId || !$competitorGroupId) { + throw new ApiErrorException('property_id and competitor_group_id are required'); + } + + $selectParams = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'competitor_group_id', 'condition' => '=', 'value' => $competitorGroupId], + ] + ]; + + $data = $this->propertyCompetitorGroupMappingRepository->findByCriteria($selectParams, $columns); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + /** + * Mapping SYNC + * Tam senkron: önce mevcutları sil, sonra yeni gelenleri ekle. + * Dönüşte ilgili kayıtları (meta alanlar dahil) array olarak döndürür. + */ + public function syncPropertyCompetitorGroupMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $propertyId = fillOnUndefined($param, 'property_id'); + $competitorGroupId = fillOnUndefined($param, 'competitor_group_id'); + $competitors = fillOnUndefined($param, 'competitor', []); + $userId = fillOnUndefined($param, 'user_id'); + + if (!$propertyId || !$competitorGroupId) { + throw new ApiErrorException('property_id and competitor_group_id are required'); + } + + // YETKİ KONTROLÜ: competitor_group_id gerçekten bu property_id'ye ait mi? + // Kullanıcı, farklı bir gruba (başka property'ye ait) yazmaya çalışırsa engelle. + $groupRow = $this->propertyCompetitorGroupRepository->findByCriteria([ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $competitorGroupId], + ], + 'firstRow' => 1 + ], ['id', 'property_id']); + + if (!$groupRow) { + throw new ApiErrorException('Competitor group not found'); + } + + if ((int)$groupRow['property_id'] !== (int)$propertyId) { + // İstenen davranış: kullanıcı farklı bir grup ID gönderirse ve bu grup bu property'e ait değilse izin verme + throw new ApiErrorException('Permission denied for this competitor group'); + } + + // 1) Eski kayıtları temizle (tam eşitleme) — yalnızca ilgili property_id + competitor_group_id çiftini hedefle + // Not: Repository delete() metodunda filtre anahtarı 'criteria' olmalı; 'where' kullanılırsa tüm kayıtlar silinebilir. + $deleteWhere = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'competitor_group_id', 'condition' => '=', 'value' => $competitorGroupId], + ] + ]; + $deleteResult = $this->propertyCompetitorGroupMappingRepository->delete($deleteWhere); + if (($deleteResult['status'] ?? 'success') !== 'success') { + throw new Exception($deleteResult['message'] ?? 'delete_error'); + } + + // 2) Yeni kayıtları ekle + $now = time(); + $rows = []; + foreach ($competitors as $c) { + $source = $c['source'] ?? 'extranetwork'; + $key = $c['key'] ?? null; + if (!$key) { // key zorunlu + continue; + } + $rows[] = [ + 'competitor_group_id' => $competitorGroupId, + 'property_id' => $propertyId, + 'competitor_property_source' => $source ?: 'extranetwork', + 'competitor_property_key' => (string)$key, + 'status' => 1, + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => $now, + 'updated_at' => $now, + ]; + } + + if (!empty($rows)) { + $insertResult = $this->propertyCompetitorGroupMappingRepository->insert($rows); + if (($insertResult['status'] ?? '') !== 'success') { + throw new Exception($insertResult['message'] ?? 'insert_error'); + } + } + + // 3) Güncel kayıtları geri döndür + $selectParams = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'competitor_group_id', 'condition' => '=', 'value' => $competitorGroupId], + ] + ]; + + $columns = [ + 'id', + 'competitor_group_id', + 'property_id', + 'competitor_property_source', + 'competitor_property_key', + 'status', + 'created_by', + 'updated_by', + 'created_at', + 'updated_at', + ]; + + $rowsResult = $this->propertyCompetitorGroupMappingRepository->findByCriteria($selectParams, $columns); + + $response = [ + 'status' => true, + 'data' => $rowsResult, + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyConfigService.php b/app/Core/Service/PropertyConfigService.php new file mode 100644 index 0000000..c98bba5 --- /dev/null +++ b/app/Core/Service/PropertyConfigService.php @@ -0,0 +1,475 @@ +propertyConfigRepository = $propertyConfigRepository; + $this->propertyConfigCreateValidator = $propertyConfigCreateValidator; + $this->siteConfigRepository = $siteConfigRepository; + $this->propertyFactService = $propertyFactService; + $this->rateKey = 'profile_rate_value'; + $this->siteConfigKey = 'profile_rate_mapping'; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "config_key" => fillOnUndefined($param, "config_key"), + "config_value_json" => fillOnUndefined($param, "config_value_json"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $validationResult = $this->propertyConfigCreateValidator->validate($insertData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $userCreateResult = $this->propertyConfigRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyConfigRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyConfigRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyConfigRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyConfig($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + $configRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + + ]; + + if ($params['config_keys']) { + + $configRequest['whereIn'] = [ + ["field" => "config_key", "value" => $params['config_keys']] + ]; + } + $configResponse = $this->select($configRequest, ['property_id', 'config_key', 'config_value_json']); + + if ($configResponse['status'] != 'success') { + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + $configCollection = collect($configResponse['data']); + + foreach ($configCollection as $config) { + $configItem['property_id'] = $config['property_id']; + $configItem['config_key'] = $config['config_key']; + $configItem['config_value_json'] = $config['config_value_json']; + $return[] = $configItem; + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_config' => $return]]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyConfigUpdate($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $requestKeys = collect($params['config_keys'])->keyBy("config_key")->keys()->toArray(); + + + $configRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + "whereIn" => [ + ["field" => "config_key", "value" => $requestKeys] + ] + ]; + + $configResponse = $this->select($configRequest); + + $configCollection = collect($configResponse['data']); + + foreach ($params['config_keys'] as $config_key) { + + $configKeyCheck = $configCollection->where('config_key', '=', $config_key['config_key']) + ->first(); + + if ($configKeyCheck) { + $updateData = [ + 'config_value_json' => $config_key['config_value_json'], + 'updated_by' => $params['user_id'], + 'status' => 1, + ]; + $updateStatus = $this->update($configKeyCheck['id'], $updateData); + + if ($updateStatus['status'] != 'success') { + throw new Exception($updateStatus['message']); + } + } else { + $createData = [ + 'property_id' => $params['property_id'], + 'config_key' => $config_key['config_key'], + 'config_value_json' => $config_key['config_value_json'], + 'updated_by' => $params['user_id'], + 'created_by' => $params['user_id'], + ]; + $createStatus = $this->create($createData); + if ($createStatus['status'] != 'success') { + throw new Exception($createStatus['message']); + } + } + } + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'config_keys' => $requestKeys + + ]; + + $propertyConfig = $this->getPropertyConfig($requestParams); + + if ($propertyConfig['status'] != 'success') { + throw new ApiErrorException($propertyConfig['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyConfig['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function checkRateForId($params) + { + + $response = $params; + $response['property_rate_for'] = $response['property_rate_for'] == 'Property.Fact.SubCategoryFacts' ? 'Property.Fact.SubCategoryFacts' . '.' . $response['sub_category_id'] : $response['property_rate_for']; + return $response; + } + + public function rateProperty($rateParams) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $rateParams = $this->checkRateForId($rateParams); + $selectProperty = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $rateParams['property_id']], + ['field' => 'config_key', 'condition' => '=', 'value' => $this->rateKey], + ], + 'firstRow' => 1 + + ]; + $propertyRates = $this->select($selectProperty); + + if ($propertyRates['status'] != "success") { + throw new Exception($propertyRates['message']); + } + + if ($propertyRates['data'] == null) { + $configValue[] = $rateParams['property_rate_for']; + $configValueJson = json_encode($configValue); + $updateParams = [ + 'property_id' => $rateParams['property_id'], + 'config_key' => $this->rateKey, + 'config_value_json' => $configValueJson, + 'status' => 1, + 'created_by' => $rateParams['user_id'], + 'updated_by' => $rateParams['user_id'], + 'created_at' => time(), + 'updated_at' => time() + ]; + $updateStatus = $this->create($updateParams); + if ($updateStatus['status'] != 'success') { + throw new Exception($updateStatus['message']); + } + } else { + $propertyRates = $propertyRates['data'] ? $propertyRates['data'] : []; + $configValue = json_decode($propertyRates['config_value_json'], 1); + $configValue = is_array($configValue) ? $configValue : []; + if (!in_array($rateParams['property_rate_for'], $configValue)) { + array_push($configValue, $rateParams['property_rate_for']); + $configValueJson = json_encode($configValue); + $updateParams = [ + 'config_value_json' => $configValueJson, + 'updated_by' => $rateParams['user_id'], + 'updated_at' => time() + ]; + $updateStatus = $this->update($propertyRates['id'], $updateParams); + if ($updateStatus['status'] != 'success') { + throw new Exception($updateStatus['message']); + } + } + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $configValue]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyDashBoard($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $siteConfigRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'config_key', 'condition' => '=', 'value' => $this->siteConfigKey], + ], + 'firstRow' => 1 + ]; + + $siteConfig = $this->siteConfigRepository->findByCriteria($siteConfigRequest); + + $siteConfig = $siteConfig ? $siteConfig : []; + $rateConfig = fillOnUndefined($siteConfig, 'config_value_json', null); + $rateConfig = json_decode($rateConfig, 1); + $dashboardSections = is_array($rateConfig) && isset($rateConfig['dashboard_section']) ? $rateConfig['dashboard_section'] : []; + + + foreach ($dashboardSections as $key => $value) { + $return[$key]['title'] = $value['title']; + $return[$key]['icon'] = $value['icon']; + $return[$key]['description'] = $value['description']; + if (isset($value['menus'])) { + $return[$key]['menus'] = $value['menus']; + } + } + + $amenityMenu = $this->propertyFactService->getSubCategoryMenus(['parent_id' => 1, 'sub_category_id' => null]); + if ($amenityMenu['status'] != 'success') { + throw new ApiErrorException($amenityMenu['message']); + } + + $facilityMenu = $this->propertyFactService->getSubCategoryMenus(['parent_id' => 44, 'sub_category_id' => null]); + if ($facilityMenu['status'] != 'success') { + throw new ApiErrorException($facilityMenu['message']); + } + + + $return['amenities']['menus'] = $amenityMenu['data']['menu']; + $return['facility']['menus'] = $facilityMenu['data']['menu']; + + $wizardParams = [ + 'menu_array' => $return, + 'property_id' => $params['property_id'] + ]; + + + $return = $this->checkWizard($wizardParams); + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['dashboard' => $return]]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + public function checkWizard($params) + { + + $selectProperty = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'config_key', 'condition' => '=', 'value' => $this->rateKey], + ], + 'firstRow' => 1 + ]; + $propertyRates = $this->propertyConfigRepository->findByCriteria($selectProperty); + $propertyRates = $propertyRates ? $propertyRates : []; + $rates = fillOnUndefined($propertyRates, 'config_value_json', '[]'); + $rates = json_decode($rates, 1); + $return = []; + foreach ($params['menu_array'] as $key => $value) { + $return[$key] = $value; + $menus = []; + $completed = 0; + if (isset($value['menus'])) { + foreach ($value['menus'] as $menu) { + $menu['wizard_completed'] = array_search($menu['alias'], $rates) > -1; + $completed = array_search($menu['alias'], $rates) > -1 ? $completed + 1 : $completed; + $menus[] = $menu; + } + $return[$key]['menus'] = $menus; + $return[$key]['total_module'] = count($menus); + $return[$key]['completed_module'] = $completed; + } + } + return $return; + } +} diff --git a/app/Core/Service/PropertyContactService.php b/app/Core/Service/PropertyContactService.php new file mode 100644 index 0000000..a5a4932 --- /dev/null +++ b/app/Core/Service/PropertyContactService.php @@ -0,0 +1,330 @@ +propertyContactRepository = $propertyContactRepository; + $this->propertyContactCreateValidator = $propertyContactCreateValidator; + $this->propertyContactUpdateValidator = $propertyContactUpdateValidator; + $this->propertyLocationUpdateValidator = $propertyLocationUpdateValidator; + + } + + /** + * @param array $param + * + * @return array + */ + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $propertyContactData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "phone_code" => fillOnUndefined($param, "phone_code"), + "phone" => fillOnUndefined($param, "phone"), + "mobile_code" => fillOnUndefined($param, "mobile_code"), + "mobile" => fillOnUndefined($param, "mobile"), + "mobile2_code" => fillOnUndefined($param, "mobile_code"), + "mobile2" => fillOnUndefined($param, "mobile2"), + "fax_code" => fillOnUndefined($param, "fax_code"), + "fax" => fillOnUndefined($param, "fax"), + "email" => fillOnUndefined($param, "email"), + "web" => fillOnUndefined($param, "web"), + "social_media_addresses" => fillOnUndefined($param, "social_media_addresses"), + "zip_code" => fillOnUndefined($param, "zip_code"), + "address" => fillOnUndefined($param, "address"), + "latitude" => fillOnUndefined($param, "latitude"), + "longitude" => fillOnUndefined($param, "longitude"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + // todo: destination service will added for destination_id check + $validationResult = $this->propertyContactCreateValidator->validate($propertyContactData); + + //todo: validation section will be updated + Validator::make($propertyContactData, + ['property_id' => 'required|integer|unique:property_contact,property_id'], + ['property_id.property_contact' => '"property_id format must be unique"']); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyContactCreateResult = $this->propertyContactRepository->create($propertyContactData); + + if ($propertyContactCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $contactData = $propertyContactCreateResult["data"]; + + $response = [ + 'status' => true, + 'data' => $contactData + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + /** + * @param array $param + * @param array $column + * + * @return array + */ + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyContentRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + if(!isset($param['address'])){ + + $validationResult = $this->propertyContactUpdateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + } + + if(isset($param['address']) || isset($param['latitude']) || isset($param['longitude'])){ + $validationResult = $this->propertyLocationUpdateValidator->validate($param); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + } + + $updateResult = $this->propertyContactRepository->update($id,$param); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + /** + * property contact data list + * + * @param $params + * + * @return array + */ + public function propertyContact($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $contactRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $contactData = $this->propertyContactRepository->findByCriteria($contactRequest); + + $contactData = $contactData ? $contactData : [] ; + + $data = []; + foreach ($contactData as $contact) { + $data = Arr::except($contact,['id','status','created_by','updated_by','created_at','updated_at']); + $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ; + } + + if(!isset($data["social_media_addresses"])){ + $data["social_media_addresses"] = ['facebook'=>'', 'twitter'=>'', 'instagram'=>''] ; + } + + $response = [ + 'status' => 1, + 'message' => '', + 'data' => ['property_contact' => $data] , + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + /** + * contact update or create + * + * @param $params + * + * @return array + */ + public function propertyContactUpdateOrCreate($params) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $contactCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $contactData = $this->propertyContactRepository->findByCriteria($contactCriteria); + if (!$contactData) { + $addData = [ + 'property_id' => $params['property_id'], + 'status' => 1, + 'created_by' => $params[ 'user_id' ], + 'updated_by' => $params[ 'user_id' ], + ]; + $saveData = array_merge($addData,$params['contact']); + + if(isset($saveData['social_media_addresses'])){ + $saveData['social_media_addresses'] = json_encode($this->clearSocialMediaAddresses($saveData['social_media_addresses'])); + } + + $createResult = $this->create($saveData); + if($createResult['status'] != 'success'){ + throw new ApiErrorException(lang('Not saved')); + } + $data = Arr::except($createResult['data'],['id','status','created_by','updated_by','created_at','updated_at']); + $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ; + $response = [ + 'status' => true, + 'data' => $data, + ]; + }else { + $saveData = $params['contact']; + if(isset($saveData['social_media_addresses'])){ + $saveData['social_media_addresses'] = json_encode($this->clearSocialMediaAddresses($saveData['social_media_addresses'])); + } + + $saveData['updated_by'] = $params['user_id']; + $updateResult = $this->update($contactData[0]['id'], $saveData) ; + + if($updateResult['status'] != 'success'){ + throw new ApiErrorException(lang('Not updated')); + } + $data = Arr::except($updateResult['data'],['id','status','created_by','updated_by','created_at','updated_at']); + $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ; + $response = [ + 'status' => true, + 'data' => ['property_contact' => $data] , + ]; + } + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return output($response); + } + + public function clearSocialMediaAddresses($params){ + $newAddressArray = []; + foreach ($params as $key => $value) { + $addressToArray = explode('/', $value) ; + $address = end($addressToArray); + if(!$address){ + array_pop($addressToArray); + $address = end($addressToArray); + } + $address = str_replace('@','',$address); + $newAddressArray[$key] = $address ; + } + return $newAddressArray; + } +} diff --git a/app/Core/Service/PropertyContentService.php b/app/Core/Service/PropertyContentService.php new file mode 100644 index 0000000..8d78ca5 --- /dev/null +++ b/app/Core/Service/PropertyContentService.php @@ -0,0 +1,291 @@ +languageService = $languageService; + $this->propertyContentCreateValidator = $propertyContentCreateValidator; + $this->propertyContentCategoryRepository = $propertyContentCategoryRepository; + $this->propertyContentRepository = $propertyContentRepository; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "content_category_id" => fillOnUndefined($param, "content_category_id"), + "content" => fillOnUndefined($param, "content"), + "locale" => fillOnUndefined($param, "locale"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $validationResult = $this->propertyContentCreateValidator->validate($insertData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $userCreateResult = $this->propertyContentRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyContentRepository->findByCriteria($param, $column); + + if (!$data) { + throw new ApiErrorException(lang('User data is not found.')) ; + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyContentRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + public function updateOrCreate($criteria = [], $saveData =[]){ + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyContentRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function propertyContent($params) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $contentRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'content_category_id', 'condition' => '=', 'value' => $params['category_id']], + ['field' => 'language_code', 'condition' => '=', 'value' => $params['language_code']], + ] + ]; + + $contentData = $this->propertyContentRepository->findByCriteria($contentRequest, ['id', 'property_id', 'content_category_id', 'language_code', 'content']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_content' => $contentData]]; + + } catch(ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function propertyContentUpdate($params) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $contentCollection = collect(fillOnUndefined($params, 'contents')) ; + $updates = $contentCollection->where('content_id', '!=' , null)->toArray(); + + // get all property contents + $propertyContentRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyContentResponse = $this->select($propertyContentRequest); + + if($propertyContentResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + $propertyContentCollection = collect($propertyContentResponse['data']); + foreach ($contentCollection as $content){ + + $contentCheck = $propertyContentCollection + ->where('property_id', '=', $params['property_id']) + ->where('content_category_id', '=', $content['category_id']) + ->where('locale', '=', $params['locale']) + ->first(); + + if($contentCheck){ + $saveData = [ + 'content' => $content['value'], + 'updated_by' => $params['user_id'], + ]; + $updateStatus = $this->update($contentCheck['id'], $saveData) ; + + if($updateStatus['status'] != 'success'){ + throw new Exception(lang('Not updated')); + } + + }else{ + + $saveData = [ + 'property_id' => $params['property_id'], + 'content_category_id' => $content['category_id'], + 'content' => $content['value'], + 'locale' => $params['locale'], + 'status' => 1, + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + + ]; + $saveStatus = $this->create($saveData) ; + if($saveStatus['status'] != 'success'){ + throw new ApiErrorException(lang('Not saved')); + } + + } + + } + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + $propertyContent = $this->propertyContent($requestParams); + + if($propertyContent['status'] != 'success'){ + throw new ApiErrorException($propertyContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } +} diff --git a/app/Core/Service/PropertyExecutiveService.php b/app/Core/Service/PropertyExecutiveService.php new file mode 100644 index 0000000..34696e5 --- /dev/null +++ b/app/Core/Service/PropertyExecutiveService.php @@ -0,0 +1,625 @@ +propertyExecutiveRepository = $propertyExecutiveRepository; + $this->propertyExecutiveTypeService = $propertyExecutiveTypeService; + $this->propertyExecutiveCreateValidator = $propertyExecutiveCreateValidator; + $this->propertyExecutiveUpdateValidator = $propertyExecutiveUpdateValidator; + $this->offerContactMappingRepository = $offerContactMappingRepository; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "executive_type_id" => fillOnUndefined($param, "executive_type_id"), + "name_surname" => fillOnUndefined($param, "name_surname"), + "email" => fillOnUndefined($param, "email"), + "phone_code" => fillOnUndefined($param, "phone_code"), + "phone" => fillOnUndefined($param, "phone"), + 'extension' => fillOnUndefined($param, 'extension'), + "mobile_code" => fillOnUndefined($param, "mobile_code"), + "mobile" => fillOnUndefined($param, "mobile"), + "fax_code" => fillOnUndefined($param, "fax_code"), + "fax" => fillOnUndefined($param, "fax"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $executiveTypeRequest = [ + 'criteria' => [ + ['field' => 'name_surname', 'condition' => '=', 'value' => $insertData['name_surname']], + ['field' => 'property_id', 'condition' => '=', 'value' => $insertData['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'firstRow' => true + ]; + $propertyExecutiveExist = $this->propertyExecutiveRepository->findByCriteria($executiveTypeRequest); + if(!empty($propertyExecutiveExist)){ + throw new ApiErrorException(lang('Registered user in the system')); + } + + $validationResult = $this->propertyExecutiveCreateValidator->validate($insertData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $userCreateResult = $this->propertyExecutiveRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyExecutiveRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyExecutiveUpdateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateResult = $this->propertyExecutiveRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData =[]){ + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyExecutiveRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getPropertyExecutive($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + // get all executive types + $executiveTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + $executiveTypeResponse = $this->propertyExecutiveTypeService->select($executiveTypeRequest); + if($executiveTypeResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + + $executiveTypeCollection = collect($executiveTypeResponse['data']); + + // get all property executive types + $propertyExecutiveTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $propertyExecutiveTypeResponse = $this->select($propertyExecutiveTypeRequest); + + if($propertyExecutiveTypeResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + $propertyExecutiveTypeCollection = collect($propertyExecutiveTypeResponse['data']); + + foreach ($executiveTypeCollection as $executiveType){ + + + // get property_executive data + $propertyExecutiveItem = []; + $executiveTypeCheck = $propertyExecutiveTypeCollection->where('executive_type_id', '=', $executiveType['id']) + ->toArray(); + foreach ($executiveTypeCheck as $propertyExecutive){ + $propertyExecutiveItem['name_surname'] = $propertyExecutive['name_surname'] ; + $propertyExecutiveItem['email'] = $propertyExecutive['email'] ; + $propertyExecutiveItem['phone_code'] = $propertyExecutive['phone_code'] ; + $propertyExecutiveItem['phone'] = $propertyExecutive['phone'] ; + $propertyExecutiveItem['mobile_code'] = $propertyExecutive['mobile_code'] ; + $propertyExecutiveItem['mobile'] = $propertyExecutive['mobile'] ; + $propertyExecutiveItem['fax_code'] = $propertyExecutive['fax_code'] ; + $propertyExecutiveItem['fax'] = $propertyExecutive['fax'] ; + $propertyExecutiveItem['view_full_phone'] = $propertyExecutive['view_full_phone'] ; + $propertyExecutiveItem['view_full_mobile'] = $propertyExecutive['view_full_mobile'] ; + $propertyExecutiveItem['view_full_fax'] = $propertyExecutive['view_full_fax'] ; + + } + + + $executiveTypeItem['executive_type_id'] = $executiveType['id'] ; + $executiveTypeItem['name'] = $executiveType['name']; + $executiveTypeItem['data'] = $propertyExecutiveItem ; + $return[] = $executiveTypeItem ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['executive_type' => $return]]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function listPropertyExecutive($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + // get all executive types + $executiveTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + + ]; + + + $executiveTypeResponse = $this->propertyExecutiveTypeService->select($executiveTypeRequest); + if($executiveTypeResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + + $executiveTypeCollection = collect($executiveTypeResponse['data']); + + // get all property executive types + $propertyExecutiveTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'orderBy' => [['field' => 'updated_at', 'value' => 'DESC']], + 'with' => ['executiveType'] + ]; + + $propertyExecutiveResponse = $this->select($propertyExecutiveTypeRequest); + + if($propertyExecutiveResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Executive Data Not Loaded')); + } + + $propertyExecutiveResponse = $propertyExecutiveResponse['data'] ; + + $return['executive_type'] = []; + foreach ($executiveTypeCollection as $executiveType){ + + + + // Get Locale data + + $executiveTypeItem['executive_type_id'] = $executiveType['id'] ; + $executiveTypeItem['name'] = $executiveType['name']; + $executiveTypeItem['language_key'] = $executiveType['language_key']; + $return['executive_type'][] = $executiveTypeItem ; + } + + $return['executives'] = [] ; + foreach ($propertyExecutiveResponse as $executive){ + $executiveItem = [ + 'id' => $executive['id'], + 'property_id' => $executive['property_id'], + 'executive_type_id' => $executive['executive_type_id'], + 'executive_type_name' => $executive['executive_type']['name'], + 'name_surname' => $executive['name_surname'], + 'email' => $executive['email'], + 'phone_code' => $executive['phone_code'], + 'phone' => $executive['phone'], + 'extension' => $executive['extension'], + 'mobile_code' => $executive['mobile_code'], + 'mobile' => $executive['mobile'], + 'fax_code' => $executive['fax_code'], + 'fax' => $executive['fax'], + 'view_full_phone' => $executive['view_full_phone'], + 'view_full_mobile' => $executive['view_full_mobile'], + 'view_full_fax' => $executive['view_full_fax'], + ]; + $return['executives'][] = $executiveItem ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return ]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyExecutiveAdd($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + + foreach ($params['executive_type'] as $executive_type){ + + $createData = [ + 'property_id' => $params['property_id'], + 'executive_type_id' => $executive_type['executive_type_id'], + 'name_surname' => fillOnUndefined($executive_type, 'name_surname'), + 'email' => fillOnUndefined($executive_type, 'email'), + 'phone_code' => fillOnUndefined($executive_type, 'phone_code'), + 'phone' => fillOnUndefined($executive_type, 'phone'), + 'extension' => fillOnUndefined($executive_type, 'extension'), + 'mobile_code' => fillOnUndefined($executive_type, 'mobile_code'), + 'mobile' => fillOnUndefined($executive_type, 'mobile'), + 'fax_code' => fillOnUndefined($executive_type, 'fax_code'), + 'fax' => fillOnUndefined($executive_type, 'fax'), + 'updated_by' => $params['user_id'], + 'created_by' => $params['user_id'], + ]; + $createStatus = $this->create($createData); + + if ($createStatus['status'] != 'success') { + throw new Exception($createStatus['message']); + } + + } + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + + $propertyExecutive = $this->listPropertyExecutive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyExecutiveUpdate($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + foreach ($params['executive_type'] as $executive_type){ + $updateData = [ + 'executive_type_id' => fillOnUndefined($executive_type, 'executive_type_id'), + 'name_surname' => fillOnUndefined($executive_type, 'name_surname'), + 'email' => fillOnUndefined($executive_type, 'email') , + 'phone_code' => fillOnUndefined($executive_type, 'phone_code'), + 'phone' => fillOnUndefined($executive_type, 'phone'), + 'extension' => fillOnUndefined($executive_type, 'extension'), + 'mobile_code' => fillOnUndefined($executive_type, 'mobile_code'), + 'mobile' => fillOnUndefined($executive_type, 'mobile') , + 'fax_code' => fillOnUndefined($executive_type, 'fax_code'), + 'fax' => fillOnUndefined($executive_type, 'fax'), + 'updated_by' => $params['user_id'], + 'status' => 1, + ]; + + $propertyExecutiveExistRequest = [ + 'criteria' => [ + ['field' => 'name_surname', 'condition' => '=', 'value' => $executive_type['name_surname']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '!=', 'value' => $executive_type['id'] ], + ['field' => 'status', 'condition' => '=', 'value' => 1] + + ], + 'firstRow' => true + ]; + + $propertyExecutiveExist = $this->propertyExecutiveRepository->findByCriteria($propertyExecutiveExistRequest); + if (isset($propertyExecutiveExist['id'])) { + throw new ApiErrorException(lang('Registered user in the system')); + } + + + $updateStatus = $this->update($executive_type['id'], $updateData) ; + + if($updateStatus['status'] != 'success'){ + throw new Exception($updateStatus['message']); + } + } + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + + $propertyExecutive = $this->listPropertyExecutive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyExecutiveDelete($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + + if(!isset($params['property_executive_id']) || !is_numeric($params['property_executive_id']) ){ + throw new ApiErrorException('property_executive_id field require'); + } + $propertyExecutiveDeleteRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['property_executive_id']], + ] + ]; + + + $propertyExecutiveTypeResponse = $this->propertyExecutiveRepository->delete($propertyExecutiveDeleteRequest); + if(!$propertyExecutiveTypeResponse){ + throw new ApiErrorException('No record to delete'); + + } + + + + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + + $propertyExecutive = $this->getPropertyExecutive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyExecutivePassive($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $updateParams = [ + "status" => 0, + "updated_by" => $params['user_id'], + "updated_at" => time(), + ]; + + $updateResult = $this->propertyExecutiveRepository->update($params['property_executive_id'], $updateParams); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $updateParams = [ + "status" => 0, + "updated_by" => $params['user_id'], + "updated_at" => time(), + ]; + + $updateCriteria = [ + 'criteria' => [ + ['field' => 'property_executive_id', 'condition' => '=', 'value' => $params['property_executive_id']], + ] + ]; + + + + $offerUpdateResult = $this->offerContactMappingRepository->findByCriteria($updateCriteria , ['id']); + $updateIds = collect($offerUpdateResult)->keyBy('id')->keys()->toArray(); + $offerUpdateResult = $this->offerContactMappingRepository->updateWhereIn($updateIds , $updateParams); + + if ($offerUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyExecutive = $this->listPropertyExecutive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyExecutiveTypeService.php b/app/Core/Service/PropertyExecutiveTypeService.php new file mode 100644 index 0000000..31836d6 --- /dev/null +++ b/app/Core/Service/PropertyExecutiveTypeService.php @@ -0,0 +1,151 @@ +propertyExecutiveTypeRepository = $propertyExecutiveTypeRepository; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $userCreateResult = $this->propertyExecutiveTypeRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyExecutiveTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyExecutiveTypeRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData =[]){ + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyExecutiveTypeRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + +} diff --git a/app/Core/Service/PropertyFactMappingService.php b/app/Core/Service/PropertyFactMappingService.php new file mode 100644 index 0000000..96ffce2 --- /dev/null +++ b/app/Core/Service/PropertyFactMappingService.php @@ -0,0 +1,338 @@ +languageService = $languageService; + $this->propertyFactMappingRepository = $propertyFactMappingRepository; + $this->applicationCacheService = $applicationCacheService; + $this->propertyFactCheckboxValidator = $propertyFactCheckboxValidator; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $userCreateResult = $this->propertyFactMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]->toArray(); + + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyFactMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deleteById($param){ + + $userCreateResult = $this->propertyFactMappingRepository->delete(); + + } + + public function removePropertyFactMapping($param = []) + { + + //Todo: validations + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + //Todo: cache datası yeni bir fonksiyon yapılıp herkes oradan geçekecek + + $cacheInfo = $this->applicationCacheService->getApplicationCache([]); + if($cacheInfo['status'] != 'success'){ + throw new ApiErrorException(lang('Cache Required')); + } + $userData = $cacheInfo['data'] ; + + + $factIds = []; + foreach ($param["facts"] as $fact){ + $factIds[] = $fact["id"]; + } + + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $userData['property_id']], + ], + "whereIn"=> + [ + ["field"=>"fact_id","value"=>$factIds] + ] + ]; + + $factMappingDatas = $this->propertyFactMappingRepository->findByCriteria($findCriteria); + if (!$factMappingDatas) { + throw new ApiErrorException(lang('Fact cannot loaded')); + } + + + // Todo: gönderilen idler ile veritabanında bulunan idler karşılaştırılacak. Uyumsuz data varsa hiç bir şey silinmeden error throw edilecek + + $deleteRowIds = []; + foreach ($factMappingDatas as $factMappingData){ + $ids = []; + $ids[] = $factMappingData["id"]; + $delete = $this->propertyFactMappingRepository->deleteById($ids); + if (!$delete) { + throw new ApiErrorException(lang('cannot delete fact')); + } + + } + $response['status'] = 1; + $response['data'] = []; + + + + } + catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function addPropertyFactMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + $propertyId = $params['property_id']; + $userId = $params['user_id']; + $propertyFactData = $params['data']; + + $addPropertyFactMapping = []; + foreach ($propertyFactData as $key => $param) + { + $addPropertyFactMapping[] = + [ + 'property_id' => $propertyId, + 'fact_id' => fillOnUndefined($param, 'id'), + 'created_by' => $userId, + 'updated_by' => $userId, + ]; + } + + //TODO : $addPropertyFactMapping için validation işlemleri yapılacaktır.(property_id ve fact id inin unique doğrulamasına bakılması unutulmamalı ) + $response = $this->propertyFactMappingRepository->createAll($addPropertyFactMapping); + + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function updatePropertyFactMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + + $validationResult = $this->propertyFactCheckboxValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $addPropertyFactMapping = []; + $addFactList = collect($params['property_fact']) + ->where('is_selected' ,'=', true); + $addFactIds = $addFactList->keyBy("id")->keys()->toArray(); + + $removeFactList = collect($params['property_fact']) + ->where('is_selected' ,'=', false); + + $removeFactIds = $removeFactList->keyBy("id")->keys()->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + "whereIn" => [ + ["field" => "fact_id", "value" => $addFactIds] + ] + ]; + $checkPropertyMappingResponse = $this->select($checkPropertyMappingRequest,['id', 'property_id', 'fact_id']); + + if($checkPropertyMappingResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Mapping data not loaded')); + } + $checkPropertyMappingCollect = collect($checkPropertyMappingResponse['data']); + + foreach ($addFactList->toArray() as $key => $param) + { + + $isFactMappingBefore = $checkPropertyMappingCollect->where('property_id', '=', $params['property_id']) + ->where('fact_id', '=', $param['id']) + ->first(); + + $description = [] ; + foreach (fillOnUndefined($param, "description", []) as $title) { + $description[$title['language_code']] = !empty($title['description']) ? $title['description'] : null; + } + + if(empty($isFactMappingBefore)){ + + $addPropertyFactMapping[] = + [ + 'property_id' => $params['property_id'], + 'fact_id' => fillOnUndefined($param, 'id'), + 'description' => !empty($description) ? json_encode($description) : null, + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + + } else { + $this->propertyFactMappingRepository->update($isFactMappingBefore['id'], ['description' => !empty($description) ? json_encode($description) : null]); + } + } + + $response = $this->propertyFactMappingRepository->createAll($addPropertyFactMapping); + + + if($removeFactIds){ + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + "whereIn" => + [ + ["field" => "fact_id", "value" => $removeFactIds] + ] + ]; + + $deletePropertyFactMapping = $this->propertyFactMappingRepository->findByCriteria($findCriteria); + + $deleteThisIds = []; + foreach ($deletePropertyFactMapping as $deleteThisItem){ + $deleteThisIds[] = $deleteThisItem['id']; + } + + if($deleteThisIds){ + $this->propertyFactMappingRepository->deleteById($deleteThisIds); + + } + } + + if ($response['status'] != 'success') { + throw new ApiErrorException(lang('Data is not added')) ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + } diff --git a/app/Core/Service/PropertyFactService.php b/app/Core/Service/PropertyFactService.php new file mode 100644 index 0000000..70b384f --- /dev/null +++ b/app/Core/Service/PropertyFactService.php @@ -0,0 +1,758 @@ +applicationCacheService = $applicationCacheService; + $this->propertyFactMappingService = $propertyFactMappingService; + $this->languageService = $languageService; + $this->propertyFactRepository = $propertyFactRepository; + $this->propertyFactMappingRepository = $propertyFactMappingRepository; + $this->propertyFactSearchValidator = $propertyFactSearchValidator; + $this->propertyRoomFactMappingService = $propertyRoomFactMappingService; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "Fact_category_id" => fillOnUndefined($param, "Fact_category_id"), + "Fact" => fillOnUndefined($param, "Fact"), + "locale" => fillOnUndefined($param, "locale"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $userCreateResult = $this->propertyFactRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]->toArray(); + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyFactRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyFact($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [] + ]; + $fectData = $this->select($requestData); + + + if ($fectData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $factCollection = collect($fectData['data']); + + $propertyFactMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $propertyFactMappingData = $this->propertyFactMappingService->select($propertyFactMappingRequest); + if ($propertyFactMappingData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $propertyFactMappingData = $propertyFactMappingData['data'] ? $propertyFactMappingData['data'] : []; + $propertyFactMapping = []; + foreach ($propertyFactMappingData as $propertyFactItem) { + $propertyFactMapping[$propertyFactItem['fact_id']] = $propertyFactItem; + } + + $return = []; + + $mainFacts = $factCollection->where('parent_id', '=', null) + ->toArray(); + $responseFacts = []; + + foreach ($mainFacts as $fact) { + + + $mainFactItem['id'] = $fact['id']; + $mainFactItem['name'] = $fact['name']; + $mainFactItem['language_key'] = $fact['language_key']; + $mainFactItem['title_language_key'] = $fact['title_language_key']; + $mainFactItem['icon'] = $fact['icon']; + if ($fact['type'] == 1) { + $mainFactItem['icon'] = 'far fa-tv-retro'; + } + $subCats = $factCollection->where('parent_id', '=', $fact['id']) + ->toArray(); + + array_multisort( + array_column($subCats, 'order_number'), SORT_ASC, + array_column($subCats, 'name'), SORT_ASC, + $subCats + ); + + + $responseSubCats = []; + foreach ($subCats as $subCat) { + + $subCatItem['id'] = $subCat['id']; + $subCatItem['name'] = $subCat['name']; + $subCatItem['language_key'] = $subCat['language_key']; + $subCatItem['title_language_key'] = $subCat['title_language_key']; + $subCatItem['icon'] = $subCat['icon']; + $subCatItem['priority'] = $subCat['order_number']; + $subCatItem['parent_id'] = $fact['id']; + + if ($subCat['type'] == 1) { + $subCatItem['icon'] = 'far fa-tv-retro'; + } + + $subFacts = $factCollection->where('parent_id', '=', $subCat['id']) + ->toArray(); + + array_multisort( + array_column($subFacts, 'order_number'), SORT_ASC, + array_column($subFacts, 'name'), SORT_ASC, + $subFacts + ); + + $responseSubFacts = []; + + foreach ($subFacts as $subFact) { + + $subFactItem['id'] = $subFact['id']; + $subFactItem['name'] = $subFact['name']; + $subFactItem['language_key'] = $subFact['language_key']; + $subFactItem['title_language_key'] = $subFact['title_language_key']; + $subFactItem['type'] = $subFact['type']; + $subFactItem['icon'] = $subFact['icon']; + $subFactItem['parent_id'] = $subCat['id']; + + $checkMappingData = isset($propertyFactMapping[$subFact['id']]) ? $propertyFactMapping[$subFact['id']] : []; + $subFactItem['is_selected'] = $checkMappingData ? true : false; + $subFactItem['mapping_id'] = fillOnUndefined($checkMappingData, 'id'); + + // Todo Will be typed when 'attributes' is added + // $subFactItem['attributes'] = null; + + + $subFactItem['description'] = null; + if ($checkMappingData && fillOnUndefined($checkMappingData, 'description')) { + $descriptionLangContents = json_decode($checkMappingData['description'], 1); + + if(isset($params['locale'])) { + $params['currentLanguage'] = $params['locale']; + } + + if (isset($params['currentLanguage']) && isset($descriptionLangContents[$params['currentLanguage']])) { + $subFactItem['description'] = $descriptionLangContents[$params['currentLanguage']]; + } + } + + $responseSubFacts[] = $subFactItem; + } + $subCatItem['fact'] = $responseSubFacts; + $responseSubCats[$subCat['id']] = $subCatItem; + } + + $mainFactItem['fact_subcategory'] = $responseSubCats; + $return[$fact['id']] = $mainFactItem; + + } + + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function searchPropertyFact($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->propertyFactSearchValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $propertyFactRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyFactData = $this->propertyFactMappingRepository->findByCriteria($propertyFactRequest, ['id', 'property_id', 'fact_id']); + $propertyFacts = collect($propertyFactData)->keyBy('fact_id')->keys()->toArray(); + + if (!$propertyFacts) { + throw new ApiErrorException(lang('Check fact data from your content')); + } + + + $searchFactRequest = [ + 'whereIn' => [ + ['field' => 'id', 'value' => $propertyFacts] + ] + ]; + + if ($params['search_term']) { + $searchFactRequest['criteria'][] = ['field' => 'name', 'condition' => 'like', 'value' => '%' . $params['search_term'] . '%']; + } + + $searchFactData = $this->propertyFactRepository->findByCriteria($searchFactRequest, ['id', 'name', 'language_key']); + + if (!$searchFactData) { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $response = [ + 'status' => true, + 'data' => $searchFactData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getPropertyRoomFact($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'parent_id', 'condition' => '=', 'value' => 293], + + ], + 'with' => [] + ]; + $factData = $this->select($requestData); + + + if ($factData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $subFacts = $factData['data'] ? $factData['data'] : []; + + $showRecommended = false; + $propertyRoomFactMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $propertyRoomFactMappingData = $this->propertyRoomFactMappingService->select($propertyRoomFactMappingRequest); + if ($propertyRoomFactMappingData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $propertyRoomFactMappingCollection = collect($propertyRoomFactMappingData['data']); + $propertyRoomFactMappingData = $propertyRoomFactMappingData['data'] ? $propertyRoomFactMappingData['data'] : []; + $propertyFactMapping = []; + foreach ($propertyRoomFactMappingData as $mappingItem) { + $propertyFactMapping[$mappingItem['fact_id']] = $mappingItem; + $propertyRoomFactMapping[$mappingItem['room_id'] . '|' . $mappingItem['fact_id']] = $mappingItem; + } + if ($propertyRoomFactMappingData) { + $showRecommended = true; + } + + + $responseSubFacts = []; + + + if ($showRecommended) { + $showRecommendedData = $propertyRoomFactMappingCollection + ->where('room_id', '=', $params['room_id']) + ->first(); + if ($showRecommendedData) { + $showRecommended = false; + } + } + + + foreach ($subFacts as $subFact) { + + $subFactItem['id'] = $subFact['id']; + $subFactItem['name'] = $subFact['name']; + $subFactItem['language_key'] = $subFact['language_key']; + $subFactItem['title_language_key'] = $subFact['title_language_key']; + $subFactItem['type'] = $subFact['type']; + if ($subFact['type'] == 1) { + $subFactItem['icon'] = $subFact['icon']; + } + + $checkMappingData = isset($propertyRoomFactMapping[$params['room_id'] . '|' . $subFact['id']]) ? $propertyRoomFactMapping[$params['room_id'] . '|' . $subFact['id']] : []; + + $checkRecommended = isset($propertyFactMapping[$subFact['id']]) ? $propertyFactMapping[$subFact['id']] : []; + + $subFactItem['is_selected'] = $checkMappingData ? true : false; + $subFactItem['is_recommended'] = $checkRecommended ? true : false; + $subFactItem['mapping_id'] = fillOnUndefined($checkMappingData, 'id'); + $subFactItem['is_feature'] = fillOnUndefined($checkMappingData, 'is_feature', 0); + + $responseSubFacts[] = $subFactItem; + } + + if (collect($responseSubFacts)->where('is_recommended', 'true')->count() == 0) { + $showRecommended = false; + } + + $response = [ + 'status' => true, + 'data' => [ + 'get_room_facts' => $responseSubFacts, + 'show_recommended' => $showRecommended, + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getSubCategoryFacts($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'type', 'condition' => '=', 'value' => 1], + ['field' => 'parent_id', 'condition' => '=', 'value' => $params['sub_category_id']], + ], + 'orderBy' => [ + ["field" => "order_number", "value" => "ASC"], + ["field" => "name", "value" => "ASC"], + ] + + ]; + $factData = $this->select($requestData); + + if ($factData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $factCollection = collect($factData['data']); + + $propertyFactMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $propertyFactMappingData = $this->propertyFactMappingService->select($propertyFactMappingRequest); + if ($propertyFactMappingData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + + $propertyFactMappingData = $propertyFactMappingData['data'] ? $propertyFactMappingData['data'] : []; + $propertyFactMapping = []; + foreach ($propertyFactMappingData as $propertyFactItem) { + $propertyFactMapping[$propertyFactItem['fact_id']] = $propertyFactItem; + } + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + $subFacts = $factCollection->toArray(); + $responseSubFacts = []; + + foreach ($subFacts as $subFact) { + + $subFactItem['id'] = $subFact['id']; + $subFactItem['name'] = $subFact['name']; + $subFactItem['language_key'] = $subFact['language_key']; + $subFactItem['title_language_key'] = $subFact['title_language_key']; + $subFactItem['type'] = $subFact['type']; + $subFactItem['icon'] = $subFact['icon']; + + $checkMappingData = isset($propertyFactMapping[$subFact['id']]) ? $propertyFactMapping[$subFact['id']] : []; + $subFactItem['is_selected'] = $checkMappingData ? true : false; + $subFactItem['mapping_id'] = fillOnUndefined($checkMappingData, 'id'); + + $subFactItem['description'] = []; + $descriptionLangContents = $checkMappingData ? json_decode($checkMappingData['description'], 1) : []; + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + $subFactItem['description'] = $responseLangDescription; + + + $responseSubFacts[] = $subFactItem; + } + + $response = [ + 'status' => true, + 'data' => $responseSubFacts, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getSubCategoryMenus($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $requestData = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'type', 'condition' => '=', 'value' => 0], + ['field' => 'id', 'condition' => '!=', 'value' => 9], // Accommodation + ] + ]; + $factData = $this->select($requestData); + + if ($factData['status'] != 'success') { + throw new ApiErrorException(lang('Fact data not loaded')); + } + $factCollection = collect($factData['data']); + $mainFacts = $factCollection->where('parent_id', '=', null)->sortBy('order_number')->toArray(); + $responseSubFacts = []; + $isFoundItem = false; + $nextItem = '/app/content/rooms'; + $prevItem = '/app/content/photos'; + $isDisable = true; + $foundIndex = -1; + $logData = []; + + foreach ($mainFacts as $mainFact) { + $subFacts = $factCollection->where('parent_id', '=', $mainFact['id'])->sortBy('order_number')->toArray(); + foreach ($subFacts as $subFact) { + + $logData[] = $subFact; + + if ($params['parent_id'] == $subFact['parent_id']) { + $subFactItem['id'] = $subFact['id']; + $subFactItem['name'] = $subFact['name']; + $subFactItem['language_key'] = $subFact['language_key']; + $subFactItem['title_language_key'] = $subFact['title_language_key']; + $subFactItem['type'] = $subFact['type']; + $subFactItem['icon'] = $subFact['icon']; + $subFactItem['alias'] = 'Property.Fact.SubCategoryFacts.' . $subFact['id']; + $subFactItem['url'] = '/app/content/facts/' . $subFact['id']; + $subFactItem['is_disable'] = $isDisable; + + $responseSubFacts[] = $subFactItem; + } + if ($params['sub_category_id'] == $subFact['id']) { + $isDisable = false; + } + + if ($isFoundItem) { + $subFactItem['icon'] = $subFact['icon']; + $foundIndex++; + } + + if ($params['sub_category_id'] == $subFact['id']) { + $isFoundItem = true; + $foundIndex = 0; + } + + if ($isFoundItem && $foundIndex == 1) { + $nextItem = '/app/content/facts/' . $subFact['id']; + } + + if (!$isFoundItem) { + $prevItem = '/app/content/facts/' . $subFact['id']; + } + + + } + + } + + $response = [ + 'status' => true, + 'data' => [ + 'menu' => $responseSubFacts, + 'prev' => $prevItem, + 'next' => $nextItem, + + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getPropertyOfferFilter($params = [], $offerAllFactIds = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $categories = $params; + $responseArray = []; + $accommodationTypes = []; + foreach ($categories as $category) { + $categoryArray = []; + $categoryItem = $category; + foreach ($category['fact_subcategory'] as $subCategory) { + $subCategoryItem = $subCategory; + if ($subCategory['id'] == 9) { + $facts = collect($subCategory['fact'])->map(function ($value) use ($offerAllFactIds) { + $value['is_selected'] = array_search($value['id'], $offerAllFactIds) > -1; + return $value; + })->values()->all(); + $subCategoryItem['fact'] = $facts ? $facts : []; + $accommodationTypes = $subCategoryItem['fact']; + } else { + $facts = collect($subCategory['fact'])->where('is_selected', '=', true)->map(function ($value) use ($offerAllFactIds) { + $value['is_selected'] = array_search($value['id'], $offerAllFactIds) > -1; + return $value; + })->values()->all(); + $subCategoryItem['fact'] = $facts ? $facts : []; + + $categoryArray[$subCategory['id']] = $subCategoryItem; + } + } + $categoryItem['fact_subcategory'] = $categoryArray; + $responseArray[$category['id']] = $categoryItem; + } + $response = [ + 'status' => true, + 'data' => [ + 'get_facts' => $responseArray, + 'accommodation_types' => $accommodationTypes, + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPropertyOfferFilterForHtml($params = [], $offerAllFactIds = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $categories = $params; + $responseArray = []; + foreach ($categories as $category) { + $categoryArray = []; + $categoryItem = $category; + foreach ($category['fact_subcategory'] as $subCategory) { + $subCategoryItem = $subCategory; + $facts = collect($subCategory['fact']) + ->where('is_selected', '=', true) + ->whereIn('id', $offerAllFactIds) + ->map(function ($value) use ($offerAllFactIds) { + return $value; + })->values()->all(); + $subCategoryItem['fact'] = $facts ? $facts : []; + + if ($facts) { + $categoryArray[$subCategory['id']] = $subCategoryItem; + } + } + $categoryItem['fact_subcategory'] = $categoryArray; + $responseArray[$category['id']] = $categoryItem; + } + + $response = [ + 'status' => true, + 'data' => $responseArray, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function checkPropertyFactMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $request = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'whereIn' => [ + ['field' => 'fact_id', 'value' => $param['fact_ids']], + ], + 'count' => 1 + ]; + $data = $this->propertyFactMappingRepository->findByCriteria($request); + if ($data < count($param['fact_ids'])) { + throw new ApiErrorException('Property - Fact Mapping not validate.'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + +} diff --git a/app/Core/Service/PropertyGroupMappingService.php b/app/Core/Service/PropertyGroupMappingService.php new file mode 100644 index 0000000..a303bf6 --- /dev/null +++ b/app/Core/Service/PropertyGroupMappingService.php @@ -0,0 +1,88 @@ +request = $request; + $this->propertyGroupRepository = $propertyGroupRepository; + $this->propertyGroupMappingRepository = $propertyGroupMappingRepository; + } + + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyGroupMappingRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getPropertyGroupMapping($propertyGroupMappingCriteria, $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyGroupMapping =$this->select($propertyGroupMappingCriteria,$column); + + if(!$propertyGroupMapping){ + throw new ApiErrorException(lang('Property Group Mapping data not found')); + } + + $response['status'] = 1; + $response['data'] = $propertyGroupMapping['data']; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyGroupService.php b/app/Core/Service/PropertyGroupService.php new file mode 100644 index 0000000..9df2342 --- /dev/null +++ b/app/Core/Service/PropertyGroupService.php @@ -0,0 +1,83 @@ +request = $request; + $this->propertyGroupRepository = $propertyGroupRepository; + } + + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyGroupRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getPropertyGroup($propertyGroupCriteria, $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyGroup =$this->select($propertyGroupCriteria,$column); + + if(!$propertyGroup){ + throw new ApiErrorException(lang('Property Group data not found')); + } + + $response['status'] = 1; + $response['data'] = $propertyGroup; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + +} diff --git a/app/Core/Service/PropertyInvoiceService.php b/app/Core/Service/PropertyInvoiceService.php new file mode 100644 index 0000000..dec93e0 --- /dev/null +++ b/app/Core/Service/PropertyInvoiceService.php @@ -0,0 +1,329 @@ +propertyRepository = $propertyRepository; + $this->bookingRepository = $bookingRepository; + $this->propertyInvoiceRepository = $propertyInvoiceRepository; + + $commissionChannelCategoryMapping = [ + 2 => 'commission_offline', + 3 => 'commission', + 4 => 'commission_channel', + ]; + + $this->commissionChannelCategoryMapping = $commissionChannelCategoryMapping; + + $this->exchangeCurrencyCode = 'EUR'; + } + + public function calculatePeriodCommission($propertyId, $periodStartDate, $periodFinishDate) + { + + $propertyDetailCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + //['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBookingEngines.channel'], + 'firstRow' => true + ]; + + $propertyDetail = $this->propertyRepository->findByCriteria($propertyDetailCriteria); + + $channelBaseCommission = []; + foreach ($propertyDetail['property_booking_engines'] as $propertyBookingEngine) { + + $commissionRateParam = isset($this->commissionChannelCategoryMapping[$propertyBookingEngine['channel']['channel_category_id']]) ? $this->commissionChannelCategoryMapping[$propertyBookingEngine['channel']['channel_category_id']] : 'commission'; + $commissionRateRate = $propertyDetail[$commissionRateParam]; + + $bookingListCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyBookingEngine['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $propertyBookingEngine['channel_id']], + ['field' => 'checkout_date', 'condition' => '>=', 'value' => $periodStartDate], + ['field' => 'checkout_date', 'condition' => '<', 'value' => $periodFinishDate], + ], + 'whereIn' => + [ + ['field' => 'status', 'value' => [1, 3]] + ] + ]; + + $bookingList = $this->bookingRepository->findByCriteria($bookingListCriteria, ['id', 'property_id', 'channel_id', 'total', 'currency_code', 'checkin_date', 'checkout_date']); + + $bookingListCollect = collect($bookingList)->groupBy('currency_code')->map(function ($group) { + return [ + 'total' => $group->sum('total') + ]; + }); + + $bookingListCollect = $bookingListCollect ? $bookingListCollect->toArray() : []; + + $exchangeRate = 1; + $exchangeRateOriginal = 1; + $exchangeRateDate = Carbon::parse($periodStartDate)->lastOfMonth()->toDateString(); + foreach ($bookingListCollect as $bookingCurrency => $bookingTotal) { + + if ($bookingCurrency != $this->exchangeCurrencyCode) { + $exchangeRateCheck = CurrencyRates::where('currency_code', $bookingCurrency) + ->where('exc_currency_code', $this->exchangeCurrencyCode) + ->where('date', $exchangeRateDate) + ->first(); + + if ($exchangeRateCheck) { + $exchangeRateCheck = $exchangeRateCheck->toArray(); + + } else { + $exchangeRateCheck = CurrencyRates::where('currency_code', $bookingCurrency) + ->where('exc_currency_code', $this->exchangeCurrencyCode) + ->where('date', '<', $exchangeRateDate) + ->orderBy('date', 'DESC') + ->first()->toArray(); + } + + $exchangeRate = $exchangeRateCheck['rate']; + $exchangeRateDate = $exchangeRateCheck['date']; + + } + + $bookingTotalWithExchange = $bookingTotal['total'] * $exchangeRate; + $bookingCommissionWithExchange = $bookingTotalWithExchange * $commissionRateRate / 100; + + $channelBaseCommission[$propertyBookingEngine['channel_id']][$bookingCurrency] = [ + 'total' => (float)number_format($bookingTotal['total'], '4', '.', ''), + 'exchangeRate' => $exchangeRate, + 'exchangeRateDate' => $exchangeRateDate, + 'exchangeData' => [ + 'total' => (float)number_format($bookingTotalWithExchange, '4', '.', ''), + 'commission' => (float)number_format($bookingCommissionWithExchange, '4', '.', ''), + 'commissionRate' => $commissionRateRate, + 'currencyCode' => $this->exchangeCurrencyCode, + ] + ]; + + } + + + } + + + $channelBaseTotal = 0; + $channelBaseTotalCommission = 0; + foreach ($channelBaseCommission as $channelBase) { + $channelBaseValue = reset($channelBase); + $channelBaseTotal += $channelBaseValue['exchangeData']['total']; + $channelBaseTotalCommission += $channelBaseValue['exchangeData']['commission']; + } + + $commission = [ + 'channelBaseTotal' => $channelBaseTotal, + 'channelBaseTotalCommission' => $channelBaseTotalCommission, + ]; + + return $commission; + } + + + public function invoiceWithPeriod($propertyId, $period) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + $excludeTaxPropertyIds = [1683]; //$propertyDetail['country'] + + $exchangeCurrencyCode = 'EUR'; + + $periodStartDate = Carbon::parse($period . '-01')->toDateString(); + $periodFinishDate = Carbon::parse($periodStartDate)->addMonth()->firstOfMonth()->toDateString(); + + + $periodFixedValueStartDate = Carbon::parse($period . '-01')->toDateString(); + $periodFixedValueFinishDate = Carbon::parse($periodStartDate)->addMonth()->firstOfMonth()->toDateString(); + + try { + + $propertyDetailCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + //['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBookingEngines.channel'], + 'firstRow' => true + ]; + + $propertyDetail = $this->propertyRepository->findByCriteria($propertyDetailCriteria); + + if (!$propertyDetail) { + throw new ApiErrorException('Property not found'); + } + + if ($propertyDetail['invoice_start_date']) { + $propertyCreateTime = Carbon::parse($propertyDetail['invoice_start_date'])->toDateString(); + } elseif ($propertyDetail['invoice_start_date']) { + $propertyCreateTime = Carbon::parse($propertyDetail['activation_date'])->toDateString(); + } + + //$propertyCreateTime = '2024-08-10'; + + if ($propertyCreateTime >= $periodFinishDate) { + throw new ApiErrorException('Property not ready for invoice: ' . $propertyCreateTime . ' - ' . $propertyDetail['name']); + } + + $conditions = [ + 'invoice_type' => $propertyDetail['invoice_type'], + 'fee' => $propertyDetail['fee'], + 'credit' => $propertyDetail['credit'], + 'commission' => $propertyDetail['commission'], + 'commission_payment' => $propertyDetail['commission_payment'], + 'commission_offline' => $propertyDetail['commission_offline'], + 'commission_channel' => $propertyDetail['commission_channel'], + ]; + + + $periodCommission = $this->calculatePeriodCommission($propertyId, $periodStartDate, $periodFinishDate); + + if ($propertyDetail['invoice_type'] == 'ANN') { + + $periodYearCount = (Carbon::parse($propertyCreateTime)->lastOfMonth()->diffInMonths($periodFinishDate) % 12) + 1; + $periodAnnuallyInvoiceDate = Carbon::parse($propertyCreateTime)->addMonth($periodYearCount * 12)->toDateString(); + + $periodFixedValueFinishDate = Carbon::parse($propertyCreateTime)->addMonths($periodYearCount * 12)->firstOfMonth()->toDateString(); + $periodFixedValueStartDate = Carbon::parse($periodFixedValueFinishDate)->subMonths($periodYearCount * 12)->firstOfMonth()->toDateString(); + + $periodCommissionFroFixed = $this->calculatePeriodCommission($propertyId, $periodFixedValueStartDate, $periodFinishDate); + + } else { + $periodCommissionFroFixed = $periodCommission; + } + + + $channelBaseTotal = $periodCommission['channelBaseTotal']; + $channelBaseTotalCommission = $periodCommission['channelBaseTotalCommission']; + + if(isset($propertyDetail['promotion_fee']) && !empty($propertyDetail['promotion_fee']) && !empty($propertyDetail['promotion_fee_month'])) { + if($periodFinishDate < Carbon::parse($propertyDetail['activation_date'])->addMonths($propertyDetail['promotion_fee_month'])->toDateString()) { + $propertyDetail['fee'] = $propertyDetail['promotion_fee']; + } + } + + $fixedValue = 0; //$propertyDetail['fee'] + if ($propertyDetail['invoice_type'] == 'MNT') { + + //if ($propertyDetail['credit'] == 0) { + $fixedValue = $propertyDetail['fee']; + //} else if ($periodCommissionFroFixed['channelBaseTotalCommission'] < $propertyDetail['credit']) { + //$fixedValue = $propertyDetail['fee']; + //} + + $isPropertyFirstMonth = Carbon::parse($propertyCreateTime)->format('Y-m') == Carbon::parse($periodStartDate)->format('Y-m') ? true : false; + + if ($isPropertyFirstMonth) { + $propertyFirstMonthDiffInDays = Carbon::parse($propertyCreateTime)->diffInDays(Carbon::parse($periodFinishDate)->subDay()); + $perDailyFixedValue = $fixedValue / Carbon::parse($periodStartDate)->daysInMonth; + + $fixedValue = $propertyFirstMonthDiffInDays * $perDailyFixedValue; + + } + + } elseif ($propertyDetail['invoice_type'] == 'ANN') { + + if (Carbon::parse($periodFixedValueStartDate)->format('Y-m') == $period) { + $fixedValue = $propertyDetail['fee']; + } + + } + + + if ($periodCommissionFroFixed['channelBaseTotal'] < $propertyDetail['credit']) { + $channelBaseTotalCommission = 0; + } else { + $channelBaseTotalCommission = ($periodCommissionFroFixed['channelBaseTotal'] - $propertyDetail['credit']) * $propertyDetail['commission'] / 100; + } + + //Suspended + if($propertyDetail['status'] == 3) { + $fixedValue = 0; + $channelBaseTotalCommission = ($periodCommissionFroFixed['channelBaseTotal']) * $propertyDetail['commission'] / 100;; + } + + $fixedTaxValue = $fixedValue * 0.20; + if (in_array($propertyDetail['id'], $excludeTaxPropertyIds)) { + $fixedTaxValue = 0; + } + + $totalInvoiceValue = $fixedValue + $fixedTaxValue + $channelBaseTotalCommission; + + + $propertyInvoiceCreateParam = [ + 'property_id' => $propertyId, + 'period' => $period, + 'fixed' => (float)number_format($fixedValue, '2', '.', ''), + 'fixed_tax' => (float)number_format($fixedTaxValue, '2', '.', ''), + 'commission' => (float)number_format($channelBaseTotalCommission, '2', '.', ''), + 'total' => (float)number_format($totalInvoiceValue, '2', '.', ''), + 'currency' => 'EUR', + 'sales' => (float)number_format($channelBaseTotal, '2', '.', ''), + 'summary' => !empty($channelBaseCommission) ? json_encode($channelBaseCommission) : null, + 'conditions' => json_encode($conditions), + 'status' => 1, + ]; + + $propertyInvoiceCheckCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'period', 'condition' => '=', 'value' => $period], + ], + 'firstRow' => true + ]; + + $propertyInvoiceCheck = $this->propertyInvoiceRepository->findByCriteria($propertyInvoiceCheckCriteria); + + if ($propertyInvoiceCheck) { + $propertyInvoiceCreate = $this->propertyInvoiceRepository->update($propertyInvoiceCheck['id'], $propertyInvoiceCreateParam); + } else { + $propertyInvoiceCreate = $this->propertyInvoiceRepository->create($propertyInvoiceCreateParam); + } + + if ($propertyInvoiceCreate['status'] != 'success') { + throw new ApiErrorException($propertyInvoiceCreate['message']); + } + + + $response = [ + 'status' => true, + 'data' => $propertyInvoiceCreate['data'], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyModuleMappingService.php b/app/Core/Service/PropertyModuleMappingService.php new file mode 100644 index 0000000..1866278 --- /dev/null +++ b/app/Core/Service/PropertyModuleMappingService.php @@ -0,0 +1,253 @@ +propertyModuleMappingRepository = $propertyModuleMappingRepository; + $this->propertyConfigService = $propertyConfigService; + $this->configKey = 'data_rate'; + $this->request = $request; + $this->currentRoute = $this->request->route(); + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "property_module_id" => fillOnUndefined($param, "property_module_id"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyModuleMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyModuleMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyModuleMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getPropertyModuleMapping($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + + $propertyModuleRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + + ], + 'with' => ['propertyModule'] + ]; + $propertyModuleResponse = $this->select($propertyModuleRequest); + + if ($propertyModuleResponse['status'] != 'success') { + throw new ApiErrorException(lang('ModuleMapping Data Not Loaded')); + } + + $propertyMappedModules = array_column($propertyModuleResponse['data'], 'property_module'); + + $totalPoint = collect($propertyMappedModules)->sum('point'); + + $return['property_modules'] = $propertyMappedModules ; + $return['data_point'] = $totalPoint ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyModuleMappingUpdate($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $propertyModuleRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_module_id', 'condition' => '=', 'value' => $params['property_module_id']], + ] + ]; + $propertyModuleResponse = $this->select($propertyModuleRequest); + + if ($propertyModuleResponse['status'] != 'success') { + throw new ApiErrorException(lang('ModuleMapping Data Not Loaded')); + } + + if (!$propertyModuleResponse['data']) { + $createData = [ + 'property_id' => $params['property_id'], + 'property_module_id' => $params['property_module_id'], + 'status' => 1, + 'updated_by' => $params['user_id'], + 'created_by' => $params['user_id'], + ]; + $createStatus = $this->create($createData); + if ($createStatus['status'] != 'success') { + throw new Exception($createStatus['message']); + } + + } + + + $propertyModuleMapping = $this->getPropertyModuleMapping($params); + + if ($propertyModuleMapping['status'] != 'success') { + throw new ApiErrorException($propertyModuleMapping['message']); + } + + $configParams = [ + 'config_keys' => [ + [ + 'config_key' => $this->configKey, + 'config_value_json' => json_encode(['point' => $propertyModuleMapping['data']['data_point']]) + ] + ], + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $params['user_id'], + ]; + + $propertyConfig = $this->propertyConfigService->propertyConfigUpdate($configParams); + + if ($propertyConfig['status'] != 'success') { + + throw new ApiErrorException($propertyConfig['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_module_mapping' => $propertyModuleMapping['data']]]; + + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyNetworkService.php b/app/Core/Service/PropertyNetworkService.php new file mode 100644 index 0000000..f78f4f4 --- /dev/null +++ b/app/Core/Service/PropertyNetworkService.php @@ -0,0 +1,190 @@ +bookingRepository = $bookingRepository; + $this->bookingRoomRepository = $bookingRoomRepository; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->propertyPromotionRepository = $propertyPromotionRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomBedRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getAllDashboardData($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + if (fillOnUndefined($params, 'property_id', null) == null) { + throw new ApiErrorException(lang('property_id is required')); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'checkin_date', 'condition' => '>', 'value' => Carbon::now()->subWeek(2)->toDate()], + ['field' => 'checkout_date', 'condition' => '<', 'value' => Carbon::now()->addWeek(2)->toDate()] + ], + 'with' => ['bookingRoom'], + 'orderBy' => [["field" => "checkin_date", "value" => "ASC"]], + ]; + + $data = $this->bookingRepository->findByCriteria($criteria); + $data = $data ? $data : []; + + + $dailyRoomCounts = []; + foreach ($data as $perData) { + + $dates = []; + $perDataDatePeriod = CarbonPeriod::create($perData['checkin_date'], Carbon::parse($perData['checkout_date'])->subDay()->toDateString()); + $dates = $perDataDatePeriod->toArray(); + + foreach ($dates as $date) { + + if (!isset($dailyRoomCounts[$date->toDateString()])) { + $dailyRoomCounts[$date->toDateString()] = 0; + } + + $dailyRoomCounts[$date->toDateString()] += count($perData['booking_room']); + + } + } + + $dayLanguages = [ + "Monday" => 'day-short-monday', + "Tuesday" => 'day-short-tuesday', + "Wednesday" => 'day-short-wednesday', + "Thursday" => 'day-short-thursday', + "Friday" => 'day-short-friday', + "Saturday" => 'day-short-saturday', + "Sunday" => 'day-short-sunday' + ]; + + $bookingWeeklyCount = []; + for ($i = 0; $i < 7; $i++) { + + $iterDay = Carbon::now()->addDay($i)->format('l'); + $iterDate = Carbon::now()->addDay($i)->format('Y-m-d'); + + + if (isset($dailyRoomCounts[$iterDate])) { + + $bookingWeeklyCount[$iterDay] = [ + 'date' => $iterDate, + 'day' => $iterDay, + 'abbreviation_day' => $dayLanguages[$iterDay], + 'count' => $dailyRoomCounts[$iterDate], + ]; + } else { + + $bookingWeeklyCount[$iterDay] = [ + 'date' => $iterDate, + 'day' => $iterDay, + 'abbreviation_day' => $dayLanguages[$iterDay], + 'count' => 0 + ]; + + } + } + + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'count' => true + ]; + + $propertyChannelMappingCount = $this->propertyChannelMappingRepository->findByCriteria($propertyChannelMappingCriteria); + + $propertyPromotionCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'count' => true + ]; + $propertyPromotionCount = $this->propertyPromotionRepository->findByCriteria($propertyPromotionCriteria); + + $exportData = [ + 'reservation_count' => $bookingWeeklyCount, + 'channel_count' => $propertyChannelMappingCount, + 'promotion_count' => $propertyPromotionCount + ]; + + + $response = [ + 'status' => true, + 'data' => $exportData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyNonrefundableService.php b/app/Core/Service/PropertyNonrefundableService.php new file mode 100644 index 0000000..3258d2b --- /dev/null +++ b/app/Core/Service/PropertyNonrefundableService.php @@ -0,0 +1,361 @@ +propertyNonrefundableRepository = $propertyNonrefundableRepository; + $this->propertyNonrefundableAddValidator = $propertyNonrefundableAddValidator; + $this->propertyRoomRateChannelMappingRepository = $propertyRoomRateChannelMappingRepository ; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + } + + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyNonrefundableRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createForm($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $roomRateChannelMappingRequest= [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channels']] + ], + 'with' => ['propertyRoomRateMapping.propertyRoomRate', 'propertyRoomRateMapping.propertyRoom', 'propertyChannel'], + ]; + + $roomRateChannelMappingResponse = $this->propertyRoomRateChannelMappingRepository->findByCriteria($roomRateChannelMappingRequest) ; + $roomRateChannelMappings = $roomRateChannelMappingResponse ? $roomRateChannelMappingResponse : [] ; + $roomRates = [] ; + + $channels = [] ; + + foreach ( $roomRateChannelMappings as $roomRateChannelMapping) { + $channels[] = [ + 'id' => $roomRateChannelMapping['property_channel']['id'], + 'name' => $roomRateChannelMapping['property_channel']['name'], + 'logo' => $roomRateChannelMapping['property_channel']['logo'], + ]; + $roomRates[$roomRateChannelMapping['room_rate_mapping_id']] = [ + 'room_rate_mapping_id' => $roomRateChannelMapping['room_rate_mapping_id'], + 'name' => $roomRateChannelMapping['property_room_rate_mapping']['property_room']['name'] . ' - '. $roomRateChannelMapping['property_room_rate_mapping']['property_room_rate']['name'], + 'room_id' => $roomRateChannelMapping['property_room_rate_mapping']['property_room']['id'], + 'room_name' => $roomRateChannelMapping['property_room_rate_mapping']['property_room']['name'], + 'rate_id' => $roomRateChannelMapping['property_room_rate_mapping']['property_room_rate']['id'], + 'rate_name' => $roomRateChannelMapping['property_room_rate_mapping']['property_room_rate']['name'], + ]; + } + + array_multisort( + array_column($roomRates, 'room_name'), SORT_ASC, + array_column($roomRates, 'rate_name'), SORT_ASC, + $roomRates + ); + + $channels = collect($channels)->unique('id')->sort()->values()->toArray(); + + $responseData = [ + 'channels' => $channels, + 'room_rate_mapping' => $roomRates, + ]; + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function storePropertyNonrefundable($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyNonrefundableAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $roomRateChannelMappingRequest= [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channels']] + ], + ]; + + $roomRateChannelMappingResponse = $this->propertyRoomRateChannelMappingRepository->findByCriteria($roomRateChannelMappingRequest) ; + $roomRateChannelMappings = $roomRateChannelMappingResponse ? $roomRateChannelMappingResponse : [] ; + + $rateChannel = [] ; + foreach ($roomRateChannelMappings as $roomRateChannelMapping) { + $rateChannel[$roomRateChannelMapping['room_rate_mapping_id'].'|'.$roomRateChannelMapping['channel_id']] =[ + "id" => $roomRateChannelMapping['id'], + "property_id" => $roomRateChannelMapping['property_id'], + "channel_id" => $roomRateChannelMapping['channel_id'], + "room_rate_mapping_id" => $roomRateChannelMapping['room_rate_mapping_id'], + ]; + } + + $propertyChannelMappingRequest= [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channels']] + ], + ]; + + $propertyChannelMappingResponse = $this->propertyChannelMappingRepository->findByCriteria($propertyChannelMappingRequest) ; + $propertyChannelMappings = $propertyChannelMappingResponse ? $propertyChannelMappingResponse : [] ; + + + + $propertyChannel = [] ; + foreach ($propertyChannelMappings as $propertyChannelMapping) { + $propertyChannel[$propertyChannelMapping['channel_id']] =[ + "id" => $propertyChannelMapping['id'], + "property_id" => $propertyChannelMapping['property_id'], + "channel_id" => $propertyChannelMapping['channel_id'], + ]; + } + + + $roomRateMappings = fillOnUndefined($params, 'room_rate_mapping', []) ; + $channels = fillOnUndefined($params, 'channels', []) ; + $storeData = [] ; + foreach ( $roomRateMappings as $roomRateMapping) { + foreach ($channels as $channel) { + $checkChannelKey = $roomRateMapping['room_rate_mapping_id'].'|'.$channel ; + if(isset($rateChannel[$checkChannelKey])) { + if (isset($propertyChannel[$channel])) { + $storeData[] = [ + 'property_id' => $params['property_id'], + 'channel_id' => $channel, + 'channel_mapping_id' => $propertyChannel[$channel]['id'], + 'room_rate_mapping_id' => $roomRateMapping['room_rate_mapping_id'], + 'action_type' => $roomRateMapping['action_type'], + 'value_type' => $roomRateMapping['value_type'], + 'value' => $roomRateMapping['value'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id"), + 'updated_by' => fillOnUndefined($params, "user_id"), + 'created_at' => time(), + 'updated_at' => time(), + ]; + } + } + } + } + + $roomRates = collect($params['room_rate_mapping'])->keyBy('room_rate_mapping_id')->keys()->toArray(); + $params['delete_room_rates'] = $roomRates; + $nonrefundableDeleteStatus = $this->deleteChannelsWithRatesNonrefundableData($params) ; + if($nonrefundableDeleteStatus['status'] != "success"){ + throw new ApiErrorException($nonrefundableDeleteStatus['message']); + } + + $addNonrefundableStatus = $this->propertyNonrefundableRepository->insert($storeData); + if($addNonrefundableStatus['status'] != "success"){ + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deleteChannelsWithRatesNonrefundableData($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $nonrefundableRequest= [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channels']] + ], + ]; + + $nonrefundableResponse = $this->propertyNonrefundableRepository->findByCriteria($nonrefundableRequest) ; + $nonrefundableData = $nonrefundableResponse ? $nonrefundableResponse : [] ; + $roomRates = $params['delete_room_rates']; + $deleteNonrefundableData = collect($nonrefundableData)->whereIn('room_rate_mapping_id', $roomRates)->values(); + $deleteIds = $deleteNonrefundableData->keyBy('id')->keys()->toArray(); + if($deleteIds){ + $nonrefundableDeleteStatus = $this->propertyNonrefundableRepository->destroy($deleteIds) ; + if($nonrefundableDeleteStatus['status'] != "success"){ + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getNonrefundableData($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $nonrefundableRequest= [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'whereIn' => [ + ['field' => 'channel_id', 'value' => $params['channels']] + ], + 'with' => ['propertyChannel', 'propertyRoomRateMapping.propertyRoomRate', 'propertyRoomRateMapping.propertyRoom'] + ]; + $nonrefundableResponse = $this->propertyNonrefundableRepository->findByCriteria($nonrefundableRequest, ['id', 'property_id', 'channel_id', 'channel_mapping_id', 'room_rate_mapping_id', 'action_type', 'value_type', 'value']) ; + $nonrefundableData = $nonrefundableResponse ? $nonrefundableResponse : [] ; + $nonrefundableCollection = collect($nonrefundableData) ; + + $channelList = $nonrefundableCollection->unique('channel_id')->map(function ($value){ + return $value['property_channel']; + })->sortBy('name')->values()->toArray(); + + $responseData = [] ; + foreach ($channelList as $channel) { + $channelData = $nonrefundableCollection->where('channel_id', '=', $channel['id'])->values()->toArray(); + $channelItem = $channel ; + $responseChannelData = [] ; + foreach ($channelData as $data) { + $dataItem = $data ; + $dataItem['name'] = $data['property_room_rate_mapping']['property_room']['name'] . ' - ' . $data['property_room_rate_mapping']['property_room_rate']['name']; + $dataItem['room_name'] = $data['property_room_rate_mapping']['property_room']['name']; + $dataItem['rate_name'] = $data['property_room_rate_mapping']['property_room_rate']['name']; + unset($dataItem['property_room_rate_mapping']); + unset($dataItem['property_channel']); + $responseChannelData[] = $dataItem; + } + $responseChannelData = collect($responseChannelData)->values()->toArray(); + + array_multisort( + array_column($responseChannelData, 'room_name'), SORT_ASC, + array_column($responseChannelData, 'rate_name'), SORT_ASC, + $responseChannelData + ); + + $channelItem['nonrefundable_data'] = $responseChannelData; + $responseData[] = $channelItem ; + } + + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyPaymentService.php b/app/Core/Service/PropertyPaymentService.php new file mode 100644 index 0000000..48a2b75 --- /dev/null +++ b/app/Core/Service/PropertyPaymentService.php @@ -0,0 +1,3850 @@ +request = $request; + $this->paymentTypeRepository = $paymentTypeRepository; + $this->paymentTransactionRepository = $paymentTransactionRepository; + $this->propertyPaymentMappingRepository = $propertyPaymentMappingRepository; + $this->propertyPaymentInstallmentRepository = $propertyPaymentInstallmentRepository; + $this->paymentBinNumberRepository = $paymentBinNumberRepository; + $this->currencyRatesRepository = $currencyRatesRepository; + $this->propertyPaymentMappingCreateValidator = $propertyPaymentMappingCreateValidator; + $this->propertyPaymentMappingUpdateValidator = $propertyPaymentMappingUpdateValidator; + $this->propertyPaymentMappingStatusUpdateValidator = $propertyPaymentMappingStatusUpdateValidator; + $this->propertyPaymentMappingSetDefaultValidator = $propertyPaymentMappingSetDefaultValidator; + $this->propertyPaymentInstallmentsUpdateValidator = $propertyPaymentInstallmentsUpdateValidator; + $this->currencyService = $currencyService; + $this->propertyPaymentTransactionCreateValidator = $propertyPaymentTransactionCreateValidator; + $this->propertyPaymentTransactionUpdateValidator = $propertyPaymentTransactionUpdateValidator; + + } + + public function getExchangeRates() + { + + $exchangeRate = []; + + $exchangeRatesDailyLastParam = [ + 'criteria' => [], + 'orderBy' => [["field" => "date", "value" => "DESC"]], + 'firstRow' => true + ]; + + $exchangeRatesDailyLast = $this->currencyRatesRepository->findByCriteria($exchangeRatesDailyLastParam); + + + if (isset($exchangeRatesDailyLast['date'])) { + $exchangeRatesDailyParam = [ + 'criteria' => [ + ['field' => 'date', 'condition' => '=', 'value' => $exchangeRatesDailyLast['date']] + ] + ]; + + $exchangeRatesDaily = $this->currencyRatesRepository->findByCriteria($exchangeRatesDailyParam); + + foreach ($exchangeRatesDaily as $rate) { + $exchangeRate[$rate['currency_code'] . $rate['exc_currency_code']] = $rate['rate']; + } + } + + + return $exchangeRate; + } + + public function getPaymentTransactionDetail($paymentCode) + { + + $response = ['status' => false, 'message' => '']; + try { + + $paymentTransactionParam = [ + 'criteria' => [ + ['field' => 'code', 'condition' => '=', 'value' => $paymentCode] + ], + 'with' => ['paymentTypeMapping.paymentType', 'property'], + 'firstRow' => true + ]; + + $paymentTransaction = $this->paymentTransactionRepository->findByCriteria($paymentTransactionParam); + + if (empty($paymentTransaction)) { + throw new ApiErrorException(lang('Payment Transaction is not found.')); + } + + $response = [ + 'status' => true, + 'data' => $paymentTransaction, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function getPaymentTypeMapping($propertyId, $currency, $creditCardNumber) + { + + $paymentTypeAndInstallment['propertyPaymentMappingId'] = null; + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = []; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = null; + $propertyPaymentMappingInstallment = []; + + $preferredBankPos = null; + + $creditCardNumber = substr($creditCardNumber, 0, 6); + + + $paymentBinNumberParam = [ + 'criteria' => [ + ['field' => 'bin_number', 'condition' => '=', 'value' => $creditCardNumber] + ], + 'firstRow' => true + ]; + + $paymentBinNumber = $this->paymentBinNumberRepository->findByCriteria($paymentBinNumberParam); + + if (!empty($paymentBinNumber)) { + $preferredBankPos = $paymentBinNumber['payment_type_id']; + } + + $propertyPaymentMappingParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'with' => ['paymentType'] + ]; + + $propertyPaymentMapping = $this->propertyPaymentMappingRepository->findByCriteria($propertyPaymentMappingParam); + $propertyPaymentMappingCollect = collect($propertyPaymentMapping); + + + if (empty($propertyPaymentMapping)) { + throw new ApiErrorException(lang('Payment Type Mapping not found')); + } + + //Eğer aynı banka ve aynı currency ve taksit var ise + $propertyPaymentMappingSelect = $propertyPaymentMappingCollect->where('currency_code', $currency)->where('payment_type_id', $preferredBankPos)->where('installment', 1)->sortByDesc('id')->first(); + if (!is_null($propertyPaymentMappingSelect)) { + + $paymentMappingInstallmentParam = [ + 'criteria' => [ + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $propertyPaymentMappingSelect['id']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + + ], + 'orderBy' => [["field" => "installment", "value" => "ASC"]], + ]; + + $propertyPaymentMappingInstallment = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentMappingInstallmentParam, ['installment', 'commission']); + + $paymentTypeAndInstallment['propertyPaymentMappingId'] = $propertyPaymentMappingSelect['id']; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = $propertyPaymentMappingSelect['currency_code']; + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = $propertyPaymentMappingInstallment; + + } + + //Eğer aynı currency ve banka olmayıp taksit var ise + if (is_null($paymentTypeAndInstallment['propertyPaymentMappingId'])) { + $propertyPaymentMappingSelect = $propertyPaymentMappingCollect->where('currency_code', $currency)->where('installment', 1)->where('payment_type.pos_code', '<>', 'POS')->sortByDesc('id')->first(); + if (!is_null($propertyPaymentMappingSelect)) { + + $paymentMappingInstallmentParam = [ + 'criteria' => [ + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $propertyPaymentMappingSelect['id']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'orderBy' => [["field" => "installment", "value" => "ASC"]], + ]; + + $propertyPaymentMappingInstallment = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentMappingInstallmentParam, ['installment', 'commission']); + + $paymentTypeAndInstallment['propertyPaymentMappingId'] = $propertyPaymentMappingSelect['id']; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = $propertyPaymentMappingSelect['currency_code']; + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = $propertyPaymentMappingInstallment; + + } + } + + //Eğer aynı currency ise + if (is_null($paymentTypeAndInstallment['propertyPaymentMappingId'])) { + $propertyPaymentMappingSelect = $propertyPaymentMappingCollect->where('currency_code', $currency)->sortByDesc('id')->first(); + if (!is_null($propertyPaymentMappingSelect)) { + $paymentTypeAndInstallment['propertyPaymentMappingId'] = $propertyPaymentMappingSelect['id']; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = $propertyPaymentMappingSelect['currency_code']; + } + } + + + //Eğer hiç bişey yok ise default + if (is_null($paymentTypeAndInstallment['propertyPaymentMappingId'])) { + $propertyPaymentMappingSelect = $propertyPaymentMappingCollect->where('is_default', 1)->sortByDesc('id')->first(); + if (!is_null($propertyPaymentMappingSelect)) { + $paymentTypeAndInstallment['propertyPaymentMappingId'] = $propertyPaymentMappingSelect['id']; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = $propertyPaymentMappingSelect['currency_code']; + + + if (!is_null($paymentTypeAndInstallment['propertyPaymentMappingCurrency']) && !is_null($preferredBankPos) && $propertyPaymentMappingSelect['payment_type_id'] == $preferredBankPos) { + + $paymentMappingInstallmentParam = [ + 'criteria' => [ + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $propertyPaymentMappingSelect['id']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'orderBy' => [["field" => "installment", "value" => "ASC"]], + ]; + + $propertyPaymentMappingInstallment = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentMappingInstallmentParam, ['installment', 'commission']); + + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = $propertyPaymentMappingInstallment; + + } else if ($propertyPaymentMappingCollect->whereIn('payment_type.pos_code', ['MOK', 'SPY'])->isNotEmpty()) { + $paymentMappingInstallmentParam = [ + 'criteria' => [ + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $propertyPaymentMappingSelect['id']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'orderBy' => [["field" => "installment", "value" => "ASC"]], + ]; + + $propertyPaymentMappingInstallment = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentMappingInstallmentParam, ['installment', 'commission']); + + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = $propertyPaymentMappingInstallment; + } + + + } + + } + + //FOR Turkish credit cards are forced TRY currency via TRY POS + if (!empty($paymentBinNumber)) { + if ($paymentTypeAndInstallment['propertyPaymentMappingCurrency'] != 'TRY') { + + $propertyPaymentMappingSelect = $propertyPaymentMappingCollect + ->where('currency_code', 'TRY') + ->sortByDesc('id')->first(); + + if (!is_null($propertyPaymentMappingSelect)) { + + $paymentMappingInstallmentParam = [ + 'criteria' => [ + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $propertyPaymentMappingSelect['id']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'orderBy' => [["field" => "installment", "value" => "ASC"]], + ]; + + + $propertyPaymentMappingInstallment = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentMappingInstallmentParam, ['installment', 'commission']); + + + $paymentTypeAndInstallment['propertyPaymentMappingId'] = $propertyPaymentMappingSelect['id']; + $paymentTypeAndInstallment['propertyPaymentMappingCurrency'] = $propertyPaymentMappingSelect['currency_code']; + $paymentTypeAndInstallment['propertyPaymentMappingInstallment'] = $propertyPaymentMappingInstallment; + } + } + } + + return $paymentTypeAndInstallment; + + } + + public function initializePayment($params = []) + { + $response = ['status' => false, 'message' => '']; + try { + + $exchangeRateStore = 1; + $paymentCode = getPaymentGenerate(fillOnUndefined($params, 'type')); + $ipAddress = $this->request->getClientIp() == '127.0.0.1' ? '185.137.215.118' : $this->request->getClientIp(); + $paymentCheckUrl = Config::get('app.url') . '/paymentCheck/' . $paymentCode; + + if (isset($params['preferredPaymentTypeId'])) { + + $propertyPaymentMappingParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['preferredPaymentTypeId']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['propertyId']], + ['field' => 'status', 'condition' => '<>', 'value' => 0], + ], + 'firstRow' => true, + 'with' => ['paymentType'] + ]; + + $propertyPaymentMapping = $this->propertyPaymentMappingRepository->findByCriteria($propertyPaymentMappingParam); + + if (empty($propertyPaymentMapping)) { + throw new ApiErrorException(lang('Payment Type not found')); + } + + $paymentTypeMapping = [ + "propertyPaymentMappingId" => $propertyPaymentMapping['id'], + 'propertyPaymentMappingInstallment' => [], + 'propertyPaymentMappingCurrency' => $propertyPaymentMapping['currency_code'], + ]; + + + } else { + + $paymentTypeMapping = $this->getPaymentTypeMapping($params['propertyId'], $params['currency'], $params['creditCard']['number']); + + if (is_null($paymentTypeMapping['propertyPaymentMappingId'])) { + throw new ApiErrorException(lang('Payment Type not found')); + } + } + + $installmentRate = []; + if ($params['installment'] > 0) { + + if (empty($paymentTypeMapping['propertyPaymentMappingInstallment'])) { + throw new ApiErrorException(lang('Pos not available installment')); + } + + $propertyPaymentMappingInstallment = collect($paymentTypeMapping['propertyPaymentMappingInstallment']); + + $installmentRate = $propertyPaymentMappingInstallment->where('installment', $params['installment'])->first(); + + if (empty($propertyPaymentMappingInstallment->where('installment', $params['installment'])->first())) { + throw new ApiErrorException(lang('Pos not available this installment number')); + } + + } + + + $paymentTypeMappingId = $paymentTypeMapping['propertyPaymentMappingId']; + + $paymentTypeParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $paymentTypeMappingId] + ], + 'with' => ['paymentType'], + 'firstRow' => true + ]; + + $paymentType = $this->propertyPaymentMappingRepository->findByCriteria($paymentTypeParam); + + $params['amount'] = moneyDoubleFormatDecimal($params['amount']); + $params['base_amount'] = moneyDoubleFormatDecimal($params['amount']); + $params['base_currency'] = $params['currency']; + + + //Eğer istenen döviz tipi postan farklı ise convert edilecek + if ($params['currency'] != $paymentType['currency_code']) { + + $exchangeRate = $this->getExchangeRates(); + + if (!isset($exchangeRate[$params['currency'] . $paymentType['currency_code']])) { + throw new ApiErrorException(lang('Currency exchange value not found.')); + } + + $exchangeRateStore = $exchangeRate[$params['currency'] . $paymentType['currency_code']]; + + $params['amount'] = moneyDoubleFormatDecimal($params['amount'] * $exchangeRateStore); + $params['currency'] = $paymentType['currency_code']; + + } + + if ($params['installment'] > 0 && !empty($installmentRate)) { + $params['amount'] = moneyDoubleFormatDecimal($params['amount'] + ($params['amount'] * $installmentRate['commission'] / 100)); + $params['installmentRate'] = $installmentRate; + } + + $paymentParam = []; + + //TODO: PaymentFactory + if ($paymentType['payment_type']['pos_code'] == 'POS') { + + $posAccount = []; + $posAccount['bank'] = $paymentType['payment_type']['bank_code']; + $posAccount['model'] = $paymentType['payment_type']['threed_model']; + $posAccount['env'] = $paymentType['status'] == 1 ? 'production' : 'test'; + + foreach ($paymentType['paramsArray'] as $paramKey => $param) { + + if (isset($paymentType['payment_type']['paramsArray'][$paramKey])) { + $posAccount[$paymentType['payment_type']['paramsArray'][$paramKey]['key']] = $param; + } + } + + $POS = new \App\Core\Payment\Pos\Pos($posAccount); + + $params['installment'] = $params['installment'] == 1 ? 0 : $params['installment']; + + $orderParam = [ + 'id' => $paymentCode, + 'email' => '', + 'name' => $params['creditCard']['name'], + 'amount' => (double)$params['amount'], + 'installment' => $params['installment'], + 'currency' => $paymentType['currency_code'], + 'ip' => $ipAddress, + 'success_url' => $paymentCheckUrl, + 'fail_url' => $paymentCheckUrl, + 'transaction' => 'pay', // pay => Auth, pre PreAuth + 'lang' => 'tr', + 'rand' => microtime() + ]; + + $params['orderParam'] = $orderParam; + + + $creditCard = [ + 'name' => $params['creditCard']['name'], + //'type' => 'visa', + 'number' => $params['creditCard']['number'], + 'month' => $params['creditCard']['month'], + 'year' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'] + ]; + + //dd($creditCard, $orderParam); + + $POS->prepare($orderParam, $creditCard); + $paymentParam = $POS->get3dFormData(); + + if (empty($paymentParam)) { + throw new ApiErrorException(lang('Failed to create 3D Form data.')); + } + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'STR') { + + + try { + + //Secret key + $secretKey = $paymentType['paramsArray']['secretKey']; + $stripe = new \Stripe\StripeClient($secretKey); + + $token = $stripe->tokens->create([ + 'card' => [ + 'number' => $params['creditCard']['number'], + 'exp_month' => $params['creditCard']['month'], + 'exp_year' => $params['creditCard']['year'], + 'cvc' => $params['creditCard']['cvv'] + ], + ]); + + + $source = $stripe->sources->create([ + 'currency' => $params['currency'], + 'amount' => ($params['amount'] * 100), + 'type' => 'three_d_secure', + 'three_d_secure' => [ + 'card' => $token->card->id, + ], + 'redirect' => [ + 'return_url' => $paymentCheckUrl + ], + ]); + + //Pending, 3DSecure + if ($source['status'] == 'failed') { + + //Direct Payment + $charge = $stripe->charges->create([ + 'card' => $token->id, + 'currency' => $params['currency'], + 'amount' => ($params['amount'] * 100), + 'description' => $paymentCode, + ]); + + if ($charge['status'] == 'succeeded') { + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode + ], + ]; + + } + + } else { + //Aksi tüm durumlarda 3dSecure devam et + //} elseif (in_array($source['status'], ['pending', 'chargeable'])) { + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } + + } catch (Exception $e) { + $response['message'] = $e->getMessage(); + } + + + $paymentTransactionStatus = 0; + if ($response['status']) { + + $paymentTransactionStatus = 1; + + if (isset($response['data']['redirectUrl'])) { + $paymentTransactionStatus = 2; + } + } + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'bank_order_id' => isset($charge) ? $charge->id : null, + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => isset($source) ? json_encode($source) : null, + 'response' => isset($charge) ? json_encode($charge) : null, + 'message' => fillOnUndefined($response, 'message'), + 'status' => $paymentTransactionStatus, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + //STRIPE END + + + } elseif ($paymentType['payment_type']['pos_code'] == 'ENW') { + + + try { + + //Secret key + $secretKey = config('app.stripeENWKey'); + $stripe = new \Stripe\StripeClient($secretKey); + + $token = $stripe->tokens->create([ + 'card' => [ + 'number' => $params['creditCard']['number'], + 'exp_month' => $params['creditCard']['month'], + 'exp_year' => $params['creditCard']['year'], + 'cvc' => $params['creditCard']['cvv'] + ], + ]); + + + $source = $stripe->sources->create([ + 'currency' => $params['currency'], + 'amount' => ($params['amount'] * 100), + 'type' => 'three_d_secure', + 'three_d_secure' => [ + 'card' => $token->card->id, + ], + 'redirect' => [ + 'return_url' => $paymentCheckUrl + ], + ]); + + //Pending, 3DSecure + if ($source['status'] == 'failed') { + + //Direct Payment + $charge = $stripe->charges->create([ + 'card' => $token->id, + 'currency' => $params['currency'], + 'amount' => ($params['amount'] * 100), + 'description' => $paymentCode, + ]); + + if ($charge['status'] == 'succeeded') { + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode + ], + ]; + + } + + } else { + //Aksi tüm durumlarda 3dSecure devam et + //} elseif (in_array($source['status'], ['pending', 'chargeable'])) { + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } + + } catch (Exception $e) { + $response['message'] = $e->getMessage(); + } + + + $paymentTransactionStatus = 0; + if ($response['status']) { + + $paymentTransactionStatus = 1; + + if (isset($response['data']['redirectUrl'])) { + $paymentTransactionStatus = 2; + } + } + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'bank_order_id' => isset($charge) ? $charge->id : null, + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => isset($source) ? json_encode($source) : null, + 'response' => isset($charge) ? json_encode($charge) : null, + 'message' => fillOnUndefined($response, 'message'), + 'status' => $paymentTransactionStatus, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + //STRIPE ENW END + + + } elseif ($paymentType['payment_type']['pos_code'] == 'SPY') { + + + $paymentInitializeParam = [ + 'merchantId' => $paymentType['paramsArray']['merchantId'], + 'merchantKey' => $paymentType['paramsArray']['merchantKey'], + 'appKey' => $paymentType['paramsArray']['appKey'], + 'appSecret' => $paymentType['paramsArray']['appSecret'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + + $sipayService = new App\Core\Payment\Sipay\Sipay($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentParam = $sipayService->paySmart3D($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'MOK') { + + $paymentInitializeParam = [ + 'userName' => $paymentType['paramsArray']['userName'], + 'password' => $paymentType['paramsArray']['password'], + 'dealerCode' => $paymentType['paramsArray']['dealerCode'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + + $mokaService = new App\Core\Payment\Moka\Moka($paymentInitializeParam); + + $params['currency'] = $params['currency'] == 'TRY' ? 'TL' : $params['currency']; + + $paymentCreateParam = [ + 'key' => $params['orderId'], + 'CardHolderFullName' => $params['creditCard']['name'], + 'CardNumber' => $params['creditCard']['number'], + 'ExpMonth' => $params['creditCard']['month'], + 'ExpYear' => $params['creditCard']['year'], + 'CvcNumber' => $params['creditCard']['cvv'], + 'Currency' => $params['currency'], + 'Amount' => (double)$params['amount'],//10.50 + 'InstallmentNumber' => isset($params['installment']) ? $params['installment'] : 1, + 'OtherTrxCode' => $params['orderId'], + 'Description' => fillOnUndefined($params, 'description'), + 'RedirectUrl' => $paymentCheckUrl, + 'IsPreAuth' => 0, //0: Direct Provision 1: PreProvision + 'ClientIP' => config('app.env') == 'local' ? '185.137.215.118' : $ipAddress + ]; + + $paymentParam = $mokaService->DoDirectPaymentThreeD($paymentCreateParam); + + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'BOG') { + + + $paymentInitializeParam = [ + 'clientId' => $paymentType['paramsArray']['clientId'], + 'secretKey' => $paymentType['paramsArray']['secretKey'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $bankOfGeorgiaService = new App\Core\Payment\BankOfGeorgia\Payriff($paymentInitializeParam); + + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + if ($creditPaymentParam['currencyCode'] != 'GEL') { + throw new ApiErrorException(lang('This payment method only support GEL.')); + } + + $paymentParam = $bankOfGeorgiaService->paymentInitialize($creditPaymentParam); + + + if (!$paymentParam['status']) { + throw new ApiErrorException('Payment Initialize is not started.'); + } + + $paymentParam = $paymentParam['data']; + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'TBC') { + + + $paymentInitializeParam = [ + 'clientId' => $paymentType['paramsArray']['clientId'], + 'clientSecret' => $paymentType['paramsArray']['clientSecret'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $tbcBankService = new App\Core\Payment\TBCBankGeorgia\TBCBankGeorgia($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl, + 'ipAddress' => $ipAddress + ]; + + $paymentParam = $tbcBankService->paymentInitialize($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException('Payment Initialize is not started.'); + } + + $paymentParam = $paymentParam['data']; + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'QNB') { + + + $paymentInitializeParam = [ + 'merchantId' => $paymentType['paramsArray']['merchantId'], + 'merchantKey' => $paymentType['paramsArray']['merchantKey'], + 'appKey' => $paymentType['paramsArray']['appKey'], + 'appSecret' => $paymentType['paramsArray']['appSecret'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $qnbPayService = new App\Core\Payment\QNBPay\QNBPay($paymentInitializeParam); + + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentParam = $qnbPayService->paySmart3D($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'TBC') { + + + $paymentInitializeParam = [ + 'clientId' => $paymentType['paramsArray']['clientId'], + 'clientSecret' => $paymentType['paramsArray']['clientSecret'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $tbcBankService = new App\Core\Payment\TBCBankGeorgia\TBCBankGeorgia($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl, + 'ipAddress' => $ipAddress + ]; + + $paymentParam = $tbcBankService->paymentInitialize($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException('Payment Initialize is not started.'); + } + + $paymentParam = $paymentParam['data']; + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'WEE') { + + + $paymentInitializeParam = [ + 'merchantId' => $paymentType['paramsArray']['merchantId'], + 'apiKey' => $paymentType['paramsArray']['apiKey'], + 'secretKey' => $paymentType['paramsArray']['secretKey'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + 'ipAddress' => $ipAddress + ]; + + $weePayService = new App\Core\Payment\WeePay\WeePay($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentParam = $weePayService->paySmart3D($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'HLK') { + + + $paymentInitializeParam = [ + 'merchantId' => $paymentType['paramsArray']['merchantId'], + 'merchantKey' => $paymentType['paramsArray']['merchantKey'], + 'appKey' => $paymentType['paramsArray']['appKey'], + 'appSecret' => $paymentType['paramsArray']['appSecret'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $paymentTypeService = new App\Core\Payment\HalkOde\HalkOde($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentParam = $paymentTypeService->paySmart3D($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'ESN') { + + + $paymentInitializeParam = [ + 'merchant' => $paymentType['paramsArray']['merchant'], + 'merchantKey' => $paymentType['paramsArray']['merchantKey'], + 'contactMail' => $paymentType['paramsArray']['contactMail'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $esnekPosService = new App\Core\Payment\Esnekpos\Esnekpos($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentRequest = $esnekPosService->EYV3DPay($creditPaymentParam); + + if (!$paymentRequest['status']) { + throw new ApiErrorException($paymentRequest['message']); + } + + $paymentRequest = $paymentRequest['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentRequest), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'KVY') { + + $paymentInitializeParam = [ + 'customerId' => $paymentType['paramsArray']['customerId'], + 'merchantId' => $paymentType['paramsArray']['merchantId'], + 'userName' => $paymentType['paramsArray']['userName'], + 'password' => $paymentType['paramsArray']['password'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $paymentTypeService = new App\Core\Payment\KuveytTurk\KuveytTurk($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $paymentParam = $paymentTypeService->threeDModelPayGate($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + $paymentParam = $paymentParam['data']; + + $params['creditCard']['number'] = creditCardMask($params['creditCard']['number']); + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => $paymentParam, + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'RTL') { + + + $paymentInitializeParam = [ + 'userName' => $paymentType['paramsArray']['userName'], + 'password' => $paymentType['paramsArray']['password'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + 'ipAddress' => $ipAddress + ]; + + $retailPayService = new App\Core\Payment\RetailPay\RetailPay($paymentInitializeParam); + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + $creditPaymentParam['creditCard'] = [ + 'holderName' => $params['creditCard']['name'], + 'number' => $params['creditCard']['number'], + 'expiryMonth' => $params['creditCard']['month'], + 'expiryYear' => $params['creditCard']['year'], + 'cvv' => $params['creditCard']['cvv'], + 'installment' => $params['installment'], + ]; + + + $creditPaymentParam['client'] = [ + 'name' => isset($params['client']['name']) ? $params['client']['name'] : 'Extranetwork', + 'email' => isset($params['client']['email']) ? $params['client']['email'] : 'info@extranetwork.com', + 'phone' => isset($params['client']['phone']) ? $params['client']['phone'] : '+908508886428', + ]; + + + $paymentParam = $retailPayService->ordersAuthorize($creditPaymentParam); + + + if (!$paymentParam['status']) { + throw new ApiErrorException(lang('3D Form data not generated.')); + } + + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam['data']), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } elseif ($paymentType['payment_type']['pos_code'] == 'PYR') { + + + $paymentInitializeParam = [ + 'secretKey' => $paymentType['paramsArray']['secretKey'], + 'env' => $paymentType['status'] == 1 ? 'production' : 'test', + ]; + + $payriffService = new App\Core\Payment\Payriff\Payriff($paymentInitializeParam); + + + $creditPaymentParam = [ + 'amount' => (double)$params['amount'], + 'orderId' => $paymentCode, + 'orderCode' => $params['orderId'], + 'currencyCode' => $params['currency'], + 'paymentCheckUrl' => $paymentCheckUrl + ]; + + if ($creditPaymentParam['currencyCode'] != 'AZN') { + throw new ApiErrorException(lang('This payment method only support AZN.')); + } + + $paymentParam = $payriffService->paymentInitialize($creditPaymentParam); + + if (!$paymentParam['status']) { + throw new ApiErrorException('Payment Initialize is not started.'); + } + + $paymentParam = $paymentParam['data']; + + $paymentTransactionParam = [ + 'property_id' => $params['propertyId'], + 'code' => $paymentCode, + 'order_id' => $params['orderId'], + 'transaction_type' => fillOnUndefined($params, 'type', 'BKG'), + 'payment_type_mapping_id' => $paymentTypeMappingId, + 'base_amount' => $params['base_amount'], + 'base_currency' => $params['base_currency'], + 'exchange_rate' => $exchangeRateStore, + 'amount' => $params['amount'], + 'currency' => $paymentType['currency_code'], + 'installment' => $params['installment'], + 'params' => json_encode($params), + 'extra_params' => json_encode($paymentParam), + 'status' => 2, + ]; + + $paymentTransactionCreate = $this->paymentTransactionRepository->create($paymentTransactionParam); + + if ($paymentTransactionCreate['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => [ + 'paymentCode' => $paymentCode, + 'redirectUrl' => Config::get('app.url') . '/paymentRedirect/' . $paymentCode + ], + ]; + + } else { + throw new ApiErrorException(lang('Payment Type not found')); + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + + public function checkPayment($paymentCode, $params = []) + { + $response = ['status' => false, 'message' => '', 'data' => []]; + try { + + //dd(Input::All()); + $bankOrderId = null; + + $paymentTransactionDetail = $this->getPaymentTransactionDetail($paymentCode); + if (!$paymentTransactionDetail['status']) { + throw new ApiErrorException(lang('Payment Transaction not found.')); + } + + $paymentTransactionDetail = $paymentTransactionDetail['data']; + + $responseUrl = $paymentTransactionDetail['paramsArray']['responseUrl']; + $response['data']['responseUrl'] = $responseUrl; + $response['data']['paymentCode'] = $paymentCode; + + if ($paymentTransactionDetail['status'] != 3) { + Log::error($paymentCode); + Log::error($params); + throw new Exception('A previously terminated transaction.'); + } + + + if ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'POS') { + + $posAccount = []; + $posAccount['bank'] = $paymentTransactionDetail['payment_type_mapping']['payment_type']['bank_code']; + $posAccount['model'] = $paymentTransactionDetail['payment_type_mapping']['payment_type']['threed_model']; + $posAccount['env'] = $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test'; + + + foreach ($paymentTransactionDetail['payment_type_mapping']['paramsArray'] as $paramKey => $param) { + + if (isset($paymentTransactionDetail['payment_type_mapping']['payment_type']['paramsArray'][$paramKey])) { + $posAccount[$paymentTransactionDetail['payment_type_mapping']['payment_type']['paramsArray'][$paramKey]['key']] = $param; + } + } + + $POS = new \App\Core\Payment\Pos\Pos($posAccount); + + if (isset($paymentTransactionDetail['paramsArray']['creditCard'])) { + $paymentTransactionDetail['paramsArray']['orderParam']['creditCardMonth'] = $paymentTransactionDetail['paramsArray']['creditCard']['month']; + $paymentTransactionDetail['paramsArray']['orderParam']['creditCardYear'] = $paymentTransactionDetail['paramsArray']['creditCard']['year']; + $paymentTransactionDetail['paramsArray']['orderParam']['creditCardYearCvv'] = $paymentTransactionDetail['paramsArray']['creditCard']['cvv']; + } + + $POS->prepare($paymentTransactionDetail['paramsArray']['orderParam']); + + $payment = $POS->payment(); + + if ($payment->isSuccess()) { + + $bankOrderId = $payment->response->trans_id; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($payment->response), + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + } else { + + $errorMessage = null; + + + if (!empty($payment->response->error_message)) { + $errorMessage = $payment->response->error_message; + } + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => json_encode($payment->response), + ]; + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + throw new ApiErrorException($payment->response->error_message); + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'STR') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $secretKey = $paymentTransactionDetail['payment_type_mapping']['paramsArray']['secretKey']; + $stripe = new \Stripe\StripeClient($secretKey); + + $charge = $stripe->charges->create([ + 'currency' => $paymentTransactionDetail['currency'], + 'amount' => ($paymentTransactionDetail['amount'] * 100), + 'source' => $params['source'], + 'description' => $paymentTransactionDetail['code'] + ]); + + Log::debug($charge); + + if ($charge['status'] == 'succeeded') { + + $bankOrderId = $charge->id; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($charge), + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + + } catch (Exception $e) { + $errorMessage = $e->getMessage(); + } + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($charge) ? json_encode($charge) : null, + ]; + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + throw new ApiErrorException($errorMessage); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'ENW') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $secretKey = config('app.stripeENWKey'); + $stripe = new \Stripe\StripeClient($secretKey); + + $charge = $stripe->charges->create([ + 'currency' => $paymentTransactionDetail['currency'], + 'amount' => ($paymentTransactionDetail['amount'] * 100), + 'source' => $params['source'], + 'description' => $paymentTransactionDetail['code'] . ' - ' . $paymentTransactionDetail['property_id'] . ' - ' . $paymentTransactionDetail['property']['name'] + ]); + + Log::debug($charge); + + if ($charge['status'] == 'succeeded') { + + $bankOrderId = $charge->id; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($charge), + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + + } catch (Exception $e) { + + $errorMessage = $e->getMessage(); + } + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($charge) ? json_encode($charge) : null, + ]; + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + throw new ApiErrorException($errorMessage); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'SPY') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'merchantId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantId'], + 'merchantKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantKey'], + 'appKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appKey'], + 'appSecret' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appSecret'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $sipayService = new App\Core\Payment\Sipay\Sipay($paymentInitializeParam); + + $checkPaymentStatus = $sipayService->checkPaymentStatus($paymentCode); + + if (isset($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($params['sipay_status'] == 1 && $checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['order_id']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($params['status_description']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'MOK') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'userName' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['userName'], + 'password' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['password'], + 'dealerCode' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['dealerCode'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $mokaService = new App\Core\Payment\Moka\Moka($paymentInitializeParam); + + $paramPaymentDetail = [ + //'PaymentId' => fillOnUndefined($param,'OtherTrxCode'), + 'OtherTrxCode' => $paymentTransactionDetail['order_id'], + ]; + + $getPaymentDetail = $mokaService->getPaymentDetail($paramPaymentDetail); + + if (!$getPaymentDetail['status']) { + throw new ApiErrorException($getPaymentDetail['message']); + } + + if (floatval($paymentTransactionDetail['amount']) != floatval($getPaymentDetail['data']['PaymentDetail']['Amount'])) { + throw new Exception('Payment received, but amounts do not match!'); + } + + if ($getPaymentDetail['data']['IsSuccessful'] && $getPaymentDetail['data']['PaymentDetail']['TrxStatus'] == 1) { + + $bankOrderId = $getPaymentDetail['data']['PaymentDetail']['DealerPaymentId']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($getPaymentDetail) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } else { + + throw new ApiErrorException(reset($getPaymentDetail['data']['PaymentTrxDetailList'])['ResultMessage']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($getPaymentDetail) ? json_encode($getPaymentDetail) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'BOG') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + + $paymentInitializeParam = [ + 'clientId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['clientId'], + 'secretKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['secretKey'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $bankOfGeorgiaService = new App\Core\Payment\BankOfGeorgia\Payriff($paymentInitializeParam); + + + $checkoutOrderInfo = $bankOfGeorgiaService->checkoutOrderInfo($paymentTransactionDetail['extraParamsArray']['order_id']); + + + if (!$checkoutOrderInfo['status']) { + throw new ApiErrorException($checkoutOrderInfo['message']); + } + + if (floatval($paymentTransactionDetail['amount']) != floatval($checkoutOrderInfo['data']['purchaseUnit']['amount']['value'])) { + throw new Exception('Payment received, but amounts do not match!'); + } + + + if ($checkoutOrderInfo['data']['status'] == 'PERFORMED') { + + $bankOrderId = $checkoutOrderInfo['data']['id']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkoutOrderInfo) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } else { + + $errorMessage = $checkoutOrderInfo['data']['message']; + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkoutOrderInfo) ? json_encode($checkoutOrderInfo) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + throw new ApiErrorException($checkoutOrderInfo['data']['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkoutOrderInfo) ? json_encode($checkoutOrderInfo) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'TBC') { + + $bankOrderId = null; + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + $paymentInitializeParam = [ + 'clientId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['clientId'], + 'clientSecret' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['clientSecret'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $tbcBankService = new App\Core\Payment\TBCBankGeorgia\TBCBankGeorgia($paymentInitializeParam); + + $checkoutOrderInfo = $tbcBankService->checkoutOrderInfo($paymentTransactionDetail['extraParamsArray']['payId']); + + if (!$checkoutOrderInfo['status']) { + //throw new ApiErrorException($checkoutOrderInfo['message']); + $errorMessage = $checkoutOrderInfo['message']; + } + + if (floatval($paymentTransactionDetail['amount']) != floatval($checkoutOrderInfo['data']['confirmedAmount'])) { + //throw new Exception('Payment received, but amounts do not match!'); + $errorMessage = 'Payment received, but amounts do not match!'; + } + + if (empty($errorMessage)) { + + $bankOrderId = $checkoutOrderInfo['data']['payId']; + + if ($checkoutOrderInfo['data']['status'] == 'Succeeded') { + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkoutOrderInfo) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + //throw new Exception('api-unknown_error'); + $errorMessage = 'api-unknown_error'; + } + + } else { + + $errorMessage = $checkoutOrderInfo['data']['userMessage']; + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkoutOrderInfo) ? json_encode($checkoutOrderInfo) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkoutOrderInfo) ? json_encode($checkoutOrderInfo) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + throw new ApiErrorException($errorMessage); + + } + + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'QNB') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'merchantId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantId'], + 'merchantKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantKey'], + 'appKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appKey'], + 'appSecret' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appSecret'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $qnbPayService = new App\Core\Payment\QNBPay\QNBPay($paymentInitializeParam); + + $checkPaymentStatus = $qnbPayService->checkPaymentStatus($paymentCode); + + if (isset($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + //throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($params['payment_status'] == 1 && $checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['order_id']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($params['status_description']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'WEE') { + + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'merchantId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantId'], + 'apiKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['apiKey'], + 'secretKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['secretKey'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $weePayService = new App\Core\Payment\WeePay\WeePay($paymentInitializeParam); + + $checkPaymentStatus = $weePayService->checkPaymentStatus($paymentCode); + + if (isset($checkPaymentStatus['data']['price'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['data']['price'])) { + throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($params['status'] == 'success' && $checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['paymentId']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($checkPaymentStatus['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'HLK') { + + $errorMessage = null; + + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'merchantId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantId'], + 'merchantKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantKey'], + 'appKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appKey'], + 'appSecret' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['appSecret'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $qnbPayService = new App\Core\Payment\HalkOde\HalkOde($paymentInitializeParam); + + $checkPaymentStatus = $qnbPayService->checkPaymentStatus($paymentCode); + + if (isset($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + //throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($params['payment_status'] == 1 && $checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['order_id']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($params['status_description']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'ESN') { + + $errorMessage = null; + + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'merchant' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchant'], + 'merchantKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantKey'], + 'contactMail' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['contactMail'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $esnekPosService = new App\Core\Payment\Esnekpos\Esnekpos($paymentInitializeParam); + + $checkPaymentStatus = $esnekPosService->checkPaymentStatus($paymentCode); + + if (isset($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + //throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($params['RETURN_CODE'] == 0 && $checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['REFNO']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($checkPaymentStatus['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'KVY') { + + $errorMessage = null; + + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + $paymentInitializeParam = [ + 'customerId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['customerId'], + 'merchantId' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['merchantId'], + 'userName' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['userName'], + 'password' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['password'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $posService = new App\Core\Payment\KuveytTurk\KuveytTurk($paymentInitializeParam); + + $checkPaymentStatus = $posService->checkPaymentStatus($paymentCode, $params); + + //dd($paymentTransactionDetail, $params, $checkPaymentStatus); + + if (isset($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['serviceResponse']['transaction_amount'])) { + //throw new ApiErrorException('Payment received, but amounts do not match!'); + } + } + + if ($checkPaymentStatus['status']) { + + $bankOrderId = isset($checkPaymentStatus['data']['ProvisionNumber']) ? $checkPaymentStatus['data']['ProvisionNumber'] : null; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($checkPaymentStatus['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'RTL') { + + $bankOrderId = null; + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + + $paymentInitializeParam = [ + 'userName' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['userName'], + 'password' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['password'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $retailPayService = new App\Core\Payment\RetailPay\RetailPay($paymentInitializeParam); + + if (!isset($params['order_id'])) { + throw new ApiErrorException('order_id not found!'); + } + + + $orderCharge = $retailPayService->orderCharge($params['order_id']); + + if (!$orderCharge['status']) { + throw new ApiErrorException($orderCharge['message']); + } + + $checkPaymentStatus = $retailPayService->checkPaymentStatus($params['order_id']); + + /*if (isset($checkPaymentStatus['data']['price'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['data']['price'])) { + throw new ApiErrorException('Payment received, but amounts do not match!'); + } + }*/ + + + if ($checkPaymentStatus['status']) { + + $bankOrderId = $checkPaymentStatus['data']['id']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($checkPaymentStatus['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException($checkPaymentStatus['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($checkPaymentStatus['serviceResponse']) ? json_encode($checkPaymentStatus['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } elseif ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'PYR') { + + $bankOrderId = null; + $errorMessage = null; + + if ($paymentTransactionDetail['status'] == 1) { + + $bankOrderId = $paymentTransactionDetail['bank_order_id']; + + } else { + + try { + + + $paymentInitializeParam = [ + 'secretKey' => $paymentTransactionDetail['payment_type_mapping']['paramsArray']['secretKey'], + 'env' => $paymentTransactionDetail['payment_type_mapping']['status'] == 1 ? 'production' : 'test', + ]; + + $payriffService = new App\Core\Payment\Payriff\Payriff($paymentInitializeParam); + + if (!isset($paymentTransactionDetail['extraParamsArray']['payload']['orderId'])) { + throw new ApiErrorException('order_id not found!'); + } + + + $orderInformation = $payriffService->orderInformation($paymentTransactionDetail['extraParamsArray']['payload']['orderId']); + + if (!$orderInformation['status']) { + throw new ApiErrorException($orderInformation['message']); + } + + /*if (isset($checkPaymentStatus['data']['price'])) { + if (floatval($paymentTransactionDetail['amount']) != floatval($checkPaymentStatus['data']['price'])) { + throw new ApiErrorException('Payment received, but amounts do not match!'); + } + }*/ + + + if ($orderInformation['status']) { + + if ($orderInformation['serviceResponse']['payload']['paymentStatus'] == 'APPROVED') { + $bankOrderId = $orderInformation['serviceResponse']['payload']['orderId']; + + $updateParam = [ + 'bank_order_id' => $bankOrderId, + 'status' => 1, + 'message' => null, + 'response' => json_encode($orderInformation['serviceResponse']) + ]; + $paymentTransactionUpdateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + if ($paymentTransactionUpdateResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + } else { + + throw new ApiErrorException('Payment not confirmed!'); + } + + + } else { + + throw new ApiErrorException($orderInformation['message']); + + } + + } catch (ApiErrorException $e) { + + $errorMessage = $e->getMessage(); + } + + } + + + if (!empty($errorMessage)) { + + $updateParam = [ + 'status' => 0, + 'message' => $errorMessage, + 'response' => isset($orderInformation['serviceResponse']) ? json_encode($orderInformation['serviceResponse']) : null, + ]; + + $updateResult = $this->paymentTransactionRepository->update($paymentTransactionDetail['id'], $updateParam); + + } + + } + + $response['status'] = true; + $response['data']['bankOrderId'] = $bankOrderId; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + //Mask CreditCard Number + if ($paymentTransactionDetail['payment_type_mapping']['payment_type']['pos_code'] == 'POS') { + + if (isset($paymentTransactionDetail['extraParamsArray']['inputs']['Pan'])) { + $paymentTransactionDetail['extraParamsArray']['inputs']['Pan'] = creditCardMask($paymentTransactionDetail['extraParamsArray']['inputs']['Pan']); + } elseif (isset($paymentTransactionDetail['extraParamsArray']['inputs']['pan'])) { + $paymentTransactionDetail['extraParamsArray']['inputs']['pan'] = creditCardMask($paymentTransactionDetail['extraParamsArray']['inputs']['pan']); + } elseif (isset($paymentTransactionDetail['extraParamsArray']['inputs']['cardnumber'])) { + $paymentTransactionDetail['extraParamsArray']['inputs']['cardnumber'] = creditCardMask($paymentTransactionDetail['extraParamsArray']['inputs']['cardnumber']); + } + + $this->updatePaymentTransaction($paymentTransactionDetail['id'], ['extra_params' => json_encode($paymentTransactionDetail['extraParamsArray'])]); + } + + $paymentTransactionDetail = $this->getPaymentTransactionDetail($paymentCode); + $response['data']['paymentTransactionDetail'] = $paymentTransactionDetail['data']; + + return $response; + } + + + /***/ + + public function selectPaymentTransaction($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->paymentTransactionRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePaymentTransaction($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->paymentTransactionRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPaymentTypeList($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $paymentRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + + $paymentResponse = $this->paymentTypeRepository->findByCriteria($paymentRequest); + + $paymentMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + ]; + + $paymentMappingResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentMappingRequest); + $paymentMapping = collect($paymentMappingResponse); + $paymentList = collect($paymentResponse)->map(function ($value) use ($paymentMapping) { + $hasMapping = $paymentMapping->where("payment_type_id", "=", $value['id']) + ->where("status", "!=", 0) + ->first(); + return [ + 'id' => $value['id'], + 'pos_code' => $value['pos_code'], + 'bank_code' => $value['bank_code'], + 'threed_model' => $value['threed_model'], + 'name' => $value['name'], + 'installment' => $value['installment'], + 'icon' => $value['icon'], + 'status' => $value['status'], + 'bank_params' => $value['paramsArray'], + "has_setup" => isset($hasMapping) + ]; + + + })->values()->all(); + + + $response = [ + 'status' => true, + 'data' => $paymentList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPaymentMappingList($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $paymentMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['paymentType', 'propertyPaymentMappingInstallments'], + 'orderBy' => [ + ['field' => 'payment_type_id', 'value' => 'ASC'] + ] + ]; + + if (isset($params['property_payment_mapping_id'])) { + $paymentMappingRequest['criteria'][] = ['field' => 'id', 'condition' => '=', 'value' => $params['property_payment_mapping_id']]; + } + + $paymentMappingResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentMappingRequest); + $paymentMappingList = collect($paymentMappingResponse)->map(function ($value) { + + $fieldKeys = $value['paramsArray']; + $fieldsValues = collect($value['payment_type']['paramsArray'])->map(function ($value, $key) use ($fieldKeys) { + $return = $value; + $return['value'] = isset($fieldKeys[$key]) ? $fieldKeys[$key] : null; + return $return; + }); + + return [ + 'id' => $value['id'], + 'property_id' => $value['property_id'], + 'payment_type_id' => $value['payment_type_id'], + 'payment_type_status' => $value['payment_type']['status'], + 'currency_code' => $value['currency_code'], + 'is_default' => $value['is_default'], + 'pos_code' => $value['payment_type']['pos_code'], + 'bank_code' => $value['payment_type']['bank_code'], + 'threed_model' => $value['payment_type']['threed_model'], + 'name' => $value['payment_type']['name'], + 'payment_installment' => $value['payment_type']['installment'], + 'status' => $value['status'], + 'icon' => $value['payment_type']['icon'], + 'payment_params_array' => $fieldsValues, + 'fields' => $fieldKeys, + 'has_installments' => $value['property_payment_mapping_installments'] ? true : false, + 'installments' => $value['property_payment_mapping_installments'], + ]; + })->values(); + + $paymentMappingList = isset($params['property_payment_mapping_id']) ? $paymentMappingList->first() : $paymentMappingList->all(); + + + $response = [ + 'status' => true, + 'data' => $paymentMappingList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function createPaymentMapping($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + DB::beginTransaction(); + + $validationResult = $this->propertyPaymentMappingCreateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $paymentType = $this->paymentTypeRepository->find($params['payment_type_id']); + $paymentMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['paymentType'] + ]; + $oldPaymentResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentMappingRequest); + $oldPayments = collect($oldPaymentResponse)->map(function ($value) { + $return = $value; + $return['pos_code'] = $value['payment_type']['pos_code']; + return $return; + }); + + $activeMappings = $oldPayments->where('status', '=', 1)->all(); + if ($activeMappings) { + $isDefault = $params['is_default']; + } else { + $isDefault = 1; + } + + + $fields = $params['fields']; + $fieldsJson = json_encode($fields); + + $insertMapping = [ + 'property_id' => $params['property_id'], + 'payment_type_id' => $params['payment_type_id'], + 'params' => $fieldsJson, + 'installment' => $paymentType['installment'] ? $paymentType['installment'] : 0, + 'currency_code' => $params['currency'], + 'is_default' => $isDefault, + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ($paymentType['pos_code'] == 'POS') { + if ($params['currency'] == 'TRY') { + $hasMapping = $oldPayments->where('currency_code', '=', $params['currency']) + ->where('payment_type_id', '=', $params['payment_type_id']) + ->first(); + + if (!$hasMapping) { + $hasMapping = $oldPayments->where('currency_code', '=', $params['currency']) + ->where('pos_code', '!=', 'POS') + ->where('status', '=', 1) + ->first(); + } + } else { + $hasMapping = $oldPayments + ->where('currency_code', '=', $params['currency']) + ->where('status', '=', 1) + ->first(); + } + } else { + + $hasMapping = $oldPayments->where('currency_code', '=', $params['currency']) + ->where('status', '=', 1) + ->where('pos_code', '!=', 'POS') + ->first(); + } + + if ($hasMapping) { + throw new ApiErrorException('payment mapping error'); + } + + $insertPaymentMapping = $this->propertyPaymentMappingRepository->create($insertMapping); + + if ($insertPaymentMapping['status'] != 'success') { + throw new ApiErrorException($insertPaymentMapping['message']); + } + $insertPaymentMappingData = $insertPaymentMapping['data']; + + if ($params['is_default'] == 1) { + $updateThisIds = $oldPayments->where('is_default', '=', 1)->keyBy('id')->keys()->all(); + + $updateUseMappingData = [ + "is_default" => 0, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->propertyPaymentMappingRepository->updateWhereIn($updateThisIds, $updateUseMappingData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + public function updatePaymentMappingStatus($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyPaymentMappingStatusUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $paymentMapping = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['paymentType'] + ]; + + $oldPaymentResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentMapping); + $oldPayments = collect($oldPaymentResponse)->map(function ($value) { + $return = $value; + $return['pos_code'] = $value['payment_type']['pos_code']; + return $return; + }); + + + $thisPaymentMapping = $oldPayments->where('id', '=', $params['property_payment_mapping_id'])->first(); + if (!$thisPaymentMapping) { + throw new Exception('api-unknown_error'); + } + $hasMapping = null; + + if ($params['set_status'] == 1) { + if ($thisPaymentMapping['pos_code'] == 'POS') { + if ($thisPaymentMapping['currency_code'] == 'TRY') { + $hasMapping = $oldPayments + ->where('currency_code', '=', $thisPaymentMapping['currency_code']) + ->where('payment_type_id', '=', $thisPaymentMapping['payment_type_id']) + ->where('id', '!=', $thisPaymentMapping['id']) + ->first(); + + if (!$hasMapping) { + $hasMapping = $oldPayments->where('currency_code', '=', $thisPaymentMapping['currency_code']) + ->where('pos_code', '!=', 'POS') + ->where('status', '=', 1) + ->first(); + } + } else { + $hasMapping = $oldPayments + ->where('currency_code', '=', $thisPaymentMapping['currency_code']) + ->where('status', '=', 1) + ->first(); + } + } else { + $hasMapping = $oldPayments->where('currency_code', '=', $thisPaymentMapping['currency_code']) + ->where('status', '=', 1) + ->first(); + } + + if ($hasMapping) { + throw new ApiErrorException('payment mapping error'); + } + + } + + + $updateMappingCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_payment_mapping_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $updateUseMappingData = [ + "status" => $params['set_status'], + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->propertyPaymentMappingRepository->updateWhere($updateMappingCriteria, $updateUseMappingData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $thisPaymentMapping['status'] = $params['set_status']; + + $response = [ + 'status' => true, + 'data' => $thisPaymentMapping, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + public function setPaymentMappingDefault($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyPaymentMappingSetDefaultValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'is_default', 'condition' => '=', 'value' => 1], + ] + ]; + + $updateResult = $this->propertyPaymentMappingRepository->findByCriteria($updateMappingCriteria, ['id']); + $updateThisIds = collect($updateResult)->keyBy('id')->keys()->all(); + + $updateUseMappingData = [ + "is_default" => 0, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->propertyPaymentMappingRepository->updateWhereIn($updateThisIds, $updateUseMappingData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + $updateUseMappingData = [ + "is_default" => 1, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->propertyPaymentMappingRepository->update($params['property_payment_mapping_id'], $updateUseMappingData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + public function updatePaymentMapping($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyPaymentMappingUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $paymentTypeRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_payment_mapping_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['paymentType'], + 'firstRow' => 1 + ]; + $paymentTypeResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentTypeRequest); + if (!isset($paymentTypeResponse['payment_type']['paramsArray'])) { + throw new ApiErrorException('payment mapping error'); + } + + $getPaymentParams = $paymentTypeResponse['payment_type']['paramsArray']; + $fields = $params['fields']; + + foreach ($getPaymentParams as $key => $getPaymentParam) { + if (!isset($fields[$key])) { + throw new ApiErrorException('field error'); + } + } + + $fieldsJson = json_encode($fields); + $updateMapping = [ + 'params' => $fieldsJson, + 'is_default' => $params['is_default'], + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'updated_at' => Carbon::now()->timestamp, + ]; + + $updatePaymentMapping = $this->propertyPaymentMappingRepository->update($params['property_payment_mapping_id'], $updateMapping); + if ($updatePaymentMapping['status'] != 'success') { + throw new ApiErrorException($updatePaymentMapping['message']); + } + + if ($params['is_default'] == 1) { + $oldPaymentMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '!=', 'value' => $params['property_payment_mapping_id']], + ], + 'with' => ['paymentType'] + ]; + $oldPaymentResponse = $this->propertyPaymentMappingRepository->findByCriteria($oldPaymentMappingRequest); + $oldPayments = collect($oldPaymentResponse) + ->where('is_default', '=', 1) + ->map(function ($value) { + $return = $value; + $return['pos_code'] = $value['payment_type']['pos_code']; + return $return; + }); + + $updateThisIds = $oldPayments->keyBy('id')->keys()->all(); + $updateUseMappingData = [ + "is_default" => 0, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->propertyPaymentMappingRepository->updateWhereIn($updateThisIds, $updateUseMappingData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + public function updateInstallments($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + + $validationResult = $this->propertyPaymentInstallmentsUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateMapping = [ + 'installment' => $params['has_installments'] ? 1 : 0, + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'updated_at' => Carbon::now()->timestamp, + ]; + + $updatePaymentMapping = $this->propertyPaymentMappingRepository->update($params['property_payment_mapping_id'], $updateMapping); + if ($updatePaymentMapping['status'] != 'success') { + throw new ApiErrorException($updatePaymentMapping['message']); + } + + $paymentTypeRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_payment_mapping_id']], + ], + 'with' => ['paymentType', 'propertyPaymentMappingInstallments'], + 'firstRow' => 1 + ]; + $paymentTypeResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentTypeRequest); + + if (!isset($paymentTypeResponse['payment_type']['paramsArray'])) { + throw new ApiErrorException('payment mapping error'); + } + + + if ($paymentTypeResponse['payment_type']['installment'] != 1) { + throw new ApiErrorException('installments access error'); + } + $oldInstallments = $paymentTypeResponse['property_payment_mapping_installments']; + $oldInstallments = collect($oldInstallments); + + $installmentArray = []; + foreach ($params['installments'] as $installment) { + + $checkHasInstallment = $oldInstallments->where('installment', '=', $installment['installment'])->first(); + + if ($checkHasInstallment) { + $updateInstallmentData = [ + 'commission' => fillOnUndefinedAndEmpty($installment, 'commission', 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'updated_at' => Carbon::now()->timestamp, + ]; + + $updateInstallment = $this->propertyPaymentInstallmentRepository->update($checkHasInstallment['id'], $updateInstallmentData); + if ($updateInstallment['status'] != 'success') { + throw new ApiErrorException($updateInstallment['message']); + } + + } else { + $installmentArray[] = [ + 'property_id' => $params['property_id'], + 'property_payment_mapping_id' => $params['property_payment_mapping_id'], + 'installment' => $installment['installment'], + 'commission' => fillOnUndefinedAndEmpty($installment, 'commission', 0), + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + } + + if ($installmentArray) { + $insertPaymentMapping = $this->propertyPaymentInstallmentRepository->insert($installmentArray); + if ($insertPaymentMapping['status'] != 'success') { + throw new ApiErrorException($insertPaymentMapping['message']); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + public function updatePaymentInstallmentStatus($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $paymentInstallmentRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['installment_id']], + ['field' => 'property_payment_mapping_id', 'condition' => '=', 'value' => $params['property_payment_mapping_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => 1 + ]; + $installmentResponse = $this->propertyPaymentInstallmentRepository->findByCriteria($paymentInstallmentRequest); + + if (!$installmentResponse) { + throw new Exception('api-unknown_error'); + } + + $updateInstallmentData = [ + 'status' => fillOnUndefinedAndEmpty($params, 'set_status', 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'updated_at' => Carbon::now()->timestamp, + ]; + + $updateInstallment = $this->propertyPaymentInstallmentRepository->update($installmentResponse['id'], $updateInstallmentData); + if ($updateInstallment['status'] != 'success') { + throw new ApiErrorException($updateInstallment['message']); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPaymentType($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $paymentRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['payment_type_id']], + ], + 'firstRow' => 1 + ]; + + $paymentResponse = $this->paymentTypeRepository->findByCriteria($paymentRequest); + if (!$paymentResponse) { + throw new Exception('api-unknown_error'); + } + + $paymentMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'payment_type_id', 'condition' => '=', 'value' => $params['payment_type_id']], + ], + 'with' => ['paymentType', 'propertyPaymentMappingInstallments'], + 'orderBy' => [ + ['field' => 'payment_type_id', 'value' => 'ASC'] + ] + ]; + $paymentMappingResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentMappingRequest); + $paymentMappingResponse = collect($paymentMappingResponse); + + $currencyList = $this->currencyService->getCurrencyList(); + if ($currencyList['status'] != 'success') { + throw new Exception($currencyList['message']); + } + + $currencyList = collect($currencyList['data'])->map(function ($value) use ($paymentMappingResponse, $paymentResponse) { + $thisMapping = $paymentMappingResponse->where('currency_code', '=', $value['code'])->first(); + + $installments = collect(isset($thisMapping) ? $thisMapping['property_payment_mapping_installments'] : []); + $installmentArray = []; + for ($i = 1; $i <= 12; $i++) { + $installment = $installments->where('installment', '=', $i)->first(); + $installmentArray[] = [ + "installment_id" => isset($installment) ? $installment['id'] : null, + "installment" => $i, + "commission" => isset($installment) ? $installment['commission'] : null, + "has_installments" => isset($installment), + "status" => $installment['status'] ? $installment['status'] : 0, + ]; + } + + return [ + 'code' => $value['code'], + 'name' => $value['name'], + 'id' => isset($thisMapping) ? $thisMapping['id'] : null, + 'bank_params' => isset($paymentResponse) ? $paymentResponse['paramsArray'] : null, + 'language_key' => $value['language_key'], + 'fields' => isset($thisMapping) ? $thisMapping['paramsArray'] : null, + 'has_installments' => isset($thisMapping) ? $thisMapping['installment'] : 0, + 'status' => isset($thisMapping) && $thisMapping['status'] == 1 ? 1 : 0, + 'is_default' => isset($thisMapping) ? $thisMapping['is_default'] : null, + 'installments' => isset($thisMapping['installment']) && $thisMapping['installment'] ? $installmentArray : [] + ]; + })->values()->all(); + + $getPayment = [ + 'id' => $paymentResponse['id'], + 'pos_code' => $paymentResponse['pos_code'], + 'bank_code' => $paymentResponse['bank_code'], + 'threed_model' => $paymentResponse['threed_model'], + 'name' => $paymentResponse['name'], + 'installment' => $paymentResponse['installment'], + 'icon' => $paymentResponse['icon'], + 'status' => $paymentResponse['status'], + 'currencies' => $currencyList, + ]; + + $response = [ + 'status' => true, + 'data' => $getPayment, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function createManualPayment($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + if ($params['payment_type_mapping_id']) { + $paymentRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '!=', 'value' => 0], + ['field' => 'id', 'condition' => '=', 'value' => $params['payment_type_mapping_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => 1 + ]; + $paymentResponse = $this->propertyPaymentMappingRepository->findByCriteria($paymentRequest); + if (!$paymentResponse) { + throw new Exception('api-unknown_error'); + } + } + + $validationResult = $this->propertyPaymentTransactionCreateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $orderId = getCodeGenerate('LNK'); + $baseAmount = fillOnUndefined($params, 'base_amount'); + $commission = fillOnUndefined($params, 'commission'); + $amount = $baseAmount + (($baseAmount * $commission) / 100); + + $paramsColumn = [ + "title" => fillOnUndefined($params, 'title'), + "description" => fillOnUndefined($params, 'description'), + "email" => fillOnUndefined($params, 'email'), + "base_amount" => $baseAmount, + "commission" => $commission, + "amount" => $amount + + ]; + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'payment_type_mapping_id' => fillOnUndefined($params, 'payment_type_mapping_id'), + 'code' => null, + 'order_id' => $orderId, + 'transaction_type' => 'LNK', + 'bank_order_id' => null, + 'base_amount' => $amount, + 'base_currency' => fillOnUndefined($params, 'currency'), + 'exchange_rate' => 1, + 'amount' => $amount, + 'currency' => fillOnUndefined($params, 'currency'), + 'installment' => 0, + 'params' => json_encode($paramsColumn), + "status" => fillOnUndefined($params, "status", 5), + "created_by" => fillOnUndefined($params, "user_id", null), + ]; + + + $userCreateResult = $this->paymentTransactionRepository->create($insertData); + + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + + $userData['payment_link'] = Config::get('app.paymentFormLink') . $userData['order_id']; + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function updateManualPayment($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->propertyPaymentTransactionUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $paymentRequest = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $params['order_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $paymentResponse = $this->paymentTransactionRepository->findByCriteria($paymentRequest); + if (!$paymentResponse) { + throw new Exception('api-unknown_error'); + } + + $paymentTransactions = collect($paymentResponse); + + $hasSuccessTransaction = $paymentTransactions->whereNotIn('status', [0, 5])->count(); + + if ($hasSuccessTransaction) { + throw new Exception('enw-payment-payment_link-paid_payment-message'); + } + + $updateMe = $paymentTransactions->where('status', '=', 5)->first(); + $paymentTransactionId = $updateMe['id']; + + $baseAmount = fillOnUndefined($params, 'base_amount'); + $commission = fillOnUndefined($params, 'commission'); + $amount = $baseAmount + (($baseAmount * $commission) / 100); + + $paramsColumn = [ + "title" => fillOnUndefined($params, 'title'), + "description" => fillOnUndefined($params, 'description'), + "email" => fillOnUndefined($params, 'email'), + "base_amount" => $baseAmount, + "commission" => $commission, + "amount" => $amount + + ]; + + $updateData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'payment_type_mapping_id' => fillOnUndefined($params, 'payment_type_mapping_id'), + 'base_amount' => $amount, + 'base_currency' => fillOnUndefined($params, 'currency'), + 'exchange_rate' => 1, + 'amount' => $amount, + 'currency' => fillOnUndefined($params, 'currency'), + 'params' => json_encode($paramsColumn), + ]; + + + $userCreateResult = $this->paymentTransactionRepository->update($paymentTransactionId, $updateData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + + $userData['payment_link'] = Config::get('app.paymentFormLink') . $userData['order_id']; + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function createManualPaymentForm($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $currencyList = $this->currencyService->getCurrencyList(); + if ($currencyList['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData['currency_list'] = $currencyList['data']; + + $paymentMappingList = $this->getPaymentMappingList($params); + if ($paymentMappingList['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $userData['payment_mapping_list'] = $paymentMappingList['data']; + + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function editManualPaymentForm($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $currencyList = $this->currencyService->getCurrencyList(); + if ($currencyList['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData['currency_list'] = $currencyList['data']; + + $paymentMappingList = $this->getPaymentMappingList($params); + if ($paymentMappingList['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $userData['payment_mapping_list'] = $paymentMappingList['data']; + + + $paymentRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['payment_transaction_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $paymentResponse = $this->paymentTransactionRepository->findByCriteria($paymentRequest); + if (!$paymentResponse) { + throw new Exception('api-unknown_error'); + } + + $paymentTransactions = collect($paymentResponse); + + $hasSuccessTransaction = $paymentTransactions->whereNotIn('status', [0, 5])->count(); + + if ($hasSuccessTransaction) { + throw new Exception('api-unknown_error'); + } + + $updateMe = $paymentTransactions->where('status', '=', 5)->first(); + + $userData['manual_payment_data'] = $updateMe; + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getManualPayment($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $paymentRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['payment_transaction_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['relatedTransactions'], + 'firstRow' => 1 + ]; + $paymentResponse = $this->paymentTransactionRepository->findByCriteria($paymentRequest); + if (!$paymentResponse) { + throw new ApiErrorException('api-unknown_error'); + } + + $paymentResponse['payment_link'] = $paymentResponse['status'] == 5 && $paymentResponse['transaction_type'] != 'BKG' ? Config::get('app.paymentFormLink') . $paymentResponse['order_id'] : null; + + $response = [ + 'status' => true, + 'data' => $paymentResponse, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyPersonPricingPolicyService.php b/app/Core/Service/PropertyPersonPricingPolicyService.php new file mode 100644 index 0000000..3884ad4 --- /dev/null +++ b/app/Core/Service/PropertyPersonPricingPolicyService.php @@ -0,0 +1,902 @@ +propertyPricingPolicyAdultRepository = $propertyPricingPolicyAdultRepository; + $this->propertyPricingPolicyChildRepository = $propertyPricingPolicyChildRepository; + $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository = $propertyChannelRoomRatePricingPolicyAdultMappingRepository; + $this->updateRoomRateChannelPersonPricingAdultPolicyValidator = $updateRoomRateChannelPersonPricingAdultPolicyValidator; + $this->updateRoomRateChannelPersonPricingChildPolicyValidator = $updateRoomRateChannelPersonPricingChildPolicyValidator; + $this->propertyChannelRoomRatePricingPolicyChildMappingRepository = $propertyChannelRoomRatePricingPolicyChildMappingRepository; + $this->propertyRoomRepository = $propertyRoomRepository; + $this->propertyPricingPolicyAdultAddValidator = $propertyPricingPolicyAdultAddValidator; + $this->propertyPricingPolicyAdultUpdateValidator = $propertyPricingPolicyUpdateValidator; + $this->propertyPricingPolicyChildAddValidator = $propertyPricingPolicyChildAddValidator; + $this->propertyPricingPolicyChildUpdateValidator = $propertyPricingPolicyChildUpdateValidator; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + + + } + + + public function getPropertyPersonPricingPolicyList($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyId = fillOnUndefined($params, 'property_id'); + $propertyPersonPricingPolicyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ] + ]; + $propertyPersonPricingAdultPolicy = $this->propertyPricingPolicyAdultRepository->findByCriteria($propertyPersonPricingPolicyRequest, ['id', 'property_id', 'name', 'adult_action_type', 'adult', "action_type", "type", "value", "status"]); + $propertyPersonPricingAdultPolicy = $propertyPersonPricingAdultPolicy ? $propertyPersonPricingAdultPolicy : []; + + + $propertyPersonPricingChildPolicy = $this->propertyPricingPolicyChildRepository->findByCriteria($propertyPersonPricingPolicyRequest, ['id', 'property_id', 'name', "adult", "child_order", "child_age_start", "child_age_end", "type", "value", "status"]); + $propertyPersonPricingChildPolicy = $propertyPersonPricingChildPolicy ? $propertyPersonPricingChildPolicy : []; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ["person_pricing_adult_policy" => $propertyPersonPricingAdultPolicy, "person_pricing_child_policy" => $propertyPersonPricingChildPolicy]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function createPropertyPersonPricingAdultPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $validate = [ + 'name' => fillOnUndefinedAndEmpty($params, 'name', null), + 'adult_action_type' => fillOnUndefined($params, 'adult_action_type'), + 'adult' => fillOnUndefined($params, 'adult'), + 'action_type' => fillOnUndefinedAndEmpty($params, 'action_type', null), + 'type' => fillOnUndefinedAndEmpty($params, 'type', null), + 'value' => fillOnUndefinedAndEmpty($params, 'value', null), + 'property_id' => fillOnUndefinedAndEmpty($params, 'property_id', null), + 'reservation_start_date' => fillOnUndefinedAndEmpty($params, 'reservation_start_date', null), + 'reservation_end_date' => fillOnUndefinedAndEmpty($params, 'reservation_end_date', null), + ]; + + $validationResult = $this->propertyPricingPolicyAdultAddValidator->validate($validate); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $createData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => $validate['name'], + 'adult_action_type' => $validate['adult_action_type'], + 'adult' => $validate['adult'], + 'action_type' => $validate['action_type'], + 'type' => $validate['type'], + 'value' => $validate['value'], + 'reservation_start_date' => $validate['reservation_start_date'], + 'reservation_end_date' => $validate['reservation_end_date'], + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $createResult = $this->propertyPricingPolicyAdultRepository->create($createData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyPersonPricingAdultPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $validate = [ + 'name' => fillOnUndefinedAndEmpty($params, 'name', null), + 'adult_action_type' => fillOnUndefined($params, 'adult_action_type'), + 'adult' => fillOnUndefined($params, 'adult'), + 'pricing_policy_id' => fillOnUndefinedAndEmpty($params, 'pricing_policy_id', null), + 'property_id' => fillOnUndefinedAndEmpty($params, 'property_id', null), + 'action_type' => fillOnUndefinedAndEmpty($params, 'action_type', null), + 'type' => fillOnUndefinedAndEmpty($params, 'type', null), + 'value' => fillOnUndefinedAndEmpty($params, 'value', null), + 'reservation_start_date' => fillOnUndefinedAndEmpty($params, 'reservation_start_date', null), + 'reservation_end_date' => fillOnUndefinedAndEmpty($params, 'reservation_end_date', null), + ]; + + $validationResult = $this->propertyPricingPolicyAdultUpdateValidator->validate($validate); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateData = + [ + 'name' => $validate['name'], + 'adult_action_type' => $validate['adult_action_type'], + 'adult' => $validate['adult'], + 'action_type' => $validate['action_type'], + 'type' => $validate['type'], + 'value' => $validate['value'], + 'reservation_start_date' => $validate['reservation_start_date'], + 'reservation_end_date' => $validate['reservation_end_date'], + "status" => fillOnUndefined($params, "status", 1), + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyPricingPolicyAdultRepository->update($validate['pricing_policy_id'], $updateData); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyPersonPricingAdultPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $adultCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['pricing_policy_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['channelRoomRatePricingPolicyAdultMapping'], + 'firstRow' => true + ]; + + $propertyPersonPricingAdultPolicy = $this->propertyPricingPolicyAdultRepository->findByCriteria($adultCriteria); + + if (empty($propertyPersonPricingAdultPolicy)) { + throw new ApiErrorException('Adult policy data not found'); + } + + DB::beginTransaction(); + + $channelRoomRatePricingPolicyAdultMappingIds = collect($propertyPersonPricingAdultPolicy['channel_room_rate_pricing_policy_adult_mapping'])->pluck('id')->toArray(); + if ($channelRoomRatePricingPolicyAdultMappingIds) { + $deleteChannelRoomRatePricingPolicyAdultMapping = $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository->destroy($channelRoomRatePricingPolicyAdultMappingIds); + } + + $deletePropertyPricingPolicyAdult = $this->propertyPricingPolicyAdultRepository->destroy([$propertyPersonPricingAdultPolicy['id']]); + + if ($deletePropertyPricingPolicyAdult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $deletePropertyPricingPolicyAdult['data']]; + + DB::commit(); + + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function createPropertyPersonPricingChildPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + $validationResult = $this->propertyPricingPolicyChildAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $createData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult' => fillOnUndefined($params, 'adult'), + 'child_order' => fillOnUndefined($params, 'child_order'), + 'child_age_start' => fillOnUndefined($params, 'child_age_start'), + 'child_age_end' => fillOnUndefined($params, 'child_age_end'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $createResult = $this->propertyPricingPolicyChildRepository->create($createData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyPersonPricingChildPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $validationResult = $this->propertyPricingPolicyChildUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_rate_channel_mapping_id', 'condition' => '=', 'value' => $params['room_rate_channel_mapping_id']], + ], + 'with' => ['propertyPricingPolicyChild'] + ]; + + $propertyChannelRoomRatePersonPricingPolicyMapping = $this->propertyChannelRoomRatePricingPolicyChildMappingRepository->findByCriteria($criteria); + $propertyChannelRoomRatePersonPricingPolicyMapping = $propertyChannelRoomRatePersonPricingPolicyMapping ? $propertyChannelRoomRatePersonPricingPolicyMapping : []; + + if (!empty($propertyChannelRoomRatePersonPricingPolicyMapping)) { + + $oldDataMappingCollect = collect($propertyChannelRoomRatePersonPricingPolicyMapping)->map(function ($value) { + return [ + 'id' => $value['property_pricing_policy_child']['id'], + 'name' => $value['property_pricing_policy_child']['name'], + 'adult' => $value['property_pricing_policy_child']['adult'], + 'child_order' => $value['property_pricing_policy_child']['child_order'], + 'child_age_start' => $value['property_pricing_policy_child']['child_age_start'], + 'child_age_end' => $value['property_pricing_policy_child']['child_age_end'], + 'type' => $value['property_pricing_policy_child']['type'], + 'value' => $value['property_pricing_policy_child']['value'], + 'reservation_start_date' => $value['property_pricing_policy_child']['reservation_start_date'], + 'reservation_end_date' => $value['property_pricing_policy_child']['reservation_end_date'], + ]; + }); + + for ($age = $params['child_age_start']; $age <= $params['child_age_end']; $age++) { + $checkOldData = $oldDataMappingCollect->where('adult', '=', $params['adult']) + ->where('child_age_start', '<=', $age) + ->where('child_age_end', '>', $age) + ->where('child_order', '=', $params['child_order']) + ->where('reservation_start_date', $params['reservation_start_date']) + ->where('reservation_end_date', $params['reservation_end_date']) + ->where('id', '!=', $params['pricing_policy_id']) + ->first(); + if ($checkOldData) { + throw new ApiErrorException('This mapping added before'); + } + } + + } + $updateData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult' => fillOnUndefined($params, 'adult'), + 'child_order' => fillOnUndefined($params, 'child_order'), + 'child_age_start' => fillOnUndefined($params, 'child_age_start'), + 'child_age_end' => fillOnUndefined($params, 'child_age_end'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + "status" => fillOnUndefined($params, "status", 1), + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyPricingPolicyChildRepository->update($params['pricing_policy_id'], $updateData); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyPersonPricingChildPolicy($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $adultCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['pricing_policy_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['channelRoomRatePricingPolicyChildMapping'], + 'firstRow' => true + ]; + + $propertyPersonPricingChildPolicy = $this->propertyPricingPolicyChildRepository->findByCriteria($adultCriteria); + + if (empty($propertyPersonPricingChildPolicy)) { + throw new ApiErrorException('Child policy data not found'); + } + + DB::beginTransaction(); + + $channelRoomRatePricingPolicyChildMappingIds = collect($propertyPersonPricingChildPolicy['channel_room_rate_pricing_policy_child_mapping'])->pluck('id')->toArray(); + if ($channelRoomRatePricingPolicyChildMappingIds) { + $deleteChannelRoomRatePricingPolicyAdultMapping = $this->propertyChannelRoomRatePricingPolicyChildMappingRepository->destroy($channelRoomRatePricingPolicyChildMappingIds); + } + + $deletePropertyPricingPolicyChild = $this->propertyPricingPolicyChildRepository->destroy([$propertyPersonPricingChildPolicy['id']]); + + if ($deletePropertyPricingPolicyChild['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $deletePropertyPricingPolicyChild['data']]; + + DB::commit(); + + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function updateRoomRatePricingAdultPolicy($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->updateRoomRateChannelPersonPricingAdultPolicyValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_rate_channel_mapping_id', 'condition' => '=', 'value' => $params['room_rate_channel_mapping_id']], + ], + 'with' => ['propertyPricingPolicyAdult'] + ]; + + $propertyChannelRoomRatePersonPricingPolicyMapping = $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository->findByCriteria($criteria); + $propertyChannelRoomRatePersonPricingPolicyMapping = $propertyChannelRoomRatePersonPricingPolicyMapping ? $propertyChannelRoomRatePersonPricingPolicyMapping : []; + // $deleteThis = collect($propertyChannelRoomRatePersonPricingPolicyMapping)->keyBy('id')->keys()->toArray(); + $insertData = []; + if ($params['is_selected'] == true) { + + /*foreach ($propertyChannelRoomRatePersonPricingPolicyMapping as $adultMapping) { + $property_pricing_policy_adult = fillOnUndefined($adultMapping, 'property_pricing_policy_adult'); + $adultCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['pricing_policy_adult_id']], + ] + ]; + + $propertyPersonPricingAdultPolicy = $this->propertyPricingPolicyAdultRepository->findByCriteria($adultCriteria, ['id', 'property_id', 'name', 'adult_action_type', 'adult', "action_type", "type", "value", 'reservation_start_date', 'reservation_end_date', "status"]); + if ( + $property_pricing_policy_adult['adult_action_type'] == $propertyPersonPricingAdultPolicy['adult_action_type'] && + $property_pricing_policy_adult['adult'] == $propertyPersonPricingAdultPolicy['adult'] + ) { + + throw new ApiErrorException('enw-person_pricing_one_selected_error'); + } + }*/ + + $insertData[] = [ + 'property_id' => $params['property_id'], + 'pricing_policy_adult_id' => $params['pricing_policy_adult_id'], + 'room_rate_channel_mapping_id' => $params['room_rate_channel_mapping_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, 'user_id'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ($insertData) { + $createResult = $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository->insert($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } else { + + $criteria = [ + 'criteria' => [ + ['field' => 'pricing_policy_adult_id', 'condition' => '=', 'value' => $params['pricing_policy_adult_id']], + ['field' => 'room_rate_channel_mapping_id', 'condition' => '=', 'value' => $params['room_rate_channel_mapping_id']], + ], + 'firstRow' => true + ]; + + $propertyChannelRoomRatePersonPricingPolicyMapping = $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository->findByCriteria($criteria); + + if ($propertyChannelRoomRatePersonPricingPolicyMapping['id']) { + $deleteThisArray = $this->propertyChannelRoomRatePricingPolicyAdultMappingRepository->destroy([$propertyChannelRoomRatePersonPricingPolicyMapping['id']]); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateRoomRatePricingChildPolicy($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->updateRoomRateChannelPersonPricingChildPolicyValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_rate_channel_mapping_id', 'condition' => '=', 'value' => $params['room_rate_channel_mapping_id']], + ], + 'with' => ['propertyPricingPolicyChild'] + ]; + + $propertyChannelRoomRatePersonPricingPolicyMapping = $this->propertyChannelRoomRatePricingPolicyChildMappingRepository->findByCriteria($criteria); + $propertyChannelRoomRatePersonPricingPolicyMapping = $propertyChannelRoomRatePersonPricingPolicyMapping ? $propertyChannelRoomRatePersonPricingPolicyMapping : []; + + if ($params['is_selected'] == true) { + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['pricing_policy_child_id']], + ], + 'firstRow' => 1 + ]; + + $addPricingPolicy = $this->propertyPricingPolicyChildRepository->findByCriteria($criteria); + if (!$addPricingPolicy) { + throw new ApiErrorException('Child data not found'); + } + + $oldDataMappingCollect = collect($propertyChannelRoomRatePersonPricingPolicyMapping)->map(function ($value) { + return [ + 'id' => $value['property_pricing_policy_child']['id'], + 'name' => $value['property_pricing_policy_child']['name'], + 'adult' => $value['property_pricing_policy_child']['adult'], + 'child_order' => $value['property_pricing_policy_child']['child_order'], + 'child_age_start' => $value['property_pricing_policy_child']['child_age_start'], + 'child_age_end' => $value['property_pricing_policy_child']['child_age_end'], + 'type' => $value['property_pricing_policy_child']['type'], + 'value' => $value['property_pricing_policy_child']['value'], + ]; + }); + + for ($age = $addPricingPolicy['child_age_start']; $age <= $addPricingPolicy['child_age_end']; $age++) { + /*$checkOldData = $oldDataMappingCollect->where('adult', '=', $addPricingPolicy['adult']) + ->where('child_age_start', '<=', $age) + ->where('child_age_end', '>', $age) + ->where('child_order', '=', $addPricingPolicy['child_order']) + ->first(); + if ($checkOldData) { + throw new ApiErrorException('This mapping added before'); + }*/ + } + + $insertData[] = [ + 'property_id' => $params['property_id'], + 'pricing_policy_child_id' => $params['pricing_policy_child_id'], + 'room_rate_channel_mapping_id' => $params['room_rate_channel_mapping_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, 'user_id'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + if ($insertData) { + $createResult = $this->propertyChannelRoomRatePricingPolicyChildMappingRepository->insert($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + if ($params['is_selected'] == false) { + $deleteThis = collect($propertyChannelRoomRatePersonPricingPolicyMapping) + ->where('pricing_policy_child_id', '=', $params['pricing_policy_child_id']) + ->keyBy('id')->keys()->toArray(); + if ($deleteThis) { + $deleteThisArray = $this->propertyChannelRoomRatePricingPolicyChildMappingRepository->destroy($deleteThis); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getRoomRateChannelPersonPricingPolicy($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomRateMapping.propertyRoomRateChannel.propertyRoomRateChannelPricingAdultPolicy', 'propertyRoomRateMapping.propertyRoomRateChannel.propertyRoomRateChannelPricingChildPolicy', 'propertyRoomRateMapping.propertyRoomRate'] + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'exclude_occupancy', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + + $propertyPricingAdultPolicyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyPricingAdultPolicy = $this->propertyPricingPolicyAdultRepository->findByCriteria($propertyPricingAdultPolicyRequest, ['id', 'property_id', 'name', 'adult_action_type', 'adult', "action_type", "type", 'reservation_start_date', 'reservation_end_date', "value"]); + $propertyPricingAdultPolicy = $propertyPricingAdultPolicy ? $propertyPricingAdultPolicy : []; + + array_multisort( + array_column($propertyPricingAdultPolicy, 'adult'), SORT_ASC, + array_column($propertyPricingAdultPolicy, 'adult_action_type'), SORT_ASC, + $propertyPricingAdultPolicy + ); + + $propertyPricingChildPolicyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyPricingChildPolicy = $this->propertyPricingPolicyChildRepository->findByCriteria($propertyPricingChildPolicyRequest, ['id', 'property_id', 'name', 'adult', 'child_order', 'child_age_start', 'child_age_end', 'reservation_start_date', 'reservation_end_date', 'type', 'value']); + $propertyPricingChildPolicy = $propertyPricingChildPolicy ? $propertyPricingChildPolicy : []; + + + $return = []; + + foreach ($roomData as $room) { + + if ($room['property_room_rate_mapping']) { + $item = $room; + $item['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + $roomRateMappings = $room['property_room_rate_mapping']; + $mapping = []; + $addedMapping = 0; + foreach ($roomRateMappings as $roomRateMapping) { + $propertyRoomRateChannel = null; + if (isset($roomRateMapping['property_room_rate_channel'])) { + $propertyRoomRateChannel = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('room_rate_mapping_id', '=', $roomRateMapping['id']) + ->first(); + } + + $mappingStatus = false; + $propertyPersonPricingAdultPolicyArray = []; + $propertyPersonPricingChildPolicyArray = []; + + if ($propertyRoomRateChannel) { + if ($propertyRoomRateChannel['status'] == 1) { + $mappingStatus = true; + + foreach ($propertyPricingAdultPolicy as $adultPolicy) { + $propertyRoomRateChannelAdultPricingPolicy = []; + if (isset($propertyRoomRateChannel['property_room_rate_channel_pricing_adult_policy'])) { + + $propertyRoomRateChannelAdultPricingPolicy = collect($propertyRoomRateChannel['property_room_rate_channel_pricing_adult_policy']) + ->where('pricing_policy_adult_id', '=', $adultPolicy['id']) + ->where('room_rate_channel_mapping_id', '=', $propertyRoomRateChannel['id']) + ->values()->toArray(); + } + + $propertyPersonPricingAdultPolicyArray[] = [ + 'id' => $adultPolicy['id'], + 'property_id' => $adultPolicy['property_id'], + 'name' => $adultPolicy['name'], + 'adult_action_type' => $adultPolicy['adult_action_type'], + 'adult' => $adultPolicy['adult'], + 'action_type' => $adultPolicy['action_type'], + 'type' => $adultPolicy['type'], + 'value' => $adultPolicy['value'], + 'reservation_start_date' => $adultPolicy['reservation_start_date'], + 'reservation_end_date' => $adultPolicy['reservation_end_date'], + 'pricing_adult_policy_is_selected' => $propertyRoomRateChannelAdultPricingPolicy ? true : false, + ]; + + } + + + foreach ($propertyPricingChildPolicy as $childPolicy) { + $propertyRoomRateChannelChildPricingPolicy = []; + if (isset($propertyRoomRateChannel['property_room_rate_channel_pricing_child_policy'])) { + $propertyRoomRateChannelChildPricingPolicy = collect($propertyRoomRateChannel['property_room_rate_channel_pricing_child_policy']) + ->where('pricing_policy_child_id', '=', $childPolicy['id']) + ->where('room_rate_channel_mapping_id', '=', $propertyRoomRateChannel['id']) + ->values()->toArray(); + } + + $propertyPersonPricingChildPolicyArray[] = [ + 'id' => $childPolicy['id'], + 'property_id' => $childPolicy['property_id'], + 'name' => $childPolicy['name'], + 'adult' => $childPolicy['adult'], + 'child_order' => $childPolicy['child_order'], + 'child_age_start' => $childPolicy['child_age_start'], + 'child_age_end' => $childPolicy['child_age_end'], + 'reservation_start_date' => $childPolicy['reservation_start_date'], + 'reservation_end_date' => $childPolicy['reservation_end_date'], + 'type' => $childPolicy['type'], + 'value' => $childPolicy['value'], + 'pricing_child_policy_is_selected' => $propertyRoomRateChannelChildPricingPolicy ? true : false, + ]; + } + + array_multisort(array_column($propertyPersonPricingChildPolicyArray, 'adult'), SORT_ASC, + array_column($propertyPersonPricingChildPolicyArray, 'child_order'), SORT_ASC, + $propertyPersonPricingChildPolicyArray); + } + } + + + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['is_selected'] = $mappingStatus; + $roomRateMapping['has_date'] = $propertyRoomRateChannel['has_date'] == 0 ? false : true; + $roomRateMapping['end_date'] = $propertyRoomRateChannel['end_date']; + $roomRateMapping['start_date'] = $propertyRoomRateChannel['start_date']; + $roomRateMapping['room_rate_channel_mapping_id'] = $propertyRoomRateChannel['id']; + $roomRateMapping['room_rate_channel_adult_pricing_policy'] = $propertyPersonPricingAdultPolicyArray; + $roomRateMapping['room_rate_channel_child_pricing_policy'] = $propertyPersonPricingChildPolicyArray; + + + unset($roomRateMapping['property_room_rate']); + unset($roomRateMapping['property_room_rate_channel']); + if ($mappingStatus) { + $addedMapping++; + $mapping[] = $roomRateMapping; + } + } + $item['property_room_rate_mapping'] = $mapping; + if ($addedMapping > 0) { + $return[] = $item; + } + } + + } + + $collection = collect($return); + $sorted = $collection->sortBy('id')->values()->all(); + + $response = [ + 'status' => true, + 'data' => $sorted, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function checkChannelRoomPricingType($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = + [ + "criteria" => + [ + ["field" => "property_id", "condition" => "=", "value" => $params['property_id']], + ["field" => "channel_id", "condition" => "=", "value" => $params['channel_id']], + ], + 'with' => ['channelRoomPricingType'], + 'firstRow' => true + ]; + $mapping = $this->propertyChannelMappingRepository->findByCriteria($criteria); + if (!$mapping) { + throw new ApiErrorException('Property Channel Setup not found '); + } + + if ($mapping['channel_room_pricing_type']['code'] != 'PRS') { + throw new ApiErrorException('Property Channel Room Pricing Type is not Per Pricing'); + } + + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyPhotoService/PropertyPhotoCategoryService.php b/app/Core/Service/PropertyPhotoService/PropertyPhotoCategoryService.php new file mode 100644 index 0000000..54241e3 --- /dev/null +++ b/app/Core/Service/PropertyPhotoService/PropertyPhotoCategoryService.php @@ -0,0 +1,105 @@ +propertyPhotoCategoryRepository = $propertyPhotoCategoryRepository; + + } + + + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPhotoCategoryRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + public function getPropertyPhotoCategoryList($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + // get all photo category types + $photoCategoryRequest = [ + 'with' => [] + ]; + $photoCategoryResponse = $this->select($photoCategoryRequest); + + if($photoCategoryResponse['status'] == false){ + throw new ApiErrorException(lang('Category Data Not Loaded')); + } + $photoCategoryCollection = collect($photoCategoryResponse['data']); + foreach ($photoCategoryCollection as $photoCategory){ + + + + // Get Locale data + $nameLocale = []; + + + $photoCategoryItem['id'] = $photoCategory['id']; + $photoCategoryItem['category_name'] = $photoCategory['category_name']; + + $return[] = $photoCategoryItem ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['photo_category_list' => $return]]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyPhotoService/PropertyPhotoService.php b/app/Core/Service/PropertyPhotoService/PropertyPhotoService.php new file mode 100644 index 0000000..32748ed --- /dev/null +++ b/app/Core/Service/PropertyPhotoService/PropertyPhotoService.php @@ -0,0 +1,1212 @@ +propertyPhotoRepository = $propertyPhotoRepository; + $this->photoGoogleLabelRepository = $photoGoogleLabelRepository ; + $this->googleVisionLabelService = $googleVisionLabelService; + $this->propertyRoomPhotoMappingService = $propertyRoomPhotoMappingService; + $this->propertyRoomService = $propertyRoomService ; + $this->offerPhotoMappingService = $offerPhotoMappingService ; + $this->propertyWebPhotoMappingService = $propertyWebPhotoMappingService; + $this->propertyPhotoValidator = $propertyPhotoValidator ; + $this->propertyPlaceService = $propertyPlaceService ; + $this->propertyPlacePhotoMappingRepository = $propertyPlacePhotoMappingRepository ; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPhotoRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateWhere($criteria, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyPhotoRepository->updateWhere($criteria, $param); + + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyPhotos($params) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + $propertyId = $params['property_id']; + + $getPropertyPhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => + [ + ["field" => "photo_order", "value" => "ASC"] + ], + ]; + + $customIds = fillOnUndefined($params, 'custom', []); + if(!empty($customIds)) { + $getPropertyPhotoCriteria['whereIn'] = [ + ["field" => "id", "value" => $customIds] + ]; + } + + $getPropertyPhotos = $this->propertyPhotoRepository->findByCriteria($getPropertyPhotoCriteria); + $getPropertyPhotos = $getPropertyPhotos ? $getPropertyPhotos : []; + + + $filteredList = []; + foreach ($getPropertyPhotos as $key => $getPropertyPhoto) + { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + }else { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_medium.{$getPropertyPhoto['file_ext']}"; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + }else{ + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_thumbnail.{$getPropertyPhoto['file_ext']}"; + } + + $filteredList[] = + [ + 'id' => $getPropertyPhoto['id'], + 'property_id' => $getPropertyPhoto['property_id'], + 'property_photo_category_id' => $getPropertyPhoto['property_photo_category_id'], + 'photo_url' => $photoUrlFilePath, + 'photo_url_thump' => $photoUrlThumbFilePath, + "photo_name" => $getPropertyPhoto["photo_name"], + "photo_rank" => $getPropertyPhoto["photo_rank"], + "file_size" => $getPropertyPhoto["file_size"], + "file_ext" => $getPropertyPhoto["file_ext"], + "photo_resolution" => $getPropertyPhoto["photo_resolution"], + "photo_order" => $getPropertyPhoto["photo_order"], + "is_default" => $getPropertyPhoto["is_default"], + "is_compatible_with_myweb_slider" => $getPropertyPhoto["is_compatible_with_myweb_slider"], + "is_temp" => $getPropertyPhoto["is_temp"], + "status" => $getPropertyPhoto["status"], + ]; + } + + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => $filteredList]; + + }catch (ApiErrorException $e){ + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + }catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + return output($response); + } + + public function matchGoogleLabelPhotoCategory($params) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + + $collectLabels = collect($params); + + $descriptions = $collectLabels->keyBy('description')->keys()->toArray(); + $labelCriteria = [ + 'whereIn' => [ + ["field" => "label", "value" => $descriptions] + ], + 'with' => ['photoCategoryLabelMapping.photoCategory'] + ]; + $categoryList = $this->photoGoogleLabelRepository->findByCriteria($labelCriteria); + + $dbLabels = []; + $ratedCategories = []; + foreach ($categoryList as $category){ + $label = $category["label"]; + $categoryId = $category["photo_category_label_mapping"]["photo_category"]["id"]; + $categoryName = $category["photo_category_label_mapping"]["photo_category"]["category_name"]; + + //$dbLabels[$label][$categoryId]["category_name"] = $categoryName; + + $rate = $collectLabels->where('description', '=', $label)->first(); + + $ratedCategories[$categoryId]["category_id"] = $categoryId; + $ratedCategories[$categoryId]["category_name"] = $categoryName; + if(!isset($ratedCategories[$categoryId]["rate"])){ + $ratedCategories[$categoryId]["rate"] = 0; + } + else{ + $ratedCategories[$categoryId]["rate"] += $rate['score']; + } + + } + + $winner = collect($ratedCategories)->sortByDesc('rate')->first(); + + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => $winner]; + + }catch (ApiErrorException $e){ + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + }catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + return output($response); + } + + public function insertPropertyPhoto($param) + { + return $this->propertyPhotoRepository->create($param); + } + + public function setPhotoOrder($params){ + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + foreach ($params['set_photo_order'] as $orderList){ + $updateData = [ + 'photo_order' => $orderList['photo_order'], + 'updated_at' => time() , + ]; + $updateCriteria = [ + 'criteria' => [ + ['field' => 'id' , 'condition' => '=', 'value' => $orderList['photo_id'] ], + ['field' => 'property_id' , 'condition' => '=', 'value' => $params['property_id'] ], + ] + ]; + $updateStatus = $this->updateWhere($updateCriteria, $updateData); + if($updateStatus['status'] != 'success'){ + throw new Exception($updateStatus['message']); + } + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => []]; + } + }catch (ApiErrorException $e){ + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + }catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + return output($response); + + + } + + public function setPhotoCategory($params){ + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + foreach ($params['set_photo_category'] as $photoList){ + $updateData = [ + 'property_photo_category_id' => $photoList['photo_category_id'], + 'updated_at' => time() , + ]; + $updateCriteria = [ + 'criteria' => [ + ['field' => 'id' , 'condition' => '=', 'value' => $photoList['photo_id'] ], + ['field' => 'property_id' , 'condition' => '=', 'value' => $params['property_id'] ], + ] + ]; + + $updateStatus = $this->updateWhere($updateCriteria, $updateData); + + if($updateStatus['status'] != 'success'){ + throw new ApiErrorException(lang('User data is not updated.')); + } + } + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => []]; + }catch (ApiErrorException $e){ + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + }catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + return output($response); + + + } + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyPhotoRepository->update($id,$param); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + // todo: query performance should be corrected + public function setDefaultPhoto($params) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + + $photo_id = $params['photo_id']; + $propertyId = $params['property_id']; + + $requestDataCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'id', 'condition' => '=', 'value' => $photo_id], + ], + ]; + + $requestDataCheck = $this->propertyPhotoRepository->findByCriteria($requestDataCriteria,['id']); + + if (empty($requestDataCheck)) { + throw new ApiErrorException(lang('PropertyPhoto data not found')); + } + + $propertyPhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'is_default', 'condition' => '=', 'value' => 1] + ], + ]; + + $getPropertyPhotoData = $this->propertyPhotoRepository->findByCriteria($propertyPhotoCriteria,['id','is_default']); + + if (!empty($getPropertyPhotoData)) { + foreach ($getPropertyPhotoData as $photoData ) { + $updatedPhotoisDefault = $this->update($photoData['id'],['is_default' => 0]); + } + + if ($updatedPhotoisDefault['status'] == false) { + throw new ApiErrorException(lang('PropertyPhoto "is_default fields" can not updated')); + } + } + + $PhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'id', 'condition' => '=', 'value' => $photo_id], + ['field' => 'is_default', 'condition' => '=', 'value' => 0], + ], + ]; + + $getPhotoData = $this->propertyPhotoRepository->findByCriteria($PhotoCriteria); + + if (!empty($getPhotoData)) { + $setPropertPhotoDefault = $this->update($photo_id,['is_default' => 1]); + } + + if ($setPropertPhotoDefault['status'] == false) { + throw new ApiErrorException(lang('PropertyPhoto "is_default" can not updated')); + } + + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => '']; + + }catch (ApiErrorException $e){ + $response['message'] = $e->getMessage(); + + }catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + $response['message'] = $e->getMessage(); + Log::error($message); + } + return output($response); + } + + public function publishPhotos($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + $photos = $params['photos']; + $photoData = []; + + foreach ( $photos as $photo ) { + if ( !is_null($photo['photo_id']) ) { + if ( $photo['is_temp'] == 0 ) { + $photoData['publish'][] = [$photo['photo_id'] ]; + } else{ + $photoData['unPublish'][] = [$photo['photo_id']]; + } + } + } + + if (Arr::has($photoData,'publish')) { + $photoPublishCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'whereIn' => [ + ['field' => 'id', 'condition' => '=', 'value' => $photoData['publish']], + ] + ]; + + $propertyPhotoPublishData = $this->propertyPhotoRepository->findByCriteria($photoPublishCriteria, ['id', 'is_temp']); + + if ( empty($propertyPhotoPublishData) ) { + throw new ApiErrorException(lang('photo is_temp data not loaded')); + } + + foreach ( $propertyPhotoPublishData as $publishData ) { + $updatePhotoPublishData = $this->update($publishData['id'], ['is_temp' => 0]); + } + if ( $updatePhotoPublishData[ 'status' ] == false ) { + throw new ApiErrorException(lang('PropertyPhoto can not published')); + } + } + + if (Arr::has($photoData,'unPublish')) { + $photoUnPublishCriteria = [ + 'criteria' => [ + [ 'field' => 'property_id', 'condition' => '=', 'value' => $params[ 'property_id' ] ], + ], + 'whereIn' => [ + [ 'field' => 'id', 'condition' => '=', 'value' => $photoData[ 'unPublish' ] ], + ] + ]; + + $propertyPhotoUnPublishData = $this->propertyPhotoRepository->findByCriteria($photoUnPublishCriteria, [ 'id', 'is_temp' ]); + + foreach ( $propertyPhotoUnPublishData as $unPublishData ) { + $updatePhotoUnPublishData = $this->update($unPublishData[ 'id' ], [ 'is_temp' => 1 ]); + } + + if ( $updatePhotoUnPublishData[ 'status' ] == false ) { + throw new ApiErrorException(lang('PropertyPhoto can not unpublished')); + } + } + + $response = [ 'status' => 1, 'statusCode' => 200, 'message' => '', 'data' => '' ]; + + } catch ( ApiErrorException $e ) { + $response[ 'message' ] = $e->getMessage(); + $response[ 'statusCode' ] = 404; + } catch ( Exception $e ) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + $response[ 'message' ] = $e->getMessage(); + Log::error($message); + } + return output($response); + } + + public function deletePhotos($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + DB::beginTransaction(); + + $photos = $params['photos']; + + if (empty($photos)) { + throw new ApiErrorException(lang('property photos not found')); + } + + $photoDeleteCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'id', 'condition' => '=', 'value' => $photos], + ] + ]; + + $propertyPhotoDeleteData = $this->propertyPhotoRepository->findByCriteria($photoDeleteCriteria); + + if (empty($propertyPhotoDeleteData)) { + throw new ApiErrorException(lang('property photos delete data not loaded')); + } + + $propertyPhotoDeleteData = $propertyPhotoDeleteData ? $propertyPhotoDeleteData : [] ; + $defaultPhotoDeleted = false ; + foreach ( $propertyPhotoDeleteData as $deleteData ) { + + $destroyCriteria = [ + 'photo_id' => $deleteData['id'], + 'property_id' => $params['property_id'] + ]; + $roomPhotoDelete = $this->propertyRoomPhotoMappingService->destroy($destroyCriteria); + if ($roomPhotoDelete['status'] == false) { + throw new ApiErrorException($roomPhotoDelete['message']); + } + + $offerPhotoDelete = $this->offerPhotoMappingService->destroy($destroyCriteria); + if ($offerPhotoDelete['status'] == false) { + throw new ApiErrorException($offerPhotoDelete['message']); + } + + $webPhotoDelete = $this->propertyWebPhotoMappingService->destroy($destroyCriteria); + if ($webPhotoDelete['status'] == false) { + throw new Exception('api-unknown_error'); + } + + + $placePhotoDelete = $this->propertyPlaceService->destroyPhotoMapping($destroyCriteria); + if ($placePhotoDelete['status'] == false) { + throw new Exception('api-unknown_error'); + } + + + if($deleteData['id']){ + $propertyPhotoDelete = $this->propertyPhotoRepository->destroy([$deleteData['id']]); + if ($propertyPhotoDelete['status'] == false) { + throw new Exception('api-unknown_error'); + } + } + + if($deleteData['is_default']){ + $defaultPhotoDeleted = true ; + } + + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'_200x200.'.$deleteData['file_ext']; + + if (File::exists($photoUrlThumbFilePath)) { + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'_200x200.' .$deleteData['file_ext']; + }else{ + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name']. '_thumbnail.'.$deleteData['file_ext']; + } + + //delete thumbnail image + // $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'_200x200.'.$deleteData['file_ext']; + if (File::exists($filePath)) { + if(!File::delete($filePath)){ + Log::alert($filePath . ' not deleted'); + } + } + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'_1024x768.'.$deleteData['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name']. '_1024x768.' .$deleteData['file_ext']; + }else { + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name']. '_medium.'.$deleteData['file_ext']; + } + + + //delete large image + // $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'_1024x768.'.$deleteData['file_ext']; + if (File::exists($filePath)) { + if(!File::delete($filePath)){ + Log::alert($filePath . ' not deleted'); + } + } + + //delete original image + $filePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/'.$deleteData['photo_name'].'.'.$deleteData['file_ext']; + if (File::exists($filePath)) { + if(!File::delete($filePath)){ + Log::alert($filePath . ' not deleted'); + } + } + + + } + + if($defaultPhotoDeleted){ + $photoCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $propertyPhotoData = $this->propertyPhotoRepository->findByCriteria($photoCriteria, ['id']); + if($propertyPhotoData){ + $data = $this->propertyPhotoRepository->update($propertyPhotoData['id'], ['is_default' => 1]); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + $response = [ 'status' => 1, 'statusCode' => 200, 'message' => '', 'data' => '' ]; + DB::commit(); + + } catch ( ApiErrorException $e ) { + $response[ 'message' ] = $e->getMessage(); + DB::rollBack(); + + } catch ( Exception $e ) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + $response[ 'message' ] = $e->getMessage(); + DB::rollBack(); + Log::error($message); + } + return output($response); + } + + public function propertyPhotoUploadFilter($param) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try + { + $propertyId = fillOnUndefined($param, 'property_id'); + $uploadedPhoto = $this->uploadPhoto($param); + if($uploadedPhoto['status'] != 'success'){ + + throw new ApiErrorException($uploadedPhoto['message']) ; + } + $uploadedPhoto = $uploadedPhoto['data'] ; + + + $defaultPhotoCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_default', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $propertyPhotoData = $this->propertyPhotoRepository->findByCriteria($defaultPhotoCriteria, ['id']); + + $insertPropertyPhoto = + [ + 'property_id' => $propertyId, + 'property_photo_category_id' => 1, + 'photo_path' => $uploadedPhoto['photo_path'], + 'photo_name' => $uploadedPhoto['photo_name'], + 'file_size' => $uploadedPhoto['file_size'], + 'file_ext' => $uploadedPhoto['file_ext'], + 'photo_resolution' => $uploadedPhoto['file_resolution'], + 'is_default' => $propertyPhotoData ? 0 : 1, + 'is_compatible_with_myweb_slider' => $uploadedPhoto['is_compatible_with_myweb_slider'], + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time() + ]; + + $response = $this->insertPropertyPhoto($insertPropertyPhoto); + $photoId = $response['data']['id']; + + $getPhotoCategory['category_id'] = 1; + $getPhotoCategory['category_name'] = 'Property'; + + // Set Photo Order.... + $selectLastPhotoCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId] + ], + 'orderBy' => [ + ['field' => 'photo_order', 'value' => 'DESC'] + ], + 'firstRow' => true + ]; + $selectLastPhoto = $this->select($selectLastPhotoCriteria); + $selectLastPhoto = $selectLastPhoto['data']; + $lastOrder = fillOnUndefined($selectLastPhoto, 'photo_order'); + $lastOrder += 1; + + $updatePhotoValues = [ + 'property_photo_category_id' => $getPhotoCategory['category_id'], + 'photo_order' => $lastOrder, + ]; + $updatePhoto = $this->update($photoId , $updatePhotoValues) ; // update + $updatePhoto = $updatePhoto["data"]; + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_1024x768.{$updatePhoto['file_ext']}"; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_200x200.{$updatePhoto['file_ext']}"; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_1024x768.{$updatePhoto['file_ext']}"; + }else { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_medium.{$updatePhoto['file_ext']}"; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_200x200.{$updatePhoto['file_ext']}"; + }else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$updatePhoto['property_id']}" . "/{$updatePhoto['photo_name']}_thumbnail.{$updatePhoto['file_ext']}"; + } + + $responsePropertyPhoto = []; + $responsePropertyPhoto[] = + [ + 'id' => $updatePhoto['id'], + 'property_id' => $updatePhoto['property_id'], + 'property_photo_category_id' => $updatePhoto['property_photo_category_id'], + 'property_photo_category_name' => $getPhotoCategory['category_name'], + 'photo_name' => $updatePhoto['photo_name'], + 'file_ext' => $updatePhoto['file_ext'], + 'photo_url' => $photoUrlFilePath, + 'photo_url_thump' => $photoUrlThumbFilePath, + 'is_default' => $updatePhoto['is_default'], + 'is_temp' => $updatePhoto['is_temp'], + 'status' => $updatePhoto['status'], + ]; + + $response = ['status' => 1, 'statusCode' => 200 ,'message' => '', 'data' => $responsePropertyPhoto]; + + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['status'] = false; + } + + return output($response); + } + + public function getPropertyRoomPhoto($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + $propertyId = $params['property_id']; + $roomId = $params['room_id']; + $roomCategory = 11; // For room category priority + + + $getPropertyRoomCriteria = + [ + 'criteria' => + [ + ['field' => 'id', 'condition' => '=', 'value' => $roomId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'firstRow' => 1 + ]; + $roomInfo = $this->propertyRoomService->select($getPropertyRoomCriteria); + $roomInfo = $roomInfo['data'] ? $roomInfo['data'] : []; + if(!$roomInfo){ + throw new ApiErrorException(lang('Property room not found')); + } + + + $getPropertyPhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyRooms.propertyRoom'], + 'orderBy' => + [ + ["field" => "photo_order", "value" => "ASC"] + ], + ]; + $getPropertyPhotos = $this->propertyPhotoRepository->findByCriteria($getPropertyPhotoCriteria); + $getPropertyPhotos = $getPropertyPhotos ? $getPropertyPhotos : null; + + + $getPropertyPhotos = collect($getPropertyPhotos)->map(function ($value) { + $response = $value ; + + $propertyRoomPhotos = collect($value['property_rooms']) + ->map(function ($value) { + return $value['property_room'] ; + })->values()->all(); + + $response['property_rooms'] = $propertyRoomPhotos; + return $response ; + })->values()->all(); + + if (empty($getPropertyPhotos)) { + throw new ApiErrorException(lang('Property photos not found')); + } + + $getPropertyRoomPhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['propertyRoom'] + ]; + $roomPhotos = $this->propertyRoomPhotoMappingService->select($getPropertyRoomPhotoCriteria); + $roomPhotos = $roomPhotos['data'] ? $roomPhotos['data'] : []; + + + $roomPhotos = collect($roomPhotos); + + + $roomPhotos = $roomPhotos->map(function ($value) { + $response = $value ; + $response['room_type_id'] = $value['property_room']['room_type_id']; + unset($response['property_room']); + return $response ; + }); + + + $filteredList = []; + $showRecommended = true ; + foreach ($getPropertyPhotos as $key => $getPropertyPhoto) { + + $checkMapping = $roomPhotos + ->where('photo_id', '=', $getPropertyPhoto['id']) + ->where('room_id', '=', $roomId) + ->first(); + + $requestedRooms = collect($getPropertyPhoto['property_rooms']) + ->where('room_type_id', '=', $roomInfo['room_type_id']) + ->keyBy('id')->keys(); + + + $checkRecommended = $roomPhotos + ->where('photo_id', '=', $getPropertyPhoto['id']) + ->whereIn('room_id', $requestedRooms) + ->first(); + + if($checkMapping){ + $showRecommended = false ; + } + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + }else { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_medium.{$getPropertyPhoto['file_ext']}"; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + }else{ + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_thumbnail.{$getPropertyPhoto['file_ext']}"; + } + + $filteredItem = [ + 'id' => $getPropertyPhoto['id'], + 'property_id' => $getPropertyPhoto['property_id'], + 'property_photo_category_id' => $getPropertyPhoto['property_photo_category_id'], + 'photo_url' => $photoUrlFilePath, + 'photo_url_thump' => $photoUrlThumbFilePath, + "photo_name" => $getPropertyPhoto["photo_name"], + "photo_rank" => $getPropertyPhoto["photo_rank"], + "file_size" => $getPropertyPhoto["file_size"], + "file_ext" => $getPropertyPhoto["file_ext"], + "photo_resolution" => $getPropertyPhoto["photo_resolution"], + "photo_order" => $getPropertyPhoto["photo_order"], + "is_default" => $getPropertyPhoto["is_default"], + "is_temp" => $getPropertyPhoto["is_temp"], + "status" => $getPropertyPhoto["status"], + "is_selected" => $checkMapping ? true : false, + "is_recommended" => $checkRecommended ? true : false, + 'order_priority' => $getPropertyPhoto['property_photo_category_id'] == $roomCategory ? 0 : 1 , + ]; + $filteredList[] = $filteredItem ; + + } + + if(collect($filteredList)->where('is_recommended', 'true')->count() == 0){ + $showRecommended = false ; + } + array_multisort( + array_column($filteredList, 'order_priority'), SORT_ASC, + array_column($filteredList, 'photo_order'), SORT_ASC, + $filteredList + ); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => '', 'data' => ['get_room_photos' => $filteredList, 'show_recommended' => $showRecommended] ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + return output($response); + } + + public function uploadPhoto($params = []){ + + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try + { + $validateParams = [ + 'photo' => $params['photo'] + ]; + + $uploadedFile = $params['photo']; + $validationResult = $this->propertyPhotoValidator->validate($validateParams); + if ($validationResult->errors()->first()) { + throw new ApiErrorException($validationResult->errors()->all()); + } + + $uploadedOriginalImage = Image::make($uploadedFile); + $imageWidth = $uploadedOriginalImage->width() ; + $imageHeight = $uploadedOriginalImage->height(); + + $fileExt = $uploadedFile->getClientOriginalExtension(); + $fileSize = (int)ceil(Image::make($uploadedFile)->filesize() / 1024); + + $imageExtension = 'jpg'; + $fileExt = $fileExt != $imageExtension ? $imageExtension : $fileExt; + $quality = 80; + + $urlPath = '/property-photos/' . $params['property_id'] . "/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath ; + $fileName = time().'_'.generateRandomString(10); ; + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + $originalImageMustResize = ($imageHeight > 2000 || $imageWidth > 2000) ; + + if($imageHeight < 768){ + throw new ApiErrorException('image size error: minimum height must be 768px') ; + } + + + if ($imageHeight > $imageWidth) { + + $ratio = $imageHeight/768; + //$ratio200 = 768/200; + $resizeWidth = intval($imageWidth/$ratio); + //$resizeThumbWidth = intval($resizeWidth/$ratio200); + + if($originalImageMustResize){ + $imageHRatio = $imageHeight / 2000 ; + $imageResizedOriginalWidth = intval($imageWidth / $imageHRatio); + $image = $uploadedOriginalImage->fit($imageResizedOriginalWidth, 2000)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality) ; + }else{ + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality) ; + } + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300,300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt ); + } + else{ + + $ratio = $imageHeight/768; + $resizeWidth = intval($imageWidth/$ratio); + + $ratioTumbnail = 768/300; + $resizeThumbWidth = intval($resizeWidth/$ratioTumbnail); + + + if($originalImageMustResize){ + $imageWRatio = $imageWidth / 2000 ; + $imageResizedOriginalHeight = intval($imageHeight / $imageWRatio); + $image = $uploadedOriginalImage->fit(2000, $imageResizedOriginalHeight)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality) ; + }else{ + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality) ; + } + + if($resizeWidth > 1599){ + $image->fit(1600, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300,300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } + else{ + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } + + } + + $isCompatibleWithMywebSlider = 0; + if($imageWidth >= 1150 && $imageHeight >= 600){ + $isCompatibleWithMywebSlider = 1; + } + + $response = [ + 'status' => true, + 'data' => [ + 'photo_path' => $urlPath, + 'photo_name' => $fileName, + 'file_size' => $fileSize, + 'file_ext' => $fileExt, + 'file_resolution' => $imageWidth .'x'. $imageHeight, + 'is_compatible_with_myweb_slider' => $isCompatibleWithMywebSlider + ] + ]; + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['status'] = false; + } + + return output($response); + } + + public function getPropertyPlacePhoto($params) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + $propertyId = $params['property_id']; + $placeId = $params['place_id']; + $placeCategory = 0; + $getPropertyPlaceCriteria = + [ + 'criteria' => + [ + ['field' => 'id', 'condition' => '=', 'value' => $placeId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'firstRow' => 1 + ]; + $placeInfo = $this->propertyPlaceService->select($getPropertyPlaceCriteria); + $placeInfo = $placeInfo['data'] ? $placeInfo['data'] : []; + + if(!$placeInfo){ + throw new ApiErrorException(lang('Property place not found')); + } + + + $getPropertyPhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyPlaces.propertyPlace'], + 'orderBy' => + [ + ["field" => "photo_order", "value" => "ASC"] + ], + ]; + $getPropertyPhotos = $this->propertyPhotoRepository->findByCriteria($getPropertyPhotoCriteria); + $getPropertyPhotos = $getPropertyPhotos ? $getPropertyPhotos : null; + + + $getPropertyPhotos = collect($getPropertyPhotos)->map(function ($value) { + $response = $value ; + + $propertyPlacePhotos = collect($value['property_places']) + ->map(function ($value) { + return $value['property_place'] ; + })->values()->all(); + + $response['property_places'] = $propertyPlacePhotos; + return $response ; + })->values()->all(); + + if (empty($getPropertyPhotos)) { + throw new ApiErrorException(lang('Property photos not found')); + } + + $getPropertyPlacePhotoCriteria = + [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['propertyPlace'] + ]; + $placePhotos = $this->propertyPlacePhotoMappingRepository->findByCriteria($getPropertyPlacePhotoCriteria); + + $placePhotos = $placePhotos ? $placePhotos : []; + + + $placePhotos = collect($placePhotos); + + + $placePhotos = $placePhotos->map(function ($value) { + $response = $value ; + $response['place_category_id'] = $value['property_place']['place_category_id']; + unset($response['property_place']); + return $response ; + }); + + + $filteredList = []; + $showRecommended = true ; + foreach ($getPropertyPhotos as $key => $getPropertyPhoto) { + + $checkMapping = $placePhotos + ->where('photo_id', '=', $getPropertyPhoto['id']) + ->where('place_id', '=', $placeId) + ->first(); + + $requestedPlaces = collect($getPropertyPhoto['property_places']) + ->where('place_category_id', '=', $placeInfo['place_category_id']) + ->keyBy('id')->keys(); + + + $checkRecommended = $placePhotos + ->where('photo_id', '=', $getPropertyPhoto['id']) + ->whereIn('place_id', $requestedPlaces) + ->first(); + + if($checkMapping){ + $showRecommended = false ; + } + + $photoUrlFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_1024x768.{$getPropertyPhoto['file_ext']}"; + }else { + $photoUrlFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_medium.{$getPropertyPhoto['file_ext']}"; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_200x200.{$getPropertyPhoto['file_ext']}"; + }else{ + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$getPropertyPhoto['property_id']}" . "/{$getPropertyPhoto['photo_name']}_thumbnail.{$getPropertyPhoto['file_ext']}"; + } + + $filteredItem = [ + 'id' => $getPropertyPhoto['id'], + 'property_id' => $getPropertyPhoto['property_id'], + 'property_photo_category_id' => $getPropertyPhoto['property_photo_category_id'], + 'photo_url' => $photoUrlFilePath, + 'photo_url_thump' => $photoUrlThumbFilePath, + "photo_name" => $getPropertyPhoto["photo_name"], + "photo_rank" => $getPropertyPhoto["photo_rank"], + "file_size" => $getPropertyPhoto["file_size"], + "file_ext" => $getPropertyPhoto["file_ext"], + "photo_resolution" => $getPropertyPhoto["photo_resolution"], + "photo_order" => $getPropertyPhoto["photo_order"], + "is_default" => $getPropertyPhoto["is_default"], + "is_temp" => $getPropertyPhoto["is_temp"], + "status" => $getPropertyPhoto["status"], + "is_selected" => $checkMapping ? true : false, + "is_recommended" => $checkRecommended ? true : false, + 'order_priority' => $getPropertyPhoto['property_photo_category_id'] == $placeCategory ? 0 : 1 , + ]; + $filteredList[] = $filteredItem ; + + } + + if(collect($filteredList)->where('is_recommended', 'true')->count() == 0){ + $showRecommended = false ; + } + array_multisort( + array_column($filteredList, 'order_priority'), SORT_ASC, + array_column($filteredList, 'photo_order'), SORT_ASC, + $filteredList + ); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => '', 'data' => ['get_place_photos' => $filteredList, 'show_recommended' => $showRecommended] ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + $response['statusCode'] = 204; + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + return output($response); + } + +} diff --git a/app/Core/Service/PropertyPlaceService.php b/app/Core/Service/PropertyPlaceService.php new file mode 100644 index 0000000..39ee735 --- /dev/null +++ b/app/Core/Service/PropertyPlaceService.php @@ -0,0 +1,2027 @@ +propertyPlaceRepository = $propertyPlaceRepository; + $this->propertyPlaceCategoryRepository = $propertyPlaceCategoryRepository; + $this->propertyPlaceWorkingHourRepository = $propertyPlaceWorkingHourRepository; + $this->propertyPlaceCreateValidator = $propertyPlaceCreateValidator; + $this->propertyPlacePhotoMappingRepository = $propertyPlacePhotoMappingRepository; + $this->propertyPlacePhotoMappingAddValidator = $propertyPlacePhotoMappingAddValidator; + $this->propertyPlaceUpdateValidator = $propertyPlaceUpdateValidator; + $this->propertyPlaceFactTitleFactMappingRepository = $propertyPlaceFactTitleFactMappingRepository; + $this->propertyPlaceFactMappingRepository = $propertyPlaceFactMappingRepository; + $this->propertyPlaceFactMappingUpdateValidator = $propertyPlaceFactMappingUpdateValidator; + $this->placeCategoryFieldRepository = $placeCategoryFieldRepository; + $this->placeCategoryFieldOptionRepository = $placeCategoryFieldOptionRepository; + $this->placeCategoryFieldOptionFieldMappingRepository = $placeCategoryFieldOptionFieldMappingRepository; + $this->propertyPlaceCategoryFieldValueRepository = $propertyPlaceCategoryFieldValueRepository; + $this->placeCategoryFieldMappingRepository = $placeCategoryFieldMappingRepository; + $this->propertyUnitRepository = $propertyUnitRepository; + $this->languageService = $languageService; + + $this->include = [ + [ + 'id' => 1, + 'name' => 'Paid Services', + 'language_key' => 'input-option-paid_services', + ], + [ + 'id' => 2, + 'name' => 'Free', + 'language_key' => 'input-option-free', + ] + ]; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyPlaceCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $description = []; + foreach (fillOnUndefined($param, "description", []) as $desc) { + $description[$desc['language_code']] = $desc['description']; + } + + $languageName = []; + foreach (fillOnUndefined($param, "language_name", []) as $value) { + $languageName[$value['language_code']] = $value['name']; + } + + + $insertData = [ + "property_id" => fillOnUndefined($param, "property_id"), + "name" => fillOnUndefined($param, "name"), + "language_name" => !empty($languageName) ? json_encode($languageName) : null, + "place_category_id" => fillOnUndefined($param, "place_category_id"), + "place_working_hour_id" => fillOnUndefined($param, "place_working_hour_id"), + "reservation_requirement" => fillOnUndefined($param, "reservation_requirement"), + "include" => fillOnUndefined($param, "include"), + "web" => fillOnUndefined($param, "web"), + "menu" => fillOnUndefined($param, "menu"), + "contact_form" => fillOnUndefined($param, "contact_form"), + "description" => !empty($description) ? json_encode($description) : null, + "status" => 1, + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyPlaceRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $placeData = $userCreateResult['data']; + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_place_category_id', 'condition' => '=', 'value' => $placeData['place_category_id']], + ], + 'with' => ['placeCategoryField'], + 'orderBy' => [["field" => "order_number", "value" => "ASC"]], + ]; + $placeCategoryMappingData = $this->placeCategoryFieldMappingRepository->findByCriteria($placeCategoryRequest); + $placeCategoryMappingData = $placeCategoryMappingData ? $placeCategoryMappingData : []; + $placeCategories = collect($placeCategoryMappingData)->map(function ($value) { + return $value['place_category_field']; + }); + + $fieldValues = fillOnUndefined($param, 'field_values', []); + $insertFieldValue = []; + + foreach ($fieldValues as $fieldKey => $fieldValue) { + + if (strpos($fieldKey, '_unit') > -1) { + continue; + } + + if (strpos($fieldKey, '_max') > -1) { + continue; + } + + $fieldInfo = $placeCategories->where('id', '=', $fieldValue['field_id'])->where('name', '=', $fieldValue['field_name'])->first(); + if (!$fieldInfo) { + throw new Exception('api-unknown_error'); + } + + $fieldStatics = [ + 'property_id' => $param['property_id'], + 'place_id' => $placeData['id'], + 'property_place_category_id' => $placeData['place_category_id'], + 'place_category_field_id' => $fieldValue['field_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($param, 'user_id'), + 'updated_by' => fillOnUndefined($param, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ($fieldInfo['element'] == 'multiselect') { + foreach ($fieldValue['field_value'] as $item) { + $value = [ + 'input_value' => null, + 'option_value' => $item, + 'unit_value' => null, + ]; + $insertFieldValue[] = array_merge($fieldStatics, $value); + } + } elseif ($fieldInfo['element'] == 'inputunit') { + $searchKey = $fieldValue['field_id'] . '_unit'; + if (!isset($fieldValues[$searchKey]['field_unit_value'])) { + throw new Exception('api-unknown_error'); + } + $value = [ + 'input_value' => $fieldValue['field_value'], + 'option_value' => null, + 'unit_value' => $fieldValues[$searchKey]['field_unit_value'], + ]; + + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } elseif ($fieldInfo['element'] == 'slider') { + + $maxData = null; + if (isset($fieldValues['3_max']) && isset($fieldValues['3_max']['field_max_value']) && $fieldValues['3_max']['field_max_value']) { + $maxData = $fieldValues['3_max']['field_max_value']; + } + + + if (($fieldValue['field_value'] && $maxData === NULL) || $maxData && !$fieldValue['field_value']) { + throw new Exception('Min Age and Max Age is required'); + } + + $inputValue = $fieldValue['field_value'] && $maxData ? $fieldValue['field_value'] . '-' . $maxData : null; + $value = [ + 'input_value' => $inputValue, + 'option_value' => null, + 'unit_value' => null, + ]; + + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } else { + $value = [ + 'input_value' => $fieldInfo['element'] != 'select' ? $fieldValue['field_value'] : null, + 'option_value' => $fieldInfo['element'] == 'select' ? $fieldValue['field_value'] : null, + 'unit_value' => null, + ]; + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } + } + + if ($insertFieldValue) { + $createResult = $this->propertyPlaceCategoryFieldValueRepository->insert($insertFieldValue); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPlaceRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectPhotoMapping($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPlacePhotoMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + DB::beginTransaction(); + $placeId = fillOnUndefined($param, "property_place_id"); + $placeRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => $placeId], + ], + 'firstRow' => true + ]; + $propertyWebData = $this->propertyPlaceRepository->findByCriteria($placeRequest, ['id', 'name', 'place_category_id']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Place mapping not found.')); + } + + + $paramPlaceCategoryId = fillOnUndefined($param, 'place_category_id'); + + if ($paramPlaceCategoryId && ($propertyWebData['place_category_id'] != $paramPlaceCategoryId)) { + + $propertyPlaceFactMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'property_place_id', 'condition' => '=', 'value' => $placeId] + ] + + ]; + $propertyPlaceFactMappingData = $this->propertyPlaceFactMappingRepository->findByCriteria($propertyPlaceFactMappingRequest); + + $propertyPlaceFactMappingData = $propertyPlaceFactMappingData ? $propertyPlaceFactMappingData : []; + + $propertyPlaceFactMappingIds = collect($propertyPlaceFactMappingData)->keyBy('id')->keys()->all(); + + if ($propertyPlaceFactMappingIds) { + + $propertyPlaceFactMappingDelete = $this->propertyPlaceFactMappingRepository->destroy($propertyPlaceFactMappingIds); + + if ($propertyPlaceFactMappingDelete['status'] != "success") { + throw new Exception('api-unknown_error'); + } + } + + + $propertyPlacePhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'place_id', 'condition' => '=', 'value' => $placeId] + ] + + ]; + + $propertyPlacePhotoMapping = $this->propertyPlacePhotoMappingRepository->findByCriteria($propertyPlacePhotoMappingRequest); + $propertyPlacePhotoMapping = $propertyPlacePhotoMapping ? $propertyPlacePhotoMapping : []; + + $propertyPlacePhotoMappingIds = collect($propertyPlacePhotoMapping)->keyBy('id')->keys()->all(); + if ($propertyPlacePhotoMappingIds) { + + $propertyPlacePhotoMappingDelete = $this->propertyPlacePhotoMappingRepository->destroy($propertyPlacePhotoMappingIds); + + if ($propertyPlacePhotoMappingDelete['status'] != "success") { + throw new Exception('api-unknown_error'); + } + } + + } + + $description = []; + foreach (fillOnUndefined($param, "description", []) as $desc) { + $description[$desc['language_code']] = $desc['description']; + } + + $languageName = []; + foreach (fillOnUndefined($param, "language_name", []) as $value) { + $languageName[$value['language_code']] = $value['name']; + } + + $updateData = [ + "name" => fillOnUndefined($param, "name"), + "language_name" => !empty($languageName) ? json_encode($languageName) : null, + "place_category_id" => fillOnUndefined($param, "place_category_id"), + "place_working_hour_id" => fillOnUndefined($param, "place_working_hour_id"), + "reservation_requirement" => fillOnUndefined($param, "reservation_requirement"), + "include" => fillOnUndefined($param, "include"), + "description" => !empty($description) ? json_encode($description) : null, + "web" => fillOnUndefined($param, "web"), + "menu" => fillOnUndefined($param, "menu"), + "contact_form" => fillOnUndefined($param, "contact_form"), + "status" => fillOnUndefined($param, "status", 1), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + $validationResult = $this->propertyPlaceUpdateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateResult = $this->propertyPlaceRepository->update($placeId, $updateData); + + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + + $fieldValuesRequest = [ + 'criteria' => [ + ['field' => 'place_id', 'condition' => '=', 'value' => $placeId], + ], + + ]; + $oldValuesData = $this->propertyPlaceCategoryFieldValueRepository->findByCriteria($fieldValuesRequest); + $oldValuesData = $oldValuesData ? $oldValuesData : []; + + $deleteThisIds = collect($oldValuesData)->keyBy('id')->keys()->all(); + + if ($deleteThisIds) { + $deleteThisArray = $this->propertyPlaceCategoryFieldValueRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_place_category_id', 'condition' => '=', 'value' => $updateData['place_category_id']], + ], + 'with' => ['placeCategoryField'], + 'orderBy' => [["field" => "order_number", "value" => "ASC"]], + ]; + $placeCategoryMappingData = $this->placeCategoryFieldMappingRepository->findByCriteria($placeCategoryRequest); + $placeCategoryMappingData = $placeCategoryMappingData ? $placeCategoryMappingData : []; + $placeCategories = collect($placeCategoryMappingData)->map(function ($value) { + return $value['place_category_field']; + }); + + $fieldValues = fillOnUndefined($param, 'field_values', []); + $insertFieldValue = []; + foreach ($fieldValues as $fieldKey => $fieldValue) { + + if (strpos($fieldKey, '_unit') > -1) { + continue; + } + + $fieldInfo = $placeCategories->where('id', '=', $fieldValue['field_id'])->where('name', '=', $fieldValue['field_name'])->first(); + if (!$fieldInfo) { + throw new Exception('api-unknown_error'); + } + + $fieldStatics = [ + 'property_id' => $updateData['property_id'], + 'place_id' => $placeId, + 'property_place_category_id' => $updateData['place_category_id'], + 'place_category_field_id' => $fieldValue['field_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($param, 'user_id'), + 'updated_by' => fillOnUndefined($param, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ($fieldInfo['element'] == 'multiselect') { + foreach ($fieldValue['field_value'] as $item) { + $value = [ + 'input_value' => null, + 'option_value' => $item, + 'unit_value' => null, + ]; + $insertFieldValue[] = array_merge($fieldStatics, $value); + } + } elseif ($fieldInfo['element'] == 'inputunit') { + $searchKey = $fieldValue['field_id'] . '_unit'; + $fieldUnitValue = null; + if (isset($fieldValues[$searchKey]['field_unit_value'])) { + $fieldUnitValue = $fieldValues[$searchKey]['field_unit_value']; + } + $value = [ + 'input_value' => $fieldValue['field_value'], + 'option_value' => null, + 'unit_value' => $fieldUnitValue == "" ? null : $fieldUnitValue, + ]; + + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } elseif ($fieldInfo['element'] == 'slider') { + + if (isset($fieldValue['field_value']) && !empty($fieldValue['field_value'])) { + + $count = collect($fieldValue['field_value'])->count(); + if ($count == 1) { + throw new Exception('Min Age and Max Age is required'); + } + + if (($fieldValue['field_value'][0] && $fieldValue['field_value'][1] === NULL) || ($fieldValue['field_value'][0] === NULL && $fieldValue['field_value'][1])) { + throw new Exception('Min Age and Max Age is required'); + } + + } + $saveValue = null; + if (!in_array("", $fieldValue['field_value'])) { + $saveValue = implode('-', $fieldValue['field_value']); + } + + + $value = [ + 'input_value' => $saveValue, + 'option_value' => null, + 'unit_value' => null, + ]; + + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } else { + $value = [ + 'input_value' => $fieldInfo['element'] != 'select' ? $fieldValue['field_value'] : null, + 'option_value' => $fieldInfo['element'] == 'select' && !empty($fieldValue['field_value']) ? $fieldValue['field_value'] : null, + 'unit_value' => null, + + ]; + $insertFieldValue[] = array_merge($fieldStatics, $value); + + } + } + + if ($insertFieldValue) { + $createResult = $this->propertyPlaceCategoryFieldValueRepository->insert($insertFieldValue); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyPlaceCategories($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + $categoryTriesRequest = [ + 'parent_id' => null, + 'placeCategories' => $placeCategories + ]; + + + $categoryTries = $this->categoryTries($categoryTriesRequest); + + + $response = [ + 'status' => true, + 'data' => $categoryTries, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + private function categoryTries($params) + { + + $placeCategories = $params['placeCategories']; + $parentId = $params['parent_id']; + $placeCategoryList = $placeCategories->where('parent_id', '=', $parentId)->all(); + $responseData = []; + foreach ($placeCategoryList as $placeCategory) { + + $responseItem = [ + "id" => $placeCategory['id'], + "name" => $placeCategory['name'], + "language_key" => $placeCategory['language_key'], + "parent_id" => $placeCategory['parent_id'], + "level" => $placeCategory['level'], + "order_number" => $placeCategory['order_number'], + "icon" => $placeCategory['icon'], + "child" => null + ]; + + $checkChild = $placeCategories->where('parent_id', '=', $placeCategory['id'])->count(); + + if ($checkChild > 0) { + $categoryTriesRequest = [ + 'parent_id' => $placeCategory['id'], + 'placeCategories' => $placeCategories + ]; + $categoryTries = $this->categoryTries($categoryTriesRequest); + $responseItem['child'] = $categoryTries; + } + + $responseData[$placeCategory['id']] = $responseItem; + + } + + + return $responseData; + + } + + private function categoryTriesSingleArray($params) + { + + $placeCategories = $params['placeCategories']; + $parentId = $params['parent_id']; + $placeCategoryList = $placeCategories->where('parent_id', '=', $parentId)->all(); + $responseData = []; + foreach ($placeCategoryList as $placeCategory) { + + $responseItem = [ + "id" => $placeCategory['id'], + "name" => $placeCategory['name'], + "language_key" => $placeCategory['language_key'], + "parent_id" => $placeCategory['parent_id'], + "level" => $placeCategory['level'], + "order_number" => $placeCategory['order_number'], + "icon" => $placeCategory['icon'], + + ]; + + $checkChild = $placeCategories->where('parent_id', '=', $placeCategory['id'])->count(); + $categoryTries = []; + if ($checkChild > 0) { + $categoryTriesRequest = [ + 'parent_id' => $placeCategory['id'], + 'placeCategories' => $placeCategories + ]; + $categoryTries = $this->categoryTriesSingleArray($categoryTriesRequest); + } + $responseData[] = $responseItem; + $responseData = array_merge($responseData, $categoryTries); + } + + return $responseData; + + } + + public function getPropertyWorkingHours($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $placeWorkingHourData = $this->propertyPlaceWorkingHourRepository->findByCriteria($placeCategoryRequest); + $placeWorkingHours = collect($placeWorkingHourData)->map(function ($value) { + + return [ + "id" => $value['id'], + "name" => $value['name'], + "language_key" => $value['language_key'], + "status" => $value['status'], + ]; + + }); + + $response = [ + 'status' => true, + 'data' => $placeWorkingHours, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function listPlaces($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeRequest = [ + 'criteria' => [ + //['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyPlaceCategory', 'propertyPlaceWorkingHour'] + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + $placeData = $placeData ? $placeData : []; + + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + $places = []; + + foreach ($placeData as $place) { + $include = collect($this->include)->where('id', '=', $place['include'])->first(); + + $descriptionLangContents = json_decode($place['description'], 1); + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + + $languageNameContents = json_decode($place['language_name'], 1); + $responseLanguageName = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLanguageName[] = [ + 'language_code' => $langKey, + 'name' => isset($languageNameContents[$langKey]) ? $languageNameContents[$langKey] : null + ]; + } + + $exportPlace = [ + "id" => $place['id'], + "property_id" => $place['property_id'], + "name" => $place['name'], + "place_category_id" => $place['place_category_id'], + "place_working_hour_id" => $place['place_working_hour_id'], + "place_working_hour_name" => $place['property_place_working_hour']['name'], + "place_working_hour_language_key" => $place['property_place_working_hour']['language_key'], + "reservation_requirement" => $place['reservation_requirement'], + "contact_form" => $place['contact_form'], + "include_name" => isset($include) ? $include['name'] : null, + "include_language_key" => isset($include) ? $include['language_key'] : null, + "order_number" => $place['order_number'], + "description" => $responseLangDescription, + "language_name" => $responseLanguageName, + "web" => $place['web'], + "menu" => $place['menu'], + "include" => $place['include'], + "status" => $place['status'], + ]; + + $categoryParentRequest = [ + 'parent_id' => isset($place['property_place_category']) ? $place['property_place_category']['parent_id'] : null, + 'placeCategories' => $placeCategories + ]; + + $placeCategoryArray = []; + + $placeCategoryArray[] = $place['property_place_category']; + if ($place['property_place_category']['parent_id'] != null) { + $parentCategory = $this->categoryParents($categoryParentRequest); + $placeCategoryArray = array_merge($placeCategoryArray, $parentCategory); + } + $categories = collect($placeCategoryArray)->sortBy('level')->all(); + + $level = 1; + $categoryFilter = []; + foreach ($categories as $category) { + $exportPlace['category_tree'][$level] = [ + "id" => $category['id'], + "name" => $category['name'], + "language_key" => $category['language_key'], + "parent_id" => $category['parent_id'], + "level" => $category['level'], + "order_number" => $category['order_number'], + "icon" => $category['icon'], + "status" => $category['status'], + ]; + $level++; + $categoryFilter[] = $category['id']; + } + $exportPlace['category_filters'] = $categoryFilter; + + $places[] = $exportPlace; + } + + + $response = [ + 'status' => true, + 'data' => $places, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + private function categoryParents($params) + { + $placeCategories = $params['placeCategories']; + $parentId = $params['parent_id']; + $placeCategory = $placeCategories->where('id', '=', $parentId)->first(); + $responseData[] = $placeCategory; + + if (isset($placeCategory) && $placeCategory['parent_id'] != null) { + $categoryParentRequest = [ + 'parent_id' => $placeCategory['parent_id'], + 'placeCategories' => $placeCategories + ]; + $parentCategory = $this->categoryParents($categoryParentRequest); + $responseData = array_merge($responseData, $parentCategory); + } + return $responseData; + } + + public function updatePropertyPlacePhotoMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyPlacePhotoMappingAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $addPropertyPlacePhotoMapping = []; + $addPhotoList = collect($params['property_place_photo']) + ->where('is_selected', '=', true); + $addPhotoIds = $addPhotoList->keyBy("id")->keys()->toArray(); + + $removePhotoList = collect($params['property_place_photo']) + ->where('is_selected', '=', false); + + $removePhotoIds = $removePhotoList->keyBy("id")->keys()->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'place_id', 'condition' => '=', 'value' => $params['place_id']], + ], + "whereIn" => [ + ["field" => "photo_id", "value" => $addPhotoIds] + ] + ]; + $checkPropertyMappingResponse = $this->select($checkPropertyMappingRequest, ['id', 'property_id', 'photo_id']); + + if ($checkPropertyMappingResponse['status'] != 'success') { + throw new ApiErrorException(lang('Mapping data not loaded')); + } + $checkPropertyMappingCollect = collect($checkPropertyMappingResponse['data']); + + foreach ($addPhotoList->toArray() as $key => $param) { + + if ( + !$checkPropertyMappingCollect->where('property_id', '=', $params['property_id']) + ->where('photo_id', '=', $param['id']) + ->first() + ) { + + $addPropertyPlacePhotoMapping[] = + [ + 'property_id' => $params['property_id'], + 'place_id' => $params['place_id'], + 'photo_id' => fillOnUndefined($param, 'id'), + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + } + } + + $response = $this->propertyPlacePhotoMappingRepository->createAll($addPropertyPlacePhotoMapping); + + if ($removePhotoIds) { + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'place_id', 'condition' => '=', 'value' => $params['place_id']], + ], + "whereIn" => + [ + ["field" => "photo_id", "value" => $removePhotoIds] + ] + ]; + + $deletePropertyPlacePhotoMapping = $this->propertyPlacePhotoMappingRepository->findByCriteria($findCriteria); + + $deleteThisIds = []; + foreach ($deletePropertyPlacePhotoMapping as $deleteThisItem) { + $deleteThisIds[] = $deleteThisItem['id']; + } + + if ($deleteThisIds) { + $this->propertyPlacePhotoMappingRepository->deleteById($deleteThisIds); + } + } + + if ($response['status'] != 'success') { + throw new ApiErrorException(lang('Data is not added')); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function updateStatus($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $placeId = fillOnUndefined($param, "property_place_id"); + $placeRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => $placeId], + ] + ]; + $propertyWebData = $this->propertyPlaceRepository->findByCriteria($placeRequest, ['id', 'name']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Place mapping not found.')); + } + + $updateData = + [ + "status" => fillOnUndefined($param, "set_status", 0), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyPlaceRepository->update($placeId, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePlace($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + DB::beginTransaction(); + + $placeRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_place_id')], + ], + 'with' => ['propertyPlaceCategory', 'propertyPlaceWorkingHour', 'propertyPlacePhotoMapping'], + "firstRow" => 1 + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + if (!$placeData) { + throw new ApiErrorException(lang('Property - Place not found.')); + } + $deleteIds = collect($placeData['property_place_photo_mapping'])->keyBy('id')->keys()->all(); + if ($deleteIds) { + $deletePhotoMapping = $this->propertyPlacePhotoMappingRepository->destroy($deleteIds); + if ($deletePhotoMapping['status'] != "success") { + throw new Exception('api-unknown_error'); + } + } + + $deletePlaceCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_place_id']] + ] + ]; + $this->propertyPlaceRepository->delete($deletePlaceCriteria); + + + $response = [ + 'status' => true, + 'data' => null, + ]; + + db::commit(); + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + db::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + db::rollBack(); + } + + return output($response); + } + + public function getPropertyPlaceCategoriesSingle($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + $categoryTries = $placeCategories->map(function ($value) { + + return [ + "id" => $value['id'], + "name" => $value['name'], + "language_key" => $value['language_key'], + "parent_id" => $value['parent_id'], + "level" => $value['level'], + "order_number" => $value['order_number'], + "icon" => $value['icon'], + ]; + })->values()->all(); + + $response = [ + 'status' => true, + 'data' => $categoryTries, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function editPlaces($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['property_place_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyPlaceCategory', 'propertyPlaceWorkingHour'], + 'firstRow' => 1 + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + if (!$placeData) { + throw new ApiErrorException(lang('Property - Place not found.')); + } + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + $place = $placeData; + $include = collect($this->include)->where('id', '=', $place['include'])->first(); + + + $exportPlace = [ + "id" => $place['id'], + "property_id" => $place['property_id'], + "name" => $place['name'], + "place_category_id" => $place['place_category_id'], + "place_working_hour_id" => $place['place_working_hour_id'], + "place_working_hour_name" => $place['property_place_working_hour']['name'], + "place_working_hour_language_key" => $place['property_place_working_hour']['language_key'], + "reservation_requirement" => $place['reservation_requirement'], + "include" => $place['include'], + "include_name" => isset($include) ? $include['name'] : null, + "include_language_key" => isset($include) ? $include['language_key'] : null, + "web" => $place['web'], + "status" => $place['status'], + ]; + + $categoryParentRequest = [ + 'parent_id' => isset($place['property_place_category']) ? $place['property_place_category']['parent_id'] : null, + 'placeCategories' => $placeCategories + ]; + + $placeCategoryArray = []; + + $placeCategoryArray[] = $place['property_place_category']; + if ($place['property_place_category']['parent_id'] != null) { + $parentCategory = $this->categoryParents($categoryParentRequest); + $placeCategoryArray = array_merge($placeCategoryArray, $parentCategory); + } + $categories = collect($placeCategoryArray)->sortBy('level')->all(); + + $level = 1; + $categoryFilter = []; + foreach ($categories as $category) { + $exportPlace['category_tree'][$level] = [ + "id" => $category['id'], + "name" => $category['name'], + "language_key" => $category['language_key'], + "parent_id" => $category['parent_id'], + "level" => $category['level'], + "order_number" => $category['order_number'], + "icon" => $category['order_number'], + "status" => $category['status'], + ]; + $level++; + $categoryFilter[] = $category['id']; + } + $exportPlace['category_filters'] = json_encode($categoryFilter); + + $categoryTries = $placeCategories->map(function ($value) { + + return [ + "id" => $value['id'], + "name" => $value['name'], + "language_key" => $value['language_key'], + "parent_id" => $value['parent_id'], + "level" => $value['level'], + "order_number" => $value['order_number'], + "icon" => $value['icon'], + ]; + })->values()->all(); + + + $responseData = [ + 'place' => $exportPlace, + 'place_categories' => $categoryTries, + 'place_includes' => $this->include, + + ]; + + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function listPlaceFacilities($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['place_id']], + ], + 'firstRow' => true, + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + if (!$placeData) { + throw new ApiErrorException(lang('Property - Place not found.')); + } + + $placeFactTitleFactMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'place_category_id', 'condition' => '=', 'value' => $placeData['place_category_id']], + ], + 'with' => ['placeCategory', 'placeFactTitle', 'placeFact'] + ]; + + $placeFactTitleFactMappingData = $this->propertyPlaceFactTitleFactMappingRepository->findByCriteria($placeFactTitleFactMappingRequest); + $placeFactTitleFactMapping = collect($placeFactTitleFactMappingData); + + $placeFactTitleFactMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_place_id', 'condition' => '=', 'value' => $params['place_id']], + ], + ]; + + $placeFactMappingData = $this->propertyPlaceFactMappingRepository->findByCriteria($placeFactTitleFactMappingRequest); + $placeFactMapping = collect($placeFactMappingData); + + $titleGroups = $placeFactTitleFactMapping->groupBy('place_fact_title_id')->toArray(); + $exportTitles = []; + + foreach ($titleGroups as $titleGroupList) { + if (!$titleGroupList) { + continue; + } + $exportTitleGroup = $titleGroupList[0]['place_fact_title']; + $facts = []; + foreach ($titleGroupList as $title) { + $checkSelected = $placeFactMapping + ->where('place_fact_title_fact_mapping_id', '=', $title['id']) + ->where('property_place_id', '=', $params['place_id']) + ->first(); + $exportItem = $title['place_fact']; + $exportItem['place_fact_title_fact_mapping_id'] = $title['id']; + $exportItem['is_selected'] = isset($checkSelected); + $facts[] = $exportItem; + } + $exportTitleGroup['facts'] = $facts; + $exportTitles[] = $exportTitleGroup; + } + + $response = [ + 'status' => true, + 'data' => $exportTitles, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePlaceFacilities($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyPlaceFactMappingUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $placeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + $propertyPlaceData = $this->propertyPlaceRepository->findByCriteria($placeRequest, ['id', 'name']); + + if (!$propertyPlaceData) { + throw new ApiErrorException(lang('Property - Place mapping not found.')); + } + + $propertyPlaceFactMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_place_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'place_id')], + ['field' => 'place_fact_title_fact_mapping_id', 'condition' => '=', 'value' => $params['place_fact_title_fact_mapping_id']], + ], + 'firstRow' => true + ]; + $propertyPlaceFactMappingData = $this->propertyPlaceFactMappingRepository->findByCriteria($propertyPlaceFactMappingRequest); + + + if ($params['is_selected']) { + + if ($propertyPlaceFactMappingData) { + throw new Exception('api-unknown_error'); + } + + $insertData = + [ + "property_id" => fillOnUndefined($params, "property_id"), + "property_place_id" => fillOnUndefined($params, "place_id"), + "place_fact_title_fact_mapping_id" => fillOnUndefined($params, "place_fact_title_fact_mapping_id"), + "status" => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $createResult = $this->propertyPlaceFactMappingRepository->create($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } else { + if (!$propertyPlaceFactMappingData) { + throw new Exception('api-unknown_error'); + } + + $deleteThis[] = $propertyPlaceFactMappingData['id']; + $this->propertyPlaceFactMappingRepository->deleteById($deleteThis); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPlaceCategoryFields($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_place_category_id', 'condition' => '=', 'value' => $params['place_category_id']], + ], + 'with' => ['placeCategoryField.placeFieldOptionMapping.placeCategoryFieldOption'], + 'orderBy' => [["field" => "order_number", "value" => "ASC"]], + + ]; + $placeCategoryMappingData = $this->placeCategoryFieldMappingRepository->findByCriteria($placeCategoryRequest); + $placeCategoryMappingData = $placeCategoryMappingData ? $placeCategoryMappingData : []; + + $oldValuesData = []; + if ($params['place_id']) { + $fieldValuesRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_place_category_id', 'condition' => '=', 'value' => $params['place_category_id']], + ['field' => 'place_id', 'condition' => '=', 'value' => $params['place_id']], + ], + + ]; + $oldValuesData = $this->propertyPlaceCategoryFieldValueRepository->findByCriteria($fieldValuesRequest); + $oldValuesData = $oldValuesData ? $oldValuesData : []; + } + $oldValues = collect($oldValuesData); + $responseFields = []; + + + $fieldUnitsRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + + ]; + $fieldUnitData = $this->propertyUnitRepository->findByCriteria($fieldUnitsRequest); + $fieldUnitData = collect($fieldUnitData); + + foreach ($placeCategoryMappingData as $mapping) { + if (!$mapping['place_category_field']) { + continue; + } + + $field = $mapping['place_category_field']; + $fieldUnitShortName = null; + $oldFieldValues = $oldValues + ->where('property_place_category_id', '=', $params['place_category_id']) + ->where('place_category_field_id', '=', $field['id']); + + if ($field['element'] == 'multiselect') { + $oldValue = $oldFieldValues->keyBy('option_value')->keys()->all(); + } elseif ($field['element'] == 'select') { + $oldValue = $oldFieldValues->keyBy('option_value')->keys()->first(); + } elseif ($field['element'] == 'slider') { + $getOldValue = $oldFieldValues->keyBy('input_value')->keys()->first(); + $oldValue = $getOldValue ? explode('-', $getOldValue) : []; + } else { + $oldValue = $oldFieldValues->first(); + $oldValue = $oldValue['input_value']; + } + + $fieldUnits = null; + $oldUnitValue = null; + $unitShortName = null; + if ($field['element'] == 'inputunit') { + $fieldAttribute = json_decode($field['field_attribute'], 1); + if (!isset($fieldAttribute['units'])) { + throw new Exception('api-unknown_error'); + } + + $oldUnit = $oldFieldValues->first(); + $oldUnitValue = $oldUnit['unit_value']; + $oldUnitData = $fieldUnitData->where('id', '=', $oldUnit['unit_value'])->first(); + $unitShortName = $oldUnitData['short_name']; + + $fieldUnits = $fieldUnitData->whereIn('id', $fieldAttribute['units'])->map(function ($unit) use ($oldUnitValue) { + return [ + "id" => $unit['id'], + "name" => $unit['name'], + "language_key" => $unit['language_key'], + "short_name" => $unit['short_name'], + "is_selected" => $oldUnitValue == $unit['id'], + ]; + })->values()->all(); + } + + $responseField = [ + 'field_id' => $field['id'], + 'field_name' => $field['name'], + 'field_value' => $oldValue, + 'field_unit_value' => $oldUnitValue, + 'field_unit_short_name' => $unitShortName, + 'field_place_category_id' => $field['id'], + 'field_label' => $field['label'], + 'field_language_key' => $field['language_key'], + 'field_element' => $field['element'], + 'field_type' => $field['type'], + 'field_attribute' => json_decode($field['field_attribute'], 1), + 'field_order_number' => $mapping['order_number'], + 'field_status' => $field['status'], + 'field_units' => $fieldUnits, + + ]; + if ($field['place_field_option_mapping']) { + $searchArray = $field['element'] != 'multiselect' ? [$oldValue] : $oldValue; + $options = collect($field['place_field_option_mapping'])->mapWithKeys(function ($value) use ($searchArray) { + + $optionIsSelected = array_search($value['place_category_field_option']['id'], $searchArray) > -1 ? true : false; + return [ + $value['place_category_field_option']['id'] => + [ + 'option_id' => $value['place_category_field_option']['id'], + 'option_name' => $value['place_category_field_option']['name'], + 'option_language_key' => $value['place_category_field_option']['language_key'], + 'option_status' => $value['place_category_field_option']['status'], + 'option_is_selected' => $optionIsSelected, + ] + ]; + + })->toArray(); + $responseField['options'] = $options; + } + $responseFields[$field['id']] = $responseField; + if ($field['element'] == 'inputunit') { + $responseField['field_id'] = $field['id'] . '_unit'; + unset($responseField['field_element']); + $responseFields[$field['id'] . '_unit'] = $responseField; + } + } + $response = [ + 'status' => true, + 'data' => $responseFields, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function destroyPhotoMapping($params) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'photo_id', 'condition' => '=', 'value' => $params['photo_id']], + ] + ]; + $deleteData = $this->propertyPlacePhotoMappingRepository->findByCriteria($deleteCriteria, ['id']); + $deleteData = $deleteData ? $deleteData : []; + if ($deleteData) { + $deleteIds = array_column($deleteData, 'id'); + $destroyResult = $this->propertyPlacePhotoMappingRepository->destroy($deleteIds); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function insertNewFieldMapping($params) + { + + // bu fonksiyon yeni bir field eklendiğinde mapping eklenebilmesi için konmuştur. + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + + die(); + $mappingData = $this->placeCategoryFieldMappingRepository->findByCriteria(); + $mapping = collect($mappingData); + $categoryList = $mapping->where('property_place_category_field_id', '=', $params['before_field'])->all(); + $withoutList = $mapping + ->where('property_place_category_field_id', '!=', $params['before_field']) + ->where('property_place_category_field_id', '!=', $params['add_field_id']) + ->all(); + + + $orderList = []; + foreach ($withoutList as $item) { + if ($item['order_number'] > 1) { + $update = [ + 'order_number' => $item['order_number'] + 1, + ]; + $orderList[$item['id']] = [ + 'order_number' => $item['order_number'] + 1, + ]; + + // $this->placeCategoryFieldMappingRepository->update($item['id'], $update) ; + } + } + + $insertThis = []; + foreach ($categoryList as $data) { + $insertData = + [ + "property_place_category_id" => $data['property_place_category_id'], + "property_place_category_field_id" => $params['add_field_id'], + "order_number" => $data['order_number'] + 1, + "status" => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + $insertThis[] = $insertData; + } + + if ($insertThis) { + $createResult = $this->placeCategoryFieldMappingRepository->insert($insertThis); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function webMenuPlaceCategoriesAndPlaces($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $placeData = $this->listPlaces($params); + if ($placeData['status'] != 'success') { + throw new ApiErrorException($placeData['message']); + } + $places = $placeData['data'] ? $placeData['data'] : []; + $responsePlaces = []; + $responsePlaceCategories = []; + foreach ($places as $place) { + $responsePlaces[] = [ + "id" => $place['id'], + "name" => $place['name'], + "language_key" => $place['name'], + "route" => 'place/' . $place['id'], + "menu_type" => "PLC", + "menu_code" => "TOP", + "order_number" => $place['order_number'], + "icon" => "fas fa-check", + "alias" => "place-" . $place['id'], + "is_selected" => false, + "order_number_mapping" => null, + "status" => $place['status'], + ]; + + $placeCategory = $place['category_tree'][1]; + $responsePlaceCategories[$placeCategory['id']] = [ + "id" => $placeCategory['id'], + "name" => $placeCategory['name'], + "language_key" => $placeCategory['language_key'], + "route" => 'place-category/' . $placeCategory['id'], + "menu_type" => "PLCCAT", + "menu_code" => "TOP", + "order_number" => $placeCategory['order_number'], + "icon" => $placeCategory["icon"] ? $placeCategory["icon"] : "fas fa-check", + "alias" => "place-category-" . $placeCategory['id'], + "is_selected" => false, + "order_number_mapping" => null + ]; + } + + $response = array_merge($responsePlaceCategories, $responsePlaces); + $response = [ + 'status' => true, + 'data' => $response, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + + public function getCategoriesInList($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $placeCategoryRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + $categoryTriesRequest = [ + 'parent_id' => $params['place_category_id'], + 'placeCategories' => $placeCategories + ]; + $categoryArray = $this->categoryTriesSingleArray($categoryTriesRequest); + $categoryIds = collect($categoryArray)->keyBy('id')->keys()->all(); + + $parentCategory = $placeCategories->where('id', $params['place_category_id'])->first(); + $responseData['category'] = [ + 'id' => $parentCategory['id'], + 'name' => $parentCategory['name'], + 'language_key' => $parentCategory['language_key'], + ]; + + $placeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'whereIn' => [ + ['field' => 'place_category_id', 'value' => $categoryIds] + ], + 'with' => [ + 'propertyPlaceCategory', 'propertyPlaceWorkingHour', + 'propertyPlacePhotoMapping.propertyPlacePhoto', + 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', + 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle' + ] + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + $placeData = $placeData ? $placeData : []; + + + $responseData['places'] = collect($placeData)->map(function ($value) { + $return = $value; + + $return['photos'] = collect($value['property_place_photo_mapping'])->map(function ($photoMap) { + return isset($photoMap['property_place_photo']) ? $photoMap['property_place_photo']['photoUrl'] : null; + })->values()->all(); + + $return['default_photo'] = collect($value['property_place_photo_mapping'])->map(function ($photoMap) { + return isset($photoMap['property_place_photo']) ? $photoMap['property_place_photo']['photoUrl'] : null; + })->values()->first(); + + unset($return['property_place_photo_mapping']); + $return['slug'] = Str::slug($return['name'], $separator = '-', $language = 'en'); + + $factMappingArray = []; + foreach ($return['property_place_fact_mapping'] as $factMapping) { + + $factMappingArray[$factMapping['property_place_fact_title_fact_mapping']['place_fact_title_id']]['category'] = [ + 'id' => $factMapping['property_place_fact_title_fact_mapping']['place_fact_title']['id'], + 'name' => $factMapping['property_place_fact_title_fact_mapping']['place_fact_title']['name'], + 'language_key' => $factMapping['property_place_fact_title_fact_mapping']['place_fact_title']['language_key'], + ]; + + $factMappingArray[$factMapping['property_place_fact_title_fact_mapping']['place_fact_title_id']]['fact'][$factMapping['property_place_fact_title_fact_mapping']['place_fact_id']] = $factMapping['property_place_fact_title_fact_mapping']['place_fact']; + } + + unset($return['property_place_fact_mapping']); + $return['fact_mapping'] = $factMappingArray; + + return $return; + })->values()->all(); + + $response = [ + 'status' => true, + 'data' => $responseData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function getPlace($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $placeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['place_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyPlaceCategory', 'propertyPlaceWorkingHour', 'propertyPlacePhotoMapping.propertyPlacePhoto', 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', 'propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle'], + 'firstRow' => true + ]; + $placeData = $this->propertyPlaceRepository->findByCriteria($placeRequest); + + if (!$placeData) { + throw new Exception('api-unknown_error'); + } + $return = $placeData; + + $return['facts'] = collect($placeData['property_place_fact_mapping'])->map(function ($factMap) { + + return [ + + 'id' => $factMap['id'], + 'property_place_fact_title_fact_mapping_id' => $factMap['property_place_fact_title_fact_mapping']['id'], + 'place_fact_id' => $factMap['property_place_fact_title_fact_mapping']['place_fact']['id'], + 'place_fact_name' => $factMap['property_place_fact_title_fact_mapping']['place_fact']['name'], + 'place_fact_language_key' => $factMap['property_place_fact_title_fact_mapping']['place_fact']['language_key'], + 'place_fact_icon' => $factMap['property_place_fact_title_fact_mapping']['place_fact']['icon'], + 'place_fact_title_id' => $factMap['property_place_fact_title_fact_mapping']['place_fact_title']['id'], + 'place_fact_title_name' => $factMap['property_place_fact_title_fact_mapping']['place_fact_title']['name'], + 'place_fact_title_language_key' => $factMap['property_place_fact_title_fact_mapping']['place_fact_title']['language_key'], + 'place_fact_title_language_icon' => $factMap['property_place_fact_title_fact_mapping']['place_fact_title']['icon'], + ]; + })->values()->all(); + + + $return['photos'] = collect($placeData['property_place_photo_mapping'])->map(function ($photoMap) { + return isset($photoMap['property_place_photo']) ? $photoMap['property_place_photo']['photoUrl'] : null; + })->values()->all(); + $return['default_photo'] = collect($placeData['property_place_photo_mapping'])->map(function ($photoMap) { + return isset($photoMap['property_place_photo']) ? $photoMap['property_place_photo']['photoUrl'] : null; + })->values()->first(); + unset($return['property_place_photo_mapping']); + unset($return['property_place_fact_mapping']); + $return['slug'] = Str::slug($return['name'], $separator = '-', $language = 'en'); + + $getPlaceCategoryFieldsRequest = [ + 'place_category_id' => $return['place_category_id'], + 'place_id' => $return['id'], + + ]; + $getPlaceCategoryFields = $this->getPlaceCategoryFields($getPlaceCategoryFieldsRequest); + if ($getPlaceCategoryFields['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $placeFields = collect($getPlaceCategoryFields['data'])->filter(function ($value, $key) { + if (strpos($key, '_unit') === false) { + return $value; + } + })->map(function ($value) { + $return = $value; + if ($value['field_element'] == 'multiselect') { + $options = collect($value['options'])->where('option_is_selected', '=', true); + $return['options'] = $options->values()->all(); + $return['field_value'] = $options->map(function ($opt) { + return $opt['option_language_key']; + })->values()->all(); + + } elseif ($value['field_element'] == 'select') { + $options = collect($value['options'])->where('option_is_selected', '', true); + $return['options'] = $options->values()->first(); + $return['field_value'] = $return['options'] ? $return['options']['option_language_key'] : null; + + } elseif ($value['field_element'] == 'slider') { + $return['field_value'] = implode('-', $return['field_value']); + } + + unset($return['options']); + + return $return; + })->values()->all(); + + $return['place_fields'] = $placeFields; + + + $placeCategoryRequest['criteria'] = [['field' => 'status', 'condition' => '=', 'value' => 1]]; + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($placeCategoryRequest); + $placeCategories = collect($placeCategoryData); + + $parentCategory = null; + $currentCategoryId = $placeData['place_category_id']; + while (is_null($parentCategory)) { + $currentCategory = $placeCategories->where('id', $currentCategoryId)->first(); + if (is_null($currentCategory['parent_id'])) { + $parentCategory = $currentCategory; + } else { + $currentCategoryId = $currentCategory['parent_id']; + } + } + + $return['category'] = [ + 'id' => $parentCategory['id'], + 'name' => $parentCategory['name'], + 'language_key' => $parentCategory['language_key'], + ]; + + $response = [ + 'status' => true, + 'data' => $return + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function propertyPlaceCategories($params, $select = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $placeCategoryData = $this->propertyPlaceCategoryRepository->findByCriteria($params, $select); + + $response = [ + 'status' => true, + 'data' => $placeCategoryData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPlaceIncludes($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $response = [ + 'status' => true, + 'data' => $this->include, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyProductMappingService.php b/app/Core/Service/PropertyProductMappingService.php new file mode 100644 index 0000000..e668ff1 --- /dev/null +++ b/app/Core/Service/PropertyProductMappingService.php @@ -0,0 +1,123 @@ +propertyProductMappingRepository = $propertyProductMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyProductMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $insertData = []; + foreach ($params['products'] as $product){ + $insertData[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'product_id' => fillOnUndefined($product, 'product_id'), + 'expiration_date' => fillOnUndefined($product, 'expiration_date'), + 'amount' => fillOnUndefined($product, 'amount'), + 'currency' => fillOnUndefined($product, 'currency'), + 'status' => fillOnUndefined($product, 'status', 1), + 'created_by' => fillOnUndefined($product, 'user_id', 1), + 'updated_by' => fillOnUndefined($product, 'user_id', 1), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + + $insertResult = $this->propertyProductMappingRepository->insert($insertData); + if ($insertResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $userData = $insertResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyProductMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyPromotionService.php b/app/Core/Service/PropertyPromotionService.php new file mode 100644 index 0000000..55c35df --- /dev/null +++ b/app/Core/Service/PropertyPromotionService.php @@ -0,0 +1,863 @@ +promotionTypeRepository = $promotionTypeRepository; + $this->propertyPromotionRepository = $propertyPromotionRepository; + $this->propertyPromotionMappingRepository = $propertyPromotionMappingRepository; + $this->propertyRoomRepository = $propertyRoomRepository; + $this->propertyPromotionAddValidator = $propertyPromotionAddValidator; + $this->propertyPromotionUpdateValidator = $propertyPromotionUpdateValidator; + $this->updateRoomRateChannelPromotionValidator = $updateRoomRateChannelPromotionValidator; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPromotionRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectPropertyPromotionMapping($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyPromotionMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPromotionTypeList($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $promotionTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'parent_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'parent_id', null)], + + ], + ]; + $promotionType = $this->promotionTypeRepository->findByCriteria($promotionTypeRequest, ['id', 'name', 'language_key', 'parent_id', 'type_code', 'order_number', 'status']); + + $promotionType = $promotionType ? $promotionType : []; + + array_multisort( + array_column($promotionType, 'order_number'), SORT_ASC, + array_column($promotionType, 'name'), SORT_ASC, + $promotionType + ); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $promotionType]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function getPropertyPromotionList($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyId = fillOnUndefined($params, 'property_id'); + $propertyPromotionRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + + ], + ]; + $propertyPromotion = $this->propertyPromotionRepository->findByCriteria($propertyPromotionRequest, + ['id', 'property_id','title', 'promotion_type_id', 'start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', + 'is_time', 'start_time', 'end_time', 'day_before', 'amount', 'min_stay', 'days', 'is_mobile', 'params', 'exclude_dates','detail', 'status'] + ); + + $propertyPromotion = $propertyPromotion ? $propertyPromotion : []; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyPromotion]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function createPropertyPromotion($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + DB::beginTransaction(); + + $promotionTypeRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'promotion_type_id', null)], + ], + 'firstRow' => 1 + ]; + $promotionType = $this->promotionTypeRepository->findByCriteria($promotionTypeRequest, ['id', 'name', 'language_key', 'parent_id', 'type_code', 'order_number', 'status']); + + + if (!$promotionType) { + throw new Exception('api-unknown_error'); + } + + + $params['start_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['start_date'])->format('Y-m-d') : null; + $params['end_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['end_date'])->format('Y-m-d') : null; + $params['reservation_start_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['reservation_start_date'])->format('Y-m-d') : null; + $params['reservation_end_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['reservation_end_date'])->format('Y-m-d') : null; + $params['is_time'] = fillOnUndefined($params, 'is_time', null) != null ? 1 : null; + $params['start_time'] = fillOnUndefined($params, 'start_time', null) != null ? Carbon::parse($params['start_time'])->format('H:i:s') : null; + $params['end_time'] = fillOnUndefined($params, 'end_time', null) != null ? Carbon::parse($params['end_time'])->format('H:i:s') : null; + $params['min_stay'] = fillOnUndefinedAndEmpty($params, 'min_stay'); + + $validationResult = $this->propertyPromotionAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $createDays = fillOnUndefined($params, 'days', null) != null ? json_encode($params['days']) : null; + $excludeDates = fillOnUndefined($params, 'exclude_dates', null) != null ? json_encode($params['exclude_dates']) : null; + $createParams = fillOnUndefined($params, 'params', null) != null ? json_encode($params['params']) : null; + $createDetail = fillOnUndefined($params, 'detail', null) != null ? json_encode($params['detail']) : null; + + + $dayBefore = fillOnUndefined($params, 'day_before'); + if ($promotionType['type_code'] == 'LST') { + $dayBefore = fillOnUndefined($params, 'last_minute'); + } + + $createData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'promotion_type_id' => fillOnUndefined($params, 'promotion_type_id'), + 'title' => fillOnUndefined($params, 'title'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'is_time' => fillOnUndefined($params, 'is_time'), + 'start_time' => fillOnUndefined($params, 'start_time'), + 'end_time' => fillOnUndefined($params, 'end_time'), + 'day_before' => $dayBefore, + 'amount' => fillOnUndefined($params, 'amount'), + 'min_stay' => fillOnUndefinedAndEmpty($params, 'min_stay'), + 'days' => $createDays, + 'exclude_dates' => $excludeDates, + 'is_mobile' => fillOnUndefined($params, 'is_mobile'), + 'params' => $createParams, + 'detail' => $createDetail, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $createResult = $this->propertyPromotionRepository->create($createData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResult['data']]; + + DB::commit(); + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getRoomRateChannelPromotion($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomRateMapping.propertyRoomRateChannel.propertyRoomRateChannelPromotion', 'propertyRoomRateMapping.propertyRoomRate'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'exclude_occupancy', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + $propertyId = fillOnUndefined($params, 'property_id'); + $propertyPromotionRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + + ], + ]; + $propertyPromotions = $this->propertyPromotionRepository->findByCriteria($propertyPromotionRequest, ['id', 'property_id', 'promotion_type_id', 'title', 'start_date', 'end_date', 'is_time', 'start_time', 'end_time', 'reservation_start_date', 'reservation_end_date', 'day_before', 'amount', 'min_stay', 'is_mobile', 'days', 'params','exclude_dates', 'detail', 'status']); + + + $return = []; + + foreach ($roomData as $room) { + + if ($room['property_room_rate_mapping']) { + $item = $room; + $item['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + $roomRateMappings = $room['property_room_rate_mapping']; + $mapping = []; + $addedMapping = 0; + foreach ($roomRateMappings as $roomRateMapping) { + $propertyRoomRateChannel = null; + if (isset($roomRateMapping['property_room_rate_channel'])) { + $propertyRoomRateChannel = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('room_rate_mapping_id', '=', $roomRateMapping['id']) + ->first(); + } + + $mappingStatus = false; + $propertyPromotionArray = []; + if ($propertyRoomRateChannel) { + if ($propertyRoomRateChannel['status'] == 1) { + + + $mappingStatus = true; + foreach ($propertyPromotions as $promotion) { + $propertyRoomRateChannelPromotion = []; + if (isset($propertyRoomRateChannel['property_room_rate_channel_promotion'])) { + + + $propertyRoomRateChannelPromotion = collect($propertyRoomRateChannel['property_room_rate_channel_promotion']) + ->where('property_promotion_id', '=', $promotion['id']) + ->where('room_rate_channel_mapping_id', '=', $propertyRoomRateChannel['id']) + ->where('status', '=', 1) + ->values()->toArray(); + } + + $propertyPromotionArray[] = [ + 'id' => $promotion['id'], + 'property_id' => $promotion['property_id'], + 'promotion_type_id' => $promotion['promotion_type_id'], + 'title' => $promotion['title'], + 'start_date' => $promotion['start_date'], + 'end_date' => $promotion['end_date'], + 'reservation_start_date' => $promotion['reservation_start_date'], + 'reservation_end_date' => $promotion['reservation_end_date'], + 'day_before' => $promotion['day_before'], + 'is_time' => $promotion['is_time'], + 'start_time' => $promotion['start_time'], + 'end_time' => $promotion['end_time'], + 'amount' => $promotion['amount'], + 'min_stay' => $promotion['min_stay'], + 'is_mobile' => $promotion['is_mobile'] ? true : false, + 'days' => $promotion['days'], + 'params' => $promotion['params'], + 'excludeDatesArray' => $promotion['excludeDatesArray'], + 'detail' => $promotion['detail'], + 'promotion_status' => $promotion['status'], + 'is_selected' => $propertyRoomRateChannelPromotion ? true : false, + ]; + } + } + } + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['is_selected'] = $mappingStatus; + $roomRateMapping['has_date'] = $propertyRoomRateChannel['has_date'] == 0 ? false : true; + $roomRateMapping['end_date'] = $propertyRoomRateChannel['end_date']; + $roomRateMapping['start_date'] = $propertyRoomRateChannel['start_date']; + $roomRateMapping['room_rate_channel_mapping_id'] = $propertyRoomRateChannel['id']; + $roomRateMapping['room_rate_channel_promotion'] = $propertyPromotionArray; + + unset($roomRateMapping['property_room_rate']); + unset($roomRateMapping['property_room_rate_channel']); + if ($mappingStatus) { + $addedMapping++; + $mapping[] = $roomRateMapping; + } + } + $item['property_room_rate_mapping'] = $mapping; + if ($addedMapping > 0) { + $return[] = $item; + } + } + + } + + $collection = collect($return); + $sorted = $collection->sortBy('id')->values()->all(); + + $response = [ + 'status' => true, + 'data' => $sorted, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyPromotion($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + $propertyPromotionRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['promotion_id']], + + ], + 'firstRow' => 1, + ]; + $propertyPromotion = $this->propertyPromotionRepository->findByCriteria($propertyPromotionRequest, ['id', 'property_id', 'promotion_type_id', 'title','start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', 'day_before', 'amount', 'min_stay', 'days', 'params', 'detail', 'status']); + + if (!$propertyPromotion) { + throw new Exception('api-unknown_error'); + } + + $params['promotion_type_id'] = $propertyPromotion['promotion_type_id']; + $params['end_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['end_date'])->format('Y-m-d') : null; + $params['reservation_start_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['reservation_start_date'])->format('Y-m-d') : null; + $params['reservation_end_date'] = fillOnUndefined($params, 'start_date', null) != null ? Carbon::parse($params['reservation_end_date'])->format('Y-m-d') : null; + $params['is_time'] = fillOnUndefined($params, 'is_time', null) != null ? 1 : null; + $params['start_time'] = fillOnUndefined($params, 'start_time', null) != null ? Carbon::parse($params['start_time'])->format('H:i:s') : null; + $params['end_time'] = fillOnUndefined($params, 'end_time', null) != null ? Carbon::parse($params['end_time'])->format('H:i:s') : null; + $params['min_stay'] = fillOnUndefinedAndEmpty($params, 'min_stay'); + + $validationResult = $this->propertyPromotionUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $createDays = fillOnUndefined($params, 'days', null) != null ? json_encode($params['days']) : null; + $excludeDates = fillOnUndefined($params, 'exclude_dates', null) != null ? json_encode($params['exclude_dates']) : null; + $createParams = fillOnUndefined($params, 'params', null) != null ? json_encode($params['params']) : null; + $createDetail = fillOnUndefined($params, 'detail', null) != null ? json_encode($params['detail']) : null; + + $dayBefore = fillOnUndefined($params, 'day_before'); + if ($propertyPromotion['promotion_type_id'] == 4) { + $dayBefore = fillOnUndefined($params, 'last_minute'); + } + + $promotionUpdateData = + [ + 'title' => fillOnUndefined($params, 'title'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'is_time' => fillOnUndefined($params, 'is_time'), + 'start_time' => fillOnUndefined($params, 'start_time'), + 'end_time' => fillOnUndefined($params, 'end_time'), + 'day_before' => $dayBefore, + 'amount' => fillOnUndefined($params, 'amount'), + 'min_stay' => fillOnUndefinedAndEmpty($params, 'min_stay'), + 'days' => $createDays, + 'exclude_dates' => $excludeDates, + 'is_mobile' => fillOnUndefined($params, 'is_mobile'), + 'params' => $createParams, + 'detail' => $createDetail, + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'updated_at' => time() + ]; + + $promotionId = fillOnUndefined($params, 'promotion_id'); + + $promotionResult = $this->propertyPromotionRepository->update($promotionId, $promotionUpdateData); + + if ($promotionResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $promotionResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updateRoomRateChannelPromotion($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->updateRoomRateChannelPromotionValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyPromotion.promotionType.parentPromotionType'] + ]; + + $propertyChannelRoomRatePromotionMapping = $this->propertyPromotionMappingRepository->findByCriteria($criteria); + $oldMappingData = collect($propertyChannelRoomRatePromotionMapping); + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $params['property_promotion_id']], + ], + 'with' => ['promotionType.parentPromotionType'], + 'firstRow' => 1 + ]; + + $mappedPromotion = $this->propertyPromotionRepository->findByCriteria($criteria); + if (!$mappedPromotion) { + throw new Exception('api-unknown-error'); + } + + $addThisPromotion = [ + "id" => $mappedPromotion['id'], + "property_id" => $mappedPromotion['property_id'], + "promotion_type_id" => $mappedPromotion['promotion_type_id'], + "start_date" => $mappedPromotion['start_date'], + "end_date" => $mappedPromotion['end_date'], + "reservation_start_date" => $mappedPromotion['reservation_start_date'], + "reservation_end_date" => $mappedPromotion['reservation_end_date'], + 'is_time' => $mappedPromotion['is_time'], + 'start_time' => $mappedPromotion['start_time'], + 'end_time' => $mappedPromotion['end_time'], + 'is_mobile' => $mappedPromotion['is_mobile'], + "day_before" => $mappedPromotion['day_before'], + "amount" => $mappedPromotion['amount'], + "min_stay" => $mappedPromotion['min_stay'], + "days" => $mappedPromotion['days'], + "params" => $mappedPromotion['params'], + "detail" => $mappedPromotion['detail'], + "status" => $mappedPromotion['status'], + 'promotion_type_name' => $mappedPromotion['promotion_type']['name'], + 'promotion_type_language_key' => $mappedPromotion['promotion_type']['language_key'], + 'promotion_type_code' => $mappedPromotion['promotion_type']['type_code'], + 'parent_promotion_type_name' => $mappedPromotion['promotion_type']['parent_promotion_type']['name'], + 'parent_promotion_type_language_key' => $mappedPromotion['promotion_type']['parent_promotion_type']['language_key'], + 'parent_promotion_type_code' => $mappedPromotion['promotion_type']['parent_promotion_type']['type_code'], + ]; + + $oldDataMappingCollect = collect($oldMappingData)->map(function ($value) { + return [ + 'id' => $value['id'], + 'property_id' => $value['property_id'], + 'property_promotion_id' => $value['property_promotion_id'], + 'room_rate_channel_mapping_id' => $value['room_rate_channel_mapping_id'], + 'promotion_type_id' => $value['property_promotion']['promotion_type_id'], + 'start_date' => $value['property_promotion']['start_date'], + 'end_date' => $value['property_promotion']['end_date'], + 'is_time' => $value['property_promotion']['is_time'], + 'start_time' => $value['property_promotion']['start_time'], + 'end_time' => $value['property_promotion']['start_time'], + 'is_mobile' => $value['property_promotion']['is_mobile'], + 'reservation_start_date' => $value['property_promotion']['reservation_start_date'], + 'reservation_end_date' => $value['property_promotion']['reservation_end_date'], + 'day_before' => $value['property_promotion']['day_before'], + 'amount' => $value['property_promotion']['amount'], + 'min_stay' => $value['property_promotion']['min_stay'], + 'days' => $value['property_promotion']['days'], + 'promotion_type_name' => $value['property_promotion']['promotion_type']['name'], + 'promotion_type_language_key' => $value['property_promotion']['promotion_type']['language_key'], + 'promotion_type_code' => $value['property_promotion']['promotion_type']['type_code'], + 'parent_promotion_type_name' => $value['property_promotion']['promotion_type']['parent_promotion_type']['name'], + 'parent_promotion_type_language_key' => $value['property_promotion']['promotion_type']['parent_promotion_type']['language_key'], + 'parent_promotion_type_code' => $value['property_promotion']['promotion_type']['parent_promotion_type']['type_code'], + 'mapping_status' => $value['status'] + ]; + }); + + + $haveThisMapping = $oldDataMappingCollect + ->where('property_promotion_id', '=', $params['property_promotion_id']) + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('property_id', '=', $params['property_id']); + + + if ($params['is_selected'] == true) { + + // control adding roles ; + + + /*$checkRole = $oldDataMappingCollect + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('property_promotion_id', '=', $params['property_promotion_id']) + ->where('property_id', '=', $params['property_id']) + ->where('mapping_status', '=', 1) + ->first(); + + dd($checkRole,$params, $oldDataMappingCollect); + if ($checkRole) { + throw new Exception('enw-booking_engine_promotion-overlapping_error'); + }*/ + + if ($addThisPromotion['parent_promotion_type_code'] == 'ERB' && $addThisPromotion['promotion_type_code'] == 'PRD') { + $checkRoles = $oldDataMappingCollect + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('promotion_type_code', '=', $addThisPromotion['promotion_type_code']) + ->where('mapping_status', '=', 1); + + + $overLappingError = null; + foreach ($checkRoles as $checkRole) { + + + + if ($checkRole && ($checkRole['min_stay'] == $addThisPromotion['min_stay'])) { + if ($checkRole['start_date'] <= $addThisPromotion['start_date']) { + if ($checkRole['reservation_start_date'] <= $addThisPromotion['reservation_start_date']) { + //$overLappingError = true; + } elseif ($checkRole['reservation_start_date'] >= $addThisPromotion['reservation_start_date'] + && $addThisPromotion['reservation_end_date'] >= $checkRole['reservation_start_date']) { + $overLappingError = true; + + } + + + } /*elseif ($checkRole['start_date'] >= $addThisPromotion['start_date'] && $addThisPromotion['end_date'] >= $checkRole['start_date']) { + + + if ($checkRole['reservation_start_date'] <= $addThisPromotion['reservation_start_date']) { + $overLappingError = true; + dd($checkRole); + } elseif ($checkRole['reservation_start_date'] >= $addThisPromotion['reservation_start_date'] + && $addThisPromotion['reservation_end_date'] >= $checkRole['reservation_start_date']) { + $overLappingError = true; + } + }*/ + } + } + + if ($overLappingError) { + throw new Exception('enw-booking_engine_promotion-overlapping_error'); + } + } + + if ($addThisPromotion['parent_promotion_type_code'] == 'ERB' && $addThisPromotion['promotion_type_code'] == 'BFD') { + + $checkRole = $oldDataMappingCollect + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('promotion_type_code', '=', $addThisPromotion['promotion_type_code']) + ->where('day_before', '=', $addThisPromotion['day_before']) + ->where('min_stay', '=', $addThisPromotion['min_stay']) + ->where('is_mobile', '=', $addThisPromotion['is_mobile']) + ->where('mapping_status', '=', 1) + ->first(); + if ($checkRole) { + throw new Exception('enw-booking_engine_promotion-overlapping_error'); + } + } + + if ($addThisPromotion['promotion_type_code'] == 'LST') { + + $checkRole = $oldDataMappingCollect + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('promotion_type_code', '=', $addThisPromotion['promotion_type_code']) + ->where('min_stay', '=', $addThisPromotion['min_stay']) + ->where('is_time', '=', $addThisPromotion['is_time']) + ->where('is_mobile', '=', $addThisPromotion['is_mobile']) + ->where('amount', '=', $addThisPromotion['amount']) + ->where('mapping_status', '=', 1) + ->first(); + if ($checkRole) { + throw new Exception('enw-booking_engine_promotion-overlapping_error'); + } + } + + + if ($addThisPromotion['promotion_type_code'] == 'DSC') { + + $checkRole = $oldDataMappingCollect + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('promotion_type_code', '=', $addThisPromotion['promotion_type_code']) + ->where('min_stay', '=', $addThisPromotion['min_stay']) + ->where('is_time', '=', $addThisPromotion['is_time']) + ->where('is_mobile', '=', $addThisPromotion['is_mobile']) + ->where('amount', '=', $addThisPromotion['amount']) + ->where('mapping_status', '=', 1) + ->first(); + + //dd($addThisPromotion,$checkRole, $params['room_rate_channel_mapping_id'],$oldDataMappingCollect); + if ($checkRole) { + throw new Exception('enw-booking_engine_promotion-overlapping_error'); + } + + } + + + if ($haveThisMapping->first()) { + $thisMapping = $haveThisMapping->first(); + $updateData = [ + 'status' => 1, + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'updated_at' => Carbon::now()->timestamp, + ]; + $updateThis = $this->propertyPromotionMappingRepository->update($thisMapping['id'], $updateData); + if ($updateThis['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } else { + + $insertData = []; + $insertData[] = [ + 'property_id' => $params['property_id'], + 'room_rate_channel_mapping_id' => $params['room_rate_channel_mapping_id'], + 'property_promotion_id' => $params['property_promotion_id'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, 'user_id'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ($insertData) { + $createResult = $this->propertyPromotionMappingRepository->insert($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + } + + + // Pasife alma işlemi + if ($params['is_selected'] == false) { + $deleteThis = collect($propertyChannelRoomRatePromotionMapping) + ->where('property_promotion_id', '=', $params['property_promotion_id']) + ->where('room_rate_channel_mapping_id', '=', $params['room_rate_channel_mapping_id']) + ->where('property_id', '=', $params['property_id']) + ->keyBy('id')->keys()->toArray(); + + + if ($deleteThis) { + $updateData = [ + 'status' => 0, + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'updated_at' => Carbon::now()->timestamp, + ]; + $deleteThisArray = $this->propertyPromotionMappingRepository->update($deleteThis, $updateData); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + } + + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + db::rollBack(); + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyPromotion($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + DB::beginTransaction(); + + try { + + $propertyPromotionRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['promotion_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + + ] + ]; + $propertyPromotion = $this->propertyPromotionRepository->findByCriteria($propertyPromotionRequest); + if (!$propertyPromotion) { + throw new Exception('No promotion found.'); + } + + $propertyPromotionDeleteIds = $propertyPromotion ? collect($propertyPromotion)->pluck('id')->toArray() : null; + + + $propertyPromotionMappingRequest = [ + 'criteria' => [ + ['field' => 'property_promotion_id', 'condition' => '=', 'value' => $params['promotion_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + + ] + ]; + $propertyPromotionMapping = $this->propertyPromotionMappingRepository->findByCriteria($propertyPromotionMappingRequest, ['id']); + $propertyPromotionMappingDeleteIds = $propertyPromotionMapping ? collect($propertyPromotionMapping)->pluck('id')->toArray() : null; + + if(!empty($propertyPromotionMappingDeleteIds)) { + $propertyPromotionMappingDelete = $this->propertyPromotionMappingRepository->destroy($propertyPromotionMappingDeleteIds); + if ($propertyPromotionMappingDelete['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + $propertyPromotionDelete = $this->propertyPromotionRepository->destroy($propertyPromotionDeleteIds); + + if ($propertyPromotionDelete['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + if($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyQuickPricingService.php b/app/Core/Service/PropertyQuickPricingService.php new file mode 100644 index 0000000..61ba58c --- /dev/null +++ b/app/Core/Service/PropertyQuickPricingService.php @@ -0,0 +1,130 @@ +propertyQuickPricingMappingRepository = $propertyQuickPricingMappingRepository; + $this->propertyQuickPricingCreateValidator = $propertyQuickPricingCreateValidator; + } + + public function createPropertyQuickPricingMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyQuickPricingCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = [ + "property_id" => fillOnUndefined($param, "property_id"), + "channel_id" => fillOnUndefined($param, "channel_id"), + "room_rate_channel_mapping_id" => fillOnUndefined($param, "room_rate_channel_mapping_id"), + "action_type" => fillOnUndefined($param, "action_type"), + "price_type" => fillOnUndefined($param, "price_type", 'PER'), + "price_value" => fillOnUndefined($param, "price_value"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertDataResult = $this->propertyQuickPricingMappingRepository->create($insertData); + if ($insertDataResult['status'] != 'success') { + throw new Exception($insertDataResult['message']); + } + + $insertDataResult = $insertDataResult["data"]; + + $response = [ + 'status' => true, + 'data' => $insertDataResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = 'api-unknown_error'; + } + + return output($response); + } + + public function selectPropertyQuickPricingMapping($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyQuickPricingMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyQuickPricingMapping($deleteThisId) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteThisId = is_array($deleteThisId) ? $deleteThisId : [$deleteThisId]; + $deleteThisArray = $this->propertyQuickPricingMappingRepository->destroy($deleteThisId); + + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomAvailabilityQueueService.php b/app/Core/Service/PropertyRoomAvailabilityQueueService.php new file mode 100644 index 0000000..646e6ef --- /dev/null +++ b/app/Core/Service/PropertyRoomAvailabilityQueueService.php @@ -0,0 +1,115 @@ +propertyRoomAvailabilityQueueRepository = $propertyRoomAvailabilityQueueRepository; + + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomAvailabilityQueueRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomAvailabilityQueueRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->propertyRoomAvailabilityQueueRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyRoomAvailabilityService.php b/app/Core/Service/PropertyRoomAvailabilityService.php new file mode 100644 index 0000000..d133e04 --- /dev/null +++ b/app/Core/Service/PropertyRoomAvailabilityService.php @@ -0,0 +1,802 @@ +propertyRoomAvailabilityRepository = $propertyRoomAvailabilityRepository; + $this->propertyRoomAvailabilityAddValidator = $propertyRoomAvailabilityAddValidator; + $this->propertyRoomAvailabilityUpdateValidator = $propertyRoomAvailabilityUpdateValidator; + $this->propertyRoomAvailabilityDeleteValidator = $propertyRoomAvailabilityDeleteValidator; + $this->propertyRoomAvailabilityBulkUpdateValidator = $propertyRoomAvailabilityBulkUpdateValidator; + $this->propertyRoomAvailabilityBulkInsertValidator = $propertyRoomAvailabilityBulkInsertValidator; + $this->propertyRoomService = $propertyRoomService; + + $this->propertyChannelRepository = $propertyChannelRepository; + $this->propertyRoomRateMappingRepository = $RoomAvailabilityMappingRepository; + $this->propertyRepository = $propertyRepository; + $this->propertyRoomConnectedRepository = $propertyRoomConnectedRepository; + + + } + + + public function bulkUpdate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $startDate = Carbon::parse($params['start_date']); + $endDate = Carbon::parse($params['end_date']); + $diffInDays = $startDate->diffInDays($endDate); + $availabilityTypeId = fillOnUndefined($params, 'availability_type_id', 1); + $propertyId = fillOnUndefined($params, 'property_id', 0); + + $includeDays = fillOnUndefined($params, 'include_days', []); + $insertData = []; + + $validationResult = $this->propertyRoomAvailabilityBulkInsertValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + if ($params["update_type"] == "availability") { + $updateColumn = "availability"; + } elseif ($params["update_type"] == "room_stop_sell") { + $updateColumn = "stop_sell"; + } + + + $updateData = [ + $updateColumn => $params['value'], + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'updated_at' => Carbon::now()->timestamp + ]; + + $selectIds = $this->selectRoomRateIds($params); + if ($selectIds['status'] != 'success') { + throw new ApiErrorException('array error'); + } + $selectIds = $selectIds['data']; + + $RoomAvailabilityMappingRequest = [ + 'whereIn' => [ + ['field' => 'id', 'value' => $selectIds['room_rate_mapping_ids']], + ] + ]; + $selectedRoomRateMapping = $this->propertyRoomRateMappingRepository->findByCriteria($RoomAvailabilityMappingRequest); + $selectedRoomRateMapping = $selectedRoomRateMapping ? $selectedRoomRateMapping : []; + $selectedRoomRateMapping = collect($selectedRoomRateMapping); + + + + $oldRoomAvailabilitiesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'date', 'condition' => '>=', 'value' => $params['start_date']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['end_date']], + ] + ]; + + $oldRoomAvailability = $this->propertyRoomAvailabilityRepository->findbyCriteria($oldRoomAvailabilitiesCriteria); + $oldRoomAvailability = $oldRoomAvailability ? $oldRoomAvailability : []; + $updateThis = []; + $deleteThis = []; + $newAvailabilityArray = []; + + foreach ($params['room_rates'] as $RoomAvailability) { + $startDate = Carbon::parse($params['start_date']); + for ($i = 0; $i <= $diffInDays; $i++) { + if ($availabilityTypeId == 1) { + $checkKey = $RoomAvailability['room_id'] . "||" . $startDate->format('Y-m-d') . "||" . $params['availability_type_id'];; + $newAvailabilityArray[$checkKey] = [ + 'property_id' => $propertyId, + 'property_room_id' => $RoomAvailability['room_id'], + 'availability_type_id' => $availabilityTypeId, + 'date' => $startDate->format('Y-m-d'), + $updateColumn => fillOnUndefined($params, 'value', 0), + ]; + } else { + foreach ($RoomAvailability['room_rate_mapping_id'] as $RoomAvailabilityMapping) { + $checkKey = $RoomAvailability['room_id'] . "|" . $RoomAvailabilityMapping . "|" . $startDate->format('Y-m-d') . "|" . $params['channel_id'] . "|" . $params['availability_type_id']; + $newAvailabilityArray[$checkKey] = [ + 'property_id' => $propertyId, + 'property_room_id' => $RoomAvailability['room_id'], + 'availability_type_id' => $availabilityTypeId, + 'date' => $startDate->format('Y-m-d'), + $updateColumn => fillOnUndefined($params, 'value', 0), + 'room_rate_mapping_id' => $RoomAvailabilityMapping, + ]; + } + } + $startDate = $startDate->addDay(); + } + } + + $oldRoomAvailabilityKeys = []; + foreach ($oldRoomAvailability as $oldAvailability) { + $oldAvailabilityKey = $oldAvailability['property_room_id'] . "|" . $oldAvailability['room_rate_mapping_id'] . "|" . $oldAvailability['date'] . "|" . $oldAvailability['channel_id'] . "|" . $oldAvailability['availability_type_id']; + $oldAvailability[$updateColumn] = isset($newAvailabilityArray[$oldAvailabilityKey]) ? $newAvailabilityArray[$oldAvailabilityKey][$updateColumn] : $oldAvailability[$updateColumn]; + + $oldRoomAvailabilityKeys[$oldAvailabilityKey][] = $oldAvailability; + } + + //Sistemdeki benzer id listesi, mysql null unique index hatası için + foreach ($oldRoomAvailabilityKeys as $availabilityKey => $oldRoomAvailability) { + + if(count($oldRoomAvailability) > 1) { + $oldRoomAvailabilityKeys[$availabilityKey] = last($oldRoomAvailability); + $otherAvailabilityRowIds = collect($oldRoomAvailability)->whereNotIn('id', [$oldRoomAvailabilityKeys[$availabilityKey]['id']])->pluck('id')->toArray(); + $oldRoomAvailabilityKeys[$availabilityKey] = last($oldRoomAvailability); + $oldRoomAvailabilityKeys[$availabilityKey]['otherIds'] = $otherAvailabilityRowIds; + } else { + $oldRoomAvailabilityKeys[$availabilityKey] = reset($oldRoomAvailability); + } + + } + + $quotaCollection = collect($oldRoomAvailabilityKeys) + ->whereIn('availability_type_id', [0, 3]); + + foreach ($params['room_rates'] as $RoomAvailability) { + $startDate = Carbon::parse($params['start_date']); + + for ($i = 0; $i <= $diffInDays; $i++) { + + if (!in_array($startDate->shortEnglishDayOfWeek, $includeDays)) { + $startDate = $startDate->addDay(); + continue; + } + + + $insertDataItem = [ + 'property_id' => $propertyId, + 'property_room_id' => $RoomAvailability['room_id'], + 'availability_type_id' => $availabilityTypeId, + 'date' => $startDate->format('Y-m-d'), + $updateColumn => fillOnUndefined($params, 'value', 0), + 'status' => fillOnUndefined($params, "status", 1), + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if ("update_type" == "availability") { + if ($availabilityTypeId == 1 || $availabilityTypeId == 3) { + $poolKey = $RoomAvailability['room_id'] . "||" . $startDate->format('Y-m-d') . "||1"; + $poolAvailability = isset($oldRoomAvailabilityKeys[$poolKey]['availability']) ? $oldRoomAvailabilityKeys[$poolKey]['availability'] : 0; + $totalGuaranteedQuota = $quotaCollection + ->where('date', '=', $startDate->format('Y-m-d')) + ->where('property_room_id', '=', $RoomAvailability['room_id']) + ->where('availability_type_id', '=', 3) + ->sum('availability'); + if ($totalGuaranteedQuota > $poolAvailability) { + throw new ApiErrorException(" $propertyId - $RoomAvailability[room_id] - " . $startDate->format('Y-m-d') . " (" . $totalGuaranteedQuota . " < " . $poolAvailability . " ) Guaranteed availability total cannot be higher than Pool availability "); + } + } + } + + + if ($availabilityTypeId == 1) { + $insertDataItem['room_rate_mapping_id'] = null; + $checkKey = $RoomAvailability['room_id'] . "||" . $startDate->format('Y-m-d') . "||" . $params['availability_type_id'];; + if (isset($oldRoomAvailabilityKeys[$checkKey])) { + $updateThis[] = $oldRoomAvailabilityKeys[$checkKey]['id']; + } else { + $insertData[] = $insertDataItem; + } + + if(isset($oldRoomAvailabilityKeys[$checkKey]['otherIds'])) { + foreach ($oldRoomAvailabilityKeys[$checkKey]['otherIds'] as $otherId) { + $deleteThis[] = $otherId; + } + } + + } else { + $insertDataItem['channel_id'] = fillOnUndefined($params, 'channel_id', 1); + foreach ($RoomAvailability['room_rate_mapping_id'] as $RoomAvailabilityMapping) { + $insertDataItem['room_rate_mapping_id'] = $RoomAvailabilityMapping; + $checkKey = $RoomAvailability['room_id'] . "|" . $RoomAvailabilityMapping . "|" . $startDate->format('Y-m-d') . "|" . $params['channel_id'] . "|" . $params['availability_type_id']; + if (isset($oldRoomAvailabilityKeys[$checkKey])) { + $updateThis[] = $oldRoomAvailabilityKeys[$checkKey]['id']; + } else { + $insertData[] = $insertDataItem; + } + } + + } + $startDate = $startDate->addDay(); + } + } + + + + + if ($deleteThis) { + $destroyResult = $this->propertyRoomAvailabilityRepository->destroy($deleteThis); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + if ($updateThis) { + $thisUpdateArrayChunk = array_chunk($updateThis, 1000); + foreach ($thisUpdateArrayChunk as $updateIds) { + $data = $this->propertyRoomAvailabilityRepository->updateWhereIn($updateIds, $updateData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + $thisInsertArrayChunk = array_chunk($insertData, 1000); + foreach ($thisInsertArrayChunk as $insertThis) { + $data = $this->propertyRoomAvailabilityRepository->insert($insertThis); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + if (isset($data) && $data['status'] != 'success') { + throw new ApiErrorException($data['message']); + } + + //Connected Room Case + $roomAvailabilityUpdateForConnectedRoomParams = [ + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'availability_type_id' => [$availabilityTypeId], + 'startDate' => $params['start_date'], + 'endDate' => $params['end_date'] + ]; + + $this->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams); + //Connected Room Case + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectRoomRateIds($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $roomIds = []; + $RoomAvailabilityIds = []; + + + foreach ($params['room_rates'] as $RoomAvailability) { + $roomIds[] = $RoomAvailability['room_id']; + + if (isset($RoomAvailability['room_rate_mapping_id'])) { + foreach ($RoomAvailability['room_rate_mapping_id'] as $RoomAvailabilityMapping) { + $RoomAvailabilityIds[] = $RoomAvailabilityMapping; + } + } + } + $roomIds = array_unique($roomIds); + $RoomAvailabilityIds = array_unique($RoomAvailabilityIds); + $response = [ + 'status' => true, + 'data' => [ + 'room_ids' => $roomIds, + 'room_rate_mapping_ids' => $RoomAvailabilityIds, + ], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function roomAvailabilityUpdate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $newMappingArray = $params ? $params : []; + + $validationResult = $this->propertyRoomAvailabilityBulkUpdateValidator->validate($newMappingArray); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $newMappingArray = $newMappingArray['availability']; + + + $newMappingCollect = collect($newMappingArray); + $startDate = $newMappingCollect->min('date'); + $endDate = $newMappingCollect->max('date'); + $channelSetupTypes = $this->propertyRoomService->setChannelAvailabilityTypes(['property_id' => $params['property_id'], 'channel_id' => $params['channel_id']]); + if ($channelSetupTypes['status'] != 'success') { + throw new ApiErrorException($channelSetupTypes['message']); + } + $channelSetupTypes = $channelSetupTypes['data']; + $forGeneralId = $channelSetupTypes['forGeneralId']; + $forAvailabilityData = $channelSetupTypes['forAvailabilityData']; + $forPriceData = $channelSetupTypes['forPriceData']; + $channelWorkingAvailabilityType = $channelSetupTypes['channelAvailabilityWorkingType']; + $getPriceDataIds = collect($forPriceData)->keyBy('id')->keys()->toArray(); + $getAvailabilityDataIds = collect($forAvailabilityData)->keyBy('id')->keys()->toArray(); + $getAvailabilityDataIds = array_unique(array_merge($forGeneralId, $getAvailabilityDataIds)); + + $availabilityRequest = [ + 'property_id' => $params['property_id'], + 'start_date' => $startDate, + 'end_date' => $endDate, + 'channel_id' => $params['channel_id'], + 'availability_type_id' => $getAvailabilityDataIds, + ]; + + $availabilityArray = $this->propertyRoomService->inventoryAvailabilityData($availabilityRequest); + + + $oldMappingArray = []; + foreach ($availabilityArray as $oldAvailability) { + $mergeMappingKey = $oldAvailability['availability_type_id'] . '|' . $oldAvailability['room_id'] . '|' . $oldAvailability['room_rate_mapping_id'] . '|' . $oldAvailability['channel_id'] . '|' . $oldAvailability['date']; + $oldMappingArray[$oldAvailability['availability_type_id'] . '|' . $oldAvailability['room_id'] . '|' . $oldAvailability['room_rate_mapping_id'] . '|' . $oldAvailability['channel_id'] . '|' . $oldAvailability['date']] = [ + 'id' => $oldAvailability['id'], + 'room_id' => $oldAvailability['room_id'], + 'room_rate_mapping_id' => $oldAvailability['room_rate_mapping_id'], + 'availability_type_id' => $oldAvailability['availability_type_id'], + 'channel_id' => $oldAvailability['channel_id'], + 'date' => $oldAvailability['date'], + 'availability' => isset($newMappingArray[$mergeMappingKey]['availability']) ? $newMappingArray[$mergeMappingKey]['availability'] : $oldAvailability['availability'], + 'stop_sell' => $oldAvailability['stop_sell'], + 'old_availability' => $oldAvailability['availability'], + 'otherIds' => isset($oldAvailability['otherIds']) ? $oldAvailability['otherIds'] : [], + ]; + } + $quotaCollection = collect($oldMappingArray) + ->whereIn('availability_type_id', [0, 3]); + + $deleteThis = []; + $insertThis = []; + foreach ($newMappingArray as $key => $newMapping) { + + $channelId = $newMappingArray[$key]['room_rate_mapping_id'] != null ? fillOnUndefined($params, 'channel_id') : null; + + // check pool availability overload quota + + + $poolKey = '1|' . $newMapping['room_id'] . '|||' . $newMapping['date']; + $poolAvailability = isset($oldMappingArray[$poolKey]['availability']) ? $oldMappingArray[$poolKey]['availability'] : 0; + + // Check Guaranteed Availability - Pool Availability + if ($channelWorkingAvailabilityType == 3) { + $totalGuaranteedQuota = $quotaCollection + ->where('date', '=', $newMapping['date']) + ->where('room_id', '=', $newMapping['room_id']) + ->where('availability_type_id', '=', 3) + ->sum('availability'); + if ($totalGuaranteedQuota > $poolAvailability) { + throw new ApiErrorException('Guaranteed availability total cannot be higher than Pool availability'); + } + } + + if (isset($newMapping['availability']) && $newMapping['availability'] === "") { + $newMapping['availability'] = 0; + $newMappingArray[$key]['availability'] = 0; + } + + if (isset($newMapping['availability']) && $newMapping['availability'] === "") { + if (isset($oldMappingArray[$key])) { + $deleteThis[] = $oldMappingArray[$key]['id']; + } + } else { + + if (isset($newMappingArray[$key]['availability'])) { + $insertItemAvailability = $newMappingArray[$key]['availability']; + } elseif (isset($oldMappingArray[$key]['availability'])) { + $insertItemAvailability = $oldMappingArray[$key]['availability']; + } else { + $insertItemAvailability = 0; + } + + + if (isset($newMappingArray[$key]['stop_sell'])) { + $insertItemStopSell = $newMappingArray[$key]['stop_sell']; + } elseif (isset($oldMappingArray[$key]['stop_sell'])) { + $insertItemStopSell = $oldMappingArray[$key]['stop_sell']; + } else { + $insertItemStopSell = 0; + } + + $insertItem = [ + 'property_id' => fillOnUndefined($params, 'property_id', 0), + 'property_room_id' => fillOnUndefined($newMappingArray[$key], 'room_id', 0), + 'room_rate_mapping_id' => $newMappingArray[$key]['room_rate_mapping_id'], + 'channel_id' => $channelId, + 'availability_type_id' => fillOnUndefined($newMappingArray[$key], 'setup_type_id', null), + 'date' => fillOnUndefined($newMappingArray[$key], 'date', 0), + 'availability' => $insertItemAvailability, + 'stop_sell' => $insertItemStopSell, + 'status' => fillOnUndefined($params, "status", 1), + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + + if (isset($oldMappingArray[$key])) { + + if(isset($oldMappingArray[$key]['otherIds'])) { + foreach ($oldMappingArray[$key]['otherIds'] as $otherSimilarId) { + $deleteThis[] = $otherSimilarId; + } + } + + if ($oldMappingArray[$key]['old_availability'] != $insertItem['availability'] || $oldMappingArray[$key]['stop_sell'] != $insertItem['stop_sell']) { + $deleteThis[] = $oldMappingArray[$key]['id']; + + $insertThis[] = $insertItem; + /* + if( $newMappingArray[$key]['availability'] !== 0 ){ + $insertThis[] = $insertItem ; + } + */ + } + } else { + + $insertThis[] = $insertItem; + + /* + if($newMappingArray[$key]['availability'] !== 0){ + + $insertThis[] = $insertItem ; + } + */ + } + } + + } + sort($deleteThis); + + + if ($deleteThis) { + $deleteAvailability = $this->propertyRoomAvailabilityRepository->destroy($deleteThis); + if ($deleteAvailability['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $insertAvailability = $this->propertyRoomAvailabilityRepository->insert($insertThis); + + if ($insertAvailability['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + //Connected Room Case + $roomAvailabilityUpdateForConnectedRoomParams = [ + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'availability_type_id' => $getAvailabilityDataIds, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'user_id' => fillOnUndefined($params, "user_id", 0) + ]; + + $this->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams); + //Connected Room Case + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function dropPropertyChannelGuaranteedAndLimitedAvailability($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $roomAvailabilityCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'date', 'condition' => '>=', 'value' => date('Y-m-d')], + ], + 'whereIn' => [ + ['field' => 'availability_type_id', 'value' => [2, 3]] + ], + ]; + $roomAvailability = $this->propertyRoomAvailabilityRepository->findbyCriteria($roomAvailabilityCriteria, ['id']); + $roomAvailability = $roomAvailability ? $roomAvailability : []; + $deleteThis = array_column($roomAvailability, 'id'); + + if ($deleteThis) { + $destroyResult = $this->propertyRoomAvailabilityRepository->destroy($deleteThis); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyRoomAvailabilityRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomAvailabilityRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function roomAvailabilityUpdateForConnectedRooms($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + if(is_null($params['startDate']) || is_null($params['endDate'])) { + $response['status'] = true; + return $response; + } + + $diffInDays = Carbon::parse($params['startDate'])->diffInDays(Carbon::parse($params['endDate'])); + + //Connected Room Case + $propertyRoomConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['roomDetail'] + ]; + + + $propertyRoomConnected = $this->propertyRoomConnectedRepository->findbyCriteria($propertyRoomConnectedCriteria); + $propertyRoomConnected = $propertyRoomConnected ? $propertyRoomConnected : []; + + $propertyRoomConnectedGrouped = collect($propertyRoomConnected)->groupBy('room_id')->toArray(); + + $oldRoomAvailabilityCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $params['startDate']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['endDate']], + ] + ]; + + $oldRoomAvailability = $this->propertyRoomAvailabilityRepository->findbyCriteria($oldRoomAvailabilityCriteria); + $oldRoomAvailability = $oldRoomAvailability ? collect($oldRoomAvailability) : []; + + + foreach ($propertyRoomConnectedGrouped as $connectedRoomId => $connectedRooms) { + + $roomDetail = reset($connectedRooms)['room_detail']; + + + if ($roomDetail['is_connected_room_availability'] != 1) { + continue; + } + + //Güncellemede dikkat edilmesi gereken Oda ID leri + $connectedRoomIds = pickItemFromArray('connected_room_id', $connectedRooms); + + //dd($params,$connectedRoomIds ,$oldRoomAvailability); + + for ($i = 0; $i <= $diffInDays; $i++) { + + $date = Carbon::parse($params['startDate'])->addDays($i)->toDateString(); + + + if (empty($oldRoomAvailability)) { + continue; + } + + $issetCurrentRoomAvailability = $oldRoomAvailability + ->where('property_room_id', $connectedRoomId) + ->whereIn('availability_type_id', $params['availability_type_id']) + ->where('date', $date)->first(); + + + $roomAvailabilityFromConnectedRooms = $oldRoomAvailability + ->whereIn('property_room_id', $connectedRoomIds) + ->whereIn('availability_type_id', $params['availability_type_id']) + ->where('date', $date)->sortBy('availability'); + + $roomAvailabilityFromConnectedRoomsIds = $roomAvailabilityFromConnectedRooms->pluck('property_room_id')->toArray(); + + $intersectRooms = array_intersect($roomAvailabilityFromConnectedRoomsIds, $connectedRoomIds); + + if(count($intersectRooms) != count($connectedRoomIds)) { + continue; + } + + $roomAvailabilityFromConnectedRooms = $roomAvailabilityFromConnectedRooms->first(); + $roomAvailabilityFromConnectedRooms = fillOnUndefined($roomAvailabilityFromConnectedRooms, 'availability', 0); + + + //update + if (!empty($issetCurrentRoomAvailability)) { + + $this->propertyRoomAvailabilityRepository->update($issetCurrentRoomAvailability['id'], ['availability' => $roomAvailabilityFromConnectedRooms]); + + } else { + + $insertItem = [ + 'property_id' => $params['property_id'], + 'property_room_id' => $roomDetail['id'], + 'room_rate_mapping_id' => null, + 'channel_id' => !in_array(1,$params['availability_type_id']) ? $params['channel_id'] : null, + 'availability_type_id' => !in_array(1,$params['availability_type_id']) ? reset($params['availability_type_id']) : 1, + 'date' => $date, + 'availability' => $roomAvailabilityFromConnectedRooms, + 'stop_sell' => 0, + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + $this->propertyRoomAvailabilityRepository->insert($insertItem); + + } + + + } + + } + //Connected Room Case + + + $response = [ + 'status' => true, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + +} diff --git a/app/Core/Service/PropertyRoomBedService.php b/app/Core/Service/PropertyRoomBedService.php new file mode 100644 index 0000000..398526f --- /dev/null +++ b/app/Core/Service/PropertyRoomBedService.php @@ -0,0 +1,260 @@ +propertyRoomBedRepository = $propertyRoomBedRepository; + $this->propertyRoomBedAddValidator = $propertyRoomBedAddValidator; + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = + [ + 'room_id' => fillOnUndefined($params, 'room_id', 0), + 'bed_group' => fillOnUndefined($params, 'bed_group', 0), + 'count' => fillOnUndefined($params, 'count', 0), + 'bed_type_id' => fillOnUndefined($params, 'bed_type_id', 0), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by"), + "updated_by" => fillOnUndefined($params, "updated_by"), + ]; + + $userCreateResult = $this->propertyRoomBedRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomBedRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function validate($params){ + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $roomBedGroup = fillOnUndefined($params, 'room_bed_group', []); + $bedGroupIndex = 1; + + foreach ($roomBedGroup as $bedGroup) { + + foreach ($bedGroup as $beds) { + $insertData = + [ + 'room_id' => fillOnUndefined($params, 'room_id', null), + 'bed_group' => $bedGroupIndex, + 'count' => fillOnUndefined($beds, 'bed_type_count', null), + 'bed_type_id' => fillOnUndefined($beds, 'bed_type_id', null), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0) + ]; + $validationResult = $this->propertyRoomBedAddValidator->validate($insertData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + } + } + $response['status'] = true; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + + } + + return output($response); + + } + + public function addPropertyRoomBed($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $dataValidation = $this->validate($params); + if ($dataValidation['status'] != 'success') { + throw new ApiErrorException($dataValidation['message']); + } + + DB::beginTransaction(); + $deleteRoomBedsCriteria = [ + 'criteria' => [ + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']] + ] + ]; + $deleteRoomBeds = $this->propertyRoomBedRepository->delete($deleteRoomBedsCriteria); + + $roomBedGroup = fillOnUndefined($params, 'room_bed_group', []); + $bedGroupIndex = 1; + + foreach ($roomBedGroup as $bedGroup) { + + foreach ($bedGroup as $beds) { + + $insertData = + [ + 'room_id' => fillOnUndefined($params, 'room_id', null), + 'bed_group' => $bedGroupIndex, + 'count' => fillOnUndefined($beds, 'bed_type_count', null), + 'bed_type_id' => fillOnUndefined($beds, 'bed_type_id', null), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0) + ]; + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + } + $bedGroupIndex++; + } + $response = [ + 'status' => true, + + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomBeds($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + if(fillOnUndefined($params, 'room_id', null) == null){ + throw new ApiErrorException(lang('room_id is required')); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ], + + ]; + + $data = $this->propertyRoomBedRepository->findByCriteria($criteria, ['id', 'room_id', 'bed_group', 'count', 'bed_type_id']); + $data = $data ? $data : [] ; + $collection = collect($data) ; + + $bedGroup = $collection->unique('bed_group')->keyBy('bed_group')->keys()->all(); + + $exportArray = []; + foreach ($bedGroup as $group){ + $groupData = $collection->where('bed_group','=', $group); + $subArray = []; + foreach ($groupData as $data){ + $subArray[] = [ + 'bed_type_id' => $data['bed_type_id'], + 'bed_type_count' => $data['count'], + ]; + } + $exportArray[] = $subArray; + } + + $exportData = [ + 'room_id' => $params['room_id'], + 'room_bed_group' => $exportArray + + ]; + + $response = [ + 'status' => true, + 'data' => $exportData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomBedTypeService.php b/app/Core/Service/PropertyRoomBedTypeService.php new file mode 100644 index 0000000..a18c536 --- /dev/null +++ b/app/Core/Service/PropertyRoomBedTypeService.php @@ -0,0 +1,209 @@ +propertyRoomBedTypeRepository = $propertyRoomBedTypeRepository; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyRoomBedTypeRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomBedTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomBedTypeRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomBedTypeRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getPropertyRoomBedTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'with' => [] + ]; + + $data = $this->propertyRoomBedTypeRepository->findByCriteria($criteria, ['id', 'name', 'icon', 'language_key']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyRoomBedTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'with' => [] + ]; + + $data = $this->propertyRoomBedTypeRepository->findByCriteria($criteria, ['id', 'name']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomFactMappingService.php b/app/Core/Service/PropertyRoomFactMappingService.php new file mode 100644 index 0000000..e3a3992 --- /dev/null +++ b/app/Core/Service/PropertyRoomFactMappingService.php @@ -0,0 +1,423 @@ +languageService = $languageService; + $this->propertyRoomFactMappingRepository = $propertyRoomFactMappingRepository; + $this->applicationCacheService = $applicationCacheService; + $this->propertyRoomFactMappingAddValidator = $propertyRoomFactMappingAddValidator; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $userCreateResult = $this->propertyRoomFactMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]->toArray(); + + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomFactMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyRoomFactMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deleteById($param){ + + $userCreateResult = $this->propertyRoomFactMappingRepository->delete(); + + } + + public function removePropertyRoomFactMapping($param = []) + { + + //Todo: validations + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + //Todo: cache datası yeni bir fonksiyon yapılıp herkes oradan geçekecek + + $cacheInfo = $this->applicationCacheService->getApplicationCache([]); + if($cacheInfo['status'] != 'success'){ + throw new ApiErrorException(lang('Cache Required')); + } + $userData = $cacheInfo['data'] ; + + + $factIds = []; + foreach ($param["facts"] as $fact){ + $factIds[] = $fact["id"]; + } + + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $userData['property_id']], + ], + "whereIn"=> + [ + ["field"=>"fact_id","value"=>$factIds] + ] + ]; + + $factMappingDatas = $this->propertyRoomFactMappingRepository->findByCriteria($findCriteria); + if (!$factMappingDatas) { + throw new ApiErrorException(lang('Fact cannot loaded')); + } + + + // Todo: gönderilen idler ile veritabanında bulunan idler karşılaştırılacak. Uyumsuz data varsa hiç bir şey silinmeden error throw edilecek + + $deleteRowIds = []; + foreach ($factMappingDatas as $factMappingData){ + $ids = []; + $ids[] = $factMappingData["id"]; + $delete = $this->propertyRoomFactMappingRepository->deleteById($ids); + if (!$delete) { + throw new ApiErrorException(lang('cannot delete fact')); + } + + } + $response['status'] = 1; + $response['data'] = []; + + + + } + catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function addPropertyRoomFactMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + $propertyId = $params['property_id']; + $userId = $params['user_id']; + $propertyFactData = $params['data']; + + $addPropertyRoomFactMapping = []; + foreach ($propertyFactData as $key => $param) + { + $addPropertyRoomFactMapping[] = + [ + 'property_id' => $propertyId, + 'fact_id' => fillOnUndefined($param, 'id'), + 'created_by' => $userId, + 'updated_by' => $userId, + ]; + } + + //TODO : $addPropertyRoomFactMapping için validation işlemleri yapılacaktır.(property_id ve fact id inin unique doğrulamasına bakılması unutulmamalı ) + $response = $this->propertyRoomFactMappingRepository->createAll($addPropertyRoomFactMapping); + + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function updatePropertyRoomFactMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + + $validationResult = $this->propertyRoomFactMappingAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $addPropertyRoomFactMapping = []; + $addFactList = collect($params['property_room_fact']) + ->where('is_selected' ,'=', true); + $addFactIds = $addFactList->keyBy("id")->keys()->toArray(); + + $removeFactList = collect($params['property_room_fact']) + ->where('is_selected' ,'=', false); + + $removeFactIds = $removeFactList->keyBy("id")->keys()->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ], + "whereIn" => [ + ["field" => "fact_id", "value" => $addFactIds] + ] + ]; + $checkPropertyMappingResponse = $this->select($checkPropertyMappingRequest,['id', 'property_id', 'fact_id']); + + if($checkPropertyMappingResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Mapping data not loaded')); + } + $checkPropertyMappingCollect = collect($checkPropertyMappingResponse['data']); + + foreach ($addFactList->toArray() as $key => $param) + { + + if( + !$checkPropertyMappingCollect->where('property_id', '=', $params['property_id']) + ->where('fact_id', '=', $param['id']) + ->first() + ){ + + $addPropertyRoomFactMapping[] = + [ + 'property_id' => $params['property_id'], + 'room_id' => $params['room_id'], + 'fact_id' => fillOnUndefined($param, 'id'), + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + } + } + + $response = $this->propertyRoomFactMappingRepository->createAll($addPropertyRoomFactMapping); + + + if($removeFactIds){ + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ], + "whereIn" => + [ + ["field" => "fact_id", "value" => $removeFactIds] + ] + ]; + + $deletePropertyRoomFactMapping = $this->propertyRoomFactMappingRepository->findByCriteria($findCriteria); + + $deleteThisIds = []; + foreach ($deletePropertyRoomFactMapping as $deleteThisItem){ + $deleteThisIds[] = $deleteThisItem['id']; + } + + if($deleteThisIds){ + $this->propertyRoomFactMappingRepository->deleteById($deleteThisIds); + + } + } + + if ($response['status'] != 'success') { + throw new ApiErrorException(lang('Data is not added')) ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + public function updatePropertyRoomFactIsFeature($params = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + + /*$validationResult = $this->propertyRoomFactMappingAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ['field' => 'fact_id', 'condition' => '=', 'value' => $params['fact_id']] + ], + 'firstRow' => true + ]; + + $checkPropertyMappingResponse = $this->select($checkPropertyMappingRequest,['id', 'property_id', 'room_id', 'fact_id']); + + if($checkPropertyMappingResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Mapping data not loaded')); + } + + if(empty($checkPropertyMappingResponse['data'])){ + throw new ApiErrorException(lang('Mapping data not found')); + } + + $propertyFactMappingId = $checkPropertyMappingResponse['data']['id']; + + $updateData = [ + 'is_feature' => $params['is_feature'], + 'updated_by' => $params['user_id'] + ]; + + $updateResult = $this->update($propertyFactMappingId, $updateData); + + if ($updateResult['status'] != 'success') { + throw new ApiErrorException(lang('Mapping Fact data is not updated.')); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/PropertyRoomPhotoMappingService.php b/app/Core/Service/PropertyRoomPhotoMappingService.php new file mode 100644 index 0000000..669c791 --- /dev/null +++ b/app/Core/Service/PropertyRoomPhotoMappingService.php @@ -0,0 +1,254 @@ +languageService = $languageService; + $this->propertyRoomPhotoMappingRepository = $propertyRoomPhotoMappingRepository; + $this->applicationCacheService = $applicationCacheService; + $this->propertyRoomPhotoMappingAddValidator = $propertyRoomPhotoMappingAddValidator; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $userCreateResult = $this->propertyRoomPhotoMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]->toArray(); + + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomPhotoMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deleteById($param){ + + $userCreateResult = $this->propertyRoomPhotoMappingRepository->delete(); + + } + + public function updatePropertyRoomPhotoMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try + { + + $validationResult = $this->propertyRoomPhotoMappingAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $addPropertyRoomPhotoMapping = []; + $addPhotoList = collect($params['property_room_photo']) + ->where('is_selected' ,'=', true); + $addPhotoIds = $addPhotoList->keyBy("id")->keys()->toArray(); + + $removePhotoList = collect($params['property_room_photo']) + ->where('is_selected' ,'=', false); + + $removePhotoIds = $removePhotoList->keyBy("id")->keys()->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ], + "whereIn" => [ + ["field" => "photo_id", "value" => $addPhotoIds] + ] + ]; + $checkPropertyMappingResponse = $this->select($checkPropertyMappingRequest,['id', 'property_id', 'photo_id']); + + if($checkPropertyMappingResponse['status'] != 'success'){ + throw new ApiErrorException(lang('Mapping data not loaded')); + } + $checkPropertyMappingCollect = collect($checkPropertyMappingResponse['data']); + + foreach ($addPhotoList->toArray() as $key => $param) + { + + if( + !$checkPropertyMappingCollect->where('property_id', '=', $params['property_id']) + ->where('photo_id', '=', $param['id']) + ->first() + ){ + + $addPropertyRoomPhotoMapping[] = + [ + 'property_id' => $params['property_id'], + 'room_id' => $params['room_id'], + 'photo_id' => fillOnUndefined($param, 'id'), + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + } + } + + $response = $this->propertyRoomPhotoMappingRepository->createAll($addPropertyRoomPhotoMapping); + + if($removePhotoIds){ + + $findCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ], + "whereIn" => + [ + ["field" => "photo_id", "value" => $removePhotoIds] + ] + ]; + + $deletePropertyRoomPhotoMapping = $this->propertyRoomPhotoMappingRepository->findByCriteria($findCriteria); + + $deleteThisIds = []; + foreach ($deletePropertyRoomPhotoMapping as $deleteThisItem){ + $deleteThisIds[] = $deleteThisItem['id']; + } + + if($deleteThisIds){ + $this->propertyRoomPhotoMappingRepository->deleteById($deleteThisIds); + } + } + + if ($response['status'] != 'success') { + throw new ApiErrorException(lang('Data is not added')) ; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['data'] = ''; + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['data'] = ''; + $response['statusCode'] = 400; + } + + return output($response); + } + + + public function destroy($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'photo_id', 'condition' => '=', 'value' => $params['photo_id']], + ] + ]; + + $deleteData = $this->propertyRoomPhotoMappingRepository->findByCriteria($deleteCriteria, ['id']); + $deleteData = $deleteData ? $deleteData : [] ; + if($deleteData){ + $deleteIds = array_column($deleteData, 'id') ; + $destroyResult = $this->propertyRoomPhotoMappingRepository->destroy($deleteIds); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + +} diff --git a/app/Core/Service/PropertyRoomRateChannelMappingService.php b/app/Core/Service/PropertyRoomRateChannelMappingService.php new file mode 100644 index 0000000..0162bc2 --- /dev/null +++ b/app/Core/Service/PropertyRoomRateChannelMappingService.php @@ -0,0 +1,340 @@ +propertyRoomRateChannelMappingRepository = $propertyRoomRateChannelMappingRepository; + $this->propertyRoomRateChannelMappingAddValidator = $propertyRoomRateChannelMappingAddValidator; + $this->propertyRoomRateChannelMappingUpdateValidator = $propertyRoomRateChannelMappingUpdateValidator; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->propertyRoomRepository = $propertyRoomRepository ; + $this->propertyAvailabilityTypeRepository = $propertyAvailabilityTypeRepository ; + $this->propertyChannelMappingService = $propertyChannelMappingService ; + + + } + + + public function addPropertyRoomRateChannelMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + $validateData = + [ + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'channels' => fillOnUndefined($params, 'channels'), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $validationResult = $this->propertyRoomRateChannelMappingAddValidator->validate($validateData); + + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'room_rate_mapping_id', 'condition' => '=', 'value' => $validateData['room_rate_mapping_id']], + ] + ]; + + $this->propertyRoomRateChannelMappingRepository->delete($deleteCriteria); + + + foreach ($validateData["channels"] as $fact){ + $insertData = [ + 'property_id' => $params['property_id'] , + 'room_rate_mapping_id' => $validateData['room_rate_mapping_id'] , + 'channel_id' => $fact, + 'status' => 1, + "created_by" => $validateData['created_by'] , + "updated_by" =>$validateData['updated_by'] , + + ]; + + + $userCreateResult = $this->propertyRoomRateChannelMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomRateChannelMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $data = $this->propertyRoomRateChannelMappingRepository->findByCriteria($criteria, ['id', 'room_rate_mapping_id', 'channel_id']); + $data = $data ? $data : []; + $rateChannelMapping = []; + foreach ($data as $mapping){ + $rateChannelMapping[$mapping['channel_id'].'|'.$mapping['room_rate_mapping_id']] = $mapping ; + } + + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'with' => ['propertyRoomRateMapping.propertyRoomRate'] + ]; + + $data = $this->propertyRoomRepository->findByCriteria($criteria, ['id','property_id','name','room_type_id','max_occupancy','max_adult','max_child','exclude_occupancy','room_size','room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + $roomData = $data ? $data : []; + $channels = [] ; + foreach ($params['channels'] as $channelItem) { + $rooms = [] ; + $channel = $channelItem; + foreach ($roomData as $roomItem) { + $room = $roomItem; + unset($room['property_room_rate_mapping']); + $rates = [] ; + foreach ($roomItem['property_room_rate_mapping'] as $roomRate) { + $rate = $roomRate ; + $checkKey = $channel['id'].'|'.$roomRate['id']; + unset($rate['property_room_rate']) ; + $rate['rate_name'] = $roomRate['property_room_rate']['name']; + $rate['rate_description'] = $roomRate['property_room_rate']['name']; + $rate['min_stay'] = $roomRate['property_room_rate']['min_stay']; + $rate['max_stay'] = $roomRate['property_room_rate']['max_stay']; + $rate['is_selected'] = isset($rateChannelMapping[$checkKey]); + $rates[] = $rate; + } + $room['rates'] = $rates ; + $rooms[] = $room ; + } + $channel['rooms'] = $rooms ; + $channels[] = $channel ; + } + + $response = [ + 'status' => true, + 'data' => $channels, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyRoomRateChannelMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + $validateData = + [ + 'room_rate_channel_mapping' => fillOnUndefined($params, 'room_rate_channel_mapping'), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $validationResult = $this->propertyRoomRateChannelMappingUpdateValidator->validate($validateData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + foreach ($params['room_rate_channel_mapping'] as $mapping) { + $hasDate = isset($mapping['has_date']) ? $mapping['has_date'] : 0 ; + $startDate = isset($mapping['start_date']) ? $mapping['start_date'] : null ; + $endDate = isset($mapping['end_date']) ? $mapping['end_date'] : null ; + + + $checkData = [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $mapping['channel_id']], + ['field' => 'room_rate_mapping_id', 'condition' => '=', 'value' => $mapping['room_rate_mapping_id']], + + ]; + + $checkParams = [ + 'property_id' => $params['property_id'], + 'channel_id' => $mapping['channel_id'], + ] ; + + $checkMappingStatus =$this->propertyChannelMappingService->checkPropertyChannelMapping($checkParams); + if ($checkMappingStatus['status'] != 'success') { + return Exception('api-unknown_error'); + } + + if($mapping['is_selected'] == true){ + $addData = [ + 'property_id' => $params['property_id'] , + 'room_rate_mapping_id' => $mapping['room_rate_mapping_id'] , + 'channel_id' => $mapping['channel_id'] , + 'has_date' => $hasDate , + 'start_date' => $startDate , + 'end_date' => $endDate , + 'status' => 1, + "created_by" => $validateData['created_by'], + "updated_by" =>$validateData['updated_by'], + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + $createStatus = $this->propertyRoomRateChannelMappingRepository->updateOrCreate($checkData, $addData ); + if ($createStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + }else { + + $softDeleteData = [ + 'status' => 0, + 'has_date' => $hasDate , + 'start_date' => $startDate , + 'end_date' => $endDate , + "updated_by" =>$validateData['updated_by'], + 'updated_at' => Carbon::now()->timestamp, + ]; + + $deleteCriteria = ['criteria' => $checkData ]; + $softDelete = $this->propertyRoomRateChannelMappingRepository->updateWhere($deleteCriteria, $softDeleteData ); + if ($softDelete['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyRoomRateChannelMappingRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectChannelAvailabilityType($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyAvailabilityTypeRepository->findByCriteria($param, $column); + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomRateInclusionMappingService.php b/app/Core/Service/PropertyRoomRateInclusionMappingService.php new file mode 100644 index 0000000..03e7441 --- /dev/null +++ b/app/Core/Service/PropertyRoomRateInclusionMappingService.php @@ -0,0 +1,145 @@ +propertyRoomRateInclusionMappingRepository = $propertyRoomRateInclusionMappingRepository; + $this->propertyRoomRateInclusionMappingAddValidator = $propertyRoomRateInclusionMappingAddValidator; + + + } + + + public function addPropertyRoomRateInclusionMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + $validateData = + [ + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'facts' => fillOnUndefined($params, 'facts'), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $validationResult = $this->propertyRoomRateInclusionMappingAddValidator->validate($validateData); + + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'room_rate_id', 'condition' => '=', 'value' => $validateData['room_rate_id']], + ] + ]; + + $this->propertyRoomRateInclusionMappingRepository->delete($deleteCriteria); + + + foreach ($validateData["facts"] as $fact){ + $insertData = [ + 'room_rate_id' => $validateData['room_rate_id'] , + 'fact_id' => $fact, + 'status' => 1, + "created_by" => $validateData['created_by'] , + "updated_by" =>$validateData['updated_by'] , + + ]; + + + $userCreateResult = $this->propertyRoomRateInclusionMappingRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomRateInclusionMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_rate_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_id')], + ], + 'with' => ['propertyFact'] + ]; + + $data = $this->propertyRoomRateInclusionMappingRepository->findByCriteria($criteria, ['id', 'room_rate_id', 'fact_id']); + $return = []; + foreach ($data as $item){ + if(isset($item['property_fact'])){ + $row = $item['property_fact']; + $return[] = $row ; + } + } + + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyRoomRateMappingService.php b/app/Core/Service/PropertyRoomRateMappingService.php new file mode 100644 index 0000000..e9813be --- /dev/null +++ b/app/Core/Service/PropertyRoomRateMappingService.php @@ -0,0 +1,705 @@ +propertyRoomRateMappingRepository = $propertyRoomRateMappingRepository; + $this->propertyRoomRateMappingSetupRepository = $propertyRoomRateMappingSetupRepository; + $this->propertyRoomRateMappingAddValidator = $propertyRoomRateMappingAddValidator; + $this->propertyRoomRateMappingUpdateValidator = $propertyRoomRateMappingUpdateValidator; + $this->propertyRoomRateMappingDeleteValidator = $propertyRoomRateMappingDeleteValidator; + $this->propertyRoomRateMappingAddWithSetupValidator = $propertyRoomRateMappingAddWithSetupValidator; + $this->propertyRoomRateMappingSetStatusValidator = $propertyRoomRateMappingSetStatusValidator; + $this->propertyRoomRateChannelMappingRepository = $propertyRoomRateChannelMappingRepository; + $this->propertyRoomRateMappingConnectedValidator = $propertyRoomRateMappingConnectedValidator; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRateMappingAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + 'room_id' => fillOnUndefined($params, 'room_id', 0), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id', 0), + 'description' => fillOnUndefined($params, 'description', ''), + 'rack_rate' => fillOnUndefined($params, 'rack_rate', 0), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy', 0), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by", 0), + "updated_by" => fillOnUndefined($params, "updated_by", 0), + ]; + + $userCreateResult = $this->propertyRoomRateMappingRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRateMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomRateMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRateMappingRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function addPropertyRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $checkRoomRateMappingRequest = [ + 'criteria' => [ + ['field' => 'room_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_id')], + ['field' => 'room_rate_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_id')], + ], + ]; + + $checkRoomRateMapping = $this->propertyRoomRateMappingRepository->findByCriteria($checkRoomRateMappingRequest); + $checkRoomRateMapping = $checkRoomRateMapping ? $checkRoomRateMapping : null; + + if ($checkRoomRateMapping) { + + throw new ApiErrorException('This data was previously added'); + } + $insertData = + [ + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'description' => fillOnUndefined($params, 'description'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyRoomRateMappingWithSetup($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyRoomRateMappingAddWithSetupValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $checkRoomRateMappingRequest = [ + 'criteria' => [ + ['field' => 'room_rate_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_id')], + ], + ]; + + $checkRoomRateMapping = $this->propertyRoomRateMappingRepository->findByCriteria($checkRoomRateMappingRequest); + $checkRoomRateMapping = $checkRoomRateMapping ? $checkRoomRateMapping : []; + $oldRoomRateRooms = collect($checkRoomRateMapping)->keyBy('room_id')->keys()->toArray(); + $insertRoomRateMappingSetupData = []; + foreach ($params['room_id'] as $room) { + + if (in_array($room, $oldRoomRateRooms)) { + throw new ApiErrorException('This data was previously added'); + } + $insertRoomRateMappingData = + [ + 'room_id' => $room, + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $insertRoomRateMappingResult = $this->propertyRoomRateMappingRepository->create($insertRoomRateMappingData); + if ($insertRoomRateMappingResult['status'] != 'success') { + throw new ApiErrorException($insertRoomRateMappingResult['message']); + } + + /* $insertRoomRateMapping = $insertRoomRateMappingResult['data']; + + foreach ($params['room_rate_mapping_setup'] as $mappingSetup){ + $insertRoomRateMappingSetupData[] = [ + 'room_rate_mapping_id' => $insertRoomRateMapping['id'] , + 'setup_type' => $mappingSetup['setup_type'], + 'value_type' => $mappingSetup['value_type'], + 'value' => $mappingSetup['value'], + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id") , + "updated_by" => fillOnUndefined($params, "user_id") , + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + }*/ + + + } + + /* $insertRoomRateMappingSetupResult = $this->propertyRoomRateMappingSetupRepository->insert($insertRoomRateMappingSetupData); + if ($insertRoomRateMappingSetupResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + }*/ + + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_id')], + + ], + 'with' => ['propertyRoomRate', 'propertyRoomRateChannel'] + ]; + + $data = $this->propertyRoomRateMappingRepository->findByCriteria($criteria, ['id', 'room_id', 'room_rate_id', 'description', 'rack_rate', 'included_occupancy']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyRoomRateMappingConnected($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_rate_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_id')], + + ], + 'with' => ['propertyRoom'] + ]; + + $relationalRoomsByRate = $this->propertyRoomRateMappingRepository->findByCriteria($criteria, ['id', 'room_id', 'room_rate_id']); + $relationalRoomIds = pickItemFromArray('room_id', $relationalRoomsByRate); + + + $criteriaRoomRate = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => + [ + ['field' => 'room_id', "value" => $relationalRoomIds] + ], + 'with' => ['propertyRoom.propertyRoomType', 'propertyRoomRate'] + ]; + + $roomRates = $this->propertyRoomRateMappingRepository->findByCriteria($criteriaRoomRate); + + + $connectedValue = []; + foreach ($roomRates as $roomRate) { + if ($roomRate['room_rate_id'] == $params['room_rate_id'] && !empty($roomRate['connected_rate_id'])) { + + $connectedValue[$roomRate['room_id']] = [ + 'connected_rate_id' => $roomRate['connected_rate_id'], + 'is_affected_price' => $roomRate['is_affected_price'], + 'affect_price_action_type' => $roomRate['affect_price_action_type'], + 'affect_price_type' => $roomRate['affect_price_type'], + 'affect_price_value' => $roomRate['affect_price_value'], + ]; + + continue; + } + } + + $roomRateList = []; + foreach ($roomRates as $roomRate) { + + if ($roomRate['room_rate_id'] == $params['room_rate_id']) { + continue; + } + + $roomRateList[$roomRate['room_id']]['room'] = [ + 'room_id' => $roomRate['room_id'], + 'room_name' => $roomRate['property_room']['name'], + 'room_type' => $roomRate['property_room']['property_room_type']['name'], + 'status' => $roomRate['property_room']['status'], + ]; + + if (isset($connectedValue[$roomRate['room_id']]) && $connectedValue[$roomRate['room_id']]['connected_rate_id'] == $roomRate['room_rate_id']) { + $roomRateList[$roomRate['room_id']]['rates'][] = [ + 'id' => $roomRate['id'], + 'room_rate_id' => $roomRate['room_rate_id'], + 'room_rate_name' => $roomRate['property_room_rate']['name'], + 'connected_rate_id' => $connectedValue[$roomRate['room_id']]['connected_rate_id'], + 'is_affected_price' => $connectedValue[$roomRate['room_id']]['is_affected_price'], + 'affect_price_action_type' => $connectedValue[$roomRate['room_id']]['affect_price_action_type'], + 'affect_price_type' => $connectedValue[$roomRate['room_id']]['affect_price_type'], + 'affect_price_value' => $connectedValue[$roomRate['room_id']]['affect_price_value'], + ]; + } else { + $roomRateList[$roomRate['room_id']]['rates'][] = [ + 'id' => $roomRate['id'], + 'room_rate_id' => $roomRate['room_rate_id'], + 'room_rate_name' => $roomRate['property_room_rate']['name'], + 'connected_rate_id' => null, + 'is_affected_price' => null, + 'affect_price_action_type' => null, + 'affect_price_type' => null, + 'affect_price_value' => null, + ]; + } + + } + + $roomRateList = array_values($roomRateList); + + $response = [ + 'status' => true, + 'data' => $roomRateList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function syncPropertyRoomRateMappingConnected($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + DB::beginTransaction(); + + try { + + $validationResult = $this->propertyRoomRateMappingConnectedValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_rate_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_id')], + + ], + ]; + + $relationalRoomsByRate = $this->propertyRoomRateMappingRepository->findByCriteria($criteria); + $relationalRoomIds = pickItemFromArray('room_id', $relationalRoomsByRate); + + //ResetRoomRateConnectParam + foreach ($relationalRoomsByRate as $roomRate) { + + $resetRoomRateConnectParam = [ + 'connected_rate_id' => null, + 'is_affected_price' => null, + 'affect_price_action_type' => null, + 'affect_price_type' => null, + 'affect_price_value' => null, + ]; + + $this->propertyRoomRateMappingRepository->update($roomRate['id'], $resetRoomRateConnectParam); + + foreach ($params['connected_room_rate'] as $connectedRoomRate) { + + if ($roomRate['room_id'] == $connectedRoomRate['room_id'] && $connectedRoomRate['room_rate_id']) { + + $roomRateConnectParam = [ + 'connected_rate_id' => fillOnUndefined($connectedRoomRate, 'room_rate_id'), + 'is_affected_price' => fillOnUndefined($connectedRoomRate, 'is_affected_price'), + 'affect_price_action_type' => fillOnUndefined($connectedRoomRate, 'affect_price_action_type'), + 'affect_price_type' => fillOnUndefined($connectedRoomRate, 'affect_price_type'), + 'affect_price_value' => fillOnUndefined($connectedRoomRate, 'affect_price_value'), + ]; + + $roomRateConnect = $this->propertyRoomRateMappingRepository->update($roomRate['id'], $roomRateConnectParam); + + if ($roomRateConnect['status'] != 'success') { + throw new ApiErrorException($roomRateConnect['message']); + } + + } + } + + } + + $response = [ + 'status' => true + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return output($response); + } + + public function updatePropertyRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRateMappingUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'description' => fillOnUndefined($params, 'description'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + "updated_by" => fillOnUndefined($params, "user_id"), + ]; + + if (isset($params['status'])) { + $updateData['status'] = fillOnUndefined($params, "status", 0); + } + + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRateMappingDeleteValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'status' => 0, + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function setStatusPropertyRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validationResult = $this->propertyRoomRateMappingSetStatusValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'status' => $params['is_selected'], + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyRoomRateMappingRepository->update($params['room_rate_mapping_id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + if ($params['is_selected'] == false) { + $updateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'room_rate_mapping_id', 'condition' => '=', 'value' => $params['room_rate_mapping_id']], + ] + ]; + + $updateData = [ + "status" => 0, + "updated_by" => $params['user_id'] + ]; + + $updateResult = $this->propertyRoomRateChannelMappingRepository->updateWhere($updateCriteria, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomRateMappingSetupService.php b/app/Core/Service/PropertyRoomRateMappingSetupService.php new file mode 100644 index 0000000..2249159 --- /dev/null +++ b/app/Core/Service/PropertyRoomRateMappingSetupService.php @@ -0,0 +1,140 @@ +propertyRoomRateMappingSetupRepository = $propertyRoomRateMappingSetupRepository; + $this->propertyRoomRateMappingSetupAddValidator = $propertyRoomRateMappingSetupAddValidator; + + + } + + + public function addPropertyRoomRateMappingSetup($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + $validateData = + [ + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'setup' => fillOnUndefined($params, 'setup'), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $validationResult = $this->propertyRoomRateMappingSetupAddValidator->validate($validateData); + + + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'room_rate_mapping_id', 'condition' => '=', 'value' => $validateData['room_rate_mapping_id']], + ] + ]; + + $this->propertyRoomRateMappingSetupRepository->delete($deleteCriteria); + + + foreach ($validateData["setup"] as $item){ + $insertData = [ + 'room_rate_mapping_id' => $validateData['room_rate_mapping_id'] , + 'setup_type' => $item['setup_type'], + 'value_type' => $item['value_type'], + 'value' => $item['value'], + 'status' => 1, + "created_by" => $validateData['created_by'] , + "updated_by" =>$validateData['updated_by'] , + + ]; + + + $userCreateResult = $this->propertyRoomRateMappingSetupRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomRateMappingSetup($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'room_rate_mapping_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'room_rate_mapping_id')], + ] + ]; + + + $data = $this->propertyRoomRateMappingSetupRepository->findByCriteria($criteria, ['id', 'room_rate_mapping_id', 'setup_type', 'value_type', 'value']); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyRoomRatePriceQueueService.php b/app/Core/Service/PropertyRoomRatePriceQueueService.php new file mode 100644 index 0000000..fa523fa --- /dev/null +++ b/app/Core/Service/PropertyRoomRatePriceQueueService.php @@ -0,0 +1,115 @@ +propertyRoomRatePriceQueueRepository = $propertyRoomRatePriceQueueRepository; + + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRatePriceQueueRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomRatePriceQueueRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($ids = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deleteResult = $this->propertyRoomRatePriceQueueRepository->destroy($ids); + + if ($deleteResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult['data'] // affected row count + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyRoomRatePriceService.php b/app/Core/Service/PropertyRoomRatePriceService.php new file mode 100644 index 0000000..79ef8cb --- /dev/null +++ b/app/Core/Service/PropertyRoomRatePriceService.php @@ -0,0 +1,1183 @@ +propertyRoomRatePriceRepository = $propertyRoomRatePriceRepository; + $this->propertyRoomRatePriceAddValidator = $propertyRoomRatePriceAddValidator; + $this->propertyRoomRatePriceUpdateValidator = $propertyRoomRatePriceUpdateValidator; + $this->propertyRoomRatePriceDeleteValidator = $propertyRoomRatePriceDeleteValidator; + $this->propertyRoomRatePriceBulkInsertValidator = $propertyRoomRatePriceBulkInsertValidator; + $this->propertyRoomRatePriceBulkUpdateValidator = $propertyRoomRatePriceBulkUpdateValidator; + $this->propertyChannelRepository = $propertyChannelRepository; + $this->propertyRoomRateMappingRepository = $roomRateMappingRepository; + $this->propertyRepository = $propertyRepository; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->propertyRoomConnectedRepository = $propertyRoomConnectedRepository; + $this->propertyQuickPricingService = $propertyQuickPricingService; + $this->propertyRoomRateChannelMappingRepository = $propertyRoomRateChannelMappingRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRatePriceAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'description' => fillOnUndefined($params, 'description'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by"), + "updated_by" => fillOnUndefined($params, "updated_by"), + ]; + + $userCreateResult = $this->propertyRoomRatePriceRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRatePriceRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomRatePriceRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRatePriceRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function addPropertyRoomRatePrice($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRatePriceAddValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id', 0), + 'property_room_id' => fillOnUndefined($params, 'property_room_id', 0), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id', 0), + 'offer_id' => fillOnUndefined($params, 'offer_id', 0), + 'channel_id' => fillOnUndefined($params, 'channel_id', 0), + 'min_stay' => fillOnUndefined($params, 'min_stay', 0), + 'max_stay' => fillOnUndefined($params, 'max_stay', 0), + 'stop_sell' => fillOnUndefined($params, 'stop_sell', 0), + 'booking_on_request' => fillOnUndefined($params, 'booking_on_request', 0), + 'date' => fillOnUndefined($params, 'date', null), + 'amount' => fillOnUndefined($params, 'amount', 0), + 'currency' => fillOnUndefined($params, 'currency', null), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0), + ]; + + + $userCreateResult = $this->propertyRoomRatePriceRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyRoomRatePrices($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ] + ]; + + $data = $this->propertyRoomRatePriceRepository->findByCriteria($criteria, ['id', 'property_id', 'name', 'description', 'min_stay']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyRoomRatePrice($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRatePriceUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'description' => fillOnUndefined($params, 'description'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + "updated_by" => fillOnUndefined($params, "user_id"), + ]; + + if (isset($params['status'])) { + $updateData['status'] = fillOnUndefined($params, "status", 0); + } + + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyRoomRatePrice($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRatePriceDeleteValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'status' => 0, + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function bulkUpdate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $startDate = Carbon::parse($params['start_date']); + $endDate = Carbon::parse($params['end_date']); + $diffInDays = $startDate->diffInDays($endDate); + $includeDays = fillOnUndefined($params, 'include_days', []); + $insertData = []; + + $validationResult = $this->propertyRoomRatePriceBulkInsertValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + // Get Channel Mapping Information + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'channel_id')], + ], + 'with' => ['channel'], + 'firstRow' => 1 + ]; + + $channelData = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id', 'connected_channel_id', 'currency_code', 'property_availability_type_id']); + if (!$channelData) { + throw new ApiErrorException('Channel mapping not found'); + } + + $updateData = []; + switch ($params['update_type']) { + case 'rate': + case 'quick_pricing': + $updateData = ['amount' => $params['value']]; + break; + case 'min_stay': + $updateData = ['min_stay' => $params['value']]; + break; + case 'maxstay': + $updateData = ['max_stay' => $params['value']]; + break; + case 'stopsell': + $updateData = ['stop_sell' => $params['value']]; + break; + case 'bookingonrequest': + $updateData = ['booking_on_request' => $params['value']]; + break; + case 'rate_stop_sell': + $updateData = ['stop_sell' => $params['value']]; + break; + + } + + $updateData = array_merge($updateData, ['updated_by' => fillOnUndefined($params, "user_id", 0), 'updated_at' => Carbon::now()->timestamp,]); + + //min_stay min 1 + if(isset($updateData['min_stay']) && empty($updateData['min_stay'])) { + $updateData['min_stay'] = 1; + } + + $selectIds = $this->selectedRoomRateIds($params); + if ($selectIds['status'] != 'success') { + throw new ApiErrorException('array error'); + } + $selectIds = $selectIds['data']; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + + ]; + $property = $this->propertyRepository->findByCriteria($propertyRequest); + + if (!$property) { + throw new ApiErrorException(lang('Property not found')); + } + + //Quick Pricing + $propertyQuickPricingMappingCollect = []; + if ($params['update_type'] == 'quick_pricing') { + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomRateChannelMapping.propertyRoomRateMapping', 'propertyRoomRateChannelMapping.propertyRoomRateMapping'] + ]; + + //Connected Channel Quick Pricing Settings + if (!empty($channelData['connected_channel_id'])) { + $requestSelectCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $channelData['connected_channel_id']]; + } else { + $requestSelectCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']]; + } + + $columns = ['id', 'property_id', 'channel_id', 'room_rate_channel_mapping_id', 'action_type', 'price_type', 'price_value']; + $requestSelectResult = $this->propertyQuickPricingService->selectPropertyQuickPricingMapping($requestSelectCriteria, $columns); + + if ($requestSelectResult['status'] == 'success') { + $propertyQuickPricingMappingCollect = collect($requestSelectResult['data']); + } + } + + + $channelDataRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + $selectedChannel = $this->propertyChannelRepository->findByCriteria($channelDataRequest, ['id', 'name', 'currency_code']); + $selectedChannel = $selectedChannel ? $selectedChannel : []; + if (!$selectedChannel) { + throw new ApiErrorException('channel error'); + } + + $roomRateMappingRequest = [ + 'whereIn' => [ + ['field' => 'id', 'value' => $selectIds['room_rate_mapping_ids']], + ], + 'with' => ['propertyRoomRate'] + ]; + $selectedRoomRateMapping = $this->propertyRoomRateMappingRepository->findByCriteria($roomRateMappingRequest); + $selectedRoomRateMapping = $selectedRoomRateMapping ? $selectedRoomRateMapping : []; + $selectedRoomRateMapping = collect($selectedRoomRateMapping); + + $oldRoomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $params['start_date']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['end_date']], + ] + ]; + + $oldRoomRatePrice = $this->propertyRoomRatePriceRepository->findbyCriteria($oldRoomRatesCriteria); + $oldRoomRatePrice = $oldRoomRatePrice ? $oldRoomRatePrice : []; + $updateThis = []; + + $oldRoomRatePriceKeys = []; + foreach ($oldRoomRatePrice as $oldPrice) { + $oldPriceKey = $oldPrice['property_room_id'] . "|" . $oldPrice['room_rate_mapping_id'] . "|" . $oldPrice['date'] . "|" . $oldPrice['channel_id'] . "|" . $oldPrice['availability_type_id']; + $oldRoomRatePriceKeys[$oldPriceKey] = $oldPrice['id']; + } + + + foreach ($params['room_rates'] as $roomRate) { + foreach ($roomRate['room_rate_mapping_id'] as $roomRateMappingId) { + + if ($params['update_type'] == 'quick_pricing') { + + //Connected Channel Quick Pricing Settings + if ( !empty($channelData['connected_channel_id'])) { + $quickPricing = $propertyQuickPricingMappingCollect->where('property_id', $params['property_id']) + ->where('channel_id', $channelData['connected_channel_id'])->where('property_room_rate_channel_mapping.room_rate_mapping_id', $roomRateMappingId) + ->first(); + + } else { + $quickPricing = $propertyQuickPricingMappingCollect->where('property_id', $params['property_id']) + ->where('channel_id', $params['channel_id'])->where('property_room_rate_channel_mapping.room_rate_mapping_id', $roomRateMappingId) + ->first(); + } + + if (empty($quickPricing)) { + continue; + } + } + + $startDate = Carbon::parse($params['start_date']); + for ($i = 0; $i <= $diffInDays; $i++) { + if (!in_array($startDate->shortEnglishDayOfWeek, $includeDays)) { + $startDate = $startDate->addDay(); + continue; + } + + $currentRoomRateMapping = $selectedRoomRateMapping->where('id', '=', $roomRateMappingId)->first(); + $currentRoomRate = $currentRoomRateMapping['property_room_rate']; + + $insertDataStopSell = 0; + if ($params['update_type'] == 'rate_stop_sell') { + $insertDataStopSell = fillOnUndefined($params, 'value', 0); + } + + $insertDataMinStay = 0; + if ($params['update_type'] == 'min_stay') { + $insertDataMinStay = fillOnUndefined($params, 'value', 1); + } + + $insertDataAmount = 0; + if ($params['update_type'] == 'rate') { + $insertDataAmount = fillOnUndefined($params, 'value', 0); + } + + if ($params['update_type'] == 'quick_pricing') { + + $amount = fillOnUndefined($params, 'value', 0); + + $amountCalculated = $amount; + + $amountAffected = 0; + if ($quickPricing['price_type'] == 'PER') { + $amountAffected = ($amount * $quickPricing['price_value']) / 100; + } elseif ($quickPricing['price_type'] == 'FIX') { + $amountAffected = $quickPricing['price_value']; + } + + if ($quickPricing['action_type'] == 'INC') { + $amountCalculated = $amountCalculated + $amountAffected; + } + + if ($quickPricing['action_type'] == 'DEC') { + $amountCalculated = $amountCalculated - $amountAffected; + } + + $insertDataAmount = $amountCalculated; + } + + $insertDataItem = [ + 'property_id' => fillOnUndefined($params, 'property_id', 0), + 'property_room_id' => fillOnUndefined($roomRate, 'room_id', 0), + 'room_rate_mapping_id' => $roomRateMappingId, + 'channel_id' => fillOnUndefined($params, 'channel_id', 0), + 'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1), + 'min_stay' => $insertDataMinStay, + 'max_stay' => 0, + 'stop_sell' => $insertDataStopSell, + 'booking_on_request' => 0, + 'date' => $startDate->format('Y-m-d'), + 'amount' => $insertDataAmount, + 'currency' => $channelData['currency_code'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + + $checkKey = $roomRate['room_id'] . "|" . $roomRateMappingId . "|" . $startDate->format('Y-m-d') . "|" . $params['channel_id'] . "|" . $params['availability_type_id']; + if (isset($oldRoomRatePriceKeys[$checkKey])) { + if ($params['update_type'] == 'quick_pricing') { + $amountKey = (string)$insertDataAmount; + $updateThis[$amountKey][] = $oldRoomRatePriceKeys[$checkKey]; + } else { + $updateThis[] = $oldRoomRatePriceKeys[$checkKey]; + } + + } else { + $insertData[] = $insertDataItem; + } + + $startDate = $startDate->addDay(); + } + + } + } + + if ($updateThis) { + + if ($params['update_type'] == 'quick_pricing') { + + foreach ($updateThis as $updateDataQuickPricingAmount => $updateIds) { + $updateDataCalculated = $updateData; + $updateDataCalculated['amount'] = $updateDataQuickPricingAmount; + $data = $this->propertyRoomRatePriceRepository->updateWhereIn($updateIds, $updateDataCalculated); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + } else { + + $thisUpdateArrayChunk = array_chunk($updateThis, 1000); + foreach ($thisUpdateArrayChunk as $updateIds) { + $data = $this->propertyRoomRatePriceRepository->updateWhereIn($updateIds, $updateData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + } + + } + + if (in_array($params['update_type'], ['rate', 'rate_stop_sell', 'min_stay', 'quick_pricing'])) { + $thisInsertArrayChunk = array_chunk($insertData, 1000); + foreach ($thisInsertArrayChunk as $insertThis) { + $data = $this->propertyRoomRatePriceRepository->insert($insertThis); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + + //Connected Room Case + $roomRateUpdateForConnectedRoomParams = [ + 'quickPricing' => fillOnUndefined($params, 'quickPricing', false), + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'currency_code' => $channelData['currency_code'], + 'channel_availability_type_id' => $channelData['property_availability_type_id'], + 'startDate' => $params['start_date'], + 'endDate' => $params['end_date'], + 'user_id' => fillOnUndefined($params, "user_id", 0) + ]; + + $this->roomRateUpdateForConnectedRooms($roomRateUpdateForConnectedRoomParams); + //Connected Room Case + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectedRoomRateIds($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $roomIds = []; + $roomRateIds = []; + $channelIds = []; + foreach ($params['room_rates'] as $roomRate) { + $roomIds[] = $roomRate['room_id']; + foreach ($roomRate['room_rate_mapping_id'] as $roomRateMapping) { + $roomRateIds[] = $roomRateMapping; + } + } + $roomIds = array_unique($roomIds); + $roomRateIds = array_unique($roomRateIds); + $response = [ + 'status' => true, + 'data' => [ + 'room_ids' => $roomIds, + 'room_rate_mapping_ids' => $roomRateIds + ], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function formElementsToArray($params = []) + { + + $newMappingArray = []; + $availabilityArray = []; + + foreach ($params['rates'] as $key => $value) { + $keyExportArray = explode('_', $key); + $theDate = Carbon::parse($keyExportArray[4])->format('Y-m-d'); + $keyExportArray[3] = $keyExportArray[3] != 0 ? $keyExportArray[3] : null; + $channelId = $keyExportArray[3] != 0 ? $params['channel_id'] : null; + if ($keyExportArray[0] == 'AVA') { + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['setup_type_id'] = $keyExportArray[1]; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['room_id'] = $keyExportArray[2]; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['room_rate_mapping_id'] = $keyExportArray[3] != 0 ? $keyExportArray[3] : null; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['date'] = $theDate; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['availability'] = $value; + } elseif ($keyExportArray[0] == 'PRC') { + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['setup_type_id'] = $keyExportArray[1]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_id'] = $keyExportArray[2]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_rate_mapping_id'] = $keyExportArray[3]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['date'] = $theDate; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['amount'] = $value; + } elseif ($keyExportArray[0] == 'STS') { + if ($keyExportArray[3] != null) { + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['setup_type_id'] = $keyExportArray[1]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_id'] = $keyExportArray[2]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_rate_mapping_id'] = $keyExportArray[3]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['date'] = $theDate; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['stop_sell'] = $value; + } + + if ($keyExportArray[3] == null) { + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['setup_type_id'] = $keyExportArray[1]; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['room_id'] = $keyExportArray[2]; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['room_rate_mapping_id'] = $keyExportArray[3] != 0 ? $keyExportArray[3] : null; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['date'] = $theDate; + $availabilityArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $channelId . '|' . $theDate]['stop_sell'] = $value; + } + + } elseif ($keyExportArray[0] == 'MNS') { + if ($keyExportArray[3] != null) { + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['setup_type_id'] = $keyExportArray[1]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_id'] = $keyExportArray[2]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['room_rate_mapping_id'] = $keyExportArray[3]; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['date'] = $theDate; + $newMappingArray[$keyExportArray[1] . '|' . $keyExportArray[2] . '|' . $keyExportArray[3] . '|' . $theDate]['min_stay'] = $value; + } + } + + } + + return ['availability' => $availabilityArray, 'rates' => $newMappingArray]; + + } + + public function roomRateUpdate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $newMappingArray = $params ? $params : []; + $validationResult = $this->propertyRoomRatePriceBulkUpdateValidator->validate($newMappingArray); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $newMappingArray = $newMappingArray['rates']; + + $newMappingCollect = collect($newMappingArray); + $startDate = $newMappingCollect->min('date'); + $endDate = $newMappingCollect->max('date'); + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + + ]; + $property = $this->propertyRepository->findByCriteria($propertyRequest); + + if (!$property) { + throw new ApiErrorException(lang('Property not found')); + } + + // Get Channel Mapping Information + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'channel_id')], + ], + 'with' => ['channel'], + 'firstRow' => 1 + ]; + + $channelData = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id', 'currency_code', 'property_availability_type_id']); + if (!$channelData) { + throw new ApiErrorException('Channel mapping not found'); + } + + $oldRoomRatePrice = []; + if (!empty($newMappingArray)) { + $oldRoomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $startDate], + ['field' => 'date', 'condition' => '<=', 'value' => $endDate], + ] + ]; + + $oldRoomRatePrice = $this->propertyRoomRatePriceRepository->findbyCriteria($oldRoomRatesCriteria); + } + + $oldMappingArray = []; + foreach ($oldRoomRatePrice as $oldPrice) { + $oldMappingArray[$oldPrice['availability_type_id'] . '|' . $oldPrice['property_room_id'] . '|' . $oldPrice['room_rate_mapping_id'] . '|' . $oldPrice['date']] = [ + 'id' => $oldPrice['id'], + 'room_id' => $oldPrice['property_room_id'], + 'room_rate_mapping_id' => $oldPrice['room_rate_mapping_id'], + 'availability_type_id' => $oldPrice['availability_type_id'], + 'channel_id' => $oldPrice['channel_id'], + 'date' => $oldPrice['date'], + 'amount' => $oldPrice['amount'], + 'stop_sell' => $oldPrice['stop_sell'], + 'min_stay' => $oldPrice['min_stay'] + ]; + } + + $deleteThis = []; + $insertThis = []; + + + foreach ($newMappingArray as $key => $newMapping) { + + if (isset($newMapping['amount']) && $newMapping['amount'] === "") { + $newMapping['amount'] = 0; + } + + if (isset($newMapping['amount']) && $newMapping['amount'] === "") { + if (isset($oldMappingArray[$key])) { + $deleteThis[] = $oldMappingArray[$key]['id']; + } + } else { + + if (isset($newMappingArray[$key]['amount'])) { + $insertAmountData = fillOnUndefined($newMappingArray[$key], 'amount', 0); + + if ($newMappingArray[$key]['amount'] == '') { + $newMappingArray[$key]['amount'] = 0; + $insertAmountData = 0; + } + } + + + if (!isset($newMapping['amount'])) { + if (!isset($oldMappingArray[$key])) { + $insertAmountData = 0; + } else { + $insertAmountData = $oldMappingArray[$key]['amount']; + } + + } + + $insertStopSellData = fillOnUndefined($newMappingArray[$key], 'stop_sell', 0); + if (!isset($newMapping['stop_sell'])) { + if (isset($oldMappingArray[$key])) { + $insertStopSellData = $oldMappingArray[$key]['stop_sell']; + } else { + $insertStopSellData = 0; + } + } + + $insertMinStayData = fillOnUndefined($newMappingArray[$key], 'min_stay', 1); + $insertMinStayData = empty($insertMinStayData) ? 1 : $insertMinStayData; + if (!isset($newMapping['min_stay'])) { + if (isset($oldMappingArray[$key])) { + $insertMinStayData = $oldMappingArray[$key]['min_stay']; + } else { + $insertMinStayData = 1; + } + } + + + $insertItem = [ + 'property_id' => fillOnUndefined($params, 'property_id', 0), + 'property_room_id' => fillOnUndefined($newMappingArray[$key], 'room_id', 0), + 'room_rate_mapping_id' => fillOnUndefinedAndEmpty($newMappingArray[$key], 'room_rate_mapping_id', 0), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'availability_type_id' => fillOnUndefined($newMappingArray[$key], 'setup_type_id', null), + 'min_stay' => $insertMinStayData, + 'max_stay' => fillOnUndefined($newMappingArray[$key], 'max_stay', 0), + 'stop_sell' => $insertStopSellData, + 'booking_on_request' => fillOnUndefined($newMappingArray[$key], 'booking_on_request', 0), + 'date' => fillOnUndefined($newMappingArray[$key], 'date', 0), + 'amount' => $insertAmountData, + 'currency' => $channelData['currency_code'], + 'status' => fillOnUndefined($params, "status", 1), + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + if (isset($oldMappingArray[$key])) { + if ( + $oldMappingArray[$key]['amount'] != $insertItem['amount'] || $oldMappingArray[$key]['stop_sell'] != $insertItem['stop_sell'] || $oldMappingArray[$key]['min_stay'] != $insertItem['min_stay'] + ) { + $deleteThis[] = $oldMappingArray[$key]['id']; + if ($insertItem['amount'] !== 0) { + $insertThis[] = $insertItem; + } + } + } else { + $insertThis[] = $insertItem; + } + + } + + } + + sort($deleteThis); + + if ($deleteThis) { + $deleteRoomRatePrices = $this->propertyRoomRatePriceRepository->destroy($deleteThis); + if ($deleteRoomRatePrices['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $insertRoomRatePrices = $this->propertyRoomRatePriceRepository->insert($insertThis); + if ($insertRoomRatePrices['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + + //Connected Room Case + $roomRateUpdateForConnectedRoomParams = [ + 'quickPricing' => fillOnUndefined($params, 'quickPricing', false), + 'property_id' => $params['property_id'], + 'channel_id' => $params['channel_id'], + 'currency_code' => $channelData['currency_code'], + 'channel_availability_type_id' => $channelData['property_availability_type_id'], + 'startDate' => $startDate, + 'endDate' => $endDate, + 'user_id' => fillOnUndefined($params, "user_id", 0) + ]; + + + $this->roomRateUpdateForConnectedRooms($roomRateUpdateForConnectedRoomParams); + //Connected Room Case + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + protected function roomRateUpdateForConnectedRooms($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + if (is_null($params['startDate']) || is_null($params['endDate'])) { + $response['status'] = true; + return $response; + } + + $diffInDays = Carbon::parse($params['startDate'])->diffInDays(Carbon::parse($params['endDate'])); + + //Connected Room Case + $propertyRoomConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['roomDetail'] + ]; + + $propertyRoomConnected = $this->propertyRoomConnectedRepository->findbyCriteria($propertyRoomConnectedCriteria); + $propertyRoomConnected = $propertyRoomConnected ? $propertyRoomConnected : []; + + $propertyRoomConnectedGrouped = collect($propertyRoomConnected)->groupBy('room_id')->toArray(); + + + $propertyRoomRateChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'channel_id')], + ], + 'with' => ['propertyRoomRateMapping', 'propertyRoomRateQuickPricingMapping'] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingRepository->findByCriteria($propertyRoomRateChannelMappingCriteria, ['*']); + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping); + + $oldRoomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $params['startDate']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['endDate']], + ], + 'with' => ['roomRateMapping'] + ]; + + $oldRoomRatePriceUpdated = $this->propertyRoomRatePriceRepository->findbyCriteria($oldRoomRatesCriteria); + $oldRoomRatePriceUpdated = $oldRoomRatePriceUpdated ? collect($oldRoomRatePriceUpdated) : []; + + + foreach ($propertyRoomConnectedGrouped as $connectedRoomId => $connectedRooms) { + + $roomDetail = reset($connectedRooms)['room_detail']; + + if ($roomDetail['is_connected_room_price'] != 1) { + continue; + } + + //güncellenmesi gereken id bulalım + $connectedRoomIds = pickItemFromArray('connected_room_id', $connectedRooms); + + $availableRoomRates = $propertyRoomRateChannelMappingCollect->where('property_room_rate_mapping.room_id', $connectedRoomId); + $availableRoomRates = $availableRoomRates ? $availableRoomRates->toArray() : []; + + foreach ($availableRoomRates as $availableRoomRate) { + + + for ($i = 0; $i <= $diffInDays; $i++) { + + $date = Carbon::parse($params['startDate'])->addDays($i)->toDateString(); + + $issetCurrentRoomRatePrice = $oldRoomRatePriceUpdated->where('availability_type_id', $params['channel_availability_type_id']) + ->where('property_room_id', $connectedRoomId) + ->where('room_rate_mapping_id', $availableRoomRate['room_rate_mapping_id']) + ->where('date', $date)->first(); + + $roomPriceFromConnectedRooms = $oldRoomRatePriceUpdated + ->where('room_rate_mapping.room_rate_id', $availableRoomRate['property_room_rate_mapping']['room_rate_id']) + ->whereIn('property_room_id', $connectedRoomIds) + ->where('date', $date) + ->sum('amount'); + + + if (isset($params['quickPricing']) && $params['quickPricing']) { + + $amount = $roomPriceFromConnectedRooms; + $amountCalculated = $roomPriceFromConnectedRooms; + + $quickPricing = $availableRoomRate['property_room_rate_quick_pricing_mapping']; + + $amountAffected = 0; + if ($quickPricing['price_type'] == 'PER') { + $amountAffected = ($amount * $quickPricing['price_value']) / 100; + } elseif ($quickPricing['price_type'] == 'FIX') { + $amountAffected = $quickPricing['price_value']; + } + + if ($quickPricing['action_type'] == 'INC') { + $amountCalculated = $amountCalculated + $amountAffected; + } + + if ($quickPricing['action_type'] == 'DEC') { + $amountCalculated = $amountCalculated - $amountAffected; + } + + $roomPriceFromConnectedRooms = $amountCalculated; + + } + + + //update + if (!empty($issetCurrentRoomRatePrice)) { + + $this->propertyRoomRatePriceRepository->update($issetCurrentRoomRatePrice['id'], ['amount' => $roomPriceFromConnectedRooms]); + + } else { + + $insertItem = [ + 'property_id' => $params['property_id'], + 'property_room_id' => $availableRoomRate['property_room_rate_mapping']['room_id'], + 'room_rate_mapping_id' => $availableRoomRate['property_room_rate_mapping']['id'], + 'channel_id' => $params['channel_id'], + 'availability_type_id' => $params['channel_availability_type_id'], + 'min_stay' => 0, + 'max_stay' => 0, + 'stop_sell' => 0, + 'booking_on_request' => 0, + 'date' => $date, + 'amount' => $roomPriceFromConnectedRooms, + 'currency' => $params['currency_code'], + 'status' => 1, + 'created_by' => fillOnUndefined($params, "user_id", 0), + 'updated_by' => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + + $this->propertyRoomRatePriceRepository->insert($insertItem); + + } + + + } + + + } + + + } + //Connected Room Case + + + $response = [ + 'status' => true, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + +} diff --git a/app/Core/Service/PropertyRoomRateService.php b/app/Core/Service/PropertyRoomRateService.php new file mode 100644 index 0000000..fe19659 --- /dev/null +++ b/app/Core/Service/PropertyRoomRateService.php @@ -0,0 +1,573 @@ +propertyRoomRateRepository = $propertyRoomRateRepository; + $this->propertyRoomRateAddValidator = $propertyRoomRateAddValidator; + $this->propertyRoomRateUpdateValidator = $propertyRoomRateUpdateValidator; + $this->propertyRoomRateDeleteValidator = $propertyRoomRateDeleteValidator; + $this->propertyRoomRateAddWithInclusionValidator = $propertyRoomRateAddWithInclusionValidator; + $this->propertyRoomRateInclusionMappingRepository = $propertyRoomRateInclusionMappingRepository; + $this->propertyFactService = $propertyFactService; + $this->languageService = $languageService; + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRateAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'description' => fillOnUndefined($params, 'description'), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by"), + "updated_by" => fillOnUndefined($params, "updated_by"), + ]; + + $userCreateResult = $this->propertyRoomRateRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + try { + + $data = $this->propertyRoomRateRepository->findByCriteria($param, $column); + + if ($data) { + $descriptionLangContents = json_decode($data['description'], 1); + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + + $data['description'] = $responseLangDescription; + } + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomRateRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRateRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function addPropertyRoomRate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $desc) { + $description[$desc['language_code']] = $desc['description']; + } + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'), + "description" => !empty($description) ? json_encode($description) : null, + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyRoomRateWithInclusion($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $validateData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => trim(fillOnUndefined($params, 'name')), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + /*'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'),*/ + 'facts' => fillOnUndefined($params, 'facts'), + + ]; + $validationResult = $this->propertyRoomRateAddWithInclusionValidator->validate($validateData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $desc) { + $description[$desc['language_code']] = $desc['description']; + } + + + $insertData = [ + 'property_id' => fillOnUndefined($validateData, 'property_id'), + 'name' => fillOnUndefined($validateData, 'name'), + 'accommodation_type' => fillOnUndefined($validateData, 'accommodation_type'), + "description" => !empty($description) ? json_encode($description) : null, + /*'min_stay' => fillOnUndefined($validateData, 'min_stay'), + 'max_stay' => fillOnUndefined($validateData, 'max_stay'),*/ + "status" => fillOnUndefined($validateData, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + + $userCreateResult = $this->propertyRoomRateRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $roomRateData = $userCreateResult['data']; + $insertData = []; + foreach ($params["facts"] as $fact) { + $insertData[] = [ + 'room_rate_id' => $roomRateData['id'], + 'fact_id' => $fact, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + + + $userCreateResult = $this->propertyRoomRateInclusionMappingRepository->insert($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $roomRateData, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomRates($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'with' => ['propertyRoomRateInclusionMapping.propertyFact', 'propertyRoomRateAccommodation'] + ]; + + $data = $this->propertyRoomRateRepository->findByCriteria($criteria, ['id', 'property_id', 'name', 'description', 'accommodation_type', 'min_stay', 'max_stay']); + + $return = []; + foreach ($data as $item) { + $dataRow = $item; + if ($item['property_room_rate_inclusion_mapping']) { + $factList = collect($item['property_room_rate_inclusion_mapping'])->map(function ($value) { + return $value['property'] = [ + 'room_rate_id' => $value['room_rate_id'], + 'fact_id' => $value['fact_id'], + 'name' => $value['property_fact']['name'], + 'icon' => $value['property_fact']['icon'], + 'language_key' => $value['property_fact']['language_key'] + ]; + + })->toArray(); + $dataRow['property_room_rate_inclusion_mapping'] = $factList; + } + + + $descriptionLangContents = json_decode($dataRow['description'], 1); + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + + $dataRow['description'] = $responseLangDescription; + + $return[] = $dataRow; + } + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyRoomRate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + $validationResult = $this->propertyRoomRateUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $desc) { + $description[$desc['language_code']] = $desc['description']; + } + + $updateData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + "description" => !empty($description) ? json_encode($description) : null, + "updated_by" => fillOnUndefined($params, "user_id"), + ]; + + if (isset($params['status'])) { + $updateData['status'] = fillOnUndefined($params, "status", 0); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'room_rate_id', 'condition' => '=', 'value' => $params['id']] + ] + ]; + + $data = $this->propertyRoomRateInclusionMappingRepository->findByCriteria($criteria, ['id']); + $deleteThis = collect($data)->keyBy('id')->keys()->toArray(); + + if ($deleteThis) { + $deleteThisArray = $this->propertyRoomRateInclusionMappingRepository->destroy($deleteThis); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $updateResult["data"]; + + if (!empty($params["facts"])) { + $insertData = []; + foreach ($params["facts"] as $fact) { + if ($fact) { + $insertData[] = [ + 'room_rate_id' => $params['id'], + 'fact_id' => $fact, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + } + $userCreateResult = $this->propertyRoomRateInclusionMappingRepository->insert($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function deletePropertyRoomRate($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomRateDeleteValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'status' => 0, + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyAccommodationTypes($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $requestFact = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'sub_category_id' => 9, + ]; + $subCategoryFacts = $this->propertyFactService->getSubCategoryFacts($requestFact); + if ($subCategoryFacts['status'] != 'success') { + throw new ApiErrorException($subCategoryFacts['message']); + } + // todo burada propertnin sahip olduğu tüm accommodation geliyordu + // $propertyAccommodationList = collect($subCategoryFacts['data'])->where('is_selected', '=', true)->values()->toArray(); + $propertyAccommodationList = $subCategoryFacts['data']; + $response = [ + 'status' => true, + 'data' => $propertyAccommodationList, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyRoomService.php b/app/Core/Service/PropertyRoomService.php new file mode 100644 index 0000000..95e021b --- /dev/null +++ b/app/Core/Service/PropertyRoomService.php @@ -0,0 +1,2082 @@ +propertyRoomRepository = $propertyRoomRepository; + $this->propertyChannelMappingRepository = $propertyChannelMappingRepository; + $this->propertyRoomBedRepository = $propertyRoomBedRepository; + $this->propertyRoomRatePriceRepository = $propertyRoomRatePriceRepository; + $this->propertyRoomAvailabilityRepository = $propertyRoomAvailabilityRepository; + $this->propertyRoomAddValidator = $propertyRoomAddValidator; + $this->propertyRoomAndBedAddValidator = $propertyRoomAndBedAddValidator; + $this->propertyRoomUpdateValidator = $propertyRoomUpdateValidator; + $this->propertyRoomDeleteValidator = $propertyRoomDeleteValidator; + $this->propertyRoomInventoryValidator = $propertyRoomInventoryValidator; + $this->propertyRepository = $propertyRepository; + $this->propertyRoomTypeService = $propertyRoomTypeService; + $this->propertyRoomViewMappingRepository = $propertyRoomViewMappingRepository; + $this->propertyRoomAndBedUpdateValidator = $propertyRoomAndBedUpdateValidator; + $this->languageService = $languageService; + $this->propertyAvailabilityTypeRepository = $propertyAvailabilityTypeRepository; + $this->propertyRoomConnectedRepository = $propertyRoomConnectedRepository; + + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $description = []; + foreach (fillOnUndefined($params, "description", []) as $title) { + $description[$title['language_code']] = $title['description']; + } + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'room_size' => fillOnUndefined($params, 'room_size'), + 'room_size_type' => fillOnUndefined($params, 'room_size_type'), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count'), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count'), + 'toilet_count' => fillOnUndefined($params, 'toilet_count'), + 'lounge_count' => fillOnUndefined($params, 'lounge_count'), + 'max_child_number' => fillOnUndefined($params, 'max_child_number'), + 'description' => json_encode($description), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "created_by"), + "updated_by" => fillOnUndefined($params, "updated_by"), + ]; + + $userCreateResult = $this->propertyRoomRepository->create($insertData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function addPropertyRoom($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'room_size' => fillOnUndefined($params, 'room_size'), + 'room_size_type' => fillOnUndefined($params, 'room_size_type'), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count'), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count'), + 'toilet_count' => fillOnUndefined($params, 'toilet_count'), + 'lounge_count' => fillOnUndefined($params, 'lounge_count'), + 'max_child_number' => fillOnUndefined($params, 'max_child_number'), + 'description' => fillOnUndefined($params, 'description'), + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $userCreateResult = $this->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new ApiErrorException($userCreateResult['message']); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyRooms($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomBedGroup.propertyRoomBedType'] + ]; + + $data = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + $newRoomMapping = []; + foreach ($data as $room) { + $bedGroups = collect($room['property_room_bed_group'])->keyBy('bed_group')->keys(); + $group = []; + foreach ($bedGroups as $bedGroup) { + $thisGroup = collect($room['property_room_bed_group'])->where('bed_group', '=', $bedGroup)->map(function ($bedItem) use ($bedGroup) { + $responseMapping = $bedItem; + $responseMapping['bed_type_name'] = $bedItem['property_room_bed_type']['name']; + unset($responseMapping['property_room_bed_type']); + return $responseMapping; + })->toArray(); + $newItem = []; + foreach ($thisGroup as $item) { + $newItem[] = $item; + } + $group[] = $newItem; + } + $room['property_room_bed_group'] = $group; + $newRoomMapping[] = $room; + + } + + $response = [ + 'status' => true, + 'data' => $newRoomMapping, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyRoom($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $title) { + $description[$title['language_code']] = $title['description']; + } + $updateData = + [ + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => json_encode($params['exclude_occupancy'], true), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'description' => json_encode($description), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyRoom($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyRoomDeleteValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $updateData = + [ + 'status' => 0, + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $updateResult = $this->update($params['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyRoomRateChannel($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + //['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => [ + 'propertyRoomType', 'propertyRoomRateMapping.propertyRoomRateChannel', 'propertyRoomRateMapping.connectedRate', + 'propertyRoomRateMapping.propertyRoomRate', 'propertyRoomBedGroup.propertyRoomBedType', + 'propertyRoomViewMapping.propertyRoomViewType', 'propertyRoomConnected' + ] + ]; + + $columns = [ + 'id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'exclude_occupancy', 'room_size', + 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', + 'max_child_number', 'description', 'is_connected_room', 'is_connected_room_price', 'is_connected_room_availability', + 'occupancy_lock', 'status' + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, $columns); + + foreach ($roomData as $roomKey => $room) { + $roomData[$roomKey]['is_connected_room'] = $room['is_connected_room'] == 1 ? true : false; + $roomData[$roomKey]['is_connected_room_price'] = $room['is_connected_room_price'] == 1 ? true : false; + $roomData[$roomKey]['is_connected_room_availability'] = $room['is_connected_room_availability'] == 1 ? true : false; + } + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'with' => ['channel'] + ]; + + $channelData = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id']); + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + $return = []; + foreach ($roomData as $room) { + + $item = $room; + $descriptionLangContents = json_decode($item['description'], 1); + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + $item['description'] = $responseLangDescription; + $item['property_room_bed_group'] = []; + $item['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + if (isset($room['property_room_rate_mapping'])) { + $roomRateMappings = $room['property_room_rate_mapping']; + $mapping = []; + + foreach ($roomRateMappings as $roomRateMapping) { + + if (isset($roomRateMapping['property_room_rate_channel'])) { + + $newChannelData = []; + $roomRateChannels = $roomRateMapping['property_room_rate_channel']; + $rateChannelKey = []; + foreach ($roomRateChannels as $roomRateChannel) { + if ($roomRateChannel['status'] == 1) { + $rateChannelKey[$roomRateChannel['channel_id'] . '|' . $roomRateChannel['room_rate_mapping_id']] = $roomRateChannel['id']; + } + } + + foreach ($channelData as $channel) { + $newChannelData[] = [ + 'id' => $channel['channel']['id'], + 'name' => $channel['channel']['name'], + 'channel_category_id' => $channel['channel']['channel_category_id'], + 'country_code' => $channel['channel']['country_code'], + 'currency_code' => $channel['channel']['currency_code'], + 'logo' => $channel['channel']['logo'], + 'is_checked' => isset($rateChannelKey[$channel['channel_id'] . '|' . $roomRateMapping['id']]), + ]; + } + $roomRateMapping['property_room_rate_channel'] = $newChannelData; + } + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['min_stay'] = $roomRateMapping['property_room_rate']['min_stay']; + $roomRateMapping['max_stay'] = $roomRateMapping['property_room_rate']['max_stay']; + unset($roomRateMapping['property_room_rate']); + $mapping[] = $roomRateMapping; + + } + + $item['property_room_rate_mapping'] = $mapping; + + } + $bedGroups = collect($room['property_room_bed_group'])->keyBy('bed_group')->keys(); + $group = []; + foreach ($bedGroups as $bedGroup) { + $thisGroup = collect($room['property_room_bed_group'])->where('bed_group', '=', $bedGroup)->map(function ($bedItem) use ($bedGroup) { + $responseMapping = $bedItem; + $responseMapping['bed_type_name'] = $bedItem['property_room_bed_type']['name']; + $responseMapping['bed_type_language_key'] = $bedItem['property_room_bed_type']['language_key']; + unset($responseMapping['property_room_bed_type']); + return $responseMapping; + })->toArray(); + $newItem = []; + foreach ($thisGroup as $bedItem) { + $newItem[] = $bedItem; + } + $group[] = $newItem; + } + $item['property_room_bed_group'] = $group; + $item['property_room_view_mapping'] = collect($room['property_room_view_mapping'])->map(function ($value) { + + return $value['property_room_view_type']; + + })->all(); + + + $return[] = $item; + } + + + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyRoomInventory($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->propertyRoomInventoryValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + + ]; + $property = $this->propertyRepository->findByCriteria($propertyRequest); + + if (!$property) { + throw new ApiErrorException(lang('Property not found')); + } + + // Get Channel Mapping Information + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'channel_id')], + ], + 'with' => ['channel'], + 'firstRow' => 1 + ]; + + $channelData = $this->propertyChannelMappingRepository->findByCriteria($criteria, ['id', 'property_id', 'channel_id', 'currency_code']); + if (!$channelData) { + throw new ApiErrorException('Channel mapping not found'); + } + + + $inventoryGetParams = $params; + $inventoryGetParams['channelData'] = $channelData; + $roomRatePrices = $this->getInventory($inventoryGetParams); + + if ($roomRatePrices['status'] != 'success') { + throw new ApiErrorException($roomRatePrices['message']); + } + + $response = [ + 'status' => true, + 'data' => $roomRatePrices['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function checkPropertyRoomMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $request = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'whereIn' => [ + ['field' => 'id', 'value' => $param['room_ids']], + ], + 'count' => 1 + ]; + $data = $this->propertyRoomRepository->findByCriteria($request); + if ($data < count($param['room_ids'])) { + throw new ApiErrorException('Property - Room Mapping not validate.'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + } + + public function addPropertyRoomAndBed($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + // check room name, it is null set room type name. + if ($params['name'] == null) { + $propertyRoomTypeCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['room_type_id']], + ], + 'firstRow' => true, + ]; + $propertyType = $this->propertyRoomTypeService->select($propertyRoomTypeCriteria); + $params['name'] = $propertyType['data']['name']; + } + + $validationResult = $this->propertyRoomAndBedAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $title) { + $description[$title['language_code']] = $title['description']; + } + + + if (!$params['is_connected_room']) { + $params['is_connected_room_price'] = null; + $params['is_connected_room_availability'] = null; + $params['connected_rooms'] = []; + } + + $insertRoomData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => json_encode($params['exclude_occupancy'], true), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'description' => json_encode($description), + 'is_connected_room' => fillOnUndefined($params, 'is_connected_room', null) ? 1 : null, + 'is_connected_room_price' => fillOnUndefined($params, 'is_connected_room_price', null) ? 1 : null, + 'is_connected_room_availability' => fillOnUndefined($params, 'is_connected_room_availability', null) ? 1 : null, + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $insertRoomDataResult = $this->propertyRoomRepository->create($insertRoomData); + + if ($insertRoomDataResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $roomId = $insertRoomDataResult['data']['id']; + $roomBedGroup = fillOnUndefined($params, 'room_bed_group', []); + $bedGroupIndex = 1; + $insertBedData = []; + + + $isBedGroupInsert = true; + + if (count($roomBedGroup) == 1) { + if (count($roomBedGroup[0]) == 1) { + if (empty($roomBedGroup[0][0]['bed_type_id'])) { + $isBedGroupInsert = false; + } + + } + } + + + if ($isBedGroupInsert) { + + $roomBedGroups = []; + collect($roomBedGroup)->map(function ($value) use (&$roomBedGroups) { + $roomBedGroups[] = collect($value) + ->groupBy('bed_type_id') + ->map(function ($val) { + return $val->count(); + })->toArray(); + }); + + foreach ($roomBedGroups as $bedGroup) { + foreach ($bedGroup as $bedTypeId => $bedTypeCount) { + if (!empty($bedTypeId)) { + $insertBedData[] = + [ + 'room_id' => $roomId, + 'bed_group' => $bedGroupIndex, + 'count' => $bedTypeCount, + 'bed_type_id' => $bedTypeId, + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + } + $bedGroupIndex++; + } + $insertBedResult = $this->propertyRoomBedRepository->insert($insertBedData); + if ($insertBedResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + + if (!empty($params['room_view_type'])) { + + foreach ($params['room_view_type'] as $roomViewType) { + + $datas[] = [ + 'room_id' => $roomId, + 'room_view_type_id' => $roomViewType, + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $propertyRoomViewMappingResult = $this->propertyRoomViewMappingRepository->createAll($datas); + + if ($propertyRoomViewMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + //Connected Rooms + if ($params['is_connected_room']) { + $syncPropertyConnectedRoomParam = [ + 'property_id' => $params['property_id'], + 'room_id' => $roomId, + 'connected_rooms' => $params['connected_rooms'], + 'user_id' => fillOnUndefined($params, 'user_id') + ]; + + $syncPropertyConnectedRoom = $this->syncPropertyConnectedRoom($syncPropertyConnectedRoomParam); + + if ($syncPropertyConnectedRoom['status'] != 'success') { + throw new Exception($syncPropertyConnectedRoom['message']); + } + } + + //$userData = $insertBedResult["data"]; + $response = [ + 'status' => true, + //'data' => $userData, + ]; + + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function updatePropertyRoomAndBed($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + // check room name, it is null set room type name. + if ($params['name'] == null) { + $propertyRoomTypeCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['room_type_id']], + ], + 'firstRow' => true, + ]; + $propertyType = $this->propertyRoomTypeService->select($propertyRoomTypeCriteria); + $params['name'] = $propertyType['data']['name']; + } + + + $validationResult = $this->propertyRoomAndBedUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $description = []; + foreach (fillOnUndefined($params, "description", []) as $title) { + $description[$title['language_code']] = $title['description']; + } + + if (!$params['is_connected_room']) { + $params['is_connected_room_price'] = null; + $params['is_connected_room_availability'] = null; + $params['connected_rooms'] = []; + } + + $insertRoomData = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => json_encode($params['exclude_occupancy'], true), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'is_connected_room' => fillOnUndefined($params, 'is_connected_room', null) ? 1 : null, + 'is_connected_room_price' => fillOnUndefined($params, 'is_connected_room_price', null) ? 1 : null, + 'is_connected_room_availability' => fillOnUndefined($params, 'is_connected_room_availability', null) ? 1 : null, + 'description' => json_encode($description), + "status" => fillOnUndefined($params, "status", 1), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $insertRoomDataResult = $this->propertyRoomRepository->update(fillOnUndefined($params, 'room_id'), $insertRoomData); + + if ($insertRoomDataResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $roomId = $insertRoomDataResult['data']['id']; + $roomBedGroup = fillOnUndefined($params, 'room_bed_group', []); + $bedGroupIndex = 1; + $insertBedData = []; + + + $roomBedCriteria = [ + 'criteria' => [ + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ] + ]; + $roomBeds = $this->propertyRoomBedRepository->findByCriteria($roomBedCriteria); + + $roomBeds = collect($roomBeds)->keyBy('id')->keys()->all(); + if ($roomBeds) { + $destroyStatus = $this->propertyRoomBedRepository->destroy($roomBeds); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + $roomViewCriteria = [ + 'criteria' => [ + ['field' => 'room_id', 'condition' => '=', 'value' => $params['room_id']], + ] + ]; + $roomViews = $this->propertyRoomViewMappingRepository->findByCriteria($roomViewCriteria); + $roomViews = collect($roomViews)->keyBy('id')->keys()->all(); + + if ($roomViews) { + $destroyStatus = $this->propertyRoomViewMappingRepository->destroy($roomViews); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $isBedGroupInsert = true; + + if (count($roomBedGroup) == 1) { + if (count($roomBedGroup[0]) == 1) { + if (empty($roomBedGroup[0][0]['bed_type_id'])) { + $isBedGroupInsert = false; + } + + } + } + + + if ($isBedGroupInsert) { + + $roomBedGroups = []; + collect($roomBedGroup)->map(function ($value) use (&$roomBedGroups) { + $roomBedGroups[] = collect($value) + ->groupBy('bed_type_id') + ->map(function ($val) { + return $val->count(); + })->toArray(); + }); + + foreach ($roomBedGroups as $bedGroup) { + foreach ($bedGroup as $bedTypeId => $bedTypeCount) { + if (!empty($bedTypeId)) { + $insertBedData[] = + [ + 'room_id' => $roomId, + 'bed_group' => $bedGroupIndex, + 'count' => $bedTypeCount, + 'bed_type_id' => $bedTypeId, + "status" => fillOnUndefined($params, "status", 1), + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0), + 'created_at' => Carbon::now()->timestamp, + 'updated_at' => Carbon::now()->timestamp, + ]; + } + } + $bedGroupIndex++; + } + + $insertBedResult = $this->propertyRoomBedRepository->insert($insertBedData); + if ($insertBedResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + + if (!empty($params['room_view_type'])) { + + foreach ($params['room_view_type'] as $roomViewType) { + + $datas[] = [ + 'room_id' => $roomId, + 'room_view_type_id' => $roomViewType, + "created_by" => fillOnUndefined($params, "user_id", 0), + "updated_by" => fillOnUndefined($params, "user_id", 0), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $propertyRoomViewMappingResult = $this->propertyRoomViewMappingRepository->insert($datas); + + if ($propertyRoomViewMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } + + + //Connected Rooms + $syncPropertyConnectedRoomParam = [ + 'property_id' => $params['property_id'], + 'room_id' => $roomId, + 'connected_rooms' => $params['connected_rooms'], + 'user_id' => fillOnUndefined($params, 'user_id') + ]; + + + $syncPropertyConnectedRoom = $this->syncPropertyConnectedRoom($syncPropertyConnectedRoomParam); + + if ($syncPropertyConnectedRoom['status'] != 'success') { + throw new Exception($syncPropertyConnectedRoom['message']); + } + + + //$userData = $insertBedResult["data"]; + $response = [ + 'status' => true, + //'data' => $userData, + ]; + + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + } + + public function getPropertyRoomAndBed($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'id', 'condition' => '=', 'value' => $params['room_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomBedGroup', 'propertyRoomViewMapping'], + 'firstRow' => true + ]; + + $data = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number', 'description']); + $room = $data; + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + $descriptionLangContents = json_decode($data['description'], 1); + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + $room['description'] = $responseLangDescription; + + + $bedGroups = collect($room['property_room_bed_group'])->keyBy('bed_group')->keys(); + $group = []; + + foreach ($bedGroups as $bedGroup) { + $bedTypes = []; + $thisGroup = collect($room['property_room_bed_group'])->where('bed_group', '=', $bedGroup)->map(function ($bedItem) use ($bedGroup) { + $responseMapping = $bedItem; + return $responseMapping; + })->toArray(); + + foreach ($thisGroup as $groupItem) { + for ($i = 1; $i <= $groupItem['count']; $i++) { + $bedTypes[] = ['bed_type_id' => $groupItem['bed_type_id']]; + } + } + $group[] = $bedTypes; + } + $room['property_room_bed_group'] = $group; + $room['property_room_view_mapping'] = collect($room['property_room_view_mapping'])->keyBy('room_view_type_id')->keys()->all(); + + $newRoomMapping = $room; + + $response = [ + 'status' => true, + 'data' => $newRoomMapping, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getChannelRoomRateMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'with' => ['propertyRoomType', 'propertyRoomRateMapping.propertyRoomRateChannel', 'propertyRoomRateMapping.propertyRoomRate'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'exclude_occupancy', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + $return = []; + foreach ($roomData as $room) { + $item = $room; + $item['exclude_occupancy'] = json_decode($room['exclude_occupancy']); + if ($room['property_room_rate_mapping']) { + $roomRateMappings = $room['property_room_rate_mapping']; + $mapping = []; + foreach ($roomRateMappings as $roomRateMapping) { + $propertyRoomRateChannel = null; + if (isset($roomRateMapping['property_room_rate_channel'])) { + $propertyRoomRateChannel = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('room_rate_mapping_id', '=', $roomRateMapping['id']) + ->first(); + } + $mappingStatus = false; + if ($propertyRoomRateChannel) { + if ($propertyRoomRateChannel['status'] == 1) { + $mappingStatus = true; + } + } + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['min_stay'] = $roomRateMapping['property_room_rate']['min_stay']; + $roomRateMapping['max_stay'] = $roomRateMapping['property_room_rate']['max_stay']; + $roomRateMapping['is_selected'] = $mappingStatus; + $roomRateMapping['has_date'] = $propertyRoomRateChannel['has_date'] == 0 ? false : true; + $roomRateMapping['end_date'] = $propertyRoomRateChannel['end_date']; + $roomRateMapping['start_date'] = $propertyRoomRateChannel['start_date']; + unset($roomRateMapping['property_room_rate']); + unset($roomRateMapping['property_room_rate_channel']); + $mapping[] = $roomRateMapping; + } + $item['property_room_rate_mapping'] = $mapping; + $return[] = $item; + } + + } + + $collection = collect($return); + $sorted = $collection->sortBy('id')->values()->all(); + + $response = [ + 'status' => true, + 'data' => $sorted, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function inventoryRoomList($params = []) + { + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + isset($params['room_id']) ? ['field' => 'id', 'condition' => '=', 'value' => $params['room_id']] : null, + ], + 'with' => ['propertyRoomRateMapping.propertyRoomRate', 'propertyRoomRateMapping.propertyRoomRateChannel'], + "orderBy" => [ + ["field" => "id", "value" => "ASC"] + ], + ]; + + $roomData = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number']); + + return $roomData ? $roomData : []; + + } + + public function inventoryRoomRateData($params = []) + { + + $roomRatesCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $params['start_date']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['end_date']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'whereIn' => [ + ['field' => 'availability_type_id', 'value' => $params['availability_type_id']] + ] + ]; + + $roomRatePrice = $this->propertyRoomRatePriceRepository->findbyCriteria($roomRatesCriteria, ['id', 'property_id', 'property_room_id', 'room_rate_mapping_id', 'availability_type_id', 'channel_id', 'min_stay', 'max_stay', 'stop_sell', 'booking_on_request', 'date', 'amount', 'currency']); + $roomRatePrice = $roomRatePrice ? $roomRatePrice : []; + $priceArray = []; + foreach ($roomRatePrice as $price) { + $priceArray[$price['property_room_id'] . '|' . $price['room_rate_mapping_id'] . '|' . $price['availability_type_id'] . '|' . $price['date']] = $price; + } + + return $priceArray; + + } + + public function inventoryAvailabilityData($params = []) + { + + $availabilityTypeIds = implode(",", $params['availability_type_id']); + + $roomAvailability = []; + if(!is_null($params['start_date']) && !is_null($params['end_date'])) { + $roomAvailabilityCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'date', 'condition' => '>=', 'value' => $params['start_date']], + ['field' => 'date', 'condition' => '<=', 'value' => $params['end_date']], + ], + 'criteriaWhereRaw' => + [ + [ + 'query' => " ( `availability_type_id` = 3 OR ( `channel_id` = ? OR `channel_id` IS NULL ) AND `availability_type_id` IN ( " . $availabilityTypeIds . " ) )", + "binds" => [$params['channel_id']] + ] + ], + + ]; + + $roomAvailability = $this->propertyRoomAvailabilityRepository->findbyCriteria($roomAvailabilityCriteria); + } + + $availabilityArray = []; + foreach ($roomAvailability as $availability) { + + $availabilityArrayKey = $availability['property_room_id'] . '|' . $availability['room_rate_mapping_id'] . '|' . $availability['availability_type_id'] . '|' . $availability['channel_id'] . '|' . $availability['date']; + + $availabilityArray[$availabilityArrayKey][] = [ + 'id' => $availability['id'], + 'room_id' => $availability['property_room_id'], + 'room_rate_mapping_id' => $availability['room_rate_mapping_id'], + 'availability_type_id' => $availability['availability_type_id'], + 'channel_id' => $availability['channel_id'], + 'date' => $availability['date'], + 'availability' => $availability['availability'], + 'stop_sell' => $availability['stop_sell'], + ]; + } + + //Sistemdeki benzer id listesi, mysql null unique index hatası için + foreach ($availabilityArray as $availabilityKey => $availability) { + + if(count($availability) > 1) { + + $availabilityArray[$availabilityKey] = last($availability); + $otherAvailabilityRowIds = collect($availability)->whereNotIn('id', [$availabilityArray[$availabilityKey]['id']])->pluck('id')->toArray(); + $availabilityArray[$availabilityKey] = last($availability); + $availabilityArray[$availabilityKey]['otherIds'] = $otherAvailabilityRowIds; + } else { + $availabilityArray[$availabilityKey] = reset($availability); + } + + } + + return $availabilityArray; + + } + + public function getInventory($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $startDate = fillOnUndefinedAndEmpty($params, 'start_date', date('Y-m-d')); + $endDate = fillOnUndefinedAndEmpty($params, 'end_date', Carbon::parse($startDate)->addDay(15)->format('Y-m-d')); + + if ($endDate < $startDate) { + throw new ApiErrorException('date error'); + } + $diffInDays = Carbon::parse($startDate)->diffInDays($endDate); + + if ($diffInDays > 365) { + throw new ApiErrorException('Up to 1 yearly price updates can be made.'); //TODO: param extend + } + + $channelSetupTypes = $this->setChannelAvailabilityTypes(['property_id' => $params['property_id'], 'channel_id' => $params['channel_id']]); + if ($channelSetupTypes['status'] != 'success') { + throw new ApiErrorException($channelSetupTypes['message']); + } + $channelSetupTypes = $channelSetupTypes['data']; + $forGeneralId = $channelSetupTypes['forGeneralId']; + $forAvailabilityData = $channelSetupTypes['forAvailabilityData']; + $forPriceData = $channelSetupTypes['forPriceData']; + $getPriceDataIds = collect($forPriceData)->keyBy('id')->keys()->toArray(); + $getAvailabilityDataIds = collect($forAvailabilityData)->keyBy('id')->keys()->toArray(); + $getAvailabilityDataIds = array_unique(array_merge($forGeneralId, $getAvailabilityDataIds)); + + $generalAvailabilityCheckId = $forGeneralId[0]; + + + $roomData = $this->inventoryRoomList($params); + $priceRequest = [ + 'property_id' => $params['property_id'], + 'start_date' => $startDate, + 'end_date' => $endDate, + 'channel_id' => $params['channel_id'], + 'availability_type_id' => $getPriceDataIds, + ]; + $priceArray = $this->inventoryRoomRateData($priceRequest); + + $availabilityRequest = [ + 'property_id' => $params['property_id'], + 'start_date' => $startDate, + 'end_date' => $endDate, + 'channel_id' => $params['channel_id'], + 'availability_type_id' => $getAvailabilityDataIds, + ]; + + $availabilityArray = $this->inventoryAvailabilityData($availabilityRequest); + $quotaCollection = collect($availabilityArray) + ->where('availability_type_id', '=', 3); + + + $currencyCode = $params['channelData']['currency_code']; + + $return = []; + $keysForDevelopment = []; + + // Fill Rooms + foreach ($roomData as $room) { + $item = $room; + + $roomGeneralAvailability = collect($availabilityArray) + ->where('room_id', '=', $room['id']) + ->where('availability_type_id', '=', 1) + ->where('room_rate_mapping_id', '=', null) + ->where('channel_id', '=', null) + ->toArray(); + + // Fill General availability Keys + $startDate = Carbon::parse($params['start_date']); + $roomAvailability = []; + $quotaAvailability = []; + $roomStopSell = []; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $room['id'] . '||' . $generalAvailabilityCheckId . "||" . $startDate->format('Y-m-d'); + $responseKey = 'AVA_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + $responseKeyStopSell = 'STS_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + + $usedAvailability = $quotaCollection + ->where('date', '=', $startDate->format('Y-m-d')) + ->where('room_id', '=', $room['id']) + ->sum('availability'); + + $remainingAvailability = isset($roomGeneralAvailability[$checkKey]['availability']) ? ($roomGeneralAvailability[$checkKey]['availability'] - $usedAvailability) : 0; + + if (isset($roomGeneralAvailability[$checkKey])) { + $roomAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseKey, + 'value' => $roomGeneralAvailability[$checkKey]['availability'], + 'stop_sell' => $roomGeneralAvailability[$checkKey]['stop_sell'] + ]; + + $roomStopSell[$startDate->format('Y-m-d')] = [ + 'key' => $responseKeyStopSell, + 'value' => $roomGeneralAvailability[$checkKey]['stop_sell'], + ]; + + $keysForDevelopment[$responseKey] = $roomGeneralAvailability[$checkKey]['availability']; + $keysForDevelopment[$responseKeyStopSell] = $roomGeneralAvailability[$checkKey]['stop_sell']; + } else { + $roomAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $roomStopSell[$startDate->format('Y-m-d')] = [ + 'key' => $responseKeyStopSell, + 'value' => 0, + ]; + + $keysForDevelopment[$responseKey] = rand(1, 10); + $keysForDevelopment[$responseKeyStopSell] = 0; + } + + $responseRMKey = 'RMA_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + $quotaAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseRMKey, + 'value' => $remainingAvailability, + ]; + + + $startDate = $startDate->addDay(); + } + $item['room_availability'] = $roomAvailability; + $item['remaining_availability'] = $quotaAvailability; + $item['room_stop_sell'] = $roomStopSell; + + // Fill Room Rate Array + if (isset($room['property_room_rate_mapping'])) { + $roomRateMappings = $room['property_room_rate_mapping']; + if (isset($params['room_rate_mapping_id'])) { + $roomRateMappings = collect($roomRateMappings) + ->where('id', '=', $params['room_rate_mapping_id']) + ->toArray(); + } + $mapping = []; + foreach ($roomRateMappings as $roomRateMapping) { + + $checkMappingStatus = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('status', '=', 1) + ->first(); + + if ($checkMappingStatus) { + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['min_stay'] = $roomRateMapping['property_room_rate']['min_stay']; + $roomRateMapping['max_stay'] = $roomRateMapping['property_room_rate']['max_stay']; + $roomRateMapping['currency_code'] = $currencyCode; + unset($roomRateMapping['property_room_rate']); + foreach ($forPriceData as $roomRateAvailabilityCheckId) { + $startDate = Carbon::parse($params['start_date']); + $prices[$roomRateAvailabilityCheckId['id']]['name'] = $roomRateAvailabilityCheckId['name']; + $prices[$roomRateAvailabilityCheckId['id']]['language_key'] = $roomRateAvailabilityCheckId['language_key']; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $roomRateMapping['room_id'] . "|" . $roomRateMapping['id'] . "|" . $roomRateAvailabilityCheckId['id'] . "|" . $startDate->format('Y-m-d'); + $responsePRCKey = 'PRC_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + $responseSTSKey = 'STS_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + $responseMNSKey = 'MNS_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + + // Fill Price Keys + if (isset($priceArray[$checkKey])) { + $prices[$roomRateAvailabilityCheckId['id']]['price'][$startDate->format('Y-m-d')] = [ + 'key' => $responsePRCKey, + 'value' => $priceArray[$checkKey]['amount'], + 'stop_sell' => $priceArray[$checkKey]['stop_sell'], + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['stop_sell'][$startDate->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => $priceArray[$checkKey]['stop_sell'], + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['min_stay'][$startDate->format('Y-m-d')] = [ + 'key' => $responseMNSKey, + 'value' => $priceArray[$checkKey]['min_stay'], + ]; + + $keysForDevelopment[$responsePRCKey] = $priceArray[$checkKey]['amount']; + } else { + $prices[$roomRateAvailabilityCheckId['id']]['price'][$startDate->format('Y-m-d')] = [ + 'key' => $responsePRCKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['stop_sell'][$startDate->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => 0, + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['min_stay'][$startDate->format('Y-m-d')] = [ + 'key' => $responseMNSKey, + 'value' => 1, + ]; + + $keysForDevelopment[$responsePRCKey] = rand(1, 10); + } + + $startDate = $startDate->addDay(); + } + } + $roomRateMapping['prices'] = $prices; + $availabilities = []; + $prices = []; + foreach ($forAvailabilityData as $roomRateAvailabilityCheckId) { + $startDate = Carbon::parse($params['start_date']); + $availabilities[$roomRateAvailabilityCheckId['id']]['name'] = $roomRateAvailabilityCheckId['name']; + $availabilities[$roomRateAvailabilityCheckId['id']]['language_key'] = $roomRateAvailabilityCheckId['language_key']; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $roomRateMapping['room_id'] . "|" . $roomRateMapping['id'] . "|" . $roomRateAvailabilityCheckId['id'] . "|" . $params['channel_id'] . "|" . $startDate->format('Y-m-d'); + $responseAVAKey = 'AVA_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + + // Fill Availability Keys + if (isset($availabilityArray[$checkKey])) { + $availabilities[$roomRateAvailabilityCheckId['id']]['availability'][$startDate->format('Y-m-d')] = [ + 'key' => $responseAVAKey, + 'value' => $availabilityArray[$checkKey]['availability'], + ]; + $keysForDevelopment[$responseAVAKey] = $availabilityArray[$checkKey]['availability']; + } else { + $availabilities[$roomRateAvailabilityCheckId['id']]['availability'][$startDate->format('Y-m-d')] = [ + 'key' => $responseAVAKey, + 'value' => null, + ]; + $keysForDevelopment[$responseAVAKey] = rand(1, 10); + } + $startDate = $startDate->addDay(); + } + } + $roomRateMapping['availabilities'] = $availabilities; + $mapping[] = $roomRateMapping; + } + + + } + $item['property_room_rate_mapping'] = $mapping; + if ($mapping) { + $return[] = $item; + } + } + + } + // log::debug(json_encode($keysForDevelopment)); + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function setChannelAvailabilityTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + // Get Channel Setup + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'channel_id')], + ], + 'firstRow' => 1 + ]; + + $channelSetupData = $this->propertyChannelMappingRepository->findByCriteria($criteria); + if (!$channelSetupData) { + throw new ApiErrorException('Channel mapping not found'); + } + + $propertyChannelSetupTypeId = $channelSetupData['property_availability_type_id']; + // Get All Availability types + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $allAvailabilityTypes = $this->propertyAvailabilityTypeRepository->findByCriteria($criteria); + if (!$allAvailabilityTypes) { + throw new ApiErrorException('Availability types not found'); + } + + switch ($propertyChannelSetupTypeId) { + default : + $forGeneralId = [1]; + $forAvailabilityId = []; + $forPriceId = [1]; + break; + case 2: + $forGeneralId = [1]; + $forAvailabilityId = [2]; + $forPriceId = [2]; + break; + case 3: + $forGeneralId = [1]; + $forAvailabilityId = [3]; + $forPriceId = [1, 3]; + break; + } + + $forGeneralData = $forGeneralId ? collect($allAvailabilityTypes)->whereIn('id', $forGeneralId)->toArray() : []; + $forAvailabilityData = $forGeneralId ? collect($allAvailabilityTypes)->whereIn('id', $forAvailabilityId)->toArray() : []; + $forPriceData = $forGeneralId ? collect($allAvailabilityTypes)->whereIn('id', $forPriceId)->toArray() : []; + + $returnData = [ + 'forGeneralId' => $forGeneralId, + 'forGeneralData' => $forGeneralData, + 'forAvailabilityData' => $forAvailabilityData, + 'forPriceData' => $forPriceData, + 'channelAvailabilityWorkingType' => $propertyChannelSetupTypeId + ]; + + $response = [ + 'status' => true, + 'data' => $returnData, + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function roomIncludeOccupancies($params = []) + { + $occupancies = []; + for ($i = 1; $i <= $params['max_adult']; $i++) { + for ($j = 0; $j <= $params['max_child']; $j++) { + $paxTotal = $i + $j; + if ($paxTotal > $params['max_occupancy']) { + continue; + } + $occupancy = str_repeat('A', $i) . str_repeat('C', $j); + if (array_search($occupancy, $params['exclude_occupancy']) > -1) { + continue; + } + $occupancies[] = $occupancy; + } + } + return $occupancies; + } + + public function getGroupInventory($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $startDate = fillOnUndefinedAndEmpty($params, 'start_date', date('Y-m-d')); + $endDate = fillOnUndefinedAndEmpty($params, 'end_date', Carbon::parse($startDate)->addDay(15)->format('Y-m-d')); + + if ($endDate < $startDate) { + throw new ApiErrorException('date error'); + } + $diffInDays = Carbon::parse($startDate)->diffInDays($endDate); + if ($diffInDays > 15) { + throw new ApiErrorException('date error'); + } + + + $roomData = $this->inventoryRoomList($params); + + $priceRequest = [ + 'property_id' => $params['property_id'], + 'start_date' => $startDate, + 'end_date' => $endDate, + 'channel_id' => $params['channel_id'], + 'availability_type_id' => 1, + ]; + + $availabilityRequest = [ + 'property_id' => $params['property_id'], + 'start_date' => $startDate, + 'end_date' => $endDate, + 'channel_id' => $params['channel_id'], + 'availability_type_id' => 1, + ]; + + $availabilityArray = $this->inventoryAvailabilityData($availabilityRequest); + $quotaCollection = collect($availabilityArray) + ->where('availability_type_id', '=', 3); + + + $currencyCode = $params['channelData']['currency_code']; + + $return = []; + $keysForDevelopment = []; + + // Fill Rooms + foreach ($roomData as $room) { + $item = $room; + + $roomGeneralAvailability = collect($availabilityArray) + ->where('room_id', '=', $room['id']) + ->where('availability_type_id', '=', 1) + ->where('room_rate_mapping_id', '=', null) + ->where('channel_id', '=', null) + ->toArray(); + + // Fill General availability Keys + $startDate = Carbon::parse($params['start_date']); + $roomAvailability = []; + $quotaAvailability = []; + $roomStopSell = []; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $room['id'] . '||' . $generalAvailabilityCheckId . "||" . $startDate->format('Y-m-d'); + $responseKey = 'AVA_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + $responseKeyStopSell = 'STS_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + + $usedAvailability = $quotaCollection + ->where('date', '=', $startDate->format('Y-m-d')) + ->where('room_id', '=', $room['id']) + ->sum('availability'); + + $remainingAvailability = isset($roomGeneralAvailability[$checkKey]['availability']) ? ($roomGeneralAvailability[$checkKey]['availability'] - $usedAvailability) : 0; + + if (isset($roomGeneralAvailability[$checkKey])) { + $roomAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseKey, + 'value' => $roomGeneralAvailability[$checkKey]['availability'], + 'stop_sell' => $roomGeneralAvailability[$checkKey]['stop_sell'] + ]; + + $roomStopSell[$startDate->format('Y-m-d')] = [ + 'key' => $responseKeyStopSell, + 'value' => $roomGeneralAvailability[$checkKey]['stop_sell'], + ]; + + $keysForDevelopment[$responseKey] = $roomGeneralAvailability[$checkKey]['availability']; + $keysForDevelopment[$responseKeyStopSell] = $roomGeneralAvailability[$checkKey]['stop_sell']; + } else { + $roomAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $roomStopSell[$startDate->format('Y-m-d')] = [ + 'key' => $responseKeyStopSell, + 'value' => 0, + ]; + + $keysForDevelopment[$responseKey] = rand(1, 10); + $keysForDevelopment[$responseKeyStopSell] = 0; + } + + $responseRMKey = 'RMA_' . $generalAvailabilityCheckId . '_' . $room['id'] . '_' . '0' . '_' . $startDate->format('Ymd'); + $quotaAvailability[$startDate->format('Y-m-d')] = [ + 'key' => $responseRMKey, + 'value' => $remainingAvailability, + ]; + + + $startDate = $startDate->addDay(); + } + $item['room_availability'] = $roomAvailability; + $item['remaining_availability'] = $quotaAvailability; + $item['room_stop_sell'] = $roomStopSell; + + // Fill Room Rate Array + if (isset($room['property_room_rate_mapping'])) { + $roomRateMappings = $room['property_room_rate_mapping']; + if (isset($params['room_rate_mapping_id'])) { + $roomRateMappings = collect($roomRateMappings) + ->where('id', '=', $params['room_rate_mapping_id']) + ->toArray(); + } + $mapping = []; + foreach ($roomRateMappings as $roomRateMapping) { + + $checkMappingStatus = collect($roomRateMapping['property_room_rate_channel']) + ->where('channel_id', '=', $params['channel_id']) + ->where('status', '=', 1) + ->first(); + + if ($checkMappingStatus) { + $roomRateMapping['name'] = $roomRateMapping['property_room_rate']['name']; + $roomRateMapping['min_stay'] = $roomRateMapping['property_room_rate']['min_stay']; + $roomRateMapping['max_stay'] = $roomRateMapping['property_room_rate']['max_stay']; + $roomRateMapping['currency_code'] = $currencyCode; + unset($roomRateMapping['property_room_rate']); + foreach ($forPriceData as $roomRateAvailabilityCheckId) { + $startDate = Carbon::parse($params['start_date']); + $prices[$roomRateAvailabilityCheckId['id']]['name'] = $roomRateAvailabilityCheckId['name']; + $prices[$roomRateAvailabilityCheckId['id']]['language_key'] = $roomRateAvailabilityCheckId['language_key']; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $roomRateMapping['room_id'] . "|" . $roomRateMapping['id'] . "|" . $roomRateAvailabilityCheckId['id'] . "|" . $startDate->format('Y-m-d'); + $responsePRCKey = 'PRC_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + $responseSTSKey = 'STS_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + $responseMNSKey = 'MNS_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + + // Fill Price Keys + if (isset($priceArray[$checkKey])) { + $prices[$roomRateAvailabilityCheckId['id']]['price'][$startDate->format('Y-m-d')] = [ + 'key' => $responsePRCKey, + 'value' => $priceArray[$checkKey]['amount'], + 'stop_sell' => $priceArray[$checkKey]['stop_sell'], + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['stop_sell'][$startDate->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => $priceArray[$checkKey]['stop_sell'], + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['min_stay'][$startDate->format('Y-m-d')] = [ + 'key' => $responseMNSKey, + 'value' => $priceArray[$checkKey]['min_stay'], + ]; + + $keysForDevelopment[$responsePRCKey] = $priceArray[$checkKey]['amount']; + } else { + $prices[$roomRateAvailabilityCheckId['id']]['price'][$startDate->format('Y-m-d')] = [ + 'key' => $responsePRCKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['stop_sell'][$startDate->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => 0, + ]; + + $prices[$roomRateAvailabilityCheckId['id']]['min_stay'][$startDate->format('Y-m-d')] = [ + 'key' => $responseMNSKey, + 'value' => 1, + ]; + + $keysForDevelopment[$responsePRCKey] = rand(1, 10); + } + + $startDate = $startDate->addDay(); + } + } + $roomRateMapping['prices'] = $prices; + $availabilities = []; + $prices = []; + foreach ($forAvailabilityData as $roomRateAvailabilityCheckId) { + $startDate = Carbon::parse($params['start_date']); + $availabilities[$roomRateAvailabilityCheckId['id']]['name'] = $roomRateAvailabilityCheckId['name']; + $availabilities[$roomRateAvailabilityCheckId['id']]['language_key'] = $roomRateAvailabilityCheckId['language_key']; + for ($i = 0; $i <= $diffInDays; $i++) { + $checkKey = $roomRateMapping['room_id'] . "|" . $roomRateMapping['id'] . "|" . $roomRateAvailabilityCheckId['id'] . "|" . $params['channel_id'] . "|" . $startDate->format('Y-m-d'); + $responseAVAKey = 'AVA_' . $roomRateAvailabilityCheckId['id'] . '_' . $roomRateMapping['room_id'] . '_' . $roomRateMapping['id'] . '_' . $startDate->format('Ymd'); + + // Fill Availability Keys + if (isset($availabilityArray[$checkKey])) { + $availabilities[$roomRateAvailabilityCheckId['id']]['availability'][$startDate->format('Y-m-d')] = [ + 'key' => $responseAVAKey, + 'value' => $availabilityArray[$checkKey]['availability'], + ]; + $keysForDevelopment[$responseAVAKey] = $availabilityArray[$checkKey]['availability']; + } else { + $availabilities[$roomRateAvailabilityCheckId['id']]['availability'][$startDate->format('Y-m-d')] = [ + 'key' => $responseAVAKey, + 'value' => null, + ]; + $keysForDevelopment[$responseAVAKey] = rand(1, 10); + } + $startDate = $startDate->addDay(); + } + } + $roomRateMapping['availabilities'] = $availabilities; + $mapping[] = $roomRateMapping; + } + + + } + $item['property_room_rate_mapping'] = $mapping; + if ($mapping) { + $return[] = $item; + } + } + + } + // log::debug(json_encode($keysForDevelopment)); + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getParamsForPdfInvenyory($params = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $criteria = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $params['token']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $mapping = $this->propertyChannelMappingRepository->findbyCriteria($criteria); + if (!isset($mapping)) { + throw new ApiErrorException('Channel mapping not found'); + } + + + $startDate = date('Y-m') . "-01"; + + $return = [ + 'property_id' => $mapping['property_id'], + 'channel_id' => $mapping['channel_id'], + 'start_date' => $startDate, + 'end_date' => Carbon::parse($startDate)->addMonth(6)->format('Y-m-d'), + ]; + + + $response = [ + 'status' => true, + 'data' => $return, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function syncPropertyConnectedRoom($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $deletePropertyRoomConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ] + ]; + + $deletePropertyRoomConnected = $this->propertyRoomConnectedRepository->delete($deletePropertyRoomConnectedCriteria); + + if (!empty($params['connected_rooms'])) { + + if (in_array($params['room_id'], $params['connected_rooms'])) { + throw new ApiErrorException('The room itself cannot be defined as a connected room.'); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'whereIn' => [ + ['field' => 'id', 'value' => $params['connected_rooms']], + ] + ]; + + $rooms = $this->propertyRoomRepository->findByCriteria($criteria, ['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'room_size', 'room_size_type', 'room_type_count', 'room_count', 'bathroom_count', 'toilet_count', 'lounge_count', 'max_child_number', 'description']); + + if (count($rooms) != count($params['connected_rooms'])) { + throw new ApiErrorException('Connected rooms are not available for this property.'); + } + + foreach ($rooms as $connectedRoom) { + + $connectedRoomCreateParam = [ + 'property_id' => $params['property_id'], + 'room_id' => $params['room_id'], + 'connected_room_id' => $connectedRoom['id'], + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + ]; + + $connectedRoomCreate = $this->propertyRoomConnectedRepository->create($connectedRoomCreateParam); + + if ($connectedRoomCreate['status'] != 'success') { + throw new Exception('Could not add connecting rooms.'); + } + + } + + } + + $response = [ + 'status' => true + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyRoomSizeTypeService.php b/app/Core/Service/PropertyRoomSizeTypeService.php new file mode 100644 index 0000000..0a5664d --- /dev/null +++ b/app/Core/Service/PropertyRoomSizeTypeService.php @@ -0,0 +1,44 @@ +propertyRoomSizeTypeRepository = $propertyRoomSizeTypeRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomSizeTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/PropertyRoomTypeService.php b/app/Core/Service/PropertyRoomTypeService.php new file mode 100644 index 0000000..a91a1a8 --- /dev/null +++ b/app/Core/Service/PropertyRoomTypeService.php @@ -0,0 +1,252 @@ +propertyRoomTypeRepository = $propertyRoomTypeRepository; + $this->propertyRoomRepository = $propertyRoomRepository; + + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyRoomTypeRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomTypeRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRoomTypeRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyRoomTypeRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + public function getPropertyRoomTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + ]; + + $data = $this->propertyRoomTypeRepository->findByCriteria($criteria, ['id', 'name', 'language_key']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyMappedRoomTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $propertyRoomCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ] + ]; + $propertyRoomData = $this->propertyRoomRepository->findByCriteria($propertyRoomCriteria, ['id', 'name', 'room_type_id']); + $propertyRoomData = $propertyRoomData ? $propertyRoomData : []; + $mappedRoomTypes = collect($propertyRoomData)->keyBy("room_type_id")->keys()->toArray(); + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'whereIn' => [ + ['field' => 'id', 'value' => $mappedRoomTypes] + ], + ]; + + $roomTypeData = $this->propertyRoomTypeRepository->findByCriteria($criteria, ['id', 'name', 'language_key']); + + $response = [ + 'status' => true, + 'data' => $roomTypeData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addPropertyRoomTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + ]; + + $data = $this->propertyRoomTypeRepository->findByCriteria($criteria, ['id', 'name']); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyRoomViewTypeService.php b/app/Core/Service/PropertyRoomViewTypeService.php new file mode 100644 index 0000000..dc3180b --- /dev/null +++ b/app/Core/Service/PropertyRoomViewTypeService.php @@ -0,0 +1,58 @@ +propertyRoomViewTypeRepository = $propertyRoomViewTypeRepository; + + } + + public function getPropertyRoomViewTypes($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRoomViewTypes = $this->propertyRoomViewTypeRepository->findByCriteria($params, ['id', 'name', 'language_key']); + + if (empty($propertyRoomViewTypes)) { + throw new ApiErrorException(lang('Property Room View Type Not Found.')); + } + + $response = [ + 'status' => true, + 'data' => $propertyRoomViewTypes, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertyService.php b/app/Core/Service/PropertyService.php new file mode 100644 index 0000000..6bad724 --- /dev/null +++ b/app/Core/Service/PropertyService.php @@ -0,0 +1,690 @@ +request = $request; + $this->userPropertyMappingService = $userPropertyMappingService; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + $this->propertyRepository = $propertyRepository; + $this->propertySearchValidator = $propertySearchValidator; + $this->propertyCreateValidator = $propertyCreateValidator; + $this->permissionService = $permissionService; + $this->propertyUpdateValidator = $propertyUpdateValidator; + $this->languageService = $languageService; + $this->notificationService = $notificationService; + $this->restClient = $restClient; + $this->minimumAgePolicies = [ + [ + 'value' => 0, + 'language_key' => 'enw-input-all_ages' + ], + + ]; + $this->propertyLanguageSpokenRepository = $propertyLanguageSpokenRepository; + + for ($i = 1; $i <= 18; $i++) { + $this->minimumAgePolicies[] = [ + 'value' => $i, + 'language_key' => "{$i}+", + ]; + } + } + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->propertyRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyData = + [ + "name" => fillOnUndefined($param, "name"), + "country" => fillOnUndefined($param, "country"), + "property_type_id" => fillOnUndefined($param, "property_type_id"), + "chain_id" => fillOnUndefined($param, "chain_id"), + "rating" => fillOnUndefined($param, "rating"), + "official_name" => fillOnUndefined($param, "official_name"), + "tax_office" => fillOnUndefined($param, "tax_office"), + "tax_number" => fillOnUndefined($param, "tax_number"), + "currency_type" => fillOnUndefined($param, "currency_type"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + + ]; + + $validationResult = $this->propertyCreateValidator->validate($propertyData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $propertyCreateResult = $this->propertyRepository->create($propertyData); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $propertyCreateResult["data"] + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->propertyRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getProperty($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + //['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyLanguageSpoken'], + 'firstRow' => true + + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $propertyData = $this->select($propertyRequest, $getPropertyFields); + + $propertyLanguageSpokenArray = collect($propertyData['data']['property_language_spoken'])->keyBy('language_code')->keys()->all(); + $languageSpokenRequest['selected_languages'] = $propertyLanguageSpokenArray; + + $languageSpokenData = $this->languageService->propertyLanguageSpoken($languageSpokenRequest); + if ($languageSpokenData['status'] != 'success') { + throw new ApiErrorException($languageSpokenData['message']); + } + + if ($propertyData['data']['chain_id'] === NULL) { + $propertyData['data']['chain_id'] = self::CHAIN_ID; + } + $return['property_info'] = $propertyData['data']; + unset($return['property_info']['property_language_spoken']); + $return['property_info']['has_locale_name'] = false; + $return['property_language_spoken'] = $languageSpokenData['data']; + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + + if (isset($propertyAdditionalInfo['data'])) { + $return['additional_info'] = $propertyAdditionalInfo['data']; + + if (isset($return['additional_info']['locale_name']) && $return['additional_info']['locale_name']) { + $return['property_info']['has_locale_name'] = true; + } + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property' => $return, 'minimum_age_policies' => $this->minimumAgePolicies]]; + + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function getPropertyList($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'user_id', 'condition' => '=', 'value' => $params['user_id']], + ], + 'with' => ['property.defaultPropertyPhoto'] + ]; + $propertyData = $this->userPropertyMappingService->select($propertyRequest); + + if ($propertyData['status'] != 'success') { + throw new ApiErrorException(lang('Property data not loaded')); + } + + $propertyList = collect($propertyData['data'])->map(function ($value) use ($params) { + + $menuParams = [ + 'user_id' => $params['user_id'], + 'property_id' => $value['property']['id'], + 'locale' => $params['locale'] + ]; + + if (is_array($value['property']) && $value['property']['status'] != 0) { + $defaultPhoto = isset($value['property']['default_property_photo']) ? $value['property']['default_property_photo'] : null; + + $photoUrlThumbFilePath = '/assets/img/placeholder.png'; + if (isset($defaultPhoto['photo_name'])) { + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}"; + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}"; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_thumbnail.{$defaultPhoto['file_ext']}"; + } + } + + + return $value['property'] = [ + 'id' => $value['property']['id'], + 'name' => $value['property']['name'], + 'default_photo' => $photoUrlThumbFilePath, + 'property_menu' => $this->permissionService->getMenuTreeForUser($menuParams) + ]; + } + })->toArray(); + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_list' => $propertyList]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function propertyUpdate($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + DB::beginTransaction(); + $return = []; + + $propertyData = fillOnUndefined($params, 'property_info'); + + $validationResult = $this->propertyUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $updateData = []; + $validateKeys = ['name', 'property_type_id', 'chain_id', 'rating', 'currency_type', 'currency_type', 'checkin_time', 'checkout_time', 'official_name', 'tax_office', 'tax_number', 'country', 'content_code']; + foreach ($propertyData as $key => $value) { + + if (!in_array($key, $validateKeys)) { + throw new ApiErrorException(lang('Error Columns')); + } + $updateData[$key] = $value; + } + + if ($updateData) { + $updateData['updated_by'] = $params['user_id']; + $updateData['updated_at'] = time(); + } + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'firstRow' => true + ]; + + $propertyData = $this->propertyRepository->findByCriteria($propertyRequest, ['status']); + + if (!empty($propertyData)) { + if ($propertyData['status'] === 2) { + $updateData['status'] = 1; + } + } + + $propertyUpdateResult = $this->update($params['property_id'], $updateData); + + if ($propertyUpdateResult['status'] != 'success') { + throw new ApiErrorException($propertyUpdateResult['message']); + } + + $return['property_info'] = $propertyUpdateResult['data']; + $return['property_info']['has_locale_name'] = false; + + + $propertyLanguageSpokeRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + ]; + $propertyLanguageEraseData = $this->propertyLanguageSpokenRepository->findByCriteria($propertyLanguageSpokeRequest, ['id']); + $propertyLanguageEraseData = $propertyLanguageEraseData ? $propertyLanguageEraseData : []; + $deleteThisIds = collect($propertyLanguageEraseData)->keyBy('id')->keys()->all(); + + if ($deleteThisIds) { + $deleteThisArray = $this->propertyLanguageSpokenRepository->destroy($deleteThisIds); + if ($deleteThisArray['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $insertPropertyLanguageSpoken = []; + + foreach ($params['property_language_spoken'] as $langCode) { + + $insertItem = [ + 'property_id' => $params['property_id'], + 'language_code' => $langCode, + 'status' => 1, + 'created_by' => $params['user_id'], + 'updated_by' => $params['user_id'], + 'created_at' => time(), + 'updated_at' => time(), + ]; + $insertPropertyLanguageSpoken[] = $insertItem; + + } + + $insertRoomRatePrices = $this->propertyLanguageSpokenRepository->insert($insertPropertyLanguageSpoken); + if ($insertRoomRatePrices['status'] != 'success') { + throw new ApiErrorException($insertRoomRatePrices['message']); + } + + + $updateAdditionalInfoData = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'additional_info' => fillOnUndefined($params, 'additional_info'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $params['user_id'], + ]; + + $updateAdditionalInfo = $this->propertyAdditionalInfoService->updateOrCreatePropertyAdditionalInfo($updateAdditionalInfoData); + + if ($updateAdditionalInfo['status'] != 'success') { + throw new ApiErrorException($updateAdditionalInfo['message']); + } + + if (!$params['has_locale_name']) { + + $deleteRequest = [ + 'key_array' => ['locale_name_language', 'locale_name'], + 'property_id' => $params['property_id'] + ]; + $this->propertyAdditionalInfoService->deletePropertyAdditionalInfos($deleteRequest); + } + + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + + + if (isset($propertyAdditionalInfo['data'])) { + $return['additional_info'] = $propertyAdditionalInfo['data']; + + if (isset($return['additional_info']['locale_name']) && $return['additional_info']['locale_name_language']) { + $return['property_info']['has_locale_name'] = true; + } + + } + + $languageSpokenRequest['selected_languages'] = $params['property_language_spoken'] ? $params['property_language_spoken'] : []; + + $languageSpokenData = $this->languageService->propertyLanguageSpoken($languageSpokenRequest); + if ($languageSpokenData['status'] != 'success') { + throw new ApiErrorException($languageSpokenData['message']); + } + $return['property_language_spoken'] = $languageSpokenData['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property' => $return]]; + DB::commit(); + + } catch + (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + //PUSH NOTIFICATION + $newBookingNotificationParam = ['property_id' => $params['property_id']]; + $this->notificationService->sendLogNotification($newBookingNotificationParam); + //PUSH NOTIFICATION + } + + + return output($response); + } + + public function getPropertyDetail($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + $return = []; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyType', 'propertyChain'], + 'firstRow' => true + + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type']; + $propertyData = $this->select($propertyRequest, $getPropertyFields); + + $return = $propertyData['data']; + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + + if (isset($propertyAdditionalInfo['data'])) { + $return['additional_info'] = $propertyAdditionalInfo['data']; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function kommoApiPost($method, $payloadJson, $token = null) + { + + $response = ['status' => false, 'message' => '', 'data' => null]; + try { + + $headers['Content-Type'] = 'application/json'; + $headers['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImE5ZWMxNDUwMjM0NDQ5NWZiZjY0YjVmNTBkZWQzODMzYWQyMGM3NGZmYWIyZWIyMmE4NTg5ZjBlMjk5Njg4NWQzYzI1MGUyMmEzMzM0Njc2In0.eyJhdWQiOiJiM2E4ZmI2NC0yODRkLTQ2ODctYTFhMC0yMGMwMDY0MWEwN2YiLCJqdGkiOiJhOWVjMTQ1MDIzNDQ0OTVmYmY2NGI1ZjUwZGVkMzgzM2FkMjBjNzRmZmFiMmViMjJhODU4OWYwZTI5OTY4ODVkM2MyNTBlMjJhMzMzNDY3NiIsImlhdCI6MTc2NjY3NDY2MiwibmJmIjoxNzY2Njc0NjYyLCJleHAiOjE4OTMzNjk2MDAsInN1YiI6IjE0NDY4NTAwIiwiZ3JhbnRfdHlwZSI6IiIsImFjY291bnRfaWQiOjM1NDc3MTE5LCJiYXNlX2RvbWFpbiI6ImtvbW1vLmNvbSIsInZlcnNpb24iOjIsInNjb3BlcyI6WyJjcm0iLCJmaWxlcyIsImZpbGVzX2RlbGV0ZSIsIm5vdGlmaWNhdGlvbnMiLCJwdXNoX25vdGlmaWNhdGlvbnMiXSwiaGFzaF91dWlkIjoiNmZlNzhmYjYtNDQ4ZC00MGNiLWE2ZDYtNzg5Y2MyYTIyNzBkIiwidXNlcl9mbGFncyI6MCwiYXBpX2RvbWFpbiI6ImFwaS1nLmtvbW1vLmNvbSJ9.dUcX6NUXRZOK0MhywNloo_5o6dFfjTLSDj9LinVNS2c66NHlsEmWRg2h8kP0NB75VeiYVP624kQMMMztR4trcjQuvvNElBWEw5kCAlIUMD4IZDmyduSvZ6JGYnC24ukVnH6voMW7uN3wyGgBrI3EOsrExAZwP10sQZBQNDqeUBb8ZWFXMaBiFeWEpoZpcaG_DMNgD3BEYLeYSsjSwUsOOyaLpKroJktrYnFjIgdH4qhoImpXmM0rL3z_VXpz85X-7sVp7vLwsyZH48yrReDIL1RQu__sIQVPr40_k8XbQ2vLQLYSFjT52Hajh98IdGpb7DgQUEKVF0z_hByDXo5PJQ'; + + $serviceUrl = 'https://extranetwork.kommo.com/api/v4/' . $method; + + $result = $this->restClient->post($serviceUrl, + [ + 'headers' => $headers, + 'body' => json_encode($payloadJson) + ] + ); + + + $getResponseBody = $result->getBody()->getContents(); + $getResponse = json_decode($getResponseBody, 1); + + $response = [ + 'status' => true, + 'data' => $getResponse, + //'message' => $getResponse['message'] + ]; + + } catch (RequestException $e) { + $getResponse = json_decode($e->getResponse()->getBody()->getContents(), 1); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $getResponse['message']; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function kommoCreateLead($params) + { + + $response = ['status' => false, 'message' => '', 'data' => null]; + try { + + $kommoCompanyParam = [ + [ + "name" => $params['property'], + "custom_fields_values" => [ + [ + "field_code" => "PHONE", + "values" => [ + [ + "value" => $params['phone_number'] + ] + ] + ], + [ + "field_code" => "EMAIL", + "values" => [ + [ + "value" => $params['email'] + ] + ] + ] + ] + ] + ]; + + $kommoCompany = $this->kommoApiPost('companies', $kommoCompanyParam); + $kommoCompany = $kommoCompany['status'] == 'success' && !empty($kommoCompany['status']) ? $kommoCompany['data'] : null; + $kommoCompanyId = reset($kommoCompany['_embedded']['companies'])['id']; + + $kommoContactParam = [ + [ + "name" => $params['name_surname'], + "custom_fields_values" => [ + [ + "field_code" => "PHONE", + "values" => [ + [ + "value" => $params['phone_number'] + ] + ] + ], + [ + "field_code" => "EMAIL", + "values" => [ + [ + "value" => $params['email'] + ] + ] + ] + ] + ] + ]; + + $kommoContact = $this->kommoApiPost('contacts', $kommoContactParam); + $kommoContact = $kommoContact['status'] == 'success' && !empty($kommoContact['status']) ? $kommoContact['data'] : null; + $kommoContactId = reset($kommoContact['_embedded']['contacts'])['id']; + + $kommoLeadParam = [ + [ + "name" => $params['property'], + "pipeline_id" => 12343583, + "status_id" => 95388747, + "_embedded" => [ + "companies" => [ + [ + "id" => $kommoCompanyId + ] + ], + "contacts" => [ + [ + "id" => $kommoContactId + ] + ] + ], + "custom_fields_values" => [ + [ + "field_id" => 2522776, + "values" => [ + [ + "value" => "Web Form" + ] + ] + ] + ] + ] + ]; + + $kommoLead = $this->kommoApiPost('leads', $kommoLeadParam); + $kommoLead = $kommoLead['status'] == 'success' && !empty($kommoLead['status']) ? $kommoLead['data'] : null; + + + $response = [ + 'status' => true, + 'data' => $kommoLead + ]; + + + } catch (RequestException $e) { + $getResponse = json_decode($e->getResponse()->getBody()->getContents(), 1); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $getResponse['message']; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + +} diff --git a/app/Core/Service/PropertySummaryService.php b/app/Core/Service/PropertySummaryService.php new file mode 100644 index 0000000..5decad7 --- /dev/null +++ b/app/Core/Service/PropertySummaryService.php @@ -0,0 +1,255 @@ +propertyRepository = $propertyRepository; + $this->bookingRepository = $bookingRepository; + $this->propertySummaryRepository = $propertySummaryRepository; + + $commissionChannelCategoryMapping = [ + 2 => 'commission_offline', + 3 => 'commission', + 4 => 'commission_channel', + ]; + + $this->commissionChannelCategoryMapping = $commissionChannelCategoryMapping; + + $this->exchangeCurrencyCode = 'EUR'; + } + + public function calculatePeriodCommission($propertyId, $type, $periodStartDate, $periodFinishDate) + { + + $propertyDetailCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + //['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBookingEngines.channel'], + 'firstRow' => true + ]; + + $propertyDetail = $this->propertyRepository->findByCriteria($propertyDetailCriteria); + + $propertyCreateTime = Carbon::parse($propertyDetail['invoice_start_date'])->toDateString(); + + if ($propertyCreateTime > $periodFinishDate) { + throw new ApiErrorException('Property not ready for transaction: ' . $propertyCreateTime . ' - ' . $propertyDetail['name']); + } + + $channelBaseCommission = []; + foreach ($propertyDetail['property_booking_engines'] as $propertyBookingEngine) { + + $commissionRateParam = isset($this->commissionChannelCategoryMapping[$propertyBookingEngine['channel']['channel_category_id']]) ? $this->commissionChannelCategoryMapping[$propertyBookingEngine['channel']['channel_category_id']] : 'commission'; + $commissionRateRate = $propertyDetail[$commissionRateParam]; + + + $bookingListCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyBookingEngine['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $propertyBookingEngine['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => + [ + ['field' => 'status', 'value' => [1, 3]] + ] + ]; + + if ($type == 1) { + $bookingListCriteria['criteria'][] = ['field' => 'checkout_date', 'condition' => '>=', 'value' => $periodStartDate]; + $bookingListCriteria['criteria'][] = ['field' => 'checkout_date', 'condition' => '<', 'value' => $periodFinishDate]; + } + + if ($type == 2) { + $bookingListCriteria['criteria'][] = ['field' => 'reservation_time', 'condition' => '>=', 'value' => Carbon::parse($periodStartDate, 'UTC')->timestamp]; + $bookingListCriteria['criteria'][] = ['field' => 'reservation_time', 'condition' => '<', 'value' => Carbon::parse($periodFinishDate, 'UTC')->timestamp]; + } + + $bookingList = $this->bookingRepository->findByCriteria($bookingListCriteria, ['id', 'property_id', 'channel_id', 'total', 'currency_code', 'checkin_date', 'checkout_date']); + + $bookingListCollect = collect($bookingList)->groupBy('currency_code')->map(function ($group) { + return [ + 'total' => $group->sum('total') + ]; + }); + + $bookingListCollect = $bookingListCollect ? $bookingListCollect->toArray() : []; + + $exchangeRate = 1; + $exchangeRateOriginal = 1; + $exchangeRateDate = Carbon::parse($periodStartDate)->lastOfMonth()->toDateString(); + foreach ($bookingListCollect as $bookingCurrency => $bookingTotal) { + + if ($bookingCurrency != $this->exchangeCurrencyCode) { + $exchangeRateCheck = CurrencyRates::where('currency_code', $bookingCurrency) + ->where('exc_currency_code', $this->exchangeCurrencyCode) + ->where('date', $exchangeRateDate) + ->first(); + + if ($exchangeRateCheck) { + $exchangeRateCheck = $exchangeRateCheck->toArray(); + + } else { + $exchangeRateCheck = CurrencyRates::where('currency_code', $bookingCurrency) + ->where('exc_currency_code', $this->exchangeCurrencyCode) + ->where('date', '<', $exchangeRateDate) + ->orderBy('date', 'DESC') + ->first()->toArray(); + } + + $exchangeRate = $exchangeRateCheck['rate']; + $exchangeRateDate = $exchangeRateCheck['date']; + + } + + $bookingTotalWithExchange = $bookingTotal['total'] * $exchangeRate; + $bookingCommissionWithExchange = $bookingTotalWithExchange * $commissionRateRate / 100; + + $channelBaseCommission[$propertyBookingEngine['channel_id']][$bookingCurrency] = [ + 'count' => count($bookingList), + 'total' => (float)number_format($bookingTotal['total'], '4', '.', ''), + 'exchangeRate' => $exchangeRate, + 'exchangeRateDate' => $exchangeRateDate, + 'exchangeData' => [ + 'total' => (float)number_format($bookingTotalWithExchange, '4', '.', ''), + 'commission' => (float)number_format($bookingCommissionWithExchange, '4', '.', ''), + 'commissionRate' => $commissionRateRate, + 'currencyCode' => $this->exchangeCurrencyCode, + ] + ]; + + } + + + } + + + $channelBaseCount = 0; + $channelBaseTotal = 0; + $channelBaseTotalCommission = 0; + foreach ($channelBaseCommission as $channelBase) { + $channelBaseValue = reset($channelBase); + $channelBaseCount += $channelBaseValue['count']; + $channelBaseTotal += $channelBaseValue['exchangeData']['total']; + $channelBaseTotalCommission += $channelBaseValue['exchangeData']['commission']; + } + + $commission = [ + 'channelBaseCount' => $channelBaseCount, + 'channelBaseTotal' => $channelBaseTotal, + 'channelBaseTotalCommission' => $channelBaseTotalCommission, + ]; + + return $commission; + } + + + public function summaryWithPeriod($propertyId, $period, $type) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + $periodStartDate = Carbon::parse($period . '-01')->toDateString(); + $periodFinishDate = Carbon::parse($periodStartDate)->addMonth()->firstOfMonth()->toDateString(); + + + try { + + $propertyDetailCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + //['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyBookingEngines.channel'], + 'firstRow' => true + ]; + + $propertyDetail = $this->propertyRepository->findByCriteria($propertyDetailCriteria); + + if (!$propertyDetail) { + throw new ApiErrorException('Property not found'); + } + + + $conditions = [ + 'type' => $type, + 'commission' => $propertyDetail['commission'], + 'commission_payment' => $propertyDetail['commission_payment'], + 'commission_offline' => $propertyDetail['commission_offline'], + 'commission_channel' => $propertyDetail['commission_channel'], + ]; + + $periodCommission = $this->calculatePeriodCommission($propertyId, $type, $periodStartDate, $periodFinishDate); + + $propertySummaryCreateParam = [ + 'property_id' => $propertyId, + 'period' => $period, + 'count' => $periodCommission['channelBaseCount'], + 'commission' => (float)number_format($periodCommission['channelBaseTotalCommission'], '2', '.', ''), + 'total' => (float)number_format($periodCommission['channelBaseTotal'], '2', '.', ''), + 'currency' => $this->exchangeCurrencyCode, + 'type' => $type, + 'status' => 1, + ]; + + + $propertySummaryCheckCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'period', 'condition' => '=', 'value' => $period], + ['field' => 'type', 'condition' => '=', 'value' => $type], + ], + 'firstRow' => true + ]; + + $propertySummaryCheck = $this->propertySummaryRepository->findByCriteria($propertySummaryCheckCriteria); + + if ($propertySummaryCheck) { + $propertySummaryCreate = $this->propertySummaryRepository->update($propertySummaryCheck['id'], $propertySummaryCreateParam); + } else { + $propertySummaryCreate = $this->propertySummaryRepository->create($propertySummaryCreateParam); + } + + if ($propertySummaryCreate['status'] != 'success') { + throw new ApiErrorException($propertySummaryCreate['message']); + } + + + $response = [ + 'status' => true, + 'data' => $propertySummaryCreate['data'], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyTypeService.php b/app/Core/Service/PropertyTypeService.php new file mode 100644 index 0000000..f99862e --- /dev/null +++ b/app/Core/Service/PropertyTypeService.php @@ -0,0 +1,95 @@ +propertyTypeRepository = $propertyTypeRepository; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyTypeRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyTypes($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ["field" => "name", "value" => "ASC"] + ], + ]; + + $searchResult = $this->select($searchCriteria, ['id', 'name', 'language_key']); + if($searchResult['status'] != 'success'){ + throw new Exception($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_type' =>$return ] ]; + } catch + (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyWebAboutUsService.php b/app/Core/Service/PropertyWebAboutUsService.php new file mode 100644 index 0000000..3fc8326 --- /dev/null +++ b/app/Core/Service/PropertyWebAboutUsService.php @@ -0,0 +1,207 @@ +propertyWebAboutUsRepository = $propertyWebAboutUsRepository; + $this->languageService = $languageService; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebAboutUsRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyCreateResult = $this->propertyWebAboutUsRepository->insert($params); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $propertyCreateResult["data"] + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function getPropertyWebAboutUs($param = [], $column = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if($getApplicationLanguages['status'] != 'success'){ + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data'] ; + + $requestPropertyWebAboutUs = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => fillOnUndefined($param, 'mode')] + ] + ]; + + $propertyWebAboutUs = $this->select($requestPropertyWebAboutUs, $column); + + if($propertyWebAboutUs['status'] != 'success'){ + throw new ApiErrorException($propertyWebAboutUs['message']); + } + + $propertyWebAboutUs = !empty($propertyWebAboutUs['data']) ? collect($propertyWebAboutUs['data'])->keyBy('language_code')->toArray() : []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code'] ; + $responseAboutUs[] = [ + 'language_code' => $langKey, + 'value' => isset($propertyWebAboutUs[$langKey]) ? $propertyWebAboutUs[$langKey]['value'] : null + ]; + } + + $return = $responseAboutUs; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => $return ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function updatePropertyWebAboutUs($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $return = []; + + + $getDeletePropertyWebAboutRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + $getDeletePropertyWebAboutRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + $deleteWebAboutUsId = $this->propertyWebAboutUsRepository->findByCriteria($getDeletePropertyWebAboutRequest, ['id']) ; + $deleteWebAboutUsId = array_column($deleteWebAboutUsId, 'id') ; + + if (!empty($deleteWebAboutUsId)) { + $destroyStatus = $this->propertyWebAboutUsRepository->destroy($deleteWebAboutUsId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $createPropertyWebAboutUsData = []; + $aboutUsDatas = isset($params['about_us']) && !empty($params['about_us']) ? $params['about_us'] : []; + foreach ($aboutUsDatas as $key => $aboutUsData){ + if($aboutUsData['value']){ + $createPropertyWebAboutUsData[$key]['property_id'] = fillOnUndefined($params,'property_id'); + $createPropertyWebAboutUsData[$key]['property_web_id'] = fillOnUndefined($params,'property_web_id'); + $createPropertyWebAboutUsData[$key]['language_code'] = $aboutUsData['language_code']; + $createPropertyWebAboutUsData[$key]['value'] = $aboutUsData['value']; + $createPropertyWebAboutUsData[$key]['status'] = $status; + $createPropertyWebAboutUsData[$key]['created_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebAboutUsData[$key]['updated_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebAboutUsData[$key]['created_at'] = time(); + $createPropertyWebAboutUsData[$key]['updated_at'] = time(); + } + } + + $propertyWebAboutUsResult = $this->create($createPropertyWebAboutUsData); + if ($propertyWebAboutUsResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebAboutUsResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_about_us' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + +} diff --git a/app/Core/Service/PropertyWebColorMappingService.php b/app/Core/Service/PropertyWebColorMappingService.php new file mode 100644 index 0000000..905d531 --- /dev/null +++ b/app/Core/Service/PropertyWebColorMappingService.php @@ -0,0 +1,217 @@ +propertyWebColorMappingRepository = $propertyWebColorMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebColorMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebColorMapping($param = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + // TODO validation yazılmalı! + + $propertyWebMenuMappingResult = $this->propertyWebColorMappingRepository->insert($param); + + if ($propertyWebMenuMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => NULL + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebColorMapping($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_color_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updatePropertyWebColorMapping($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getDeletePropertyWebColorRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + + $getDeletePropertyWebColorRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + $deleteWebColorId = $this->propertyWebColorMappingRepository->findByCriteria($getDeletePropertyWebColorRequest, ['id']) ; + $deleteWebColorId = array_column($deleteWebColorId, 'id') ; + + if (!empty($deleteWebColorId)) { + $destroyStatus = $this->propertyWebColorMappingRepository->destroy($deleteWebColorId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $myWebColors = !empty($params['colors']) ? $params['colors'] : []; + + $createPropertyWebColorMappingData = []; + foreach ($myWebColors as $key => $myWebColor){ + $createPropertyWebColorMappingData[$key]['property_id'] = fillOnUndefined($params,'property_id'); + $createPropertyWebColorMappingData[$key]['property_web_id'] = fillOnUndefined($params,'property_web_id'); + $createPropertyWebColorMappingData[$key]['color_code'] = $myWebColor['color_code']; + $createPropertyWebColorMappingData[$key]['order_number'] = $myWebColor['color_number']; + $createPropertyWebColorMappingData[$key]['status'] = $status; + $createPropertyWebColorMappingData[$key]['created_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebColorMappingData[$key]['updated_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebColorMappingData[$key]['created_at'] = time(); + $createPropertyWebColorMappingData[$key]['updated_at'] = time(); + } + + $propertyWebColorMappingResult = $this->createPropertyWebColorMapping($createPropertyWebColorMappingData); + if ($propertyWebColorMappingResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebColorMappingResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_menu_mapping' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function getPropertyWebColorMappingWithStatus($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => $params['status']] + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_color_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + +} diff --git a/app/Core/Service/PropertyWebContentService.php b/app/Core/Service/PropertyWebContentService.php new file mode 100644 index 0000000..4dd59ff --- /dev/null +++ b/app/Core/Service/PropertyWebContentService.php @@ -0,0 +1,340 @@ +languageService = $languageService; + $this->propertyWebContentRepository = $propertyWebContentRepository; + $this->propertyWebContentCategoryRepository = $propertyWebContentCategoryRepository; + $this->propertyPhotoValidator = $propertyPhotoValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + "property_id" => fillOnUndefined($param, "property_id"), + "content_category_id" => fillOnUndefined($param, "content_category_id"), + "title" => fillOnUndefined($param, "title"), + "language_code" => fillOnUndefined($param, "language_code"), + "image" => fillOnUndefined($param, "image"), + "content" => fillOnUndefined($param, "content"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $insertData['slug'] = str_slug($insertData['title']); + + //TODO: be activate validator + /*$validationResult = $this->propertyContentCreateValidator->validate($insertData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $userCreateResult = $this->propertyWebContentRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebContentRepository->findByCriteria($param, $column); + + if (!$data) { + throw new ApiErrorException(lang('Data is not found.')); + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectWebContentCategory($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebContentCategoryRepository->findByCriteria($param, $column); + + if (!$data) { + throw new ApiErrorException(lang('Data is not found.')); + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $param['slug'] = str_slug($param['title']); + + + $chekDataParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'firstRow' => true + ]; + $chekData = $this->propertyWebContentRepository->findByCriteria($chekDataParam); + if (empty($chekData)) { + throw new Exception('You are not authorized to perform this action.'); + } + + $updateResult = $this->propertyWebContentRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $chekDataParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'firstRow' => true + ]; + $chekData = $this->propertyWebContentRepository->findByCriteria($chekDataParam); + if (empty($chekData)) { + throw new Exception('You are not authorized to perform this action.'); + } + + $deleteResult = $this->propertyWebContentRepository->destroy([$id]); + if ($deleteResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function uploadPhoto($params = []) + { + + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + $validateParams = [ + 'photo' => $params['photo'] + ]; + + $uploadedFile = $params['photo']; + $validationResult = $this->propertyPhotoValidator->validate($validateParams); + if ($validationResult->errors()->first()) { + throw new ApiErrorException($validationResult->errors()->all()); + } + + $uploadedOriginalImage = Image::make($uploadedFile); + $imageWidth = $uploadedOriginalImage->width(); + $imageHeight = $uploadedOriginalImage->height(); + + $fileExt = $uploadedFile->getClientOriginalExtension(); + $fileSize = (int)ceil(Image::make($uploadedFile)->filesize() / 1024); + + $imageExtension = 'jpg'; + $fileExt = $fileExt != $imageExtension ? $imageExtension : $fileExt; + $quality = 80; + + $urlPath = '/property-web-content/' . $params['property_id'] . "/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath; + $fileName = md5(Carbon::now()->format('dmyHi') . '-' . md5($uploadedFile->getClientOriginalName())); + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + $originalImageMustResize = ($imageHeight > 2000 || $imageWidth > 2000); + + if ($imageHeight < 768) { + throw new ApiErrorException('image size error: minimum height must be 768px'); + } + + if ($imageHeight > $imageWidth) { + + $ratio = $imageHeight / 768; + //$ratio200 = 768/200; + $resizeWidth = intval($imageWidth / $ratio); + //$resizeThumbWidth = intval($resizeWidth/$ratio200); + + if ($originalImageMustResize) { + $imageHRatio = $imageHeight / 2000; + $imageResizedOriginalWidth = intval($imageWidth / $imageHRatio); + $image = $uploadedOriginalImage->fit($imageResizedOriginalWidth, 2000)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } else { + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300, 300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } else { + + $ratio = $imageHeight / 768; + $resizeWidth = intval($imageWidth / $ratio); + + $ratioThumbnail = 768 / 300; + $resizeThumbWidth = intval($resizeWidth / $ratioThumbnail); + + if ($originalImageMustResize) { + $imageWRatio = $imageWidth / 2000; + $imageResizedOriginalHeight = intval($imageHeight / $imageWRatio); + $image = $uploadedOriginalImage->fit(2000, $imageResizedOriginalHeight)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } else { + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } + + if ($resizeWidth > 1599) { + $image->fit(1600, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300, 300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } else { + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(300)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } + + } + + $response = [ + 'status' => true, + 'data' => [ + //'photo_path' => $urlPath, + //'photo_name' => $fileName, + 'image' => $fileName . '.' . $fileExt, + //'file_size' => $fileSize, + //'file_ext' => $fileExt, + 'image_resolution' => $imageWidth . 'x' . $imageHeight, + 'imageUrl' => [ + 'default' => Config::get('app.imageUrl') . '/property-web-content/' . $params['property_id'] . '/' . $fileName . '.' . $fileExt, + 'thumb' => Config::get('app.imageUrl') . '/property-web-content/' . $params['property_id'] . '/' . $fileName . '_thumbnail.' . $fileExt, + 'fixed' => Config::get('app.imageUrl') . '/property-web-content/' . $params['property_id'] . '/' . $fileName . '_medium.' . $fileExt, + ] + + ] + ]; + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['status'] = false; + } + + return output($response); + } +} diff --git a/app/Core/Service/PropertyWebLanguageMappingService.php b/app/Core/Service/PropertyWebLanguageMappingService.php new file mode 100644 index 0000000..cced69a --- /dev/null +++ b/app/Core/Service/PropertyWebLanguageMappingService.php @@ -0,0 +1,186 @@ +propertyWebLanguageMappingRepository = $propertyWebLanguageMappingRepository; + $this->languageService = $languageService; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebLanguageMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebLanguageMapping($param = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + // TODO validation yazılmalı! + + $propertyWebMenuMappingResult = $this->propertyWebLanguageMappingRepository->insert($param); + + if ($propertyWebMenuMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => NULL + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebLanguageMapping($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_language_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updatePropertyWebLanguageMapping($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getDeletePropertyWebLanguageRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + + $getDeletePropertyWebLanguageRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + $deleteWebLanguageId = $this->propertyWebLanguageMappingRepository->findByCriteria($getDeletePropertyWebLanguageRequest, ['id']) ; + $deleteWebLanguageId = array_column($deleteWebLanguageId, 'id') ; + + if (!empty($deleteWebLanguageId)) { + $destroyStatus = $this->propertyWebLanguageMappingRepository->destroy($deleteWebLanguageId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $myWebLanguages = !empty($params['languages']) ? $params['languages'] : []; + + $createPropertyWebLanguageMappingData = []; + foreach ($myWebLanguages as $key => $myWebLanguage){ + $createPropertyWebLanguageMappingData[$key]['property_id'] = fillOnUndefined($params,'property_id'); + $createPropertyWebLanguageMappingData[$key]['property_web_id'] = fillOnUndefined($params,'property_web_id'); + $createPropertyWebLanguageMappingData[$key]['language_code'] = $myWebLanguage; + $createPropertyWebLanguageMappingData[$key]['status'] = $status; + $createPropertyWebLanguageMappingData[$key]['created_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebLanguageMappingData[$key]['updated_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebLanguageMappingData[$key]['created_at'] = time(); + $createPropertyWebLanguageMappingData[$key]['updated_at'] = time(); + } + + + $propertyWebLanguageMappingResult = $this->createPropertyWebLanguageMapping($createPropertyWebLanguageMappingData); + if ($propertyWebLanguageMappingResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebLanguageMappingResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_language_mapping' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyWebLogService.php b/app/Core/Service/PropertyWebLogService.php new file mode 100644 index 0000000..80b3109 --- /dev/null +++ b/app/Core/Service/PropertyWebLogService.php @@ -0,0 +1,209 @@ +propertyWebLogRepository = $propertyWebLogRepository; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebLogRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $propertyCreateResult = $this->propertyWebLogRepository->create($params); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $propertyCreateResult["data"] + ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $updateResult = $this->propertyWebLogRepository->update($id, $param); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebLog($params){ + + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + $searchCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'ip', 'condition' => '=', 'value' => $params['ip']], + ['field' => 'web_id', 'condition' => '=', 'value' => $params['web_id']] + ], + 'firstRow' => true + ]; + + $searchResult = $this->select($searchCriteria, ['id', 'web_id']); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + + // Create + if(empty($searchResult['data'])){ + + $createData = [ + 'web_id' => fillOnUndefined($params, "web_id"), + 'ip' => fillOnUndefined($params, "ip"), + 'country_code' => fillOnUndefined($params, "country_code"), + 'device_type' => $params['isDesktop'] ? 'web' : 'mobile', + 'created_at' => time(), + 'updated_at' => time() + ]; + $createStatus = $this->create($createData) ; + + if($createStatus['status'] != 'success'){ + throw new Exception($createStatus['message']); + } + + }else{ + // Update + $updateData = [ + 'web_id' => fillOnUndefined($params, "web_id"), + 'ip' => fillOnUndefined($params, "ip"), + 'country_code' => fillOnUndefined($params, "country_code"), + 'device_type' => $params['isDesktop'] ? 'web' : 'mobile', + 'created_at' => time(), + 'updated_at' => time() + ]; + $updateStatus = $this->update($searchResult['data']['id'], $updateData) ; + + if($updateStatus['status'] != 'success'){ + throw new Exception($updateStatus['message']); + } + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $searchResult ]; + + }catch (ApiErrorException $e) + { + $response = ['status' => 0, 'statusCode' => 500 ,'message' => $e->getMessage(), 'data' => null]; + } + catch (Exception $e){ + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return output($response); + } + + public function getPropertyWebLog($param = [], $column = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + + $searchResult = $this->select($param, $column); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_logs' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyWebMenuMappingService.php b/app/Core/Service/PropertyWebMenuMappingService.php new file mode 100644 index 0000000..6b0d805 --- /dev/null +++ b/app/Core/Service/PropertyWebMenuMappingService.php @@ -0,0 +1,221 @@ +propertyWebMenuMappingRepository = $propertyWebMenuMappingRepository; + $this->propertyWebMenuService = $propertyWebMenuService; + $this->propertyPlaceService = $propertyPlaceService ; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebMenuMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebMenuMapping($param = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + // TODO validation yazılmalı! + + $propertyWebMenuMappingResult = $this->propertyWebMenuMappingRepository->insert($param); + + if ($propertyWebMenuMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => NULL + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebMenuMapping($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_menu_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updatePropertyWebMenuMapping($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getDeletePropertyWebMenuRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + + $getDeletePropertyWebMenuRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + + $deleteWebMenuId = $this->propertyWebMenuMappingRepository->findByCriteria($getDeletePropertyWebMenuRequest, ['id']) ; + $deleteWebMenuId = array_column($deleteWebMenuId, 'id') ; + + + if (!empty($deleteWebMenuId)) { + $destroyStatus = $this->propertyWebMenuMappingRepository->destroy($deleteWebMenuId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $webMenus = $this->propertyWebMenuService->getPropertyWebMenu(); + if ($webMenus['status'] != 'success') { + throw new ApiErrorException($webMenus['message']); + } + + $placeRequest = [ + 'property_id' => $params['property_id'] + ] ; + $myPlaces = $this->propertyPlaceService->webMenuPlaceCategoriesAndPlaces($placeRequest); + if ($myPlaces['status'] != 'success') { + throw new ApiErrorException($myPlaces['message']); + } + $myPlaces = $myPlaces['data'] ; + $myWebMenus = $webMenus['data']['property_web_menus'] ; + $myWebMenus = array_merge($myWebMenus, $myPlaces) ; + $webMenus = collect($myWebMenus); + $menus = collect($params['menus']); + + + $createPropertyWebMenuMappingData = []; + foreach ($menus as $menu){ + + $checkMenu = $webMenus->where('menu_type', '=', $menu['menu_type'])->where('id', '=', $menu['id'])->first(); + if (!$checkMenu) { + throw new ApiErrorException('api-unknown-error'); + } + + $createPropertyWebMenuMappingData[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_web_menu_id' => $menu['id'], + 'order_number' => $menu['order_number'], + 'type' => $menu['menu_type'], + 'menu_code' => fillOnUndefined($menu, 'menu_code', null), + 'status' => $status, + 'created_by' => fillOnUndefined($params, 'user_id'), + 'updated_by' => fillOnUndefined($params, 'user_id'), + 'created_at' => time(), + 'updated_at' => time(), + ] ; + + + } + + $propertyWebMenuMappingResult = $this->createPropertyWebMenuMapping($createPropertyWebMenuMappingData); + if ($propertyWebMenuMappingResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebMenuMappingResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_menu_mapping' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyWebMenuService.php b/app/Core/Service/PropertyWebMenuService.php new file mode 100644 index 0000000..4a2bea8 --- /dev/null +++ b/app/Core/Service/PropertyWebMenuService.php @@ -0,0 +1,91 @@ +propertyWebMenuRepository = $propertyWebMenuRepository; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebMenuRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebMenu(){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]], + 'orderBy' => [["field" => "order_number", "value" => "ASC"]], + ]; + + $searchResult = $this->select($searchCriteria, ['id', 'name', 'language_key', 'route', 'type', 'order_number', 'icon', 'alias']); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $webMenus = collect($searchResult['data'])->map(function ($value){ + $return = $value ; + $return['menu_type'] = 'MAIN' ; + return $return ; + })->values()->all() ; + $return = $webMenus; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_menus' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + + + +} diff --git a/app/Core/Service/PropertyWebMetaService.php b/app/Core/Service/PropertyWebMetaService.php new file mode 100644 index 0000000..bcd84d6 --- /dev/null +++ b/app/Core/Service/PropertyWebMetaService.php @@ -0,0 +1,222 @@ +propertyWebMetaRepository = $propertyWebMetaRepository; + $this->propertyWebMetaTagRepository = $propertyWebMetaTagRepository; + $this->propertyWebMetaMappingRepository = $propertyWebMetaMappingRepository; + } + + public function select($params = [], $column = ['*']) + { + $response = ['status' => true, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebMetaRepository->findByCriteria($params, $column); + $response = [ + 'status' => 1, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['status'] = -1; + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectTag($param = [], $column = ['*']) + { + $response = ['status' => true, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebMetaTagRepository->findByCriteria($param, $column); + $response = [ + 'status' => 1, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['status'] = -1; + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectMapping($params = [], $column = ['*']) + { + $response = ['status' => true, 'message' => '', 'data' => null]; + + try { + $propertyId = $params['property_id'] ?? null; + if ($propertyId) { + $params['criteria'][] = ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId]; + } + + $filter = $params['filter'] ?? null; + if ($filter) { + if (isset($filter['property_web_meta_id'])) { + $params['criteria'][] = ['field' => 'property_web_meta_id', 'condition' => '=', 'value' => $filter['property_web_meta_id']]; + } + if (isset($filter['property_web_meta_tag_id'])) { + $params['criteria'][] = ['field' => 'property_web_meta_tag_id', 'condition' => '=', 'value' => $filter['property_web_meta_tag_id']]; + } + if (isset($filter['code'])) { + $params['criteria'][] = ['field' => 'code', 'condition' => '=', 'value' => $filter['code']]; + } + } + + $params['with'] = ['propertyWebMeta:id,name,language_key,order_number', 'propertyWebMetaTag:id,name,language_key,order_number']; + $data = $this->propertyWebMetaMappingRepository->findByCriteria($params, $column); + $response = [ + 'status' => 1, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['status'] = -1; + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function syncTag($params = []) + { + $response = ['status' => true, 'message' => '', 'data' => null]; + + try { + $propertyId = $params['property_id'] ?? null; + $propertyWebId = $params['property_web_id'] ?? null; + $propertyWebMetaTagId = $params['property_web_meta_tag_id'] ?? null; + $propertyWebMetaId = $params['property_web_meta_id'] ?? null; + $code = $params['code'] ?? null; + $text = $params['text'] ?? null; + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $propertyWebId], + ['field' => 'property_web_meta_tag_id', 'condition' => '=', 'value' => $propertyWebMetaTagId], + ['field' => 'property_web_meta_id', 'condition' => '=', 'value' => $propertyWebMetaId], + ['field' => 'code', 'condition' => '=', 'value' => $code], + ], + 'firstRow' => 1 + ]; + + // Önce kayıt var mı kontrol ediyoruz + $existing = $this->propertyWebMetaMappingRepository->findByCriteria($criteria); + + if (!empty($existing)) { + // Kayıt var + if (is_null($text)) { + // Text boş ise silme + $id = $existing['id']; + $deleteResult = $this->propertyWebMetaMappingRepository->destroy([$id]); + if ($deleteResult['status'] != 'success') { + throw new Exception($deleteResult['message']); + } + $response = [ + 'status' => 1, + 'message' => 'Record deleted successfully.', + 'data' => null, + ]; + } else { + // Text dolu ise güncelleme + $id = $existing['id']; + $data = [ + 'code' => $code, + 'text' => is_array($text) ? json_encode($text) : $text, + 'status' => true, + 'updated_at' => time() + ]; + $updateResult = $this->propertyWebMetaMappingRepository->update($id, $data); + if ($updateResult['status'] != 'success') { + throw new Exception($updateResult['message']); + } + $response = [ + 'status' => 1, + 'message' => 'Record updated successfully.', + 'data' => $data, + ]; + } + } else { + // Kayıt yok + if (!is_null($text)) { + // Text dolu ise oluşturma + $data = [ + 'property_id' => $propertyId, + 'property_web_id' => $propertyWebId, + 'property_web_meta_tag_id' => $propertyWebMetaTagId, + 'property_web_meta_id' => $propertyWebMetaId, + 'code' => $code, + 'text' => is_array($text) ? json_encode($text) : $text, + 'status' => true, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id") + ]; + + $createResult = $this->propertyWebMetaMappingRepository->create($data); + if ($createResult['status'] != 'success') { + throw new Exception($createResult['message']); + } + + $response = [ + 'status' => 1, + 'message' => 'Record created successfully.', + 'data' => $data, + ]; + } else { + // Kayıt yok ve text de null ise işlem yapmaya gerek yok (veya başarılı dönülebilir) + $response = [ + 'status' => 1, + 'message' => 'Record not found and text is null, no action taken.', + 'data' => null, + ]; + } + } + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['status'] = -1; + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/PropertyWebPhotoMappingService.php b/app/Core/Service/PropertyWebPhotoMappingService.php new file mode 100644 index 0000000..957cdca --- /dev/null +++ b/app/Core/Service/PropertyWebPhotoMappingService.php @@ -0,0 +1,90 @@ +propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebPhotoMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + + + public function destroy($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_photo_id', 'condition' => '=', 'value' => $params['photo_id']], + ] + ]; + + $deleteData = $this->propertyWebPhotoMappingRepository->findByCriteria($deleteCriteria, ['id']); + $deleteData = $deleteData ? $deleteData : [] ; + if($deleteData){ + $deleteIds = array_column($deleteData, 'id') ; + $destroyResult = $this->propertyWebPhotoMappingRepository->destroy($deleteIds); + if ($destroyResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $response = [ + 'status' => true, + 'data' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + +} diff --git a/app/Core/Service/PropertyWebPlaceMappingService.php b/app/Core/Service/PropertyWebPlaceMappingService.php new file mode 100644 index 0000000..0e6de8c --- /dev/null +++ b/app/Core/Service/PropertyWebPlaceMappingService.php @@ -0,0 +1,182 @@ +propertyWebPlaceMappingRepository = $propertyWebPlaceMappingRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebPlaceMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebPlaceMapping($param = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + // TODO validation yazılmalı! + + $propertyWebPlaceMappingResult = $this->propertyWebPlaceMappingRepository->insert($param); + + if ($propertyWebPlaceMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => NULL + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebRoomMapping($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_room_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updatePropertyWebPlaceMapping($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getDeletePropertyWebPlaceRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + + $getDeletePropertyWebPlaceRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + + $deleteWebPlaceId = $this->propertyWebPlaceMappingRepository->findByCriteria($getDeletePropertyWebPlaceRequest, ['id']) ; + $deleteWebPlaceId = array_column($deleteWebPlaceId, 'id') ; + + + if (!empty($deleteWebPlaceId)) { + $destroyStatus = $this->propertyWebPlaceMappingRepository->destroy($deleteWebPlaceId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $myWebPlaces = !empty($params['places']) ? $params['places'] : []; + + $createPropertyWebPlaceMappingData = []; + foreach ($myWebPlaces as $key => $myWebPlace){ + $createPropertyWebPlaceMappingData[$key]['property_id'] = fillOnUndefined($params,'property_id'); + $createPropertyWebPlaceMappingData[$key]['property_web_id'] = fillOnUndefined($params,'property_web_id'); + $createPropertyWebPlaceMappingData[$key]['property_place_id'] = $myWebPlace; + $createPropertyWebPlaceMappingData[$key]['status'] = $status; + $createPropertyWebPlaceMappingData[$key]['created_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebPlaceMappingData[$key]['updated_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebPlaceMappingData[$key]['created_at'] = time(); + $createPropertyWebPlaceMappingData[$key]['updated_at'] = time(); + } + + $propertyWebPlaceMappingResult = $this->createPropertyWebPlaceMapping($createPropertyWebPlaceMappingData); + if ($propertyWebPlaceMappingResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebPlaceMappingResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_place_mapping' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyWebPopupService.php b/app/Core/Service/PropertyWebPopupService.php new file mode 100644 index 0000000..8b424b5 --- /dev/null +++ b/app/Core/Service/PropertyWebPopupService.php @@ -0,0 +1,399 @@ +languageService = $languageService; + $this->propertyWebPopupRepository = $propertyWebPopupRepository; + $this->propertyPhotoValidator = $propertyPhotoValidator; + $this->propertyWebRepository = $propertyWebRepository; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $codeParams = []; + $codeParams[] = fillOnUndefined($param, "property_id"); + $codeParams[] = fillOnUndefined($param, "title"); + $codeParams[] = fillOnUndefined($param, "language_code"); + $codeParams[] = fillOnUndefined($param, "start_date"); + $codeParams[] = fillOnUndefined($param, "end_date"); + $code = md5(implode('-', $codeParams)); + + $insertData = [ + "code" => $code, + "property_id" => fillOnUndefined($param, "property_id"), + "title" => fillOnUndefined($param, "title"), + "language_code" => fillOnUndefined($param, "language_code"), + "image" => fillOnUndefined($param, "image"), + "start_date" => fillOnUndefined($param, "start_date"), + "end_date" => fillOnUndefined($param, "end_date"), + "url" => fillOnUndefined($param, "url"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + //TODO: be activate validator + /*$validationResult = $this->propertyContentCreateValidator->validate($insertData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $createResult = $this->propertyWebPopupRepository->create($insertData); + if ($createResult['status'] != 'success') { + throw new ApiErrorException('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $createResult["data"]; + + //Domain Cache Clean + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if ($propertyWebData) { + $checkDomainStatusCacheKey = 'myweb:' . md5('checkDomainStatus-' . $propertyWebData['domain'] . '-' . Carbon::now()->toDateString()); + if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) { + Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]); + } + } + //Domain Cache Clean + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebPopupRepository->findByCriteria($param, $column); + + if (!$data) { + throw new ApiErrorException(lang('Data is not found.')); + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectWebContentCategory($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebPopupRepository->findByCriteria($param, $column); + + if (!$data) { + throw new ApiErrorException(lang('Data is not found.')); + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $chekDataParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'firstRow' => true + ]; + $chekData = $this->propertyWebPopupRepository->findByCriteria($chekDataParam); + if (empty($chekData)) { + throw new Exception('You are not authorized to perform this action.'); + } + + + $updateResult = $this->propertyWebPopupRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + //Domain Cache Clean + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if ($propertyWebData) { + $checkDomainStatusCacheKey = 'myweb:' . md5('checkDomainStatus-' . $propertyWebData['domain'] . '-' . Carbon::now()->toDateString()); + if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) { + Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]); + } + } + //Domain Cache Clean + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function delete($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $chekDataParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ], + 'firstRow' => true + ]; + $chekData = $this->propertyWebPopupRepository->findByCriteria($chekDataParam); + if (empty($chekData)) { + throw new Exception('You are not authorized to perform this action.'); + } + + $deleteResult = $this->propertyWebPopupRepository->destroy([$id]); + if ($deleteResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $urlPath = '/property-web-popup/' . $param['property_id'] . "/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath; + + $fileExplode = explode('.', $chekData['image'], 2); + $fileName = $fileExplode[0]; + $fileExt = $fileExplode[1]; + + $fileCombinations = []; + $fileCombinations[] = $filePath . $fileName . '.' . $fileExt; + $fileCombinations[] = $filePath . $fileName . '_medium.' . $fileExt; + $fileCombinations[] = $filePath . $fileName . '_thumbnail.' . $fileExt; + + foreach ($fileCombinations as $fileCombination) { + if (file_exists($fileCombination)) { + File::delete($fileCombination); + } + } + + $response = [ + 'status' => true + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function uploadPhoto($params = []) + { + + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + $validateParams = [ + 'photo' => $params['photo'] + ]; + + $uploadedFile = $params['photo']; + $validationResult = $this->propertyPhotoValidator->validate($validateParams); + if ($validationResult->errors()->first()) { + throw new ApiErrorException($validationResult->errors()->all()); + } + + $uploadedOriginalImage = Image::make($uploadedFile); + $imageWidth = $uploadedOriginalImage->width(); + $imageHeight = $uploadedOriginalImage->height(); + + $fileExt = $uploadedFile->getClientOriginalExtension(); + $fileSize = (int)ceil(Image::make($uploadedFile)->filesize() / 1024); + + $imageExtension = 'jpg'; + $fileExt = $fileExt != $imageExtension ? $imageExtension : $fileExt; + $quality = 80; + + $urlPath = '/property-web-popup/' . $params['property_id'] . "/"; + $filePath = Config::get('app.fileSystemDriver') . $urlPath; + $fileName = md5(Carbon::now()->format('dmyHi') . '-' . md5($uploadedFile->getClientOriginalName())); + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + $originalImageMustResize = ($imageHeight > 2000 || $imageWidth > 2000); + + if ($imageHeight < 768) { + throw new ApiErrorException('image size error: minimum height must be 768px'); + } + + if ($imageHeight > $imageWidth) { + + $ratio = $imageHeight / 768; + //$ratio200 = 768/200; + $resizeWidth = intval($imageWidth / $ratio); + //$resizeThumbWidth = intval($resizeWidth/$ratio200); + + if ($originalImageMustResize) { + $imageHRatio = $imageHeight / 2000; + $imageResizedOriginalWidth = intval($imageWidth / $imageHRatio); + $image = $uploadedOriginalImage->fit($imageResizedOriginalWidth, 2000)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } else { + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(600, 600)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } else { + + $ratio = $imageHeight / 768; + $resizeWidth = intval($imageWidth / $ratio); + + $ratioThumbnail = 768 / 600; + $resizeThumbWidth = intval($resizeWidth / $ratioThumbnail); + + if ($originalImageMustResize) { + $imageWRatio = $imageWidth / 2000; + $imageResizedOriginalHeight = intval($imageHeight / $imageWRatio); + $image = $uploadedOriginalImage->fit(2000, $imageResizedOriginalHeight)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } else { + $image = $uploadedOriginalImage->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt, $quality); + } + + if ($resizeWidth > 1599) { + $image->fit(1600, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(600, 600)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } else { + $image->fit($resizeWidth, 768)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_medium' . '.' . $fileExt); + $image->fit(600)->encode($imageExtension, $quality)->orientate()->save($filePath . $fileName . '_thumbnail' . '.' . $fileExt); + } + + } + + $response = [ + 'status' => true, + 'data' => [ + //'photo_path' => $urlPath, + //'photo_name' => $fileName, + 'image' => $fileName . '.' . $fileExt, + //'file_size' => $fileSize, + //'file_ext' => $fileExt, + 'image_resolution' => $imageWidth . 'x' . $imageHeight, + 'imageUrl' => [ + 'default' => Config::get('app.imageUrl') . '/property-web-popup/' . $params['property_id'] . '/' . $fileName . '.' . $fileExt, + 'thumb' => Config::get('app.imageUrl') . '/property-web-popup/' . $params['property_id'] . '/' . $fileName . '_thumbnail.' . $fileExt, + 'fixed' => Config::get('app.imageUrl') . '/property-web-popup/' . $params['property_id'] . '/' . $fileName . '_medium.' . $fileExt, + ] + + ] + ]; + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['status'] = false; + } + + return output($response); + } +} diff --git a/app/Core/Service/PropertyWebRoomMappingService.php b/app/Core/Service/PropertyWebRoomMappingService.php new file mode 100644 index 0000000..cc04bb1 --- /dev/null +++ b/app/Core/Service/PropertyWebRoomMappingService.php @@ -0,0 +1,202 @@ +propertyWebRoomMappingRepository = $propertyWebRoomMappingRepository; + $this->propertyRoomRepository = $propertyRoomRepository; + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebRoomMappingRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebRoomMapping($param = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + // TODO validation yazılmalı! + + $propertyWebMenuMappingResult = $this->propertyWebRoomMappingRepository->insert($param); + + if ($propertyWebMenuMappingResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => NULL + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebRoomMapping($params, $select = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'property_web_id', 'condition' => '=', 'value' => $params['property_web_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $searchResult = $this->select($searchCriteria, $select); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_room_mapping' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + + } + + public function updatePropertyWebRooomMapping($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $getDeletePropertyWebRoomRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + + $getDeletePropertyWebRoomRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + $deleteWebRoomId = $this->propertyWebRoomMappingRepository->findByCriteria($getDeletePropertyWebRoomRequest, ['id']) ; + $deleteWebRoomId = array_column($deleteWebRoomId, 'id') ; + + if (!empty($deleteWebRoomId)) { + $destroyStatus = $this->propertyWebRoomMappingRepository->destroy($deleteWebRoomId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $myWebRooms = !empty($params['rooms']) ? $params['rooms'] : []; + + + $propertyRoomCheckCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'whereIn' => [ + ['field' => 'id', 'value' => $myWebRooms] + ] + ]; + + $propertyRoomCheck = $this->propertyRoomRepository->findByCriteria($propertyRoomCheckCriteria, ['id']) ; + $myWebRooms = $params['rooms']; + + if(count($propertyRoomCheck) != count($params['rooms'])) { + throw new Exception('Different room type count.'); + } + + $createPropertyWebRoomMappingData = []; + foreach ($myWebRooms as $key => $myWebRoom){ + + $createPropertyWebRoomMappingData[$key]['property_id'] = fillOnUndefined($params,'property_id'); + $createPropertyWebRoomMappingData[$key]['property_web_id'] = fillOnUndefined($params,'property_web_id'); + $createPropertyWebRoomMappingData[$key]['property_room_id'] = $myWebRoom; + $createPropertyWebRoomMappingData[$key]['status'] = $status; + $createPropertyWebRoomMappingData[$key]['created_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebRoomMappingData[$key]['updated_by'] = fillOnUndefined($params, 'user_id'); + $createPropertyWebRoomMappingData[$key]['created_at'] = time(); + $createPropertyWebRoomMappingData[$key]['updated_at'] = time(); + } + + $propertyWebRoomMappingResult = $this->createPropertyWebRoomMapping($createPropertyWebRoomMappingData); + if ($propertyWebRoomMappingResult['status'] != 'success'){ + throw new ApiErrorException($propertyWebRoomMappingResult['message']); + } + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_room_mapping' => $return ] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + +} diff --git a/app/Core/Service/PropertyWebService.php b/app/Core/Service/PropertyWebService.php new file mode 100644 index 0000000..08e635b --- /dev/null +++ b/app/Core/Service/PropertyWebService.php @@ -0,0 +1,1179 @@ +propertyWebRepository = $propertyWebRepository; + $this->propertyWebGroupRepository = $propertyWebGroupRepository; + $this->propertyWebCreateValidator = $propertyWebCreateValidator; + $this->propertyWebUpdateValidator = $propertyWebUpdateValidator; + $this->propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository; + $this->propertyPhotoService = $propertyPhotoService; + $this->propertyWebUpdateContentValidator = $propertyWebUpdateContentValidator; + $this->propertyWebPublishValidator = $propertyWebPublishValidator; + $this->propertyWebMenuService = $propertyWebMenuService; + $this->propertyWebMenuMappingService = $propertyWebMenuMappingService; + $this->propertyWebSetupService = $propertyWebSetupService; + $this->propertyWebLanguageMappingService = $propertyWebLanguageMappingService; + $this->propertyWebColorMappingService = $propertyWebColorMappingService; + $this->propertyWebAboutUsService = $propertyWebAboutUsService; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + $this->propertyWebRoomMappingService = $propertyWebRoomMappingService; + $this->propertyWebPlaceMappingService = $propertyWebPlaceMappingService; + $this->propertyWebComponentRepository = $propertyWebComponentRepository; + $this->propertyWebComponentMappingRepository = $propertyWebComponentMappingRepository; + $this->propertyWebReviewRepository = $propertyWebReviewRepository; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->propertyWebCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "property_id" => fillOnUndefined($param, "property_id"), + "domain" => fillOnUndefined($param, "domain"), + "default_language" => fillOnUndefined($param, "default_language"), + "template_id" => fillOnUndefined($param, "template_id"), + "token" => getGuid(), + "status" => 1, + "is_published" => 0, + "is_dns_checked" => 0, + "created_by" => fillOnUndefined($param, "user_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyWebRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectWebGroup($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebGroupRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Web mapping not found.')); + } + + $updateData = + [ + "domain" => fillOnUndefined($param, "domain"), + "default_language" => fillOnUndefined($param, "default_language"), + "template_id" => fillOnUndefined($param, "template_id"), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + $validationResult = $this->propertyWebUpdateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateResult = $this->propertyWebRepository->update($id, $updateData); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateLanguages($param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Web updateLanguage data not found.')); + } + + $updateData = + [ + "languages" => fillOnUndefined($param, "languages"), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + $updateResult = $this->propertyWebRepository->update($propertyWebData['id'], $updateData); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + } + + public function getPropertyWeb($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'id')], + ], + "with" => ['propertyWebTemplate', 'propertyWebLanguage'], + "firstRow" => 1 + ]; + $propertyWebs = $this->select($propertyRequest, ['id', 'domain', 'default_language', 'template_id', 'token', 'status', 'is_published', 'is_dns_checked', 'weather_active', 'cover_video_id']); + if ($propertyWebs['status'] != 'success' || !$propertyWebs['data']) { + throw new ApiErrorException('Property Web Data not found'); + } + + $response = [ + 'status' => true, + 'data' => $propertyWebs['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function insertAllPropertyWebPhotosToMapping($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyPhotoRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + + $propertyPhotos = $this->propertyPhotoService->select($propertyPhotoRequest, ['*']); + if ($propertyPhotos['status'] != 'success') { + throw new ApiErrorException('Property Photo Data not found'); + } + + $propertyPhotos = $propertyPhotos['data'] ? $propertyPhotos['data'] : []; + $insertPhotos = []; + + foreach ($propertyPhotos as $propertyPhoto) { + $insertPhotos[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'id'), + 'property_photo_id' => $propertyPhoto['id'], + 'is_cover' => 0, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos); + if ($propertyWebPhotos['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebPhotos($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $propertyPhotoRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + + $propertyPhotos = $this->propertyPhotoService->getPropertyPhotos($propertyPhotoRequest); + if ($propertyPhotos['status'] != 'success') { + throw new ApiErrorException('Property Photo Data not found'); + } + $propertyPhotos = $propertyPhotos['data']; + $propertyWebPhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + $propertyWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($propertyWebPhotoMappingRequest); + + $propertyWebMappingPhotos = $propertyWebMappingPhotos ? $propertyWebMappingPhotos : []; + $propertyWebPhotos = collect($propertyWebMappingPhotos)->keyBy('property_photo_id')->toArray(); + $propertyWebCover = collect($propertyWebMappingPhotos)->where('is_cover', '=', 1)->keyBy('property_photo_id')->toArray(); + + $photoArray = []; + foreach ($propertyPhotos as $propertyPhoto) { + $propertyWebCoverPhoto = isset($propertyWebCover[$propertyPhoto['id']]) ? $propertyWebCover[$propertyPhoto['id']] : null; + $photoArray[] = [ + 'photo_id' => $propertyPhoto['id'], + 'photo_url_thump' => $propertyPhoto['photo_url_thump'], + 'is_cover' => isset($propertyWebCover[$propertyPhoto['id']]), + 'cover_order' => fillOnUndefined($propertyWebCoverPhoto,'cover_order'), + 'is_selected' => isset($propertyWebPhotos[$propertyPhoto['id']]), + 'is_compatible_with_myweb_slider' => $propertyPhoto['is_compatible_with_myweb_slider'] + + ]; + } + + $response = [ + 'status' => true, + 'data' => $photoArray, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function selectPropertyWebPhotos($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebPhotoMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function updatePropertyWebContent($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + DB::beginTransaction(); + $validationResult = $this->propertyWebUpdateContentValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $updateData = [ + "weather_active" => fillOnUndefined($params, "weather_active", null), + "cover_video_id" => fillOnUndefined($params, "cover_video_id", null), + "updated_at" => time(), + ]; + + $this->propertyWebRepository->update($params['property_web_id'], $updateData); + + + $languagesUpdateData = [ + "property_id" => fillOnUndefined($params, "property_id"), + "property_web_id" => fillOnUndefined($params, "property_web_id"), + "user_id" => fillOnUndefined($params, "user_id") + ]; + $languagesUpdateData['languages'] = NULL; + + if (!empty($params['languages'])) { + $languagesUpdateData['languages'] = json_encode($params['languages']); + } + + + $updatePropertyWebLanguageMappingResult = $this->propertyWebLanguageMappingService->updatePropertyWebLanguageMapping($params); + if ($updatePropertyWebLanguageMappingResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWebLanguageMappingResult['message']); + } + + $updatePropertyWebColorMappingResult = $this->propertyWebColorMappingService->updatePropertyWebColorMapping($params); + if ($updatePropertyWebColorMappingResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWebColorMappingResult['message']); + } + + $updatePropertyWebMenuMappingResult = $this->propertyWebMenuMappingService->updatePropertyWebMenuMapping($params); + if ($updatePropertyWebMenuMappingResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWebMenuMappingResult['message']); + } + + $updatePropertyWeAboutUsResult = $this->propertyWebAboutUsService->updatePropertyWebAboutUs($params); + if ($updatePropertyWeAboutUsResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWeAboutUsResult['message']); + } + + $updatePropertyWebRoomMappingResult = $this->propertyWebRoomMappingService->updatePropertyWebRooomMapping($params); + if ($updatePropertyWebRoomMappingResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWebRoomMappingResult['message']); + } + + + $updatePropertyWebPlaceMappingResult = $this->propertyWebPlaceMappingService->updatePropertyWebPlaceMapping($params); + if ($updatePropertyWebPlaceMappingResult['status'] != 'success') { + throw new ApiErrorException($updatePropertyWebPlaceMappingResult['message']); + } + + $updateAdditionalInfoData = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'additional_info' => fillOnUndefined($params, 'additional_info'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $params['user_id'], + 'country_code' => fillOnUndefined($params, 'property_country_code'), + ]; + + if ($params['action'] == "publish") { + $updateAdditionalInfo = $this->propertyAdditionalInfoService->updateOrCreatePropertyAdditionalInfo($updateAdditionalInfoData); + + if ($updateAdditionalInfo['status'] != 'success') { + throw new ApiErrorException($updateAdditionalInfo['message']); + } + } + + if ($params['action'] == "preview") { + $updatePhotoPreview = $this->updatePhotoPreview($params); + if ($updatePhotoPreview['status'] != 'success') { + throw new ApiErrorException($updatePhotoPreview['message']); + } + } elseif ($params['action'] == "publish") { + $updatePhotoPublish = $this->updatePhotoPublish($params); + if ($updatePhotoPublish['status'] != 'success') { + throw new ApiErrorException($updatePhotoPublish['message']); + } + } + + + //Domain Cache Clean + //if ($params['action'] == "publish") { + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if ($propertyWebData) { + $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']); + if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) { + Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]); + } + } + //} + //Domain Cache Clean + + $response = [ + 'status' => true, + 'data' => null, + ]; + + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + + } + + return output($response); + } + + public function updatePhotoPreview($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + // delete preview photos ; + $getDeletePhotosRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => 2], + ], + ]; + + $deleteWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($getDeletePhotosRequest, ['id']); + $deleteWebMappingPhotos = $deleteWebMappingPhotos ? $deleteWebMappingPhotos : []; + $deleteMappingIds = array_column($deleteWebMappingPhotos, 'id'); + if ($deleteMappingIds) { + $destroyStatus = $this->propertyWebPhotoMappingRepository->destroy($deleteMappingIds); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + + $coverPhotos = $params['cover_photos']; + $photoMapping = $params['photo_mapping']; + $insertPhotos = []; + + $coverOrder = 1; + foreach ($coverPhotos as $photoId) { + $insertPhotos[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_photo_id' => $photoId, + 'is_cover' => 1, + 'cover_order' => $coverOrder, + 'status' => 2, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + $coverOrder++; + } + + foreach ($photoMapping as $photoId) { + $insertPhotos[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_photo_id' => $photoId, + 'is_cover' => 0, + 'cover_order' => null, + 'status' => 2, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos); + if ($propertyWebPhotos['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + + } + + return output($response); + } + + public function updatePhotoPublish($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + // delete preview photos ; + $getDeletePhotosRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ], + ]; + + $deleteWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($getDeletePhotosRequest, ['id']); + $deleteWebMappingPhotos = $deleteWebMappingPhotos ? $deleteWebMappingPhotos : []; + $deleteMappingIds = array_column($deleteWebMappingPhotos, 'id'); + if ($deleteMappingIds) { + $destroyStatus = $this->propertyWebPhotoMappingRepository->destroy($deleteMappingIds); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $coverPhotos = $params['cover_photos']; + $photoMapping = $params['photo_mapping']; + $insertPhotos = []; + + $coverPhotosCollect = collect($coverPhotos); + $photoMappingCollect = collect($photoMapping); + $photoMapping = $photoMappingCollect->diff($coverPhotosCollect)->toArray(); + + $coverOrder = 1; + foreach ($coverPhotos as $photoId) { + $insertPhotos[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_photo_id' => $photoId, + 'is_cover' => 1, + 'cover_order' => $coverOrder, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + $coverOrder++; + } + + foreach ($photoMapping as $photoId) { + $insertPhotos[] = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_photo_id' => $photoId, + 'is_cover' => 0, + 'cover_order' => null, + 'status' => 1, + "created_by" => fillOnUndefined($params, "user_id"), + "updated_by" => fillOnUndefined($params, "user_id"), + "created_at" => time(), + "updated_at" => time(), + ]; + } + + $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos); + if ($propertyWebPhotos['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + + } + + return output($response); + } + + public function setPublishWeb($param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $validationResult = $this->propertyWebPublishValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Web mapping not found.')); + } + + $updateData = + [ + "is_published" => fillOnUndefined($param, "is_publish", 0), + "updated_by" => fillOnUndefined($param, "user_id"), + "updated_at" => time(), + ]; + + + $updateResult = $this->propertyWebRepository->update($param['property_web_id'], $updateData); + + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function checkDnsStatus() + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $propertyRequest = [ + 'criteria' => [ + + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_dns_checked', 'condition' => '=', 'value' => 0], + ] + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if (!$propertyWebData) { + throw new ApiErrorException(lang('Property - Web mapping not found.')); + } + + foreach ($propertyWebData as $web) { + + $checkHostName = $web['domain']; + $domainStatus = 0; + $hostNameArray = parse_url($checkHostName); + + if (isset($hostNameArray['host'])) { + $hostName = $hostNameArray['host']; + } else { + $pathArray = explode('/', $hostNameArray['path']); + $hostName = $pathArray[0]; + } + + $recordsArray = []; + $checkRecords = dns_get_record($hostName, DNS_CNAME, $authns_cname, $addtl_cname); + $recordsArray = array_merge($recordsArray, $checkRecords); + $recordsCollection = collect($recordsArray); + + if ($recordsCollection->where('type', 'CNAME')->where('target', '=', Config::get('app.getMyWebCNAME'))->isNotEmpty() === true) { + $domainStatus = 1; + } + + if ($domainStatus == 1) { + $updateData = + [ + "is_dns_checked" => 1, + "updated_by" => 1, + "updated_at" => time(), + ]; + $updateResult = $this->propertyWebRepository->update($web['id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + } + $response = [ + 'status' => true, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function selectPropertyWebComponent($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebComponentRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectPropertyWebComponentMapping($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebComponentMappingRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebComponentMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + 'property_id' => fillOnUndefined($param, 'property_id'), + 'channel_id' => fillOnUndefined($param, 'channel_id'), + 'component_id' => fillOnUndefined($param, 'component_id'), + 'parameter' => fillOnUndefined($param, 'parameter'), + 'language' => fillOnUndefined($param, 'language'), + 'status' => 1, + 'created_by' => fillOnUndefined($param, 'created_by'), + 'updated_by' => fillOnUndefined($param, 'updated_by'), + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $createResult = $this->propertyWebComponentMappingRepository->create($insertData); + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + //Domain Cache Clean + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if ($propertyWebData) { + $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']); + if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) { + Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]); + } + } + //Domain Cache Clean + + $response = [ + 'status' => true, + 'data' => $createResult['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updatePropertyWebComponentMapping($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateData = [ + 'property_id' => fillOnUndefined($param, 'property_id'), + 'channel_id' => fillOnUndefined($param, 'channel_id'), + 'component_id' => fillOnUndefined($param, 'component_id'), + 'parameter' => fillOnUndefined($param, 'parameter'), + 'language' => fillOnUndefined($param, 'language'), + 'updated_by' => fillOnUndefined($param, 'updated_by'), + 'updated_at' => time(), + ]; + + $updateResult = $this->propertyWebComponentMappingRepository->update($id, $updateData); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + //Domain Cache Clean + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], 'firstRow' => true + ]; + $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']); + + if ($propertyWebData) { + $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']); + if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) { + Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]); + } + } + //Domain Cache Clean + + $response = [ + 'status' => true, + 'data' => $updateResult['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deletePropertyWebComponentMapping($id) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id] + ] + ]; + + $deleteResult = $this->propertyWebComponentMappingRepository->delete($deleteCriteria); + if (empty($deleteResult)) { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + /*** Property Web Review ***/ + + public function selectPropertyWebReview($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebReviewRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createPropertyWebReview($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + 'property_id' => fillOnUndefined($param, 'property_id'), + 'channel_id' => fillOnUndefined($param, 'channel_id'), + 'channel' => fillOnUndefined($param, 'channel'), + 'code' => fillOnUndefined($param, 'code'), + 'language_code' => fillOnUndefined($param, 'language_code'), + 'author' => fillOnUndefined($param, 'author'), + 'profile_photo' => fillOnUndefined($param, 'profile_photo'), + 'rating' => fillOnUndefined($param, 'rating'), + 'review' => fillOnUndefined($param, 'review'), + 'time' => fillOnUndefined($param, 'time'), + 'status' => 1, + 'created_by' => fillOnUndefined($param, 'created_by'), + 'updated_by' => fillOnUndefined($param, 'updated_by'), + 'created_at' => time(), + 'updated_at' => time(), + ]; + + + $createResult = $this->propertyWebReviewRepository->create($insertData); + if ($createResult['status'] != 'success') { + throw new ApiErrorException($createResult['message']); + } + + $response = [ + 'status' => true, + 'data' => $createResult['data'], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + /*** Property Web Review ***/ + + +} diff --git a/app/Core/Service/PropertyWebSetupService.php b/app/Core/Service/PropertyWebSetupService.php new file mode 100644 index 0000000..cf3985b --- /dev/null +++ b/app/Core/Service/PropertyWebSetupService.php @@ -0,0 +1,159 @@ +propertyWebSetupRepository = $propertyWebSetupRepository; + + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + $data = $this->propertyWebSetupRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getPropertyWebSetup($params = []){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + $searchCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ], + 'firstRow' => true + ]; + + $searchResult = $this->select($searchCriteria, ['*']); + + if($searchResult['status'] != 'success'){ + throw new ApiErrorException($searchResult['message']); + } + + $return = $searchResult['data']; + + $response = ['statusCode' => 200, 'status' => true, 'message' => '', 'data' => ['property_web_setup' => $return ] ]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function updatePropertyWebSetup($params = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + DB::beginTransaction(); + + $getDeletePropertyWebSetupRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')] + ] + ]; + + $status = null; + if($params['action'] === "publish"){ + $status = 1; + }else if($params['action'] === "preview"){ + $getDeletePropertyWebSetupRequest['criteria'][] = ['field' => 'status', 'condition' => '=', 'value' => 2]; + $status = 2; + } + + $deleteWebSetupId = $this->propertyWebSetupRepository->findByCriteria($getDeletePropertyWebSetupRequest, ['id']) ; + $deleteWebSetupId = array_column($deleteWebSetupId, 'id') ; + + if (!empty($deleteWebSetupId)) { + $destroyStatus = $this->propertyWebSetupRepository->destroy($deleteWebSetupId); + if ($destroyStatus['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + } + + $webSetupInsertData = [ + "property_id" => fillOnUndefined($params, 'property_id'), + "property_web_id" => fillOnUndefined($params, 'property_web_id'), + "languages" => empty($params['languages']) ? NULL : json_encode($params['languages']), + "color" => empty($params['colors']) ? NULL : json_encode($params['colors']), + "status" => $status, + "created_by" => fillOnUndefined($params, 'user_id'), + "updated_by" => fillOnUndefined($params, 'user_id'), + "created_at" => time(), + "updated_at" => time() + ]; + + $propertyWebSetup = $this->propertyWebSetupRepository->insert($webSetupInsertData) ; + if ($propertyWebSetup['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => null + ]; + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + DB::rollBack(); + } + + return output($response); + + } + + + + +} diff --git a/app/Core/Service/PropertyWebTemplateService.php b/app/Core/Service/PropertyWebTemplateService.php new file mode 100644 index 0000000..76767c2 --- /dev/null +++ b/app/Core/Service/PropertyWebTemplateService.php @@ -0,0 +1,125 @@ +propertyWebTemplateRepository = $propertyWebTemplateRepository; + $this->propertyWebTemplateCreateValidator = $propertyWebTemplateCreateValidator; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->propertyWebTemplateCreateValidator->validate($param); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $insertData = + [ + "name" => fillOnUndefined($param, "name"), + "folder_name" => fillOnUndefined($param, "folder_name"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + $userCreateResult = $this->propertyWebTemplateRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->propertyWebTemplateRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyWebTemplateRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/QRCodeService.php b/app/Core/Service/QRCodeService.php new file mode 100644 index 0000000..029f25a --- /dev/null +++ b/app/Core/Service/QRCodeService.php @@ -0,0 +1,33 @@ +generator = $generator; + } + + public function generate($url, $size){ + + $message = "Error occurred while generating qr code"; + $response = ['status' => false, 'message' => $message, 'data' => NULL ]; + + try { + $qrCode = $this->generator->size($size)->format('png')->generate(url($url)); + $response = ['status' => true, 'message' => '', 'data' => $qrCode ]; + }catch (Exception $e){ + Log::error($message); + } + + return $response; + + } + +}*/ diff --git a/app/Core/Service/ReputationManagementService.php b/app/Core/Service/ReputationManagementService.php new file mode 100644 index 0000000..7646cbc --- /dev/null +++ b/app/Core/Service/ReputationManagementService.php @@ -0,0 +1,227 @@ +propertyReviewRepository = $propertyReviewRepository; + $this->propertyReviewChannelRepository = $propertyReviewChannelRepository; + $this->propertyReviewChannelMappingRepository = $propertyReviewChannelMappingRepository; + $this->propertyReviewCategoryRepository = $propertyReviewCategoryRepository; + + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyReviewRepository->findByCriteria($param, $column); + if (!$data) { + throw new ApiErrorException(lang('An unknown error occurred')); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectChannel($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyReviewChannelRepository->findByCriteria($param, $column); + if (!$data) { + throw new ApiErrorException(lang('An unknown error occurred')); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectCategory($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyReviewCategoryRepository->findByCriteria($param, $column); + if (!$data) { + throw new ApiErrorException(lang('An unknown error occurred')); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function selectChannelMapping($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $data = $this->propertyReviewChannelMappingRepository->findByCriteria($param, $column); + if (!$data) { + throw new ApiErrorException(lang('An unknown error occurred')); + } + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function createChannelMapping($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $createParam = [ + 'property_id' => fillOnUndefined($param, 'property_id'), + 'channel_id' => fillOnUndefined($param, 'channel_id'), + 'parameter' => fillOnUndefined($param, 'parameter'), + 'status' => fillOnUndefined($param, 'status'), + 'created_by' => fillOnUndefined($param, 'created_by'), + 'created_at' => time() + + ]; + $createResult = $this->propertyReviewChannelMappingRepository->create($createParam); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $createResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateChannelMapping($id, $param = []) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $updateResult = $this->propertyReviewChannelMappingRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $updateResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function deleteChannelMapping($id) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $deleteCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $id] + ] + ]; + + $deleteResult = $this->propertyReviewChannelMappingRepository->delete($deleteCriteria); + if (empty($deleteResult)) { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $deleteResult, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } +} diff --git a/app/Core/Service/ServiceLogService.php b/app/Core/Service/ServiceLogService.php new file mode 100644 index 0000000..caa26a0 --- /dev/null +++ b/app/Core/Service/ServiceLogService.php @@ -0,0 +1,154 @@ +serviceLogRepository = $serviceLogRepository; + + } + + public function create($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $insertData = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => fillOnUndefined($params, 'user_id', 1), + 'type' => fillOnUndefined($params, 'type', null), + 'service' => fillOnUndefined($params, 'service'), + 'request' => fillOnUndefined($params, 'request'), + 'response' => fillOnUndefined($params, 'response'), + 'response_time' => fillOnUndefined($params, 'response_time'), + 'ip_address' => fillOnUndefined($params, 'ip_address'), + 'status' => fillOnUndefined($params, 'status'), + 'created_by' => fillOnUndefined($params, 'user_id', 1), + 'updated_by' => fillOnUndefined($params, 'user_id', 1), + ]; + + $createResult = $this->serviceLogRepository->create($insertData); + + if ($createResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response = [ + 'status' => true, + 'data' => $createResult["data"], + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->serviceLogRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + + $updateResult = $this->serviceLogRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function updateOrCreate($criteria = [], $saveData = []) + { + + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->serviceLogRepository->updateOrCreate($criteria, $saveData); + if ($data['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + + + } + + +} diff --git a/app/Core/Service/SiteConfigService.php b/app/Core/Service/SiteConfigService.php new file mode 100644 index 0000000..427c5ca --- /dev/null +++ b/app/Core/Service/SiteConfigService.php @@ -0,0 +1,171 @@ +siteConfigRepository = $siteConfigRepository; + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $insertData = + [ + "config_key" => fillOnUndefined($param, "config_key"), + "config_value_json" => fillOnUndefined($param, "config_value_json"), + "key_comment" => fillOnUndefined($param, "key_comment"), + "status" => fillOnUndefined($param, "status", 1), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "updated_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + + + $validationResult = $this->siteConfigCreateValidator->validate($insertData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $userCreateResult = $this->siteConfigRepository->create($insertData); + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userCreateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->siteConfigRepository->findByCriteria($param, $column); + + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $updateResult = $this->siteConfigRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + + public function siteHints($params){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + + $siteConfigRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'config_key', 'condition' => '=', 'value' => 'hint_list'], + ], + 'firstRow' => 1 + ]; + + $siteConfig = $this->siteConfigRepository->findByCriteria($siteConfigRequest); + $siteConfig = $siteConfig ? $siteConfig : [] ; + $hintData = fillOnUndefined($siteConfig, 'config_value_json', null); + $hintData = json_decode($hintData,1); + + + foreach ($hintData as $value){ + + $return[] = [ + 'title' => $value['title'], + 'content' => $value['content'], + 'icon' => $value['icon'], + 'url' => $value['url'], + ]; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch(ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + +} diff --git a/app/Core/Service/TempPropertyService.php b/app/Core/Service/TempPropertyService.php new file mode 100644 index 0000000..9b675b7 --- /dev/null +++ b/app/Core/Service/TempPropertyService.php @@ -0,0 +1,89 @@ +request = $request; + $this->tempPropertyRepository = $tempPropertyRepository; + $this->tempPropertySearchValidator = $tempPropertySearchValidator; + } + + public function search($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $criteria = fillOnUndefined($param , 'criteria'); + $searchData = [] ; + foreach ($criteria as $item){ + $searchData[$item['field']] = $item['value']; + } + $validationResult = $this->tempPropertySearchValidator->validate($searchData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $orWhere[] = ['field' => 'name', 'condition' => 'LIKE', 'value' => $searchData['name']]; + $requestData['orWhere'] = $orWhere; + $data = $this->tempPropertyRepository->searchTempProperty($requestData, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + + } + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->tempPropertyRepository->findByCriteria($param, $column); + $response = [ + 'status' => true, + 'data' => $data, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Service/ThirdPartyServices/MondayService.php b/app/Core/Service/ThirdPartyServices/MondayService.php new file mode 100644 index 0000000..1a9bb47 --- /dev/null +++ b/app/Core/Service/ThirdPartyServices/MondayService.php @@ -0,0 +1,122 @@ +restClient = $restClient; + $this->url = 'https://api.monday.com/v2'; + + $this->authorization = 'eyJhbGciOiJIUzI1NiJ9.eyJ0aWQiOjEzMTcwODMyNiwidWlkIjoyMjE2NDU2MiwiaWFkIjoiMjAyMS0xMS0wNFQxNzo1OTo0Ni4wMDBaIiwicGVyIjoibWU6d3JpdGUiLCJhY3RpZCI6OTAxNjcyOSwicmduIjoidXNlMSJ9.VT5EjPvtx2CzoF-ZktcrqLSyxp3A6gmgnNdfDwdIExE'; + $this->contactBoardId = 1306161833; + } + + public function requestPost($query) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + $res = $this->restClient->post($this->url, + [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => $this->authorization + ], + 'body' => json_encode(['query' => $query]), + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + if(isset($getResponse['errors'])) { + throw new ApiErrorException(pickItemFromArray('message',$getResponse['errors'])); + } + + $response = ["status" => true, 'message' => '', "data" => $getResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function createBoardItems($params = []) + { + $response = ['status' => false, 'message' => '']; + + try { + + $columnValues = [ + 'text' => $params['property_name'], + 'email' => [ + 'email' => $params['email'], + 'text' => $params['email'], + ], + 'phone' => [ + 'phone' => str_replace(' ', '', $params['phone']), + ], + 'long_text4' => 'SignupForm', + 'metin' => mb_strtoupper($params['language']), + 'tarih' => [ + 'date' => Carbon::now()->toDateString(), + 'time' => Carbon::now()->format('H:i:s') + ], + ]; + + $columnValues = json_encode(json_encode($columnValues)); + + $nameSurname = $params['name'] . ' ' . $params['surname']; + + $query = <<contactBoardId}, item_name: "{$nameSurname}", column_values : {$columnValues} ) { id } } +BUR; + + $responseData = $this->requestPost($query); + + if(!$responseData['status']) { + throw new ApiErrorException($responseData['message']); + } + + $response = [ + 'status' => true, + 'data' => $responseData['data'] + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + } + +} diff --git a/app/Core/Service/UserPropertyMappingService.php b/app/Core/Service/UserPropertyMappingService.php new file mode 100644 index 0000000..e7b8a14 --- /dev/null +++ b/app/Core/Service/UserPropertyMappingService.php @@ -0,0 +1,254 @@ +request = $request; + $this->userPropertyMappingRepository = $userPropertyMappingRepository; + $this->userPropertyMappingAddValidator = $userPropertyMappingAddValidator; + $this->userPropertyMappingRemoveValidator = $userPropertyMappingRemoveValidator; + } + + + public function select($param = [], $column = ['*']) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $data = $this->userPropertyMappingRepository->findByCriteria($param, $column); + if(!$data){ + throw new ApiErrorException(lang('An unknown error occurred')); + } + + $response['status'] = 1; + $response['data'] = $data; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $userPropertyMappingData = + [ + "user_id" => fillOnUndefined($param, "user_id"), + "property_id" => fillOnUndefined($param, "property_id"), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "created_by"), + "updated_by" => fillOnUndefined($param, "created_by"), + "created_at" => time(), + "updated_at" => time(), + ]; + $propertyCreateResult = $this->userPropertyMappingRepository->create($userPropertyMappingData); + + if ($propertyCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $propertyCreateResult["data"]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function addUserProperty($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->userPropertyMappingAddValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $checkPropertyList = $this->isAllowedProperty(['user_id' => $params['user_id'], 'add_property_id' => $params['add_property_id'],]); + + if ($checkPropertyList['status'] != 'success') { + throw new ApiErrorException($checkPropertyList['message']); + } + + $criteria = + [ + "criteria" => + [ + ["field" => "user_id", "condition" => "=", "value" => $params['add_user_id']] + ] + ]; + $oldMappingList = $this->userPropertyMappingRepository->findByCriteria($criteria, ['id', 'user_id', 'property_id', 'status']); + foreach ($params['add_property_id'] as $addProperty) { + + $checkData = collect($oldMappingList) + ->where('user_id' , '=', $params['add_user_id']) + ->where('property_id', '=', $addProperty) + ->first(); + + if(!$checkData){ + $addUserPropertyMappingData = [ + "user_id" => $params['add_user_id'], + "property_id" => $addProperty, + "status" => 1, + "created_by" => $params['user_id'], + ]; + $createStatus = $this->create($addUserPropertyMappingData); + if($createStatus['status'] != 'success'){ + throw new ApiErrorException($createStatus['message']); + } + }else{ + + + $updateUserPropertyMappingData = [ + "status" => 1, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + $updateResult = $this->userPropertyMappingRepository->update($checkData['id'], $updateUserPropertyMappingData) ; + if($updateResult['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + + } + } + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function removeUserProperty($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->userPropertyMappingRemoveValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + foreach ($params['remove_property_id'] as $addProperty) { + + + $updatePropertyCriteria = [ + 'criteria' => [ + ['field' => 'user_id', 'condition' => '=', 'value' => $params['remove_user_id'] ], + ['field' => 'property_id', 'condition' => '=', 'value' => $addProperty], + ] + + ]; + + $updateUserPropertyMappingData = [ + "status" => 0, + "updated_by" => $params['user_id'], + 'updated_at' => time() + ]; + + $updateResult = $this->userPropertyMappingRepository->updateWhere($updatePropertyCriteria, $updateUserPropertyMappingData) ; + if($updateResult['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + } + + $response = ['status' => 1 , 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function isAllowedProperty($params) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $criteria = + [ + "criteria" => + [ + ["field" => "user_id", "condition" => "=", "value" => $params['user_id']] + ] + ]; + $mappingList = $this->userPropertyMappingRepository->findByCriteria($criteria, ['id', 'user_id', 'property_id']); + + $allowedProperties = collect($mappingList); + foreach ($params['add_property_id'] as $requestProperty) { + $checkProperty = $allowedProperties->where('property_id', '=', $requestProperty)->count(); + if (!$checkProperty) { + throw new ApiErrorException(lang('property {#1} not allowed', [$requestProperty])); + } + } + $response = ['status' => 1, 'message' => '', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + return output($response); + + } +} diff --git a/app/Core/Service/UserService.php b/app/Core/Service/UserService.php new file mode 100644 index 0000000..3069aff --- /dev/null +++ b/app/Core/Service/UserService.php @@ -0,0 +1,518 @@ +request = $request; + $this->userRepository = $userRepository; + $this->userCreateValidator = $userCreateValidator; + $this->userNewPasswordValidator = $userNewPasswordValidator; + $this->changePasswordValidator = $changePasswordValidator; + $this->resetPasswordValidator = $resetPasswordValidator; + $this->profileUpdateValidator = $profileUpdateValidator; + } + + /* + * + select + create + update + delete + + * */ + + public function select($param = [], $column = ['*']) + { + + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $data = $this->userRepository->findByCriteria($param, $column); + if(!$data){ + throw new ApiErrorException(lang('An unknown error occurred')); + } + + $response['status'] = 1; + $response['data'] = $data; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function create($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + // Todo add permission + $userData = + [ + "gender" => fillOnUndefined($param, "gender"), + "name" => fillOnUndefined($param, "name"), + "surname" => fillOnUndefined($param, "surname"), + "phone" => fillOnUndefined($param, "phone"), + "language" => fillOnUndefined($param, "language"), + "email" => fillOnUndefined($param, "email"), + "password" => Str::random(6), + "hash_key" => hash('sha512', Str::random(32) ), + "status" => fillOnUndefined($param, "status", 0), + "created_by" => fillOnUndefined($param, "user_id", 1), + "updated_by" => fillOnUndefined($param, "user_id", 1), + "created_at" => time(), + "updated_at" => time(), + ]; + + $validationResult = $this->userCreateValidator->validate($userData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $userPassword = $userData['password'] ; + $userData['password'] = Hash::make($userData['password']) ; + $userCreateResult = $this->userRepository->create($userData); + + if ($userCreateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response['status'] = 1; + $userCreateResult["data"]["userPassword"] = $userPassword; + $response['data'] = $userCreateResult["data"]; + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function update($param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null ]; + + try { + + // Todo add permission + $userUpdateData = fillOnUndefined($param, 'user_update_data', []) ; + $validateKeys = ['name', 'surname', 'gender', 'phone', 'password', 'status']; + $updateData = [] ; + foreach ($userUpdateData as $key => $value){ + if(!in_array($key,$validateKeys)){ + throw new ApiErrorException(lang('Disallowed field')); + } + $updateData[$key] = $value ; + if($key == 'password'){ + $updateData['password'] = Hash::make($value) ; + } + } + if($updateData){ + $updateData['updated_by'] = $param['user_id'] ; + } + + $userUpdateResult = $this->userRepository->update($param['update_user_id'], $updateData); + if ($userUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $userUpdateResult["data"]; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + private function _updateUserProfile($id, $param = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + $updateResult = $this->userRepository->update($id, $param); + if ($updateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $updateData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $updateData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function forgotPassword($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null ]; + + try { + + $userCriteria = [ + 'criteria' => [ + ['field' => 'email', 'condition' => '=', 'value' => $params['email']], + ], + 'firstRow' => 1 + ]; + $findUser = $this->select($userCriteria); + if (!$findUser['status'] || !$findUser['data']) { + throw new ApiErrorException(lang('User not found')); + } + $findUser = $findUser['data'] ; + $hashKey = hash('sha512', Str::random(32) ); + $updateParams = [ + 'hash_key' => $hashKey, + 'updated_by' => $findUser['id'], + 'updated_at' => time() + ]; + $userUpdateResult = $this->userRepository->update($findUser['id'], $updateParams); + if ($userUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $userData = $userUpdateResult["data"]; + $response = [ + 'status' => 1, + 'data' => $userData, + ]; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function resetPassword($params = []) + { + $response = ['status' => -1, 'message' => '', 'data' => null]; + + try { + + $validationResult = $this->resetPasswordValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $userCriteria = [ + 'criteria' => [ + ['field' => 'email', 'condition' => '=', 'value' => $params['email']], + ['field' => 'hash_key', 'condition' => '=', 'value' => $params['hash_key']], + ], + 'firstRow' => 1 + ]; + $findUser = $this->select($userCriteria); + if (!$findUser['status'] || !$findUser['data']) { + throw new ApiErrorException(lang('User not found')); + } + + $findUser = $findUser['data'] ; + $hashKey = hash('sha512', Str::random(32) ); + $updateParams = [ + 'hash_key' => $hashKey, + 'password' => Hash::make($params['password']), + 'updated_by' => $findUser['id'], + 'updated_at' => time() + ]; + $userUpdateResult = $this->userRepository->update($findUser['id'], $updateParams); + if ($userUpdateResult['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $response['status'] = 1; + $response['data'] = $userUpdateResult["data"]; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function findUser($id) + { + return $this->userRepository->find($id); + } + + public function checkUserKey($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try{ + $userCriteria = [ + 'criteria' => [ + ['field' => 'email' , 'condition' => '=' , 'value' => $params['email'] ], + ['field' => 'hash_key' , 'condition' => '=' , 'value' => $params['key'] ], + ], + 'firstRow' => true, + ]; + + $userData = $this->userRepository->findByCriteria($userCriteria, ['id', 'name', 'surname', 'email', 'hash_key', 'status']) ; + if(!$userData){ + throw new ApiErrorException(lang('User not found')) ; + } + if($userData['status'] == 1){ + throw new ApiErrorException(lang('This user already activated')); + } + + $response['status'] = 1; + $response['data'] = $userData; + + }catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function newPassword($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null ]; + try{ + + $userData = [ + 'email' => fillOnUndefined($params, 'email'), + 'hash_key' => fillOnUndefined($params, 'hash_key'), + 'password' => fillOnUndefined($params, 'password'), + 'password_confirmation' => fillOnUndefined($params, 'password_confirmation'), + ]; + + $validationResult = $this->userNewPasswordValidator->validate($userData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + + $userUpdateData = [ + 'password' => Hash::make($userData['password']) , + 'status' => 1 , + 'updated_by' => $params['user_id'], + 'updated_at' => time() + ]; + + $userData = $this->userRepository->update($params['user_id'], $userUpdateData) ; + + if(!$userData){ + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function changePassword($params){ + + $response = ['status' => -1, 'message' => '', 'data' => null ]; + try{ + + $userData = [ + 'user_id' => fillOnUndefined($params, 'user_id'), + 'old_password' => fillOnUndefined($params, 'old_password'), + 'password' => fillOnUndefined($params, 'password'), + 'password_confirmation' => fillOnUndefined($params, 'password_confirmation'), + ]; + + $validationResult = $this->changePasswordValidator->validate($userData); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $userUpdateData = [ + 'password' => Hash::make($userData['password']) , + 'updated_by' => $params['user_id'], + 'updated_at' => time() + ]; + + $userData = $this->userRepository->update($userData['user_id'], $userUpdateData) ; + + if(!$userData){ + throw new Exception('api-unknown_error'); + } + + $response['status'] = 1; + $response['data'] = $userData; + + + } catch (ApiErrorException $e) { + $response['status'] = 0; + $response['message'] = implode(', ', $e->getMessageArr()); + + }catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + + public function getProfile($params, $fields = ['*']){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $profileRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['user_id']], + ['field' => 'status', 'condition' => '=', 'value' => $params['status']], + ], + 'firstRow' => true + ]; + + $profileData = $this->select($profileRequest, $fields); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $profileData['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return output($response); + } + + public function profileUpdate($params = []){ + + $response = ['status' => -1, 'message' => '', 'data' => null]; + try { + + $validationResult = $this->profileUpdateValidator->validate($params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $updateData = + [ + 'name' => fillOnUndefined($params, 'name'), + 'surname' => fillOnUndefined($params, 'surname'), + 'gender' => fillOnUndefined($params, 'gender'), + 'language' => fillOnUndefined($params, 'language'), + 'phone' => fillOnUndefined($params, 'phone'), + "updated_by" => fillOnUndefined($params, "user_id"), + "updated_at" => time() + ]; + + $updateResult = $this->_updateUserProfile($params['user_id'], $updateData); + if ($updateResult['status'] != 'success') { + throw new ApiErrorException($updateResult['message']); + } + $userData = $updateResult["data"]; + $response = [ + 'status' => true, + 'data' => $userData, + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return output($response); + } + +} diff --git a/app/Core/Validator/BaseValidator.php b/app/Core/Validator/BaseValidator.php new file mode 100644 index 0000000..0f87113 --- /dev/null +++ b/app/Core/Validator/BaseValidator.php @@ -0,0 +1,109 @@ +keyMapping = [ + 'phone' => "enw-input-mobile_phone", + 'photo' => "enw-input-photo", + 'room_rate_id' => "enw-input-rate_select", + 'room_id' => "enw-input-room", + 'description' => "enw-input-description", + 'included_occupancy' => "enw-input-included_occupancy", + 'max_room_occupancy' => "enw-input-max_room_occupancy", + ]; + + } + + public function messages() + { + $messages = []; + $rules = $this->rules(); + foreach ($rules as $key => $rule) { + $ruleArray = explode('|', $rule); + $langKey = isset($this->keyMapping[$key]) ? $this->keyMapping[$key] : $key; + foreach ($ruleArray as $ruleItem) { + $ruleArray = explode(':', $ruleItem) ; + $rule = $ruleArray[0] ; + $value = isset($ruleArray[1]) ? $ruleArray[1] : null ; + switch ($rule) { + case 'required': + $messages[$key . '.' . $rule] = __('error-input-required', ['input' => __($langKey)]); + break; + case 'required_with': + $messages[$key . '.' . $rule] = __('error-input-required', ['input' => __($langKey)]); + break; + case 'required_without': + $messages[$key . '.' . $rule] = __('error-input-required', ['input' => __($langKey)]); + break; + case 'numeric': + $messages[$key . '.' . $rule] = __('error-input-numeric', ['input' => __($langKey)]); + break; + case 'array': + $messages[$key . '.' . $rule] = __('error-input-array', ['input' => __($langKey)]); + break; + case 'date': + $messages[$key . '.' . $rule] = __('error-input-date', ['input' => __($langKey)]); + break; + case 'email': + $messages[$key . '.' . $rule] = __('error-input-email', ['input' => __($langKey)]); + break; + case 'integer': + $messages[$key . '.' . $rule] = __('error-input-integer', ['input' => __($langKey)]); + break; + case 'max': + $messages[$key . '.' . $rule] = __('error-input-max', ['input' => __($langKey), 'max' => $value]); + break; + case 'min': + $messages[$key . '.' . $rule] = __('error-input-min', ['input' => __($langKey), 'min' => $value]); + break; + case 'string': + $messages[$key . '.' . $rule] = __('error-input-string', ['input' => __($langKey)]); + break; + case 'boolean': + $messages[$key . '.' . $rule] = __('error-input-boolean', ['input' => __($langKey)]); + break; + case 'date_format': + $messages[$key . '.' . $rule] = __('error-input-date-format', ['input' => __($langKey), 'format' => $value] ); + break; + case 'in': + $messages[$key . '.' . $rule] = __('error-input-in-array', ['input' => __($langKey), 'value' => $value]); + break; + case 'image': + $messages[$key . '.' . $rule] = __('error-input-image', ['input' => __($langKey)]); + break; + case 'mimes': + $messages[$key . '.' . $rule] = __('error-input-mimes', ['input' => __($langKey)]); + break; + case 'confirmed': + $messages[$key . '.' . $rule] = __('error-input-confirmed', ['input' => __($langKey)]); + break; + case 'accepted': + $messages[$key . '.' . $rule] = __('error-input-accepted', ['input' => __($langKey)]); + break; + case 'present': + $messages[$key . '.' . $rule] = __('error-input-present', ['input' => __($langKey)]); + break; + default : + $messages[$key . '.' . $rule] = __('error-input-unknown-error', ['input' => __($langKey), 'rule' => $ruleItem]); + break; + } + } + } + return $messages; + } +} diff --git a/app/Core/Validator/Booking/BookingUpdateValidator.php b/app/Core/Validator/Booking/BookingUpdateValidator.php new file mode 100644 index 0000000..54161fc --- /dev/null +++ b/app/Core/Validator/Booking/BookingUpdateValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + 'booking_id' => 'required|numeric', + 'total' => 'required|numeric', + 'currency_code' => 'required|min:3|max:3', + 'status' => 'required|numeric|in:0,1,2,3' + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/BookingEngine/ContractUploadValidator.php b/app/Core/Validator/BookingEngine/ContractUploadValidator.php new file mode 100644 index 0000000..892cdca --- /dev/null +++ b/app/Core/Validator/BookingEngine/ContractUploadValidator.php @@ -0,0 +1,49 @@ + 'required|numeric', + 'contract_file' => 'nullable|mimes:pdf|max:10240', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Destination/DestinationSearchValidator.php b/app/Core/Validator/Destination/DestinationSearchValidator.php new file mode 100644 index 0000000..7a4b06e --- /dev/null +++ b/app/Core/Validator/Destination/DestinationSearchValidator.php @@ -0,0 +1,55 @@ + 'required|min:3', + ]; + + } + + public function messages() + { + $thisMessages = + [ + "search_term.required" => lang("search_term is required"), + "search_term.min" => lang("search_term can be minimum 3 characters"), + ]; + + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/EnwContactForm/EnwContactFormCreateValidator.php b/app/Core/Validator/EnwContactForm/EnwContactFormCreateValidator.php new file mode 100644 index 0000000..a49d449 --- /dev/null +++ b/app/Core/Validator/EnwContactForm/EnwContactFormCreateValidator.php @@ -0,0 +1,46 @@ + 'required|max:100', + "surname" => 'required|max:100', + "email" => 'required|email|max:150', + "subject" => 'required|max:500' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/ExampleValidator.php b/app/Core/Validator/ExampleValidator.php new file mode 100644 index 0000000..1ca981e --- /dev/null +++ b/app/Core/Validator/ExampleValidator.php @@ -0,0 +1,66 @@ + 'required|min:32', + 'array1' => 'required|array|in:d,e,f', + 'phone' => 'required', + 'contact.address' => 'required', + 'contact.email' => 'required|email', + 'id' => 'required|integer' + ]; + } + + + public function messages() + { + + // use example 'validation.input' => __('validation_type', ['input' => __('input language_key')]), + // validation types in baseValidator switch-case block + // + + $thisMessages = [ + 'contact.email.required' => __('error-input-required', ['input' => __('myweb-contact-mail_title')]), + 'name.required' => __('error-input-required', ['input' => __('input-property_name')]), + 'name.min' => __('error-input-min', ['input' => __('input-property_name')]), + + ]; + + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Offer/OfferCreateValidator.php b/app/Core/Validator/Offer/OfferCreateValidator.php new file mode 100644 index 0000000..6d5e3a5 --- /dev/null +++ b/app/Core/Validator/Offer/OfferCreateValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + "title" => 'required|min:3|max:200', + "expire_date" => 'required|date', + "language" => 'required|min:2|max:10', + "currency" => 'required|min:3|max:3' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Offer/OfferStatusValidator.php b/app/Core/Validator/Offer/OfferStatusValidator.php new file mode 100644 index 0000000..dbf07b4 --- /dev/null +++ b/app/Core/Validator/Offer/OfferStatusValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "offer_id" => 'required|numeric', + "status" => 'required|boolean' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Offer/OfferUpdateValidator.php b/app/Core/Validator/Offer/OfferUpdateValidator.php new file mode 100644 index 0000000..729741a --- /dev/null +++ b/app/Core/Validator/Offer/OfferUpdateValidator.php @@ -0,0 +1,46 @@ + 'required|min:3|max:200', + "expire_date" => 'required|date', + "language" => 'required|min:2|max:10', + "currency" => 'required|min:3|max:3' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingAddValidator.php b/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingAddValidator.php new file mode 100644 index 0000000..4f73c41 --- /dev/null +++ b/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingAddValidator.php @@ -0,0 +1,49 @@ + 'required|numeric', + "accommodation_mapping" => 'required|array', + "accommodation_mapping.*" => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = [ + 'accommodation_mapping.required' => __('error-input-accommodation_mapping-required') + + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingCreateValidator.php b/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingCreateValidator.php new file mode 100644 index 0000000..cd1fa79 --- /dev/null +++ b/app/Core/Validator/OfferAccommodationMapping/OfferAccommodationMappingCreateValidator.php @@ -0,0 +1,44 @@ + 'required|numeric', + "property_accommodation_id" => 'required|numeric', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferCancellationPolicy/OfferCancellationPolicyCreateValidator.php b/app/Core/Validator/OfferCancellationPolicy/OfferCancellationPolicyCreateValidator.php new file mode 100644 index 0000000..f5a89df --- /dev/null +++ b/app/Core/Validator/OfferCancellationPolicy/OfferCancellationPolicyCreateValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + "has_cancellation_policy" => 'required|boolean', + ]; + + if(fillOnUndefined($params, 'has_cancellation_policy', false) == true) + { + $return['cancellation_policy'] = 'required|array|min:1'; + $return['cancellation_policy.*.days_before'] = 'required|numeric'; + $return['cancellation_policy.*.type'] = 'required|in:FIX,PER'; + $return['cancellation_policy.*.value'] = 'required|numeric'; + } + + return $return; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferContactMapping/OfferContactMappingAddValidator.php b/app/Core/Validator/OfferContactMapping/OfferContactMappingAddValidator.php new file mode 100644 index 0000000..ada466f --- /dev/null +++ b/app/Core/Validator/OfferContactMapping/OfferContactMappingAddValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + "contact_mapping" => 'array', + "contact_mapping.*" => 'numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferContactMapping/OfferContactMappingCreateValidator.php b/app/Core/Validator/OfferContactMapping/OfferContactMappingCreateValidator.php new file mode 100644 index 0000000..982024e --- /dev/null +++ b/app/Core/Validator/OfferContactMapping/OfferContactMappingCreateValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "property_executive_id" => 'required|numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferFactMapping/OfferFactMappingAddValidator.php b/app/Core/Validator/OfferFactMapping/OfferFactMappingAddValidator.php new file mode 100644 index 0000000..f09a04a --- /dev/null +++ b/app/Core/Validator/OfferFactMapping/OfferFactMappingAddValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "fact_mapping" => 'array', + "fact_mapping.*" => 'numeric', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferFactMapping/OfferFactMappingCreateValidator.php b/app/Core/Validator/OfferFactMapping/OfferFactMappingCreateValidator.php new file mode 100644 index 0000000..d07620c --- /dev/null +++ b/app/Core/Validator/OfferFactMapping/OfferFactMappingCreateValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + "category_id" => 'required|numeric', + "property_fact_parent_id" => 'required|numeric', + "property_fact_id" => 'required|numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferImportantNotes/OfferImportantNotesCreateValidator.php b/app/Core/Validator/OfferImportantNotes/OfferImportantNotesCreateValidator.php new file mode 100644 index 0000000..536a046 --- /dev/null +++ b/app/Core/Validator/OfferImportantNotes/OfferImportantNotesCreateValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "important_notes" => 'nullable|array', + "important_notes.*" => 'nullable|string' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferPaymentType/OfferPaymentTypeCreateValidator.php b/app/Core/Validator/OfferPaymentType/OfferPaymentTypeCreateValidator.php new file mode 100644 index 0000000..92a39a9 --- /dev/null +++ b/app/Core/Validator/OfferPaymentType/OfferPaymentTypeCreateValidator.php @@ -0,0 +1,42 @@ + 'required|min:3', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } +} diff --git a/app/Core/Validator/OfferPhotoMapping/OfferCoverPhotoAddValidator.php b/app/Core/Validator/OfferPhotoMapping/OfferCoverPhotoAddValidator.php new file mode 100644 index 0000000..8a9a6ea --- /dev/null +++ b/app/Core/Validator/OfferPhotoMapping/OfferCoverPhotoAddValidator.php @@ -0,0 +1,46 @@ + 'required|numeric', + "cover_photos" => 'array', + "cover_photos.*" => 'numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingAddValidator.php b/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingAddValidator.php new file mode 100644 index 0000000..56becfd --- /dev/null +++ b/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingAddValidator.php @@ -0,0 +1,46 @@ + 'required|numeric', + "photo_mapping" => 'array', + "photo_mapping.*" => 'numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingCreateValidator.php b/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingCreateValidator.php new file mode 100644 index 0000000..271f73d --- /dev/null +++ b/app/Core/Validator/OfferPhotoMapping/OfferPhotoMappingCreateValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "property_photo_id" => 'required|numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferPrice/OfferPriceCreateValidator.php b/app/Core/Validator/OfferPrice/OfferPriceCreateValidator.php new file mode 100644 index 0000000..2091e24 --- /dev/null +++ b/app/Core/Validator/OfferPrice/OfferPriceCreateValidator.php @@ -0,0 +1,51 @@ + 'required|numeric', + "date" => 'required|date', + "property_room_id" => 'required|numeric', + "property_accommodation_id" => 'required|numeric', + "number_of_rooms" => 'required|numeric', + "currency" => 'required', + "amount" => 'required|numeric', + "total_amount" => 'required|numeric', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferRoomMapping/OfferRoomMappingAddValidator.php b/app/Core/Validator/OfferRoomMapping/OfferRoomMappingAddValidator.php new file mode 100644 index 0000000..0ec5de5 --- /dev/null +++ b/app/Core/Validator/OfferRoomMapping/OfferRoomMappingAddValidator.php @@ -0,0 +1,49 @@ + 'required|numeric', + "room_mapping" => 'required|array', + "room_mapping.*" => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = [ + 'room_mapping.required' => __('error-input-room_mapping-required') + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/OfferRoomMapping/OfferRoomMappingCreateValidator.php b/app/Core/Validator/OfferRoomMapping/OfferRoomMappingCreateValidator.php new file mode 100644 index 0000000..0c2d8bc --- /dev/null +++ b/app/Core/Validator/OfferRoomMapping/OfferRoomMappingCreateValidator.php @@ -0,0 +1,46 @@ + 'required|numeric', + "property_room_id" => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Property/PropertyBrandAddValidator.php b/app/Core/Validator/Property/PropertyBrandAddValidator.php new file mode 100644 index 0000000..15a0b65 --- /dev/null +++ b/app/Core/Validator/Property/PropertyBrandAddValidator.php @@ -0,0 +1,51 @@ + 'required|numeric', + 'title' => 'nullable|json', + 'color_codes' => 'nullable|json', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Property/PropertyBrandPhotoValidator.php b/app/Core/Validator/Property/PropertyBrandPhotoValidator.php new file mode 100644 index 0000000..fde4d74 --- /dev/null +++ b/app/Core/Validator/Property/PropertyBrandPhotoValidator.php @@ -0,0 +1,48 @@ + 'nullable|mimes:jpg,jpeg,png,webp,gif|max:10240', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } +} diff --git a/app/Core/Validator/Property/PropertyCreateValidator.php b/app/Core/Validator/Property/PropertyCreateValidator.php new file mode 100644 index 0000000..8bf38ed --- /dev/null +++ b/app/Core/Validator/Property/PropertyCreateValidator.php @@ -0,0 +1,50 @@ +propertyRepository = $propertyRepository; + } + + public function rules($params = null) + { + return + [ + 'name' => 'required|min:3' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Property/PropertyLocationUpdateValidator.php b/app/Core/Validator/Property/PropertyLocationUpdateValidator.php new file mode 100644 index 0000000..15f2b56 --- /dev/null +++ b/app/Core/Validator/Property/PropertyLocationUpdateValidator.php @@ -0,0 +1,51 @@ + 'nullable|string|max:200', + 'latitude' => 'nullable', + 'longitude' => 'nullable', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Property/PropertyPhotoValidator.php b/app/Core/Validator/Property/PropertyPhotoValidator.php new file mode 100644 index 0000000..c6d179e --- /dev/null +++ b/app/Core/Validator/Property/PropertyPhotoValidator.php @@ -0,0 +1,48 @@ + 'nullable|mimes:jpg,jpeg,png,webp|max:10240', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } +} diff --git a/app/Core/Validator/Property/PropertySearchValidator.php b/app/Core/Validator/Property/PropertySearchValidator.php new file mode 100644 index 0000000..f2ef484 --- /dev/null +++ b/app/Core/Validator/Property/PropertySearchValidator.php @@ -0,0 +1,50 @@ +PropertyRepository = $PropertyRepository; + } + + public function rules($params = null) + { + return + [ + 'name' => 'required|min:3' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/Property/PropertyUpdateValidator.php b/app/Core/Validator/Property/PropertyUpdateValidator.php new file mode 100644 index 0000000..f1dc7e1 --- /dev/null +++ b/app/Core/Validator/Property/PropertyUpdateValidator.php @@ -0,0 +1,73 @@ + 'required|min:3|max:255', + 'property_info.property_type_id' => 'required|numeric', + 'property_info.chain_id' => 'required|numeric', + 'property_info.official_name' => 'nullable|min:3|max:255', + 'property_info.country' => 'required|max:5', + 'property_info.tax_office' => 'nullable|min:3|max:255', + 'property_info.tax_number' => 'nullable|min:2|max:255', + 'property_info.checkin_time' => 'nullable|min:3|max:100', + 'property_info.checkout_time' => 'nullable|min:2|max:100', + 'additional_info' => 'array', + 'additional_info.*.year_construction' => 'nullable|string|max:100', + 'additional_info.*.year_renovation' => 'nullable|string|max:100', + + ]; + if (isset($params['additional_info']['locale_name_language']) || isset($params['additional_info']['locale_name'])) { + if ( !empty($params['additional_info']['locale_name_language']) || !empty($params['additional_info']['locale_name'])) { + $return['additional_info.locale_name_language'] = 'required|min:2|max:100'; + $return['additional_info.locale_name'] = 'required'; + } + } + + return $return; + } + + public function messages() + { + + // use example 'validation.input' => __('validation_type', ['input' => __('input form language key')]), + // validation types in baseValidator switch-case block + + $thisMessages = [ + 'property_info.name.required' => __('error-input-required', ['input' => __('input-property_name')]), + 'property_info.name.min' => __('error-input-min', ['input' => __('input-property_name')]), + + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyAdditionalInfo/PropertyAdditionalInfoAddValidator.php b/app/Core/Validator/PropertyAdditionalInfo/PropertyAdditionalInfoAddValidator.php new file mode 100644 index 0000000..479ba53 --- /dev/null +++ b/app/Core/Validator/PropertyAdditionalInfo/PropertyAdditionalInfoAddValidator.php @@ -0,0 +1,50 @@ + 'required|array', + 'data.*.additional_info_key_id' => 'required|numeric', + 'data.*.value' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyAddon/PropertyAddonValidator.php b/app/Core/Validator/PropertyAddon/PropertyAddonValidator.php new file mode 100644 index 0000000..0945bda --- /dev/null +++ b/app/Core/Validator/PropertyAddon/PropertyAddonValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + "channel_id" => 'required|numeric', + "property_addon_id" => 'required|numeric', + 'type' => 'required_without:status|in:ONT,PRP', + 'amount' => 'required_without:status|numeric', + 'status' => 'nullable|numeric' + ]; + } + + public function messages() + { + return parent::messages(); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardCertificateUploadValidator.php b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardCertificateUploadValidator.php new file mode 100644 index 0000000..38756de --- /dev/null +++ b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardCertificateUploadValidator.php @@ -0,0 +1,48 @@ + 'nullable|mimes:jpg,jpeg,png,webp,gif,pdf|max:10240', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } +} diff --git a/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateCreateValidator.php b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateCreateValidator.php new file mode 100644 index 0000000..4ac7c63 --- /dev/null +++ b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateCreateValidator.php @@ -0,0 +1,45 @@ + 'required|numeric', + "category_id" => 'required|numeric', + "name" => 'max:255', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateUpdateValidator.php b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateUpdateValidator.php new file mode 100644 index 0000000..779d6d4 --- /dev/null +++ b/app/Core/Validator/PropertyAwardsCertificate/PropertyAwardsCertificateUpdateValidator.php @@ -0,0 +1,46 @@ + 'required|numeric', + "property_id" => 'required|numeric', + "category_id" => 'required|numeric', + "name" => 'max:255', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyBookingTicket/PropertyTicketCreateValidator.php b/app/Core/Validator/PropertyBookingTicket/PropertyTicketCreateValidator.php new file mode 100644 index 0000000..d9e8152 --- /dev/null +++ b/app/Core/Validator/PropertyBookingTicket/PropertyTicketCreateValidator.php @@ -0,0 +1,47 @@ + 'nullable|numeric', + 'booking_code' => 'required|string|min:18|max:18', + 'message' => 'required|string|max:2000', + 'is_note' => 'nullable|boolean', + 'ip_address' => 'required|ip', + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyBookingTicket/PropertyTicketGetValidator.php b/app/Core/Validator/PropertyBookingTicket/PropertyTicketGetValidator.php new file mode 100644 index 0000000..1d417eb --- /dev/null +++ b/app/Core/Validator/PropertyBookingTicket/PropertyTicketGetValidator.php @@ -0,0 +1,45 @@ + 'nullable|numeric', + 'booking_code' => 'required|string|min:18|max:18', + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyAddValidator.php b/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyAddValidator.php new file mode 100644 index 0000000..1b5c9a5 --- /dev/null +++ b/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyAddValidator.php @@ -0,0 +1,67 @@ + 'required|numeric', + 'name' => 'nullable', + 'before_arrival' => 'required|numeric', + 'is_nonrefundable' => 'required|boolean', + 'is_free_cancellation' => 'required|boolean', + 'type' => 'nullable|in:PER,FIX,NGT', + 'value' => 'nullable|numeric', + 'affects_price' => 'required|boolean', + 'affects_price_action_type' => 'nullable|in:INC,DEC', + 'affects_price_type' => 'nullable|in:PER,FIX', + 'affects_price_value' => 'nullable|numeric', + 'is_date_range' => 'required|boolean', + 'start_date' => 'required_without:is_date_range|date', + 'finish_date' => 'required_without:is_date_range|date|after:start_date', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyUpdateValidator.php b/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyUpdateValidator.php new file mode 100644 index 0000000..c6a62d8 --- /dev/null +++ b/app/Core/Validator/PropertyCancellationPolicy/PropertyCancellationPolicyUpdateValidator.php @@ -0,0 +1,78 @@ + 'required|numeric', + 'cancellation_policy_id' => 'required|numeric', + 'name' => 'nullable', + 'before_arrival' => 'required|numeric', + 'is_nonrefundable' => 'required|boolean', + 'is_free_cancellation' => 'required|boolean', + 'type' => 'nullable|in:PER,FIX,NGT', + 'value' => 'nullable|numeric', + 'affects_price' => 'required|boolean', + 'affects_price_action_type' => 'nullable|in:INC,DEC', + 'affects_price_type' => 'nullable|in:PER,FIX', + 'affects_price_value' => 'nullable|numeric', + 'checkData' => 'accepted', + 'is_date_range' => 'required|boolean', + 'start_date' => 'required_without:is_date_range|date', + 'finish_date' => 'required_without:is_date_range|date|after:start_date', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkData($params){ + + $data = PropertyCancellationPolicy::where('id' , '=', $params['cancellation_policy_id']) + ->where('property_id' , '=', $params['property_id']) + ->first(); + return $data ? true : false ; + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkData"] = $this->checkData($params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyCancellationPolicy/UpdateRoomRateChannelCancellationPolicyValidator.php b/app/Core/Validator/PropertyCancellationPolicy/UpdateRoomRateChannelCancellationPolicyValidator.php new file mode 100644 index 0000000..a79d37a --- /dev/null +++ b/app/Core/Validator/PropertyCancellationPolicy/UpdateRoomRateChannelCancellationPolicyValidator.php @@ -0,0 +1,57 @@ + 'required|numeric', + 'channel_id' => 'required|numeric', + 'room_rate_channel_mapping_id' => 'required|numeric', + 'cancellation_policy_id' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannel/PropertyChannelAddValidator.php b/app/Core/Validator/PropertyChannel/PropertyChannelAddValidator.php new file mode 100644 index 0000000..6e61b90 --- /dev/null +++ b/app/Core/Validator/PropertyChannel/PropertyChannelAddValidator.php @@ -0,0 +1,51 @@ + 'required', + 'channel_category_id' => 'required|numeric', + 'currency_code' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannel/PropertyChannelDeleteValidator.php b/app/Core/Validator/PropertyChannel/PropertyChannelDeleteValidator.php new file mode 100644 index 0000000..2de819e --- /dev/null +++ b/app/Core/Validator/PropertyChannel/PropertyChannelDeleteValidator.php @@ -0,0 +1,52 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } +} diff --git a/app/Core/Validator/PropertyChannel/PropertyChannelUpdateValidator.php b/app/Core/Validator/PropertyChannel/PropertyChannelUpdateValidator.php new file mode 100644 index 0000000..c20b2d2 --- /dev/null +++ b/app/Core/Validator/PropertyChannel/PropertyChannelUpdateValidator.php @@ -0,0 +1,52 @@ + 'required|numeric', + 'name' => 'required', + 'channel_category_id' => 'required|numeric', + 'currency_code' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupAddValidator.php b/app/Core/Validator/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupAddValidator.php new file mode 100644 index 0000000..a54744c --- /dev/null +++ b/app/Core/Validator/PropertyChannelBookingPaymentSetup/PropertyChannelBookingPaymentSetupAddValidator.php @@ -0,0 +1,57 @@ + 'required|numeric', + "channel_id" => 'required|numeric', + "payments" => 'nullable|array', + "payments.*.payment_type_id" => 'required|numeric', + "payments.*.is_affected_price" => 'required|boolean', + "payments.*.action_type" => 'nullable|in:INC,DEC', + "payments.*.value_type" => 'nullable|in:FIX,PER', + "payments.*.value" => 'nullable|numeric', + "payments.*.is_selected" => 'required|boolean', + "payments.*.cancellation_policy" => 'present|array|nullable', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelCoupon/PropertyChannelCouponValidator.php b/app/Core/Validator/PropertyChannelCoupon/PropertyChannelCouponValidator.php new file mode 100644 index 0000000..bbe0307 --- /dev/null +++ b/app/Core/Validator/PropertyChannelCoupon/PropertyChannelCouponValidator.php @@ -0,0 +1,49 @@ + 'required|numeric', + "channel_id" => 'required|numeric', + "code" => 'required', + "start_date" => 'required|date', + "end_date" => 'required|date', + 'type' => 'required|in:PER,FIX', + 'value' => 'required|numeric', + 'status' => 'nullable|boolean' + ]; + } + + public function messages() + { + return parent::messages(); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingAddValidator.php b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingAddValidator.php new file mode 100644 index 0000000..78f33ea --- /dev/null +++ b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingAddValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'channels' => 'required|array', + 'channels.*' => 'required|numeric' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingRemoveValidator.php b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingRemoveValidator.php new file mode 100644 index 0000000..702e352 --- /dev/null +++ b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingRemoveValidator.php @@ -0,0 +1,51 @@ + 'required|numeric', + 'channels' => 'required|array', + 'channels.*' => 'numeric' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingUpdateValidator.php b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingUpdateValidator.php new file mode 100644 index 0000000..c6f3c5f --- /dev/null +++ b/app/Core/Validator/PropertyChannelMapping/PropertyChannelMappingUpdateValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'property_channel' => 'required|array', + 'property_channel.*.id' => 'required|numeric', + 'property_channel.*.is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelMapping/PropertyChannelSetupValidator.php b/app/Core/Validator/PropertyChannelMapping/PropertyChannelSetupValidator.php new file mode 100644 index 0000000..282489f --- /dev/null +++ b/app/Core/Validator/PropertyChannelMapping/PropertyChannelSetupValidator.php @@ -0,0 +1,96 @@ + 'required|numeric', + 'channel_id' => 'required|numeric', + 'checkPayment' => 'accepted', + 'booking' => 'array', + 'payment' => 'array', + 'availability' => 'array', + 'availability.availability_type_id' => 'numeric', + + ] ; + + + if(isset($params['booking']['value'])){ + $optionalRules = [ + 'booking.booking_type_id' => 'required|numeric', + 'booking.action_type' => 'required|in:INC,DEC', + 'booking.value_type' => 'required|in:FIX,PER', + 'booking.value' => 'numeric', + ] ; + $rules = array_merge($rules, $optionalRules) ; + } + + return $rules ; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function paymentValueControl($params){ + try { + $errorStatus = false ; + + foreach ($params['payment'] as $payment) { + if( + ($payment['value']) && + ( + $payment['action_type'] == null || $payment['value_type'] == null || + !in_array($payment['action_type'], ['INC', 'DEC']) || !in_array($payment['value_type'], ['FIX', 'PER']) + + ) + ){ + $errorStatus = true ; + break; + } + } + return $errorStatus ? false : true; + } catch (Exception $e) { + return false; + } + + + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkPayment"] = $this->paymentValueControl($params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupAddValidator.php b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupAddValidator.php new file mode 100644 index 0000000..e88c7c2 --- /dev/null +++ b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupAddValidator.php @@ -0,0 +1,56 @@ + 'required', + 'channel_id' => 'required', + 'currency_code' => 'nullable|string|required_without:connected_channel_id', + 'booking_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'availability_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'room_pricing_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'connected_channel_id' => 'nullable|numeric|required_without:currency_code', + 'connected_channel_action' => 'nullable|string|required_with:connected_channel_id' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupUpdateValidator.php b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupUpdateValidator.php new file mode 100644 index 0000000..fe4d068 --- /dev/null +++ b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupUpdateValidator.php @@ -0,0 +1,56 @@ + 'required', + 'channel_id' => 'required', + 'currency_code' => 'nullable|string|required_without:connected_channel_id', + 'booking_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'availability_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'room_pricing_type_id' => 'nullable|numeric|required_without:connected_channel_id', + 'connected_channel_id' => 'nullable|numeric|required_without:currency_code', + 'connected_channel_action' => 'nullable|string|required_with:connected_channel_id' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupWithMissingParametersAddValidator.php b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupWithMissingParametersAddValidator.php new file mode 100644 index 0000000..ff1f30f --- /dev/null +++ b/app/Core/Validator/PropertyChannelSetup/PropertyChannelSetupWithMissingParametersAddValidator.php @@ -0,0 +1,50 @@ + 'required', + 'channel_id' => 'required' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyConfig/PropertyConfigCreateValidator.php b/app/Core/Validator/PropertyConfig/PropertyConfigCreateValidator.php new file mode 100644 index 0000000..2ab3ce3 --- /dev/null +++ b/app/Core/Validator/PropertyConfig/PropertyConfigCreateValidator.php @@ -0,0 +1,49 @@ + 'required|integer', + 'config_key' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyContact/PropertyContactCreateValidator.php b/app/Core/Validator/PropertyContact/PropertyContactCreateValidator.php new file mode 100644 index 0000000..5e2dc4b --- /dev/null +++ b/app/Core/Validator/PropertyContact/PropertyContactCreateValidator.php @@ -0,0 +1,79 @@ +propertyContactRepository = $propertyContactRepository; + } + + public function rules($params = null) + { + return + [ + // 'property_id' => 'required|integer|unique:property_contact,property_id', // todo: It should be added uniqueness + "checkMainPhoneAndMobilePhone" => "accepted", + 'phone' => 'nullable|max:50', + 'mobile' => 'nullable|max:50', + 'mobile2' => 'nullable|max:50', + 'fax' => 'nullable|max:50', + 'email' => 'required|email|max:100', + 'web' => 'nullable|max:100', + 'zip_code' => 'nullable|max:20', + 'address' => 'nullable|max:200', + 'latitude' => 'nullable', + 'longitude' => 'nullable', + 'status' => 'required|integer|max:4', + 'created_by' => 'required|integer', + 'updated_by' => 'required|integer', + 'social_media_addresses' => 'nullable|json|max:512', + ]; + + + } + + public function messages() + { + $thisMessages = [ + 'checkMainPhoneAndMobilePhone.accepted' => 'phone or mobile phone required' // TODO : language key eklenicek + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + public function checkMainPhoneAndMobilePhone($params) + { + if (empty($params['phone']) && empty($params['mobile'])) { + + return false; + } + return true; + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkMainPhoneAndMobilePhone"] = $this->checkMainPhoneAndMobilePhone( $params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyContact/PropertyContactUpdateValidator.php b/app/Core/Validator/PropertyContact/PropertyContactUpdateValidator.php new file mode 100644 index 0000000..6120543 --- /dev/null +++ b/app/Core/Validator/PropertyContact/PropertyContactUpdateValidator.php @@ -0,0 +1,73 @@ +propertyContactRepository = $propertyContactRepository; + } + + public function rules($params = null) + { + return + [ + "checkMainPhoneAndMobilePhone" => "accepted", + 'email' => 'required|email|max:100', + 'phone' => 'nullable|max:50', + 'mobile' => 'nullable|max:50', + 'mobile2' => 'nullable|max:50', + 'fax' => 'nullable|max:50', + 'web' => 'nullable|max:100', + 'zip_code' => 'nullable|max:20', + 'address' => 'nullable|max:200', + 'latitude' => 'nullable', + 'longitude' => 'nullable', + 'social_media_addresses' => 'nullable|json|max:512', + ]; + + } + + public function messages() + { + $thisMessages = [ + 'checkMainPhoneAndMobilePhone.accepted' => 'phone or mobile phone required' // TODO : language key eklenicek + ]; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkMainPhoneAndMobilePhone($params) + { + if (empty($params['phone']) && empty($params['mobile'])) { + + return false; + } + return true; + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkMainPhoneAndMobilePhone"] = $this->checkMainPhoneAndMobilePhone($params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyContent/PropertyContentCreateValidator.php b/app/Core/Validator/PropertyContent/PropertyContentCreateValidator.php new file mode 100644 index 0000000..34816a3 --- /dev/null +++ b/app/Core/Validator/PropertyContent/PropertyContentCreateValidator.php @@ -0,0 +1,54 @@ +propertyContentRepository = $propertyContentRepository; + } + + public function rules($params = null) + { + return + [ + 'property_id' => 'required', + 'content_category_id' => 'required', + 'locale' => 'required|string|max:2', + 'status' => 'required|integer|max:4', + 'created_by' => 'required|integer', + 'updated_by' => 'required|integer', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyExecutive/PropertyExecutiveCreateValidator.php b/app/Core/Validator/PropertyExecutive/PropertyExecutiveCreateValidator.php new file mode 100644 index 0000000..9fa0e31 --- /dev/null +++ b/app/Core/Validator/PropertyExecutive/PropertyExecutiveCreateValidator.php @@ -0,0 +1,57 @@ +propertyExecutiveRepository = $propertyExecutiveRepository; + } + + public function rules($params = null) + { + return + [ + 'property_id' => 'required|numeric', + 'executive_type_id' => 'required|numeric', + 'name_surname' => 'required|max:50', + 'email' => 'nullable|email|max:100', + 'extension' => 'nullable|max:10', + 'phone' => 'nullable|max:50', + 'mobile' => 'nullable|max:50', + 'fax' => 'nullable|max:50', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyExecutive/PropertyExecutiveUpdateValidator.php b/app/Core/Validator/PropertyExecutive/PropertyExecutiveUpdateValidator.php new file mode 100644 index 0000000..ac053f6 --- /dev/null +++ b/app/Core/Validator/PropertyExecutive/PropertyExecutiveUpdateValidator.php @@ -0,0 +1,55 @@ +propertyExecutiveRepository = $propertyExecutiveRepository; + } + + public function rules($params = null) + { + return + [ + 'executive_type_id' => 'required|numeric', + 'name_surname' => 'required|max:50', + 'email' => 'nullable|email|max:100', + 'extension' => 'nullable|max:10', + 'phone' => 'nullable|max:50', + 'mobile' => 'nullable|max:50', + 'fax' => 'nullable|max:50', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyFact/PropertyFactCheckboxValidator.php b/app/Core/Validator/PropertyFact/PropertyFactCheckboxValidator.php new file mode 100644 index 0000000..86fc15d --- /dev/null +++ b/app/Core/Validator/PropertyFact/PropertyFactCheckboxValidator.php @@ -0,0 +1,51 @@ + 'required|numeric', + 'property_fact' => 'required|array', + 'property_fact.*.id' => 'required|numeric', + 'property_fact.*.is_selected' => 'required|boolean' + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyFact/PropertyFactSearchValidator.php b/app/Core/Validator/PropertyFact/PropertyFactSearchValidator.php new file mode 100644 index 0000000..551a374 --- /dev/null +++ b/app/Core/Validator/PropertyFact/PropertyFactSearchValidator.php @@ -0,0 +1,49 @@ + 'nullable|min:3', + + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyNonrefundable/PropertyNonrefundableAddValidator.php b/app/Core/Validator/PropertyNonrefundable/PropertyNonrefundableAddValidator.php new file mode 100644 index 0000000..c25e82b --- /dev/null +++ b/app/Core/Validator/PropertyNonrefundable/PropertyNonrefundableAddValidator.php @@ -0,0 +1,56 @@ + 'required|numeric', + "channels" => 'required|array', + "channels.*" => 'required|integer', + "room_rate_mapping" => 'required|array', + "room_rate_mapping.*.room_rate_mapping_id" => 'required|numeric', + "room_rate_mapping.*.action_type" => 'required|in:DEC,INC', + "room_rate_mapping.*.value_type" => 'required|in:PER,FIX', + "room_rate_mapping.*.value" => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionCreateValidator.php b/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionCreateValidator.php new file mode 100644 index 0000000..fcc9044 --- /dev/null +++ b/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionCreateValidator.php @@ -0,0 +1,57 @@ + 'required|numeric', + "title" => 'required', + "description" => 'required', + "email" => 'nullable|email', + "currency" => "required", + "base_amount" => "required|numeric", + "commission" => "required|numeric", + "payment_method" => "required|in:online,offline", + "payment_type_mapping_id" => "nullable|numeric", + + ]; + } + + + + + public function messages() + { + $thisMessages = + [ + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionUpdateValidator.php b/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionUpdateValidator.php new file mode 100644 index 0000000..573c111 --- /dev/null +++ b/app/Core/Validator/PropertyPayment/PropertyPaymentTransactionUpdateValidator.php @@ -0,0 +1,58 @@ + 'required|numeric', + "order_id" => 'required', + "title" => 'required', + "description" => 'required', + "email" => 'nullable|email', + "currency" => "required", + "base_amount" => "required|numeric", + "commission" => "required|numeric", + "payment_method" => "required|in:online,offline", + "payment_type_mapping_id" => "nullable|numeric", + + ]; + } + + + + + public function messages() + { + $thisMessages = + [ + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentInstallmentsUpdateValidator.php b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentInstallmentsUpdateValidator.php new file mode 100644 index 0000000..ab15a80 --- /dev/null +++ b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentInstallmentsUpdateValidator.php @@ -0,0 +1,56 @@ + 'required|numeric', + 'property_payment_mapping_id' => 'required|numeric', + 'has_installments' => 'required|boolean', + 'installments' => 'array', + 'installments.*.installment' => 'required|numeric', + 'installments.*.commission' => 'required|numeric', + ]; + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingCreateValidator.php b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingCreateValidator.php new file mode 100644 index 0000000..31d9c6a --- /dev/null +++ b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingCreateValidator.php @@ -0,0 +1,102 @@ + 'required|numeric', + 'payment_type_id' => 'required|numeric', + 'currency' => 'required', + 'is_default' => 'required|boolean', + 'fields' => 'required|array', + 'check_fields' => 'accepted', + 'check_currencies' => 'accepted', + ]; + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkFields($params) + { + try { + $fields = PaymentType::where('status', 1) + ->where('id', $params['payment_type_id']) + ->first(); + if(!$fields){ + throw new Exception ('fields error'); + } + $fields = json_decode($fields['params']); + $apiKeys = $params['fields']; + $requiredKeys = collect($fields)->keys()->all() ; + foreach ($requiredKeys as $key) { + if(!isset($apiKeys[$key])){ + throw new Exception('field error') ; + } + } + return true; + } catch (Exception $e) { + return false; + } + } + + public function checkCurrencies($params) + { + try { + $currencies = Currency::get('code')->toArray() ; + if(!$currencies){ + throw new Exception ('currency error'); + } + + $apiCurrency = $params['currency']; + $requiredCurrencies = collect($currencies)->keyBy('code')->keys()->all() ; + + $arraySearch = in_array($apiCurrency, $requiredCurrencies) ; + if(!$arraySearch){ + throw new Exception ('valid currency error'); + } + return true; + } catch (Exception $e) { + return false; + } + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["check_fields"] = $this->checkFields($params); + $params["check_currencies"] = $this->checkCurrencies($params); + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingSetDefaultValidator.php b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingSetDefaultValidator.php new file mode 100644 index 0000000..e068e97 --- /dev/null +++ b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingSetDefaultValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'property_payment_mapping_id' => 'required|numeric', + + ]; + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingStatusUpdateValidator.php b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingStatusUpdateValidator.php new file mode 100644 index 0000000..00d839e --- /dev/null +++ b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingStatusUpdateValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + 'property_payment_mapping_id' => 'required|numeric', + 'set_status' => 'required|numeric', + + ]; + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingUpdateValidator.php b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingUpdateValidator.php new file mode 100644 index 0000000..e8f685f --- /dev/null +++ b/app/Core/Validator/PropertyPaymentMapping/PropertyPaymentMappingUpdateValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + 'property_payment_mapping_id' => 'required|numeric', + 'is_default' => 'required|boolean', + 'fields' => 'required|array', + ]; + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultAddValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultAddValidator.php new file mode 100644 index 0000000..8a5cfe1 --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultAddValidator.php @@ -0,0 +1,76 @@ + 'nullable', + 'adult_action_type' => 'required|in:DEC,INC', + 'adult' => 'required|numeric', + 'action_type' => 'required|in:DEC,INC', + 'type' => 'required|in:PER,FIX', + 'value' => 'required|numeric', + // "checkPricingName" => "accepted" + ]; + + + } + + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkPricingName($params) + { + try { + $isExistPricingName = PropertyPricingPolicyAdult::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + + return $isExistPricingName ? false : true; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + // $params["checkPricingName"] = $this->checkPricingName(['property_id' => $params["property_id"], 'name' => $params["name"]]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultUpdateValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultUpdateValidator.php new file mode 100644 index 0000000..8d663c3 --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyAdultUpdateValidator.php @@ -0,0 +1,86 @@ + 'required|numeric', + 'name' => 'nullable', + 'adult_action_type' => 'required|in:DEC,INC', + 'adult' => 'required|numeric', + 'action_type' => 'required|in:DEC,INC', + 'type' => 'required|in:PER,FIX', + 'value' => 'required|numeric', + 'checkData' => 'accepted', + // "checkPricingName" => "accepted" + ]; + + + } + + + public function checkData($params){ + + $data = PropertyPricingPolicyAdult::where('id' , '=', $params['pricing_policy_id']) + ->where('property_id' , '=', $params['property_id']) + ->first(); + return $data ? true : false ; + } + + public function checkPricingName($params) + { + try { + $isExistPricingName = PropertyPricingPolicyAdult::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + + return $isExistPricingName && $isExistPricingName['id'] !== $params['pricing_policy_id'] ? false : true; + + } catch (Exception $e) { + return false; + } + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkData"] = $this->checkData($params); + /* $params["checkPricingName"] = $this->checkPricingName([ + 'property_id' => $params["property_id"], + 'name' => $params["name"], + 'pricing_policy_id' => $params['pricing_policy_id'] + ]);*/ + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildAddValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildAddValidator.php new file mode 100644 index 0000000..65fecb4 --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildAddValidator.php @@ -0,0 +1,73 @@ + 'nullable', + 'adult' => 'required|numeric', + 'child_order' => 'required|numeric', + 'child_age_start' => 'required|numeric', + 'child_age_end' => 'required|numeric', + 'type' => 'required|in:PER,FIX', + 'value' => 'required|numeric', + //"checkPricingName" => "accepted" + ]; + + + } + + public function checkPricingName($params) + { + try { + $isExistPricingName = PropertyPricingPolicyChild::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + + return $isExistPricingName ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + // $params["checkPricingName"] = $this->checkPricingName(['property_id' => $params["property_id"], 'name' => $params["name"]]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildUpdateValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildUpdateValidator.php new file mode 100644 index 0000000..633a39f --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/PropertyPricingPolicyChildUpdateValidator.php @@ -0,0 +1,88 @@ + 'nullable', + 'adult' => 'required|numeric', + 'child_order' => 'required|numeric', + 'child_age_start' => 'required|numeric', + 'child_age_end' => 'required|numeric', + 'type' => 'required|in:PER,FIX', + 'value' => 'required|numeric', + 'checkData' => 'accepted', + // "checkPricingName" => "accepted" + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkData($params){ + + $data = PropertyPricingPolicyChild::where('id' , '=', $params['pricing_policy_id']) + ->where('property_id' , '=', $params['property_id']) + ->first(); + return $data ? true : false ; + } + + public function checkPricingName($params) + { + try { + $isExistPricingName = PropertyPricingPolicyChild::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + + return $isExistPricingName && $isExistPricingName['id'] !== $params['pricing_policy_id'] ? false : true; + + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkData"] = $this->checkData($params); + /* $params["checkPricingName"] = $this->checkPricingName([ + 'property_id' => $params["property_id"], + 'name' => $params["name"], + 'pricing_policy_id' => $params['pricing_policy_id'] + ]);*/ + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingAdultPolicyValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingAdultPolicyValidator.php new file mode 100644 index 0000000..bdd5268 --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingAdultPolicyValidator.php @@ -0,0 +1,58 @@ + 'required|numeric', + 'channel_id' => 'required|numeric', + 'room_rate_channel_mapping_id' => 'required|numeric', + 'pricing_policy_adult_id' => 'required|numeric', + 'is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingChildPolicyValidator.php b/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingChildPolicyValidator.php new file mode 100644 index 0000000..e564dfa --- /dev/null +++ b/app/Core/Validator/PropertyPersonPricingPolicy/UpdateRoomRateChannelPersonPricingChildPolicyValidator.php @@ -0,0 +1,58 @@ + 'required|numeric', + 'channel_id' => 'required|numeric', + 'room_rate_channel_mapping_id' => 'required|numeric', + 'pricing_policy_child_id' => 'required|numeric', + 'is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPlace/PropertyPlaceCreateValidator.php b/app/Core/Validator/PropertyPlace/PropertyPlaceCreateValidator.php new file mode 100644 index 0000000..c886f94 --- /dev/null +++ b/app/Core/Validator/PropertyPlace/PropertyPlaceCreateValidator.php @@ -0,0 +1,69 @@ + 'required|numeric', + "place_category_id" => 'required|numeric', + "place_working_hour_id" => 'required|numeric', + "name" => 'required|min:1|max:50', + "reservation_requirement" => "required|boolean", + "include" => "nullable|numeric", + "hasName" => "accepted", + + ]; + } + + + + + public function messages() + { + $thisMessages = + [ + "hasName.accepted" => "This name added before", + ]; + return array_merge(parent::messages() , $thisMessages); + } + + public function hasName($params) + { + try { + $domain = PropertyPlace::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + return $domain ? false : true; + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["hasName"] = $this->hasName($params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPlace/PropertyPlaceFactMappingUpdateValidator.php b/app/Core/Validator/PropertyPlace/PropertyPlaceFactMappingUpdateValidator.php new file mode 100644 index 0000000..4da4e07 --- /dev/null +++ b/app/Core/Validator/PropertyPlace/PropertyPlaceFactMappingUpdateValidator.php @@ -0,0 +1,47 @@ + 'required|numeric', + "place_id" => 'required|numeric', + "place_fact_title_fact_mapping_id" => 'required|numeric', + "is_selected" => "required|boolean", + + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPlace/PropertyPlacePhotoMappingAddValidator.php b/app/Core/Validator/PropertyPlace/PropertyPlacePhotoMappingAddValidator.php new file mode 100644 index 0000000..0fdad20 --- /dev/null +++ b/app/Core/Validator/PropertyPlace/PropertyPlacePhotoMappingAddValidator.php @@ -0,0 +1,88 @@ + 'required|numeric', + 'place_id' => 'required|numeric', + "checkPropertyPlace" => "accepted", + "checkPropertyPhoto" => "accepted", + 'property_place_photo' => 'required|array', + 'property_place_photo.*.id' => 'required|numeric', + 'property_place_photo.*.is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkPropertyPlace($params) + { + try { + $placeData = PropertyPlace::where('property_id', $params['property_id']) + ->where('id', $params['place_id']) + ->first(); + + return $placeData ? true : false; + } catch (Exception $e) { + return false; + } + } + + public function checkPropertyPhoto($params) + { + try { + + $photos = collect($params['property_place_photo'])->keyBy('id')->keys()->toArray(); + $arrayCount = collect($params['property_place_photo'])->count(); + $photoData = PropertyPhoto::where('property_id', $params['property_id']) + ->whereIn('id', $photos) + ->count(); + return $arrayCount == $photoData ? true : false; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkPropertyPlace"] = $this->checkPropertyPlace(['property_id' => $params["property_id"], 'place_id' => $params["place_id"] ]); + $params["checkPropertyPhoto"] = $this->checkPropertyPhoto(['property_id' => $params["property_id"], 'property_place_photo' => $params["property_place_photo"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPlace/PropertyPlaceUpdateValidator.php b/app/Core/Validator/PropertyPlace/PropertyPlaceUpdateValidator.php new file mode 100644 index 0000000..64ccbe4 --- /dev/null +++ b/app/Core/Validator/PropertyPlace/PropertyPlaceUpdateValidator.php @@ -0,0 +1,68 @@ + 'required|numeric', + "place_working_hour_id" => 'required|numeric', + "name" => 'required|min:1|max:50', + "reservation_requirement" => "required|boolean", + "include" => "nullable|numeric", + "hasName" => "accepted", + + ]; + } + + public function messages() + { + $thisMessages = + [ + "hasName.accepted" => "This name added before", + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + public function hasName($params) + { + try { + $place = PropertyPlace::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->where('id', "!=", $params['property_place_id']) + ->first(); + return $place ? false : true; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["hasName"] = $this->hasName($params); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPromotion/PropertyPromotionAddValidator.php b/app/Core/Validator/PropertyPromotion/PropertyPromotionAddValidator.php new file mode 100644 index 0000000..80f18c2 --- /dev/null +++ b/app/Core/Validator/PropertyPromotion/PropertyPromotionAddValidator.php @@ -0,0 +1,84 @@ + 'required|numeric', + 'promotion_type_id' => 'required|numeric', + 'amount' => 'required|numeric|max:100', + 'days' => 'required|array', + + ]; + + $promotionType = PromotionType::where('id' , '=', $params['promotion_type_id']) + ->first(); + + $returnAdd = []; + if($promotionType['type_code'] == 'PRD'){ + $returnAdd = [ + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'reservation_start_date' => 'required|date_format:Y-m-d', + 'reservation_end_date' => 'required|date_format:Y-m-d', + ]; + }elseif($promotionType['type_code'] == 'BFD'){ + + $returnAdd = [ + 'day_before' => 'required|numeric', + ]; + + } + if($params['min_stay'] != null){ + $returnAdd['min_stay'] = 'numeric'; + } + + + return array_merge($return, $returnAdd) ; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPromotion/PropertyPromotionUpdateValidator.php b/app/Core/Validator/PropertyPromotion/PropertyPromotionUpdateValidator.php new file mode 100644 index 0000000..55b9b2d --- /dev/null +++ b/app/Core/Validator/PropertyPromotion/PropertyPromotionUpdateValidator.php @@ -0,0 +1,83 @@ + 'required|numeric', + 'promotion_type_id' => 'required|numeric', + 'amount' => 'required|numeric|max:100', + 'days' => 'required|array', + + ]; + + $promotionType = PromotionType::where('id' , '=', $params['promotion_type_id']) + ->first(); + + $returnAdd = []; + if($promotionType['type_code'] == 'PRD'){ + $returnAdd = [ + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'reservation_start_date' => 'required|date_format:Y-m-d', + 'reservation_end_date' => 'required|date_format:Y-m-d', + ]; + }elseif($promotionType['type_code'] == 'BFD'){ + $returnAdd = [ + 'day_before' => 'required|numeric', + ]; + + } + if($params['min_stay'] != null){ + $returnAdd['min_stay'] = 'numeric'; + } + + + return array_merge($return, $returnAdd) ; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyPromotion/UpdateRoomRateChannelPromotionValidator.php b/app/Core/Validator/PropertyPromotion/UpdateRoomRateChannelPromotionValidator.php new file mode 100644 index 0000000..3c38c47 --- /dev/null +++ b/app/Core/Validator/PropertyPromotion/UpdateRoomRateChannelPromotionValidator.php @@ -0,0 +1,56 @@ + 'required|numeric', + 'room_rate_channel_mapping_id' => 'required|numeric', + 'property_promotion_id' => 'required|numeric', + 'is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyQuickPricing/PropertyQuickPricingCreateValidator.php b/app/Core/Validator/PropertyQuickPricing/PropertyQuickPricingCreateValidator.php new file mode 100644 index 0000000..aed63e0 --- /dev/null +++ b/app/Core/Validator/PropertyQuickPricing/PropertyQuickPricingCreateValidator.php @@ -0,0 +1,48 @@ + 'required|numeric', + "channel_id" => 'required|numeric', + "room_rate_channel_mapping_id" => 'required|numeric', + 'action_type' => 'required|in:INC,DEC', + 'price_type' => 'required|in:PER,FIX', + 'price_value' => 'required|numeric', + + ]; + } + + public function messages() + { + return parent::messages(); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomAddValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomAddValidator.php new file mode 100644 index 0000000..1e9831d --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomAddValidator.php @@ -0,0 +1,69 @@ + 'required|numeric', + 'name' => 'required', + "checkName" => "accepted", + 'room_type_id' => 'required|numeric', + 'room_type_count' => 'required|numeric', + 'max_occupancy' => 'required|numeric', + 'max_adult' => 'required|numeric', + 'max_child' => 'required|numeric', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkName($params) + { + try { + $roomRate = PropertyRoom::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkName"] = $this->checkName(['property_id' => $params["property_id"], 'name' => $params["name"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomAndBedAddValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomAndBedAddValidator.php new file mode 100644 index 0000000..8e0c353 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomAndBedAddValidator.php @@ -0,0 +1,81 @@ + 'required|numeric', + 'name' => 'required|max:200', + "checkName" => "accepted", + 'room_type_id' => 'required|numeric', + 'room_type_count' => 'required|numeric', + 'max_occupancy' => 'required|numeric|min:1', + 'max_adult' => 'required|numeric', + 'max_child' => 'required|numeric', + 'room_bed_group' => 'nullable|array', + 'room_bed_group.*' => 'nullable|array', + 'room_bed_group.*.*.bed_type_id' => 'nullable|numeric', + 'exclude_occupancy' => 'nullable|max:500', + 'room_size_type' => 'required|max:30', + 'room_size' => 'required|max:11', + 'is_connected_room' => 'nullable|boolean', + 'is_connected_room_price' => 'nullable|boolean', + 'is_connected_room_availability' => 'nullable|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function checkName($params) + { + try { + $roomRate = PropertyRoom::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->where('room_type_id', $params['room_type_id']) + ->where('status', 1) + ->first(); + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkName"] = $this->checkName(['property_id' => $params["property_id"], 'name' => $params["name"], 'room_type_id' => $params['room_type_id'] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomAndBedUpdateValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomAndBedUpdateValidator.php new file mode 100644 index 0000000..5936bc3 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomAndBedUpdateValidator.php @@ -0,0 +1,91 @@ + 'required|numeric', + 'room_id' => 'required|numeric', + 'name' => 'required|max:200', + "checkName" => "accepted", + 'room_type_id' => 'required|numeric', + 'room_type_count' => 'required|numeric', + 'max_occupancy' => 'required|numeric|min:1', + 'max_adult' => 'required|numeric', + 'max_child' => 'required|numeric', + 'room_bed_group' => 'nullable|array', + 'room_bed_group.*' => 'nullable|array', + 'room_bed_group.*.*.bed_type_id' => 'nullable|numeric', + 'exclude_occupancy' => 'nullable|max:500', + 'room_size_type' => 'required|max:30', + 'room_size' => 'required|max:11', + 'is_connected_room' => 'nullable|boolean', + 'is_connected_room_price' => 'nullable|boolean', + 'is_connected_room_availability' => 'nullable|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function checkName($params) + { + try { + $roomRate = PropertyRoom::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->where('room_type_id', $params['room_type_id']) + ->where('id', '!=', $params['room_id']) + ->where('status', 1) + ->first(); + + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkName"] = $this->checkName( + [ + 'property_id' => $params["property_id"], + 'name' => $params["name"], + 'room_id' => $params['room_id'] , + 'room_type_id' => $params['room_type_id'] + ]); + + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomDeleteValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomDeleteValidator.php new file mode 100644 index 0000000..ddcd146 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomDeleteValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomFactMappingAddValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomFactMappingAddValidator.php new file mode 100644 index 0000000..12478dd --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomFactMappingAddValidator.php @@ -0,0 +1,69 @@ + 'required|numeric', + 'room_id' => 'required|numeric', + "checkPropertyRoom" => "accepted", + 'property_room_fact' => 'required|array', + 'property_room_fact.*.id' => 'required|numeric', + 'property_room_fact.*.is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkPropertyRoom($params) + { + try { + $roomData = PropertyRoom::where('property_id', $params['property_id']) + ->where('id', $params['room_id']) + ->first(); + + return $roomData ? true : false; + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkPropertyRoom"] = $this->checkPropertyRoom(['property_id' => $params["property_id"], 'room_id' => $params["room_id"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomInventoryValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomInventoryValidator.php new file mode 100644 index 0000000..47a1d21 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomInventoryValidator.php @@ -0,0 +1,51 @@ + 'required|numeric', + 'channel_id' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomPhotoMappingAddValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomPhotoMappingAddValidator.php new file mode 100644 index 0000000..2c9e560 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomPhotoMappingAddValidator.php @@ -0,0 +1,88 @@ + 'required|numeric', + 'room_id' => 'required|numeric', + "checkPropertyRoom" => "accepted", + "checkPropertyPhoto" => "accepted", + 'property_room_photo' => 'required|array', + 'property_room_photo.*.id' => 'required|numeric', + 'property_room_photo.*.is_selected' => 'required|boolean', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkPropertyRoom($params) + { + try { + $roomData = PropertyRoom::where('property_id', $params['property_id']) + ->where('id', $params['room_id']) + ->first(); + + return $roomData ? true : false; + } catch (Exception $e) { + return false; + } + } + + public function checkPropertyPhoto($params) + { + try { + + $photos = collect($params['property_room_photo'])->keyBy('id')->keys()->toArray(); + $arrayCount = collect($params['property_room_photo'])->count(); + $photoData = PropertyPhoto::where('property_id', $params['property_id']) + ->whereIn('id', $photos) + ->count(); + return $arrayCount == $photoData ? true : false; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkPropertyRoom"] = $this->checkPropertyRoom(['property_id' => $params["property_id"], 'room_id' => $params["room_id"] ]); + $params["checkPropertyPhoto"] = $this->checkPropertyPhoto(['property_id' => $params["property_id"], 'property_room_photo' => $params["property_room_photo"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoom/PropertyRoomUpdateValidator.php b/app/Core/Validator/PropertyRoom/PropertyRoomUpdateValidator.php new file mode 100644 index 0000000..0596aa3 --- /dev/null +++ b/app/Core/Validator/PropertyRoom/PropertyRoomUpdateValidator.php @@ -0,0 +1,72 @@ + 'required|numeric', + 'name' => 'required', + "checkName" => "accepted", + 'room_type_id' => 'required|numeric', + 'room_type_count' => 'required|numeric', + 'max_occupancy' => 'required|numeric', + 'max_adult' => 'required|numeric', + 'max_child' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function checkName($params) + { + try { + $roomRate = PropertyRoom::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->where('id', '!=' ,$params['id']) + ->first(); + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + $params["checkName"] = $this->checkName(['property_id' => $params["property_id"], 'name' => $params["name"], 'id' => $params["id"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityAddValidator.php b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityAddValidator.php new file mode 100644 index 0000000..899e413 --- /dev/null +++ b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityAddValidator.php @@ -0,0 +1,62 @@ + 'required|numeric', + 'property_room_id' => 'required|numeric', + 'room_rate_mapping_id' => 'required|numeric', + 'channel_id' => 'required|numeric', + 'min_stay' => 'required|numeric', + 'max_stay' => 'required|numeric', + 'stop_sell' => 'required|numeric', + 'booking_on_request' => 'required|numeric', + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'amount' => 'required|numeric', + 'currency' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkInsertValidator.php b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkInsertValidator.php new file mode 100644 index 0000000..9ace505 --- /dev/null +++ b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkInsertValidator.php @@ -0,0 +1,63 @@ +updateTypes = ["availability","room_stop_sell"]; + $this->includeDays = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + } + + public function rules($params = null) + { + return + [ + 'property_id' => 'required|numeric', + 'update_type' => 'required|in:'.implode(',', $this->updateTypes), + 'value' => 'required|numeric', + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'availability_type_id' => 'required|in:1,2,3', + 'channel_id' => 'required|integer', + + 'room_rates' => 'required|array', + 'room_rates.*.room_id' => 'required|numeric', + 'room_rates.*.room_rate_mapping_id' => 'array', + 'include_days.*' => 'required|in:'.implode(',', $this->includeDays), + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkUpdateValidator.php b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkUpdateValidator.php new file mode 100644 index 0000000..a66bce3 --- /dev/null +++ b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityBulkUpdateValidator.php @@ -0,0 +1,56 @@ + 'array', + 'availability.*.setup_type_id' => 'required|numeric', + 'availability.*.room_id' => 'required|numeric', + 'availability.*.date' => 'required|date_format:Y-m-d', + 'availability.*.availability' => 'numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityDeleteValidator.php b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityDeleteValidator.php new file mode 100644 index 0000000..310b3a9 --- /dev/null +++ b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityDeleteValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityUpdateValidator.php b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityUpdateValidator.php new file mode 100644 index 0000000..23e961d --- /dev/null +++ b/app/Core/Validator/PropertyRoomAvailability/PropertyRoomAvailabilityUpdateValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'property_room_id' => 'required|numeric', + 'room_rate_mapping_id' => 'required|numeric', + 'channel_id' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomBed/PropertyRoomBedAddValidator.php b/app/Core/Validator/PropertyRoomBed/PropertyRoomBedAddValidator.php new file mode 100644 index 0000000..f14f659 --- /dev/null +++ b/app/Core/Validator/PropertyRoomBed/PropertyRoomBedAddValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'bed_group' => 'required|numeric', + 'count' => 'required|numeric', + 'bed_type_id' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddValidator.php b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddValidator.php new file mode 100644 index 0000000..f7497f3 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'name' => 'required', + 'accommodation_type' => 'required|numeric', + 'min_stay' => 'required|numeric', + 'max_stay' => 'required|numeric', + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddWithInclusionValidator.php b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddWithInclusionValidator.php new file mode 100644 index 0000000..0720479 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateAddWithInclusionValidator.php @@ -0,0 +1,70 @@ + 'required|numeric', + 'name' => 'required', + "checkName" => "accepted", + 'accommodation_type' => 'required|numeric', + /*'min_stay' => 'required|numeric', + 'max_stay' => 'required|numeric',*/ + 'facts' => 'nullable|array', + 'facts.*' => 'nullable|numeric', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function checkName($params) + { + try { + $roomRate = PropertyRoomRate::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->first(); + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + $params["checkName"] = $this->checkName(['property_id' => $params["property_id"], 'name' => $params["name"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + + } + +} diff --git a/app/Core/Validator/PropertyRoomRate/PropertyRoomRateDeleteValidator.php b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateDeleteValidator.php new file mode 100644 index 0000000..4c9f057 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateDeleteValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRate/PropertyRoomRateUpdateValidator.php b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateUpdateValidator.php new file mode 100644 index 0000000..04352b6 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRate/PropertyRoomRateUpdateValidator.php @@ -0,0 +1,71 @@ + 'required|numeric', + 'property_id' => 'required|numeric', + 'name' => 'required', + "checkName" => "accepted", + 'accommodation_type' => 'required|numeric', + 'status' => 'numeric|min:0|max:1' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkName($params) + { + try { + $roomRate = PropertyRoomRate::where('property_id', $params['property_id']) + ->where('name', $params['name']) + ->where('id', '!=' ,$params['id']) + ->first(); + return $roomRate ? false : true; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + + $params["checkName"] = $this->checkName(['property_id' => $params["property_id"], 'name' => $params["name"], 'id' => $params["id"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingAddValidator.php b/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingAddValidator.php new file mode 100644 index 0000000..1fe3b0c --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingAddValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + 'channels' => 'required|array', + 'channels.*' => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingUpdateValidator.php b/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingUpdateValidator.php new file mode 100644 index 0000000..408fc1e --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateChannelMapping/PropertyRoomRateChannelMappingUpdateValidator.php @@ -0,0 +1,54 @@ + 'required|array', + 'room_rate_channel_mapping.*.room_rate_mapping_id' => 'required|numeric', + 'room_rate_channel_mapping.*.channel_id' => 'required|numeric', + 'room_rate_channel_mapping.*.is_selected' => 'required|boolean' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingAddValidator.php b/app/Core/Validator/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingAddValidator.php new file mode 100644 index 0000000..5e90747 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateInclusionMapping/PropertyRoomRateInclusionMappingAddValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + 'facts' => 'required|array', + 'facts.*' => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddValidator.php new file mode 100644 index 0000000..e5daec0 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddValidator.php @@ -0,0 +1,55 @@ + 'required|numeric', + 'room_rate_id' => 'required|numeric', + 'description' => 'required', + 'rack_rate' => 'required|numeric', + 'included_occupancy' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddWithSetupValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddWithSetupValidator.php new file mode 100644 index 0000000..214b995 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingAddWithSetupValidator.php @@ -0,0 +1,59 @@ + 'required|array', + 'room_id.*' => 'required|numeric', + 'room_rate_id' => 'required|numeric', + // 'rack_rate' => 'required|numeric', + 'included_occupancy' => 'required|numeric', + /*'room_rate_mapping_setup' => 'required|array', + 'room_rate_mapping_setup.*.setup_type' => 'required|in:EXT_ADULT,EXT_CHILD,DIS_GUEST', + 'room_rate_mapping_setup.*.value_type' => 'required|in:FIX,PER', + 'room_rate_mapping_setup.*.value' => 'required|numeric',*/ + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingConnectedValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingConnectedValidator.php new file mode 100644 index 0000000..51a1feb --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingConnectedValidator.php @@ -0,0 +1,55 @@ + 'required|numeric', + 'room_rate_id' => 'required|numeric', + 'connected_room_rate.*.room_id' => 'required|numeric', + 'connected_room_rate.*.room_rate_id' => 'required|numeric', + 'connected_room_rate.*.is_affected_price' => 'required|boolean', + 'connected_room_rate.*.affect_price_action_type' => 'nullable|in:INC,DEC', + 'connected_room_rate.*.affect_price_type' => 'nullable|in:PER,FIX', + 'connected_room_rate.*.affect_price_value' => 'nullable|numeric', + ]; + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages(), $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingDeleteValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingDeleteValidator.php new file mode 100644 index 0000000..7207dc3 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingDeleteValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingSetStatusValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingSetStatusValidator.php new file mode 100644 index 0000000..14cbeca --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingSetStatusValidator.php @@ -0,0 +1,48 @@ + 'required|numeric', + 'is_selected' => 'required|boolean', + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingUpdateValidator.php b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingUpdateValidator.php new file mode 100644 index 0000000..8a2f468 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMapping/PropertyRoomRateMappingUpdateValidator.php @@ -0,0 +1,55 @@ + 'required|numeric', + 'room_id' => 'required|numeric', + 'room_rate_id' => 'required|numeric', + 'description' => 'required', + 'rack_rate' => 'required|numeric', + 'included_occupancy' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupAddValidator.php b/app/Core/Validator/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupAddValidator.php new file mode 100644 index 0000000..be0a74c --- /dev/null +++ b/app/Core/Validator/PropertyRoomRateMappingSetup/PropertyRoomRateMappingSetupAddValidator.php @@ -0,0 +1,61 @@ +setupType = array('EXT_ADULT', 'EXT_CHILD', 'DIS_GUEST'); + $this->valueType = array('PER', 'FIX'); + + } + + public function rules($params = null) + { + return + [ + 'room_rate_mapping_id' => 'required|numeric', + 'setup' => 'required|array', + 'setup.*.setup_type' => 'required|in:'.implode(',', $this->setupType), + 'setup.*.value_type' => 'required|in:'.implode(',', $this->valueType), + 'setup.*.value' => 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceAddValidator.php b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceAddValidator.php new file mode 100644 index 0000000..d352f3b --- /dev/null +++ b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceAddValidator.php @@ -0,0 +1,62 @@ + 'required|numeric', + 'property_room_id' => 'required|numeric', + 'room_rate_mapping_id' => 'required|numeric', + 'channel_id' => 'required|numeric', + 'min_stay' => 'required|numeric', + 'max_stay' => 'required|numeric', + 'stop_sell' => 'required|numeric', + 'booking_on_request' => 'required|numeric', + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'amount' => 'required|numeric', + 'currency' => 'required', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkInsertValidator.php b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkInsertValidator.php new file mode 100644 index 0000000..1029989 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkInsertValidator.php @@ -0,0 +1,65 @@ +updateTypes = ["rate", "minstay", "maxstay", "stopsell", "bookingonrequest","rate_stop_sell","min_stay","quick_pricing"]; + $this->includeDays = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + } + + public function rules($params = null) + { + return + [ + 'property_id' => 'required|numeric', + 'update_type' => 'required|in:'.implode(',', $this->updateTypes), + 'value' => 'required|numeric', + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d', + 'availability_type_id' => 'required|in:1,2,3', + 'channel_id' => 'required|integer', + + 'room_rates' => 'required|array', + 'room_rates.*.room_id' => 'required|numeric', + 'room_rates.*.room_rate_mapping_id' => 'required|array', + 'include_days.*' => 'required|in:'.implode(',', $this->includeDays), + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkUpdateValidator.php b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkUpdateValidator.php new file mode 100644 index 0000000..46d7390 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceBulkUpdateValidator.php @@ -0,0 +1,59 @@ +updateTypes = ["rate", "min_stay", "max_stay", "stop_sell"]; + $this->includeDays = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + } + + public function rules($params = null) + { + return + [ + 'rates' => 'array', + 'rates.*.setup_type_id' => 'required|numeric', + 'rates.*.room_id' => 'required|numeric', + 'rates.*.room_rate_mapping_id' => 'required|numeric', + 'rates.*.date' => 'required|date_format:Y-m-d', + 'rates.*.amount' => 'numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceDeleteValidator.php b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceDeleteValidator.php new file mode 100644 index 0000000..d55783d --- /dev/null +++ b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceDeleteValidator.php @@ -0,0 +1,54 @@ + 'required|numeric', + + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceUpdateValidator.php b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceUpdateValidator.php new file mode 100644 index 0000000..f4c32e5 --- /dev/null +++ b/app/Core/Validator/PropertyRoomRatePrice/PropertyRoomRatePriceUpdateValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'property_room_id' => 'required|numeric', + 'room_rate_mapping_id' => 'required|numeric', + 'channel_id' => 'required|numeric', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWeb/PropertyWebContactFormValidator.php b/app/Core/Validator/PropertyWeb/PropertyWebContactFormValidator.php new file mode 100644 index 0000000..7983116 --- /dev/null +++ b/app/Core/Validator/PropertyWeb/PropertyWebContactFormValidator.php @@ -0,0 +1,52 @@ + 'required', + "surname" => 'required', + "email" => "required|email", + "phone" => "required", + "message" => 'required|min:10', + ]; + } + + public function messages() + { + $thisMessages = [ + 'message.min' => __('error-input-min', ['input' => __('myweb-input-message')]), + 'message.required' => __('error-input-required', ['input' => __('myweb-input-message')]), + 'phone.required' => __('error-input-required', ['input' => __('enw-input-phone')]), + ]; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWeb/PropertyWebCreateValidator.php b/app/Core/Validator/PropertyWeb/PropertyWebCreateValidator.php new file mode 100644 index 0000000..c4d445d --- /dev/null +++ b/app/Core/Validator/PropertyWeb/PropertyWebCreateValidator.php @@ -0,0 +1,88 @@ + 'required|numeric', + "domain" => 'required|min:5|max:50', + "hasDomain" => "accepted", + "checkDomain" => "accepted", + "isValidDomain" => "accepted", + "default_language" => 'required|min:2|max:10', + "template_id" => 'required|numeric|min:1', + ]; + } + + public function messages() + { + $thisMessages = + [ + "checkDomain.accepted" => "This domain added before", + "hasDomain.accepted" => "This property have added other domain before", + "isValidDomain.accepted" => "Not validate domain name.", + ]; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkDomain($params) + { + try { + $domain = PropertyWeb::where('domain', $params['domain']) + ->first(); + return $domain ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function hasDomain($params) + { + try { + $domain = PropertyWeb::where('property_id', $params['property_id']) + ->first(); + return $domain ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function validDomain($domainName) + { + try { + return preg_match("/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/", $domainName) ? true : false; + } catch (Exception $e) { + return false; + } + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["isValidDomain"] = $this->validDomain($params['domain']); + $params["hasDomain"] = $this->hasDomain(['property_id' => $params["property_id"] ]); + $params["checkDomain"] = $this->checkDomain(['domain' => $params["domain"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWeb/PropertyWebPublishValidator.php b/app/Core/Validator/PropertyWeb/PropertyWebPublishValidator.php new file mode 100644 index 0000000..d96afb2 --- /dev/null +++ b/app/Core/Validator/PropertyWeb/PropertyWebPublishValidator.php @@ -0,0 +1,44 @@ + 'required|numeric', + "property_web_id" => 'required|numeric', + "is_publish" => 'required' + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWeb/PropertyWebUpdateContentValidator.php b/app/Core/Validator/PropertyWeb/PropertyWebUpdateContentValidator.php new file mode 100644 index 0000000..de4599e --- /dev/null +++ b/app/Core/Validator/PropertyWeb/PropertyWebUpdateContentValidator.php @@ -0,0 +1,50 @@ + 'required|numeric', + "property_id" => 'required|numeric', + "action" => 'required|in:preview,publish', + "photo_mapping" => "array", + "photo_mapping.*" => "integer", + "cover_photos" => 'required|array', + "cover_photos.*" => 'integer' + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWeb/PropertyWebUpdateValidator.php b/app/Core/Validator/PropertyWeb/PropertyWebUpdateValidator.php new file mode 100644 index 0000000..af43081 --- /dev/null +++ b/app/Core/Validator/PropertyWeb/PropertyWebUpdateValidator.php @@ -0,0 +1,76 @@ + 'required|numeric', + "property_id" => 'required|numeric', + "domain" => 'required|min:5|max:50', + "checkDomain" => "accepted", + "isValidDomain" => "accepted", + "default_language" => 'required|min:2|max:10', + "template_id" => 'required|numeric|min:1', + ]; + } + + public function messages() + { + $thisMessages = + [ + "checkDomain.accepted" => "This domain used other property." + ]; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkDomain($params) + { + try { + $domain = PropertyWeb::where('domain', $params['domain']) + ->whereNotIn( 'property_id', [ $params['property_id'] ]) + ->first(); + return $domain ? false : true; + } catch (Exception $e) { + return false; + } + } + + public function validDomain($domainName) + { + try { + return preg_match("/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/", $domainName) ? true : false; + } catch (Exception $e) { + return false; + } + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkDomain"] = $this->checkDomain(['domain' => $params["domain"], 'property_id' => $params["property_id"] ]); + $params["isValidDomain"] = $this->validDomain($params['domain']); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWebContent/PropertyWebContentCreateValidator.php b/app/Core/Validator/PropertyWebContent/PropertyWebContentCreateValidator.php new file mode 100644 index 0000000..f943eaa --- /dev/null +++ b/app/Core/Validator/PropertyWebContent/PropertyWebContentCreateValidator.php @@ -0,0 +1,52 @@ + 'required|numeric', + "content_category_id" => 'required|numeric', + "title" => 'required|min:2|max:250', + "language_code" => 'required|min:2|max:10', + "image" => 'nullable', + "content" => 'nullable', + ]; + } + + public function messages() + { + $thisMessages = + [ + "checkDomain.accepted" => "This domain added before", + "hasDomain.accepted" => "This property have added other domain before", + "isValidDomain.accepted" => "Not validate domain name.", + ]; + return array_merge(parent::messages(), $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/PropertyWebTemplate/PropertyWebTemplateCreateValidator.php b/app/Core/Validator/PropertyWebTemplate/PropertyWebTemplateCreateValidator.php new file mode 100644 index 0000000..5415843 --- /dev/null +++ b/app/Core/Validator/PropertyWebTemplate/PropertyWebTemplateCreateValidator.php @@ -0,0 +1,43 @@ + 'required|min:3', + "folder_name" => 'required|min:5', + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/TempProperty/TempPropertySearchValidator.php b/app/Core/Validator/TempProperty/TempPropertySearchValidator.php new file mode 100644 index 0000000..90c9f7c --- /dev/null +++ b/app/Core/Validator/TempProperty/TempPropertySearchValidator.php @@ -0,0 +1,50 @@ +tempPropertyRepository = $tempPropertyRepository; + } + + public function rules($params = null) + { + return + [ + 'name' => 'required|min:3' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/ChangePasswordValidator.php b/app/Core/Validator/User/ChangePasswordValidator.php new file mode 100644 index 0000000..6c9f40d --- /dev/null +++ b/app/Core/Validator/User/ChangePasswordValidator.php @@ -0,0 +1,69 @@ +userRepository = $userRepository; + } + + public function rules($params = null) + { + return + [ + "user_id" => "required", + "checkOldPassword" => "accepted", + 'password' => 'required|max:20|min:6|confirmed', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function checkOldPassword($params) + { + try { + + + $user = User::where('id', $params['user_id'])->first(); + $result = Hash::check($params['old_password'], $user->password) ; + return $result ? true : false; + + } catch (Exception $e) { + return false; + } + + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["checkOldPassword"] = $this->checkOldPassword(['user_id' => $params["user_id"], 'old_password' => $params["old_password"] ]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/ResetPasswordValidator.php b/app/Core/Validator/User/ResetPasswordValidator.php new file mode 100644 index 0000000..64b51f1 --- /dev/null +++ b/app/Core/Validator/User/ResetPasswordValidator.php @@ -0,0 +1,55 @@ +userRepository = $userRepository; + } + + public function rules($params = null) + { + return + [ + 'email' => 'required|email', + 'hash_key' => 'required|min:128', + 'password' => 'required|max:20|min:6|confirmed', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/UserCreateValidator.php b/app/Core/Validator/User/UserCreateValidator.php new file mode 100644 index 0000000..83aac49 --- /dev/null +++ b/app/Core/Validator/User/UserCreateValidator.php @@ -0,0 +1,73 @@ +userRepository = $userRepository; + } + + public function rules($params = null) + { + return + [ + 'name' => 'required|min:3|max:150', + 'email' => 'required|email', + 'isUniqueEmail' => 'accepted', + 'password' => 'required|max:20' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function isUniqueEmail($email) + { + try { + $criteria = + [ + "criteria" => + [ + ["field" => "email", "condition" => "=", "value" => $email] + ] + ]; + $result = $this->userRepository->findByCriteria($criteria); + + return $result ? false : true; + + } catch (Exception $e) { + return false; + } + + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + $params["isUniqueEmail"] = $this->isUniqueEmail($params["email"]); + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/UserLoginValidator.php b/app/Core/Validator/User/UserLoginValidator.php new file mode 100644 index 0000000..f4a2413 --- /dev/null +++ b/app/Core/Validator/User/UserLoginValidator.php @@ -0,0 +1,50 @@ +userRepository = $userRepository; + } + + public function rules($params = null) + { + return + [ + 'email' => 'required|email', + 'password' => 'required' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/UserNewPasswordValidator.php b/app/Core/Validator/User/UserNewPasswordValidator.php new file mode 100644 index 0000000..12a2474 --- /dev/null +++ b/app/Core/Validator/User/UserNewPasswordValidator.php @@ -0,0 +1,52 @@ +userRepository = $userRepository; + } + + public function rules($params = null) + { + return + [ + 'email' => 'required|email', + 'hash_key' => 'required|min:128', + 'password' => 'required|max:20|min:6|confirmed', + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/User/UserProfileUpdateValidator.php b/app/Core/Validator/User/UserProfileUpdateValidator.php new file mode 100644 index 0000000..9594969 --- /dev/null +++ b/app/Core/Validator/User/UserProfileUpdateValidator.php @@ -0,0 +1,44 @@ + 'required', + "surname" => 'required', + "gender" => 'nullable', + "language" => 'required', + "phone" => 'nullable' + ]; + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/UserPropertyMapping/UserPropertyMappingAddValidator.php b/app/Core/Validator/UserPropertyMapping/UserPropertyMappingAddValidator.php new file mode 100644 index 0000000..024ba3f --- /dev/null +++ b/app/Core/Validator/UserPropertyMapping/UserPropertyMappingAddValidator.php @@ -0,0 +1,53 @@ + 'required|numeric', + 'add_property_id' => 'array', + 'add_property_id.*' => 'numeric' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Core/Validator/UserPropertyMapping/UserPropertyMappingRemoveValidator.php b/app/Core/Validator/UserPropertyMapping/UserPropertyMappingRemoveValidator.php new file mode 100644 index 0000000..5d90bf0 --- /dev/null +++ b/app/Core/Validator/UserPropertyMapping/UserPropertyMappingRemoveValidator.php @@ -0,0 +1,52 @@ + 'required|numeric', + 'remove_property_id' => 'array', + 'remove_property_id.*' => 'numeric' + ]; + + + } + + public function messages() + { + $thisMessages = []; + return array_merge(parent::messages() , $thisMessages); + } + + + + public function validate(array $params, array $rules = [], array $messages = [], array $customAttributes = []) + { + return $this->make($params, $this->rules($params), $this->messages()); + } + +} diff --git a/app/Events/Event.php b/app/Events/Event.php new file mode 100644 index 0000000..4c2962b --- /dev/null +++ b/app/Events/Event.php @@ -0,0 +1,10 @@ +message = $message; + $this->messageArr = $message; + $message = is_array($message) ? implode(" -- ",$message):$message; + parent::__construct($message,$code,$previous); + } + + public function getMessageArr() + { + return is_array( $this->messageArr ) ? $this->messageArr : [$this->messageArr]; + } + + +} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php new file mode 100644 index 0000000..1a5cd78 --- /dev/null +++ b/app/Exceptions/Handler.php @@ -0,0 +1,96 @@ + "#ea4335", + "title" => ":warning: Exception ", + "text" => "<" . config("app.url") . "|" . config("app.name") . ">, " . + date("d-m-Y h:i:s") . ' ```' . + $exception->getFile() . ', ' . + $exception->getLine() . ', ' . + $exception->getMessage() . '```' + ] + ]; + + $jobCount = Jobs::count(); + if ($jobCount < 100) { + //dispatch(new SlackLogJob($param))->onQueue('slackLog'); + } else { + Log::error($param); + } + } + } + + parent::report($exception); + } + + /** + * Render an exception into an HTTP response. + * + * @param \Illuminate\Http\Request $request + * @param \Exception $exception + * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse + */ + public function render($request, Exception $exception) + { + return parent::render($request, $exception); + } +} diff --git a/app/Export/PropertyBookingListExport.php b/app/Export/PropertyBookingListExport.php new file mode 100644 index 0000000..630a003 --- /dev/null +++ b/app/Export/PropertyBookingListExport.php @@ -0,0 +1,78 @@ +dataTableData = $dataTableData; + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $cellRange = 'A1:J1'; // All headers + $event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setBold(true); + //$event->sheet->setAutoFilter($cellRange); + $event->sheet->setTitle('Property Booking List'); + }, + ]; + } + + public function columnFormats(): array + { + return [ + 'D' => NumberFormat::FORMAT_DATE_DDMMYYYY, + 'E' => NumberFormat::FORMAT_DATE_DDMMYYYY, + 'J' => NumberFormat::FORMAT_DATE_DATETIME, + ]; + } + + public function headings(): array + { + $resetData = reset($this->dataTableData); + $header = array_keys($resetData); + + return $header; + } + + public function array(): array + { + + $dataTableData = []; + + foreach ($this->dataTableData as $dataOrderKey => $dataBooking) { + + foreach ($dataBooking as $dataKey => $value) { + + if (in_array($dataKey, ['checkin_date', 'checkout_date', 'reservation_time'])) { + $value = Date::dateTimeToExcel(Carbon::parse($value)); + } + + $dataTableData[$dataOrderKey][$dataKey] = $value; + + } + + } + + + return [$dataTableData]; + } + +} diff --git a/app/Export/PropertyCompetitorExport.php b/app/Export/PropertyCompetitorExport.php new file mode 100644 index 0000000..82411ce --- /dev/null +++ b/app/Export/PropertyCompetitorExport.php @@ -0,0 +1,75 @@ +dataTableData = $dataTableData; + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function(AfterSheet $event) { + $cellRange = 'A1:Q1'; // All headers + $event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setBold(true); + //$event->sheet->setAutoFilter($cellRange); + $event->sheet->setTitle('Property Competitor Export'); + }, + ]; + } + + public function headings(): array + { + + $header = [ + 'Property' + ]; + + foreach ($this->dataTableData['date'] as $date) { + $header[] = $date; + } + + $header[] = 'Currency'; + + return $header; + } + + public function array(): array + { + + $dataTableData = []; + + foreach ($this->dataTableData['value'] as $propertyKey => $propertyValue) { + + $dataTableData[$propertyKey] = [ + 'name' => $this->dataTableData['property'][$propertyKey] + ]; + + foreach ($propertyValue as $dateKey => $value) { + $dataTableData[$propertyKey][$dateKey] = $value['amount']; + } + + $dataTableData[$propertyKey]['currency'] = $value['currency']; + + } + + + return [$dataTableData]; + } + +} diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..9277f8a --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,328 @@ +request = $request; + $this->userLoginValidator = $userLoginValidator; + $this->jwtService = $jwtService; + $this->userPropertyMappingService = $userPropertyMappingService; + $this->permissionService = $permissionService; + $this->apiAccessTokenService = $apiAccessTokenService; + } + + public function authenticate(User $user) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $return = []; + + $validationData = [ + 'email' => $this->request->input('email'), + 'password' => $this->request->input('password') + ]; + + $locale = $this->request->input('locale'); + $rememberMe = $this->request->input('remember_me') ; + + $validationResult = $this->userLoginValidator->validate($validationData); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + $user = User::where('email', $this->request->input('email'))->where('status', 1)->first(); + if (!$user) { + throw new ApiErrorException(lang('Email or password is wrong.')); + } + + if (Hash::check($this->request->input('password'), $user->password)) { + $jwtToken = $this->jwtService->jwtCreate(['user_id' => $user['id'], 'remember_me' => $rememberMe, 'day_counter' => 5]); + if ($jwtToken['status'] != 'success') { + throw new ApiErrorException(lang('An unknown error occurred.')); + } + + $jwtToken = $jwtToken['data']; + + $return = [ + 'token' => $jwtToken['token'] + ]; + } else { + throw new ApiErrorException(lang('Email or password is wrong.')); + } + + $saveToken = [ + "token" => md5(fillOnUndefined($jwtToken, "token")), + "expire_date" => fillOnUndefined($jwtToken, "exp"), + "user_id" => fillOnUndefined($user, "id"), + "invalidate" => fillOnUndefined($jwtToken, "invalidate", 0), + ]; + + $saveTokenTo = $this->apiAccessTokenService->create($saveToken); + if ($saveTokenTo['status'] != 'success') { + + throw new ApiErrorException(lang('General error')); + + } + + $return = [ + 'token' => $jwtToken['token'], + 'expire_time' => $saveTokenTo['data']['expire_time'], + 'locale' => $user['locale'] + ]; + + $onesignalKey = $this->request->input('onesignal_key'); + + if(isset($onesignalKey) && $onesignalKey){ + if(strlen($onesignalKey) > 36){ + throw new ApiErrorException(lang('Onesignal Key Size error')); + } + $userUpdateStatus = User::where('id', $user['id'])->where('status', 1) + ->update(['onesignal_key' => $onesignalKey]); + + if ($userUpdateStatus !== 1) { + throw new ApiErrorException(lang('Onesignal Key Update Error')); + } + } + + $mappingPropertiesCriteria = [ + 'criteria' => [ + ['field' => 'user_id', 'condition' => '=', 'value' => $user['id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + + ], + 'with' => ['property.defaultPropertyPhoto'], + ]; + + $mappingProperties = $this->userPropertyMappingService->select($mappingPropertiesCriteria); + if (!$mappingProperties['data']) { + throw new ApiErrorException(lang('User Property mapping not found')); + } + $propertyList = collect($mappingProperties['data'])->map(function ($value) use ($user, $locale) { + $menuParams = [ + 'user_id' => $user['id'], + 'property_id' => $value['property']['id'], + 'status' => $value['property']['status'], + 'locale' => $locale + ] ; + if (is_array($value['property'])) { + $defaultPhoto = isset($value['property']['default_property_photo']) ? $value['property']['default_property_photo'] : null ; + + $photoUrlThumbFilePath = '/assets/img/placeholder.png'; + if(isset($defaultPhoto['photo_name'])){ + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}"; + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}"; + }else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_thumbnail.{$defaultPhoto['file_ext']}"; + } + } + return $value['property'] = [ + 'id' => $value['property']['id'], + 'name' => $value['property']['name'], + 'status' => $value['property']['status'], + 'default_photo' => $photoUrlThumbFilePath , + // 'property_menu' => $this->permissionService->getMenuTreeForUser($menuParams) + ]; + } + })->where('status' , '=', 1); + + $propertyList = $propertyList->map(function ($value) { + return [ + + 'id' => $value['id'], + 'name' => $value['name'], + 'default_photo' => $value['default_photo'], + ]; + })->toArray(); + $return['property_list'] = $propertyList; + + $return['user'] = [ + 'name' => $user['name'], + 'surname' => $user['surname'], + 'language' => $user['language'] + ]; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function refreshToken(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $token = $request->header('authToken'); + $credentials = JWT::decode($token, Config::get('app.jwt.secret'), ['HS256']); + $rememberMe = $credentials->remember_me ; + $userId = $request->credentials->user_id; + + $findTokenCriteria = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => md5($token) ], + ['field' => 'expire_date', 'condition' => '>', 'value' => time() ], + ['field' => 'user_id', 'condition' => '=', 'value' => $userId ], + ['field' => 'invalidate', 'condition' => '=', 'value' => 0 ], + ], + 'firstRow' => 1 + ]; + $getTokenData = $this->apiAccessTokenService->select($findTokenCriteria); + + if(!$getTokenData['data']){ + throw new ApiErrorException(lang('Token data not found')); + } + $getTokenData = $getTokenData['data']; + $jwtToken = $this->jwtService->jwtCreate(['user_id' => $userId, 'remember_me' => $rememberMe, 'day_counter' => 0.5]); + if ($jwtToken['status'] != 'success') { + throw new ApiErrorException(lang('An unknown error occurred.')); + } + $jwtToken = $jwtToken['data']; + + $updateToken = [ + "token" => md5(fillOnUndefined($jwtToken, "token")), + "expire_date" => fillOnUndefined($jwtToken, "exp"), + "updated_at" => time(), + ]; + + + $updateTokenTo = $this->apiAccessTokenService->update($getTokenData['id'], $updateToken); + if ($updateTokenTo['status'] != 'success') { + throw new ApiErrorException(lang('General error')); + } + + $return = [ + 'token' => $jwtToken['token'], + 'expire_time' => $updateTokenTo['data']['expire_time'] + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function logOut(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $token = $request->header('authToken'); + $userId = $request->credentials->user_id; + + $findTokenCriteria = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => md5($token)], + ['field' => 'expire_date', 'condition' => '>', 'value' => time()], + ['field' => 'user_id', 'condition' => '=', 'value' => $userId], + ['field' => 'invalidate', 'condition' => '=', 'value' => 0 ], + ], + 'firstRow' => 1 + ]; + $getTokenData = $this->apiAccessTokenService->select($findTokenCriteria); + + if(!$getTokenData['data']){ + throw new ApiErrorException(lang('Token data not found.')); + } + + $getTokenData = $getTokenData['data']; + $updateToken = [ + "updated_at" => time(), + "invalidate" => 1 , + ]; + + + $updateTokenTo = $this->apiAccessTokenService->update($getTokenData['id'], $updateToken); + if ($updateTokenTo['status'] != 'success') { + throw new ApiErrorException(lang('An unknown error occurred.')); + } + + /*$userUpdateStatus = User::where('id', $userId)->where('status', 1) + ->update(['onesignal_key' => null]); + + if ($userUpdateStatus !== 1) { + throw new ApiErrorException(lang('Onesignal Key Update Error')); + }*/ + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => 'Logged out.', 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/BookingEngine/V1/BookingController.php b/app/Http/Controllers/BookingEngine/V1/BookingController.php new file mode 100644 index 0000000..a8caa60 --- /dev/null +++ b/app/Http/Controllers/BookingEngine/V1/BookingController.php @@ -0,0 +1,2661 @@ +request = $request; + $this->bookingService = $bookingService; + $this->bookingRoomService = $bookingRoomService; + $this->bookingRoomPaxService = $bookingRoomPaxService; + $this->bookingContactService = $bookingContactService; + $this->bookingPaymentService = $bookingPaymentService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyPaymentService = $propertyPaymentService; + $this->channelManagerBookingService = $channelManagerBookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + + $this->channelId = $this->request->channelId; + $this->channelToken = $this->request->channelToken; + $this->bookingEngineToken = $this->request->bookingEngineToken; + $this->bookingEnginePropertyId = $this->request->bookingEnginePropertyId; + $this->newBookingMailService = $newBookingMailService; + $this->notificationService = $notificationService; + $this->propertyAddonService = $propertyAddonService; + $this->bookingAddonService = $bookingAddonService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + $this->propertyBookingEngineSearchService = $propertyBookingEngineSearchService; + $this->channelService = $channelService; + $this->propertyBookingEngineService = $propertyBookingEngineService; + $this->currencyService = $currencyService; + $this->mailer = $mailer; + } + + public function checkRoomAndCacheData($roomInfo, $searchCacheData) + { + + $checkRoomAndCache = true; + + $roomPricesCollect = collect($searchCacheData['roomPrices']); + + foreach ($roomInfo as $roomKey => $room) { + + $cachedSearchPriceKeys = $roomPricesCollect->where('occupancyCode', $room['occupancyCode'])->keys()->toArray(); + + if (!in_array($room['rateKey'], $cachedSearchPriceKeys)) { + $checkRoomAndCache = false; + continue; + } + } + + return $checkRoomAndCache; + } + + public function getPropertyRoomAndRoomRateAvailability($param = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ['field' => 'availability', 'condition' => '>', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => $param['checkIn']], + ['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['roomDetail.propertyRoomConnected'], + 'orderBy' => [ + ['field' => 'availability_type_id', 'value' => 'ASC'], + ['field' => 'property_room_id', 'value' => 'ASC'], + ['field' => 'room_rate_mapping_id', 'value' => 'ASC'], + ['field' => 'date', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { + throw new ApiErrorException(lang('PropertyRoomAndRoomRateAvailability not found')); + } + + $response = [ + 'status' => true, + 'data' => $getPropertyRoomAndRoomRateAvailability['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function getChannelPropertyDetail($channelId, $propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'property', 'channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType', + 'channelBookingPaymentType.paymentType', 'channel' + ], + 'firstRow' => true, + ]; + + $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); + + $response = [ + 'status' => true, + 'data' => $getChannelProperty['data'], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function booking(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $roomInfo = $params['roomInfo']; + $contactInfo = $params['contactInfo']; + $searchKey = $params['searchKey']; + $couponCode = fillOnUndefined($params, 'couponCode'); + $propertyId = $this->bookingEnginePropertyId; + $extraParam = $params['extraParam'] ?? null; + + if (empty($propertyId)) { + $propertyId = $params['propertyId']; + } + + //SearchKey Check Data + $searchCacheData = $this->getCacheDataWithSearchKey($searchKey); + + if (empty($searchCacheData)) { + throw new ApiErrorException(lang('Cache data was expired.')); + } + + $requestParams = $searchCacheData['requestParams']; + + //$checkRoomAndCacheData Check Data + $checkRoomAndCacheData = $this->checkRoomAndCacheData($roomInfo, $searchCacheData); + if (!$checkRoomAndCacheData) { + throw new ApiErrorException(lang('Room rate keys are not matched.')); + } + + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + $getChannelPropertyDetail = $getChannelPropertyDetail['data']; + + $currencyCode = null; + $currencyCodes = []; + $paymentCodes = []; + $propertyIds = []; + $totalRoomsPrice = 0; + + $roomAvailabilityKeyGroup = []; + $searchCacheRoomPrices = $searchCacheData['roomPrices']; + foreach ($roomInfo as $roomOccupancy => $room) { + + $rateKeyCodeDecoded = $this->rateKeyCodeDecode($searchCacheRoomPrices[$room['rateKey']]['rateKeyCode']); + + if ($rateKeyCodeDecoded['availabilityTypeId'] == 1) { + + if (!isset($roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count'])) { + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count'] = 0; + } + + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count']++; + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['detail'] = $rateKeyCodeDecoded; + + } else { + + + if (!isset($roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count'])) { + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count'] = 0; + } + + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count']++; + $roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['detail'] = $rateKeyCodeDecoded; + + } + + + $totalRoomsPrice += $searchCacheData['roomPrices'][$room['rateKey']]['total']; + $currencyCodes[] = $searchCacheData['roomPrices'][$room['rateKey']]['currency']; + $paymentCodes[] = $searchCacheData['roomPrices'][$room['rateKey']]['bookingPaymentType']['code']; + $propertyIds[] = $rateKeyCodeDecoded['propertyId']; + + } + + $currencyCodes = array_unique($currencyCodes); + if (count($currencyCodes) != 1) { + throw new ApiErrorException(lang('Currency Code not matched')); + } + + $currencyCode = reset($currencyCodes); + + $paymentCodes = array_unique($paymentCodes); + if (count($paymentCodes) != 1) { + throw new ApiErrorException(lang('Payment Code not matched')); + } + + $paymentCode = reset($paymentCodes); + + if ($paymentCode != $params['paymentInfo']['paymentCode']) { + throw new ApiErrorException(lang('Payment Code and Payment Code Param not matched')); + } + + $propertyIds = array_unique($propertyIds); + if (count($propertyIds) != 1) { + throw new ApiErrorException(lang('Property ID not matched')); + } + + if (reset($propertyIds) != $propertyId) { + throw new ApiErrorException(lang('Property ID not matched')); + } + + //dd($roomInfo); + + $roomInfoCollect = collect($roomInfo)->groupBy('occupancyCode')->toArray(); + $roomsByOccupancies = $this->getRoomsByOccupancies($requestParams['rooms']); + foreach ($roomsByOccupancies as $roomOccupancyKey => $roomsByOccupancy) { + + if (!isset($roomInfoCollect[$roomOccupancyKey])) { + throw new ApiErrorException(lang('Room Occupancy Key not matched')); + } + + if ($roomsByOccupancy['roomCount'] != count($roomInfoCollect[$roomOccupancyKey])) { + throw new ApiErrorException(lang('Room Occupancy Count and Request Room Occupancy Count not matched')); + } + } + + + $propertyRoomAndRoomRateAvailabilityParam = [ + 'property_id' => $propertyId, + 'checkIn' => $searchCacheData['requestParams']['date']['checkIn'], + 'checkOut' => $searchCacheData['requestParams']['date']['checkOut'], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { + throw new ApiErrorException(lang('Room or rooms not available.')); + } + + $propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']); + $dateByDay = $this->getDateByDay($searchCacheData['requestParams']['date']); + + + $bookingAddon = []; + $totalAddonPrice = 0; + + + if (isset($params['addonInfo'])) { + + $propertyChannelAddonCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyAddon.fact'] + ]; + $columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'amount', 'type', 'min_stay']; + $selectPropertyChannelAddon = $this->propertyAddonService->selectPropertyChannelAddon($propertyChannelAddonCriteria, $columns); + + $propertyChannelAddon = []; + if ($selectPropertyChannelAddon['status'] == 'success') { + $propertyChannelAddon = $selectPropertyChannelAddon['data']; + } + + if (empty($propertyChannelAddon)) { + throw new ApiErrorException(lang('No additional defined products found.')); + } + + $propertyChannelAddonCollect = collect($propertyChannelAddon); + $propertyChannelAddonIds = $propertyChannelAddonCollect->pluck('id'); + $propertyChannelAddonIds = $propertyChannelAddonIds ? $propertyChannelAddonIds->toArray() : []; + $nightOfStay = Carbon::parse($searchCacheData['requestParams']['date']['checkIn'])->diff(Carbon::parse($searchCacheData['requestParams']['date']['checkOut']))->days; + + + $addonInfo = collect($params['addonInfo']); + $addonInfoIds = $addonInfo->pluck('id'); + $addonInfoIds = $addonInfoIds ? $addonInfoIds->toArray() : []; + + + if (count(array_intersect($addonInfoIds, $propertyChannelAddonIds)) != count($addonInfoIds)) { + throw new ApiErrorException(lang('Additional product values submitted do not match.')); + } + + foreach ($params['addonInfo'] as $addonInfo) { + + $selectedAddon = $propertyChannelAddonCollect->where('id', $addonInfo['id'])->first(); + + $addonInfoAttribute = null; + /*if (isset($addonInfo['attribute'])) { + foreach ($addonInfo['attribute'] as $addonAttribute) { + if (count(array_intersect_key($addonAttribute, $selectedAddon['property_addon']['attributeArray'])) != count($addonAttribute)) { + throw new ApiErrorException(lang('Additional product attribute values submitted do not match.')); + } + } + $addonInfoAttribute = $addonInfo['attribute']; + }*/ + + if (!is_null($selectedAddon['min_stay']) && $selectedAddon['min_stay'] <= $nightOfStay) { + $selectedAddon['amount'] = 0; + } + + $bookingAddon[$selectedAddon['id']] = [ + 'property_addon_id' => $selectedAddon['property_addon_id'], + 'property_channel_addon_id' => $selectedAddon['id'], + 'count' => $addonInfo['count'], + 'amount' => $selectedAddon['amount'], + 'total' => moneyDoubleFormatDecimal($addonInfo['count'] * $selectedAddon['amount']), + 'currency_code' => $currencyCode, + 'attribute' => $addonInfoAttribute + ]; + + $totalAddonPrice += $bookingAddon[$selectedAddon['id']]['total']; + } + + } + + $couponCodeData = []; + if (!is_null($couponCode)) { + + $propertyChannelCouponCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']], + ['field' => 'code', 'condition' => '=', 'value' => $couponCode], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria); + if ($propertyChannelCoupon['status'] == 'success') { + $couponCodeData = $propertyChannelCoupon['data']; + } + + //Reservation Date Check + $reservationDateCheck = true; + if (!is_null($couponCodeData['reservation_start_date']) && !is_null($couponCodeData['reservation_end_date'])) { + if (isset($searchCacheData['requestParams']['date']['checkIn']) && isset($searchCacheData['requestParams']['date']['checkOut'])) { + $reservationDateCheck = Carbon::parse($couponCodeData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($searchCacheData['requestParams']['date']['checkIn'])) + && Carbon::parse($couponCodeData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($searchCacheData['requestParams']['date']['checkOut'])); + } + } + + if(!$reservationDateCheck) { + $couponCodeData = []; + } + + } + + if (!isset($params['bookingCode'])) { + + //TODO: VALIDATORs + //1. Roominfo içindeki her bir occupancyCode ile paxes alar validatorden geçecek + //2. paxes için valdiatorden geçecek, eğer çocuk ise dt zorunlu, type, name, surname, citizen zorunlu + //3. contactInfo içi komple zorunlu validatorden geçecek + //4. searchKey, propertyId, contactInfo, roomInfo, paymentInfo zorunlu + //5. gelen ödeme tipi ile rate lerde ödmee tipleri kontrol edilecek + + + ///BOOKING START + DB::beginTransaction(); + + + $bookingCode = getCodeGenerate('BKG'); + $bookingStatus = in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) ? 1 : 2; + //1. Booking + //2. PreBooking + + + $totalRoomsPriceBeforeDiscount = $totalRoomsPrice; + $bookingDiscountAmount = 0; + if (!empty($couponCodeData)) { + if ($couponCodeData['type'] == 'PER') { + $bookingDiscountAmount = ($totalRoomsPriceBeforeDiscount * $couponCodeData['value'] / 100); + } elseif ($couponCodeData['type'] == 'FIX') { + $bookingDiscountAmount = $couponCodeData['value']; + } + $totalRoomsPrice = $totalRoomsPrice - $bookingDiscountAmount; + } + + $bookingTotalAmount = $totalRoomsPrice + $totalAddonPrice; + + + //Wholesaler MARKUP + $channelPropertyMarkup = []; + if (in_array($getChannelPropertyDetail['channel']['channel_category_id'], [7])) { + + if (!is_null($getChannelPropertyDetail['markup']) && !empty($getChannelPropertyDetail['channel']['default_currency'])) { + + $lastExchangeRate = 1; + if ($getChannelPropertyDetail['currency_code'] != $getChannelPropertyDetail['channel']['default_currency']) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($getChannelPropertyDetail['currency_code'], $getChannelPropertyDetail['channel']['default_currency']); + if ($lastExchangeRate['status'] == 'success') { + $lastExchangeRate = $lastExchangeRate['data']; + } + } + + $connectedChannelAction = !is_null($getChannelPropertyDetail['connected_channel_action']) ? json_decode($getChannelPropertyDetail['connected_channel_action'], 1) : null; + + $channelPropertyMarkup = [ + 'channel_discount' => !empty($connectedChannelAction) && isset($connectedChannelAction['value']) ? $connectedChannelAction['value'] : null, + 'channel_markup' => $getChannelPropertyDetail['markup'], + 'channel_currency_code' => $getChannelPropertyDetail['channel']['default_currency'], + 'channel_currency_exchange' => $lastExchangeRate, + ]; + + } + } + //Wholesaler MARKUP + + $bannedCharacters = ['<','>', ';', '(', ')', '=', ':', 'shell_exec']; + $bannedCheckParameter = ['name', 'surname', 'phone_number', 'email', 'note']; + + $bookingCreateParam = [ + 'property_id' => $propertyId, + 'channel_id' => $this->channelId, + 'booking_code' => $bookingCode, + 'search_key' => $params['searchKey'], + 'checkin_date' => $searchCacheData['requestParams']['date']['checkIn'], + 'checkout_date' => $searchCacheData['requestParams']['date']['checkOut'], + 'rooms' => json_encode($searchCacheData['requestParams']['rooms']), + 'payment_type_code' => $params['paymentInfo']['paymentCode'], + 'room_amount' => $totalRoomsPriceBeforeDiscount, + 'addon_amount' => $totalAddonPrice, + 'discount_amount' => $bookingDiscountAmount, + 'total' => $bookingTotalAmount, + 'currency_code' => $currencyCode, + 'channel_token' => $this->channelToken, + 'booking_engine_token' => $this->bookingEngineToken, + 'status' => $bookingStatus, + 'channel_discount' => fillOnUndefined($channelPropertyMarkup, 'channel_discount'), + 'channel_markup' => fillOnUndefined($channelPropertyMarkup, 'channel_markup'), + 'channel_currency_code' => fillOnUndefined($channelPropertyMarkup, 'channel_currency_code'), + 'channel_currency_exchange' => fillOnUndefined($channelPropertyMarkup, 'channel_currency_exchange'), + 'extra_param' => !empty($extraParam) ? json_encode($extraParam) : null, + 'coupon_code' => fillOnUndefined($couponCodeData,'code') + //Burada sor sat için bişey gelebilir + ]; + + $bookingCreate = $this->bookingService->create($bookingCreateParam); + + //$bookingCreate['status'] = 'success'; + //$bookingCreate['data']['id'] = 16; + + if ($bookingCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking could not be made')); + } + + //INSERT CONTACT DATA + $bookingContactCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'name' => $params['contactInfo']['name'], + 'surname' => $params['contactInfo']['surName'], + 'phone_code' => $params['contactInfo']['phoneCode'], + 'phone_number' => $params['contactInfo']['phoneNumber'], + 'email' => $params['contactInfo']['email'], + 'note' => fillOnUndefined($params['contactInfo'], 'note'), + 'language_code' => fillOnUndefined($params['contactInfo'], 'language_code', 'en'), + 'invoice_request' => fillOnUndefined($params['contactInfo'], 'invoice_request') ? 1 : null, + 'status' => 1 + ]; + + foreach ($bannedCheckParameter as $checkParameter) { + if (isset($bookingContactCreateParam[$checkParameter])) { + foreach ($bannedCharacters as $bannedCharacter) { + if (str_contains($bookingContactCreateParam[$checkParameter], $bannedCharacter)) { + throw new ApiErrorException(lang('Booking could not be made! - Contact')); + } + } + } + } + + $bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam); + //$bookingContactCreate['status'] = 'success'; + + if ($bookingContactCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Contact could not be made')); + } + + //INSERT ADDON DATA + foreach ($bookingAddon as $propertyAddonId => $propertyAddon) { + + $bookingAddonCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'property_channel_addon_id' => $propertyAddon['property_channel_addon_id'], + 'count' => $propertyAddon['count'], + 'amount' => $propertyAddon['amount'], + 'total' => $propertyAddon['total'], + 'currency_code' => $propertyAddon['currency_code'], + 'attribute' => !empty($propertyAddon['attribute']) ? json_encode($propertyAddon['attribute']) : null, + ]; + + $bookingAddonCreate = $this->bookingAddonService->create($bookingAddonCreateParam); + //$bookingRoomCreate['status'] = 'success'; + //$bookingRoomCreate['data']['id'] = 1; + + if ($bookingAddonCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Addon could not be made')); + } + + } + + + //INSERT ROOM DATA + foreach ($roomInfo as $roomOrder => $room) { + + $rateKeyCodeDecoded = $this->rateKeyCodeDecode($searchCacheRoomPrices[$room['rateKey']]['rateKeyCode']); + + $roomPrice = $searchCacheRoomPrices[$room['rateKey']]['total']; + $roomPriceBeforeDiscount = $searchCacheRoomPrices[$room['rateKey']]['total']; + $roomDiscountAmount = 0; + if (!empty($couponCodeData)) { + if ($couponCodeData['type'] == 'PER') { + $roomDiscountAmount = ($roomPriceBeforeDiscount * $couponCodeData['value'] / 100); + } elseif ($couponCodeData['type'] == 'FIX') { + $roomDiscountAmount = $couponCodeData['value']; + } + $roomPrice = $roomPriceBeforeDiscount - $roomDiscountAmount; + } + + $bookingRoomCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'room_order_number' => ($roomOrder + 1), + 'occupancy_code' => $room['occupancyCode'], + 'checkin_date' => $searchCacheData['requestParams']['date']['checkIn'], + 'checkout_date' => $searchCacheData['requestParams']['date']['checkOut'], + 'rate_key' => $room['rateKey'], + 'rate_key_code' => $searchCacheRoomPrices[$room['rateKey']]['rateKeyCode'], + 'availability_id' => $rateKeyCodeDecoded['availabilityTypeId'], + 'availability_code' => $searchCacheRoomPrices[$room['rateKey']]['availability']['code'], + 'room_id' => $rateKeyCodeDecoded['roomId'], + 'room_name' => $searchCacheRoomPrices[$room['rateKey']]['room']['name'], + 'room_rate_mapping_id' => $rateKeyCodeDecoded['rateMappingId'], + 'room_rate_name' => $searchCacheRoomPrices[$room['rateKey']]['rate']['name'], + 'cancellation_policy' => json_encode($searchCacheRoomPrices[$room['rateKey']]['cancellationPolicy']), + 'payment_type_code' => $searchCacheRoomPrices[$room['rateKey']]['bookingPaymentType']['code'], + 'daily_amount' => json_encode($searchCacheRoomPrices[$room['rateKey']]['policyPriceDaily']), + 'rate_detail' => json_encode($searchCacheRoomPrices[$room['rateKey']]), + 'amount' => $roomPriceBeforeDiscount, + 'discount_amount' => $roomDiscountAmount, + 'total' => $roomPrice, + 'currency_code' => $searchCacheRoomPrices[$room['rateKey']]['currency'], + 'status' => 1 + ]; + + $bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam); + //$bookingRoomCreate['status'] = 'success'; + //$bookingRoomCreate['data']['id'] = 1; + + if ($bookingRoomCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Room could not be made')); + } + + foreach ($room['paxes'] as $roomPax) { + + $bookingRoomPaxParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'booking_room_id' => $bookingRoomCreate['data']['id'], + 'type' => fillOnUndefined($roomPax, 'type'), + 'name' => fillOnUndefined($roomPax, 'name'), + 'surname' => fillOnUndefined($roomPax, 'surName'), + 'gender' => fillOnUndefined($roomPax, 'gender'), + 'citizen' => fillOnUndefined($roomPax, 'citizen'), + 'birth_date' => fillOnUndefined($roomPax, 'birthDate'), + ]; + + foreach ($bannedCheckParameter as $checkParameter) { + if (isset($bookingRoomPaxParam[$checkParameter])) { + foreach ($bannedCharacters as $bannedCharacter) { + if (str_contains($bookingRoomPaxParam[$checkParameter], $bannedCharacter)) { + throw new ApiErrorException(lang('Booking could not be made! - Pax')); + } + } + } + } + + $bookingRoomPaxCreate = $this->bookingRoomPaxService->create($bookingRoomPaxParam); + //$bookingRoomCreate['status'] = 'success'; + //$bookingRoomCreate['data']['id'] = 1; + + if ($bookingRoomPaxCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Room Pax could not be made')); + } + + + } + + } + + + } else { + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['bookingCode']] + ], + 'with' => ['bookingPayment', 'bookingRoom', 'bookingAddon'], + 'firstRow' => true + ]; + + $bookingCreate = $this->bookingService->select($bookingDetailParam); + + if ($bookingCreate['status'] != 'success' || empty($bookingCreate['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $bookingDetail = $bookingCreate['data']; + + + //DELETE OLD ADDON DATA + if (!empty(pickItemFromArray('id', $bookingDetail['booking_addon']))) { + $this->bookingAddonService->delete(pickItemFromArray('id', $bookingDetail['booking_addon'])); + } + + + //INSERT ADDON DATA + foreach ($bookingAddon as $propertyAddonId => $propertyAddon) { + + $bookingAddonCreateParam = [ + 'booking_id' => $bookingDetail['id'], + 'property_channel_addon_id' => $propertyAddon['property_channel_addon_id'], + 'count' => $propertyAddon['count'], + 'amount' => $propertyAddon['amount'], + 'total' => $propertyAddon['total'], + 'currency_code' => $propertyAddon['currency_code'], + 'attribute' => !empty($propertyAddon['attribute']) ? json_encode($propertyAddon['attribute']) : null, + ]; + + $bookingAddonCreate = $this->bookingAddonService->create($bookingAddonCreateParam); + + if ($bookingAddonCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Addon could not be made')); + } + + } + + $bookingCode = $bookingCreate['data']['booking_code']; + $bookingStatus = in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) ? 1 : 2; + + $totalRoomsPriceBeforeDiscount = $totalRoomsPrice; + $bookingDiscountAmount = 0; + if (!empty($couponCodeData)) { + if ($couponCodeData['type'] == 'PER') { + $bookingDiscountAmount = ($totalRoomsPriceBeforeDiscount * $couponCodeData['value'] / 100); + } elseif ($couponCodeData['type'] == 'FIX') { + $bookingDiscountAmount = $couponCodeData['value']; + } + $totalRoomsPrice = $totalRoomsPrice - $bookingDiscountAmount; + } + + $bookingTotalAmount = $totalRoomsPrice + $totalAddonPrice; + + + $bookingDetailUpdate = [ + 'room_amount' => $totalRoomsPriceBeforeDiscount, + 'addon_amount' => $totalAddonPrice, + 'total' => $bookingTotalAmount, + ]; + + $this->bookingService->update($bookingDetail['id'], $bookingDetailUpdate); + + + } + + //Eğer kredi kartı ise + $initializePayment = []; + if (!in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN'])) { + + $isDirectPayment = true; + + //TODO: validator + $params['paymentInfo']['creditCard']['cardExpireMonth'] = strlen($params['paymentInfo']['creditCard']['cardExpireMonth']) == 2 ? $params['paymentInfo']['creditCard']['cardExpireMonth'] : str_pad($params['paymentInfo']['creditCard']['cardExpireMonth'], 2, 0, STR_PAD_LEFT); + + $initializePaymentParam = [ + 'propertyId' => $propertyId, + 'orderId' => $bookingCode, + 'installment' => isset($params['paymentInfo']['creditCard']['installment']) ? $params['paymentInfo']['creditCard']['installment'] : 1, + 'amount' => (double)$bookingTotalAmount, + 'currency' => $currencyCode, + 'type' => 'BKG', + 'responseUrl' => $params['paymentInfo']['responseUrl'], + 'creditCard' => [ + 'name' => $params['paymentInfo']['creditCard']['cardHolder'], + 'number' => $params['paymentInfo']['creditCard']['cardNumber'], + 'month' => $params['paymentInfo']['creditCard']['cardExpireMonth'], + 'year' => $params['paymentInfo']['creditCard']['cardExpireYear'], + 'cvv' => $params['paymentInfo']['creditCard']['cardCvv'], + ] + ]; + + + $initializePayment = $this->propertyPaymentService->initializePayment($initializePaymentParam); + + if (!$initializePayment['status']) { + Log::error($initializePayment); + throw new ApiErrorException(lang('Initialize Payment could not be made')); + } + + if (isset($initializePayment['data']['redirectUrl'])) { + $isDirectPayment = false; + } + } + + //Eğer direk ödeme ile para çekilip işlem yapılmış ise + if (isset($isDirectPayment) && $isDirectPayment) { + $bookingStatus = 1; + $this->bookingService->update($bookingCreate['data']['id'], ['status' => 1]); + } + + $bookingPaymentCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'payment_code' => isset($initializePayment['data']['paymentCode']) ? $initializePayment['data']['paymentCode'] : null, + 'payment_type_code' => $params['paymentInfo']['paymentCode'], + 'total' => in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && $isDirectPayment) ? $bookingTotalAmount : null, + 'currency_code' => in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && $isDirectPayment) ? $currencyCode : null, + 'status' => (isset($isDirectPayment) && $isDirectPayment) ? 1 : 2 + ]; + + $bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam); + //$bookingContactCreate['status'] = 'success'; + + if ($bookingPaymentCreate['status'] != 'success') { + throw new ApiErrorException(lang('Booking Payment could not be made')); + } + + //Buradan eksiltme transaction ları başlatılacak ki ok ise düşsün + $roomAvailabilityStatus = true; + foreach ($roomAvailabilityKeyGroup as $roomAvailabilityKey => $roomAvailability) { + + if ($roomAvailabilityKey == 1) { + + foreach ($roomAvailability as $roomKey => $room) { + + foreach ($dateByDay as $day) { + + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $room['detail']['roomId']) + ->where('availability_type_id', $room['detail']['availabilityTypeId']) + ->where('availability', '>=', $room['count']) + ->where('status', 1) + ->first(); + + if (is_null($roomAndRoomRateAvailability)) { + $roomAvailabilityStatus = false; + break 3; + } + + //Kontenjan Azaltma + //Otelde öde ise düşürülecek kontenjan + if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || $isDirectPayment) { + $roomNewAvailability = $roomAndRoomRateAvailability['availability'] - $room['count']; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]); + + //Connected Room Case + if ($roomAndRoomRateAvailability['room_detail']['is_connected_room'] && $roomAndRoomRateAvailability['room_detail']['is_connected_room_availability']) { + + foreach ($roomAndRoomRateAvailability['room_detail']['property_room_connected'] as $connectedRoom) { + + $roomAndRoomRateAvailabilityConnected = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $connectedRoom['connected_room_id']) + ->where('availability_type_id', $room['detail']['availabilityTypeId']) + ->where('availability', '>=', $room['count']) + ->where('status', 1) + ->first(); + + if (is_null($roomAndRoomRateAvailabilityConnected)) { + continue; + } + + $roomNewAvailabilityConnected = $roomAndRoomRateAvailabilityConnected['availability'] - $room['count']; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailabilityConnected['id'], ['availability' => $roomNewAvailabilityConnected]); + } + } + //Connected Room Case + + } + } + + } + + //Connected Room Case + $roomAvailabilityUpdateForConnectedRoomParams = [ + 'property_id' => $propertyId, + 'channel_id' => $this->channelId, + 'availability_type_id' => [$roomAvailabilityKey], + 'startDate' => reset($dateByDay), + 'endDate' => last($dateByDay), + 'user_id' => fillOnUndefined($params, "user_id", 0) + ]; + + $this->propertyRoomAvailabilityService->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams); + //Connected Room Case + + } else { + + foreach ($roomAvailability as $roomKey => $roomRateMapping) { + + foreach ($roomRateMapping as $roomRateMappingKey => $roomRate) { + + foreach ($dateByDay as $day) { + + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $roomRate['detail']['roomId']) + ->where('availability_type_id', $roomRate['detail']['availabilityTypeId']) + ->where('room_rate_mapping_id', $roomRate['detail']['rateMappingId']) + ->where('channel_id', $roomRate['detail']['channelId']) + ->where('availability', '>=', $roomRate['count']) + ->where('status', 1) + ->first(); + + if (is_null($roomAndRoomRateAvailability)) { + $roomAvailabilityStatus = false; + break 4; + } + + //Kontenjan Azaltma + //Otelde öde ise düşürülecek kontenjan + if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || $isDirectPayment) { + //TODO: Garantili kontenjan ve limitlide havuzdan da azaltılmalı + $roomNewAvailability = $roomAndRoomRateAvailability['availability'] - $roomRate['count']; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]); + } + + } + + } + + } + + } + + } + + if (!$roomAvailabilityStatus) { + throw new ApiErrorException(lang('One or more of the requested rooms are not available')); + } + //BOOKING FINISHED + + + $responseData = [ + 'bookingCode' => $bookingCode, + 'total' => $bookingTotalAmount, + 'currency' => $currencyCode, + 'bookingStatus' => $bookingStatus, + 'bookingStatusText' => $bookingStatus == 1 ? 'Booking' : 'PreBooking', + + ]; + + //TODO: Eğer Booking yapılmış ise + if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && isset($isDirectPayment) && $isDirectPayment)) { + + $mailParams = ['booking_id' => $bookingCreate['data']['id']]; + $this->newBookingMailService->process($mailParams); + + //PUSH NOTIFICATION + $newBookingNotificationParam = ['booking_id' => $bookingCreate['data']['id']]; + $this->notificationService->sendNewBookingNotification($newBookingNotificationParam); + //PUSH NOTIFICATION + + + //PUSH CHANNEL MANAGER QUEUE + //if ($bookingCreate['data']['channel_id'] == 1) { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingCreate['data']['property_id']], + //['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + //Trivago + if ($channelPropertyData['channel_manager_id'] == 11 && !isset($params['extraParam']['trv_reference'])) { + continue; + } + + //Hyperguest + if ($channelPropertyData['channel_manager_id'] != 10 && !is_null($channelPropertyData['channel_manager_property_id'])) { + continue; + } + + if(in_array($channelPropertyData['channel_manager_id'],[13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $bookingCreate['data']['property_id'], + 'booking_id' => $bookingCreate['data']['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => 'Booking', + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + + //} + //PUSH CHANNEL MANAGER QUEUE + + + } + + //Eğer kredi kartı ise ve ödeme başlamış ise + if (!empty($initializePayment)) { + $responseData['paymentCode'] = $initializePayment['data']['paymentCode']; + if (isset($initializePayment['data']['redirectUrl'])) { + $responseData['redirectUrl'] = $initializePayment['data']['redirectUrl']; + } + } + + //Pay at Hotel - Info Store + if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) && isset($params['paymentInfo']['creditCard']) && !empty($params['paymentInfo']['creditCard']['cardNumber'])) { + + $creditCard = $params['paymentInfo']['creditCard']; + + $cardNumber = $creditCard['cardNumber']; + $cardLengthSize = ceil(strlen($cardNumber) / 4); + + $cardNumberParse = []; + for ($i = 0; $i < $cardLengthSize; $i++) { + $cardNumberParse['cc'][] = Crypt::encrypt(mb_substr($cardNumber, $i * 4, 4)); + } + + $cardNumberParse['cm'] = Crypt::encrypt($creditCard['cardExpireMonth']); + $cardNumberParse['cy'] = Crypt::encrypt(mb_substr($creditCard['cardExpireYear'], -2, 2)); + $cardNumberParse['cv'] = Crypt::encrypt($creditCard['cardCvv']); + $cardNumberParse['ch'] = Crypt::encrypt($creditCard['cardHolder']); + + + foreach ($cardNumberParse as $type => $value) { + + $bookingPaymentDataCreateParam = []; + + if ($type == 'cc') { + foreach ($value as $cardValue) { + $bookingPaymentDataCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'type' => $type, + 'data' => $cardValue, + ]; + $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam); + } + } else { + $bookingPaymentDataCreateParam = [ + 'booking_id' => $bookingCreate['data']['id'], + 'type' => $type, + 'data' => $value, + ]; + + $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam); + } + + } + + } + //Pay at Hotel - Info Store + + + //Booking Engine Search Update + $bookingEngineSearchParam = [ + 'criteria' => [ + ['field' => 'search_key', 'condition' => '=', 'value' => $params['searchKey']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $bookingEngineSearch = $this->propertyBookingEngineSearchService->select($bookingEngineSearchParam); + + if ($bookingEngineSearch['status'] == 'success' && !empty($bookingEngineSearch['data'])) { + + $bookingEngineSearchUpdateParam = [ + 'booking_code' => $bookingCode, + 'amount' => $bookingTotalAmount, + 'status' => 2, + ]; + + if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && isset($isDirectPayment) && $isDirectPayment)) { + $bookingEngineSearchUpdateParam['status'] = 3; + } + + $bookingEngineSearchUpdate = $this->propertyBookingEngineSearchService->update($bookingEngineSearch['data']['id'], $bookingEngineSearchUpdateParam); + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingConfirm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $bookingCode = $params['bookingCode']; + $paymentCode = $params['paymentCode']; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode] + ], + 'with' => ['property', 'bookingPayment', 'bookingRoom'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $bookingDetail = $bookingDetail['data']; + + $paymentDetailParam = [ + 'criteria' => [ + ['field' => 'code', 'condition' => '=', 'value' => $paymentCode] + ], + 'firstRow' => true + ]; + + $paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam); + + if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) { + throw new ApiErrorException(lang('Payment not found')); + } + + $paymentDetail = $paymentDetail['data']; + + if ($paymentDetail['status'] != 1) { + throw new ApiErrorException('Payment not confirmed'); + } + + if ($bookingDetail['status'] == 1) { + throw new ApiErrorException('Previously approved transaction'); + } + + + DB::beginTransaction(); + + + //Booking Confirm + $this->bookingService->update($bookingDetail['id'], ['status' => 1]); + + + //Availability Change + if ($bookingDetail['status'] == 2) { + + $propertyRoomAndRoomRateAvailabilityParam = [ + 'property_id' => $bookingDetail['property_id'], + 'checkIn' => $bookingDetail['checkin_date'], + 'checkOut' => $bookingDetail['checkout_date'], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { + throw new ApiErrorException(lang('Room or rooms not available.')); + } + + $propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']); + + + $roomAvailabilityStatus = true; + foreach ($bookingDetail['booking_room'] as $room) { + + $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]); + + foreach ($dateByDay as $day) { + + $roomRateDetail = json_decode($room['rate_detail'], 1); + $rateKeyCodeDecoded = $this->rateKeyCodeDecode($roomRateDetail['rateKeyCode']); + + if ($rateKeyCodeDecoded['availabilityTypeId'] == 1) { + + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $rateKeyCodeDecoded['roomId']) + ->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId']) + ->where('availability', '>=', 1) + ->where('status', 1) + ->first(); + + if (is_null($roomAndRoomRateAvailability)) { + $roomAvailabilityStatus = false; + break 2; + } + + //Kontenjan Azaltma + $roomNewAvailability = $roomAndRoomRateAvailability['availability'] - 1; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]); + + //Connected Room Case + if ($roomAndRoomRateAvailability['room_detail']['is_connected_room'] && $roomAndRoomRateAvailability['room_detail']['is_connected_room_availability']) { + + foreach ($roomAndRoomRateAvailability['room_detail']['property_room_connected'] as $connectedRoom) { + + $roomAndRoomRateAvailabilityConnected = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $connectedRoom['connected_room_id']) + ->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId']) + ->where('availability', '>=', 1) + ->where('status', 1) + ->first(); + + if (is_null($roomAndRoomRateAvailabilityConnected)) { + continue; + } + + $roomNewAvailabilityConnected = $roomAndRoomRateAvailabilityConnected['availability'] - 1; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailabilityConnected['id'], ['availability' => $roomNewAvailabilityConnected]); + } + } + //Connected Room Case + + } else { + + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $day) + ->where('property_room_id', $rateKeyCodeDecoded['roomId']) + ->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId']) + ->where('room_rate_mapping_id', $rateKeyCodeDecoded['rateMappingId']) + ->where('channel_id', $rateKeyCodeDecoded['channelId']) + ->where('availability', '>=', 1) + ->where('status', 1) + ->first(); + + + if (is_null($roomAndRoomRateAvailability)) { + $roomAvailabilityStatus = false; + break 2; + } + + //TODO: Garantili kontenjan ve limitlide havuzdan da azaltılmalı + //Kontenjan Azaltma + $roomNewAvailability = $roomAndRoomRateAvailability['availability'] - 1; + $this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]); + + + } + + } + + } + + //Connected Room Case + $roomAvailabilityUpdateForConnectedRoomParams = [ + 'property_id' => $bookingDetail['property_id'], + 'channel_id' => $bookingDetail['channel_id'], + 'availability_type_id' => [1], + 'startDate' => reset($dateByDay), + 'endDate' => last($dateByDay), + 'user_id' => fillOnUndefined($params, "user_id", 0) + ]; + + $this->propertyRoomAvailabilityService->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams); + //Connected Room Case + + if (!$roomAvailabilityStatus) { + throw new ApiErrorException(lang('One or more of the requested rooms are not available')); + } + + } + + //Booking Payment Update + $bookingPaymentUpdateParam = [ + 'status' => 1, + 'total' => $paymentDetail['amount'], + 'currency_code' => $paymentDetail['currency'], + ]; + + $this->bookingPaymentService->update($bookingDetail['booking_payment']['id'], $bookingPaymentUpdateParam); + + + $mailParams = ['booking_id' => $bookingDetail['id']]; + $this->newBookingMailService->process($mailParams); + + //PUSH NOTIFICATION + $newBookingNotificationParam = ['booking_id' => $bookingDetail['id']]; + $this->notificationService->sendNewBookingNotification($newBookingNotificationParam); + //PUSH NOTIFICATION + + //PUSH CHANNEL MANAGER QUEUE + //if ($bookingDetail['channel_id'] == 1) { + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['property_id']], + //['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + //Trivago + if ($channelPropertyData['channel_manager_id'] == 11 && !isset($params['extraParam']['trv_reference'])) { + continue; + } + + //Hyperguest + if ($channelPropertyData['channel_manager_id'] != 10 && !is_null($channelPropertyData['channel_manager_property_id'])) { + continue; + } + + //Yandex + if(in_array($channelPropertyData['channel_manager_id'],[13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $bookingDetail['property_id'], + 'booking_id' => $bookingDetail['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => 'Booking', + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + + //} + //PUSH CHANNEL MANAGER QUEUE + + + //Booking Engine Search Update + //if ($bookingDetail['channel_id'] == 1) { + + $bookingEngineSearchParam = [ + 'criteria' => [ + ['field' => 'search_key', 'condition' => '=', 'value' => $bookingDetail['search_key']], + ['field' => 'status', 'condition' => '=', 'value' => 2], + ], + 'firstRow' => true + ]; + + $bookingEngineSearch = $this->propertyBookingEngineSearchService->select($bookingEngineSearchParam); + + if ($bookingEngineSearch['status'] == 'success' && !empty($bookingEngineSearch['data'])) { + + $bookingEngineSearchUpdateParam = [ + 'booking_code' => $bookingDetail['booking_code'], + 'amount' => $bookingDetail['total'], + 'currency_code' => $bookingDetail['currency_code'], + 'status' => 3, + ]; + + $bookingEngineSearchUpdate = $this->propertyBookingEngineSearchService->update($bookingEngineSearch['data']['id'], $bookingEngineSearchUpdateParam); + + } + //} + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingDetail(Request $request, $bookingCode) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode], + //['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId],//TODO: Kontrol gerekli! + ], + 'with' => [ + 'bookingPayment.paymentTypeCode', 'bookingRoom.roomPax.paxCountry', 'bookingRoom.roomRateMapping.propertyRoomRate', 'bookingRoom.roomRateMapping.propertyRoom', 'bookingContact', + 'bookingProperty.propertyContact', 'bookingProperty.propertyBrand', 'bookingProperty.propertyAdditionalInfos.propertyAdditionalInfoKey', + 'bookingAddon.propertyChannelAddon.propertyAddon.fact', 'bookingChannel','propertyChannelMapping.channelBookingPaymentType', + 'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', 'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact', + 'bookingRoom.propertyRoomBed', 'bookingRoom.smokingFact','propertyBookingEngineSearch' + ], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $bookingDetail['data']['booking_property']['checkin_time'] = '14:00'; + $bookingDetail['data']['booking_property']['checkout_time'] = '12:00'; + + if (!empty($bookingDetail['data']['booking_property']['property_additional_infos'])) { + $propertyAdditionalInfos = collect($bookingDetail['data']['booking_property']['property_additional_infos']); + + $checkinTimeData = $propertyAdditionalInfos->where('property_additional_info_key.additional_info_key', 'checkin_time')->first(); + $bookingDetail['data']['booking_property']['checkin_time'] = isset($checkinTimeData['value']) ? $checkinTimeData['value'] : '14:00'; + + $checkoutTimeData = $propertyAdditionalInfos->where('property_additional_info_key.additional_info_key', 'checkout_time')->first(); + $bookingDetail['data']['booking_property']['checkout_time'] = isset($checkinTimeData['value']) ? $checkoutTimeData['value'] : '12:00'; + } + unset($bookingDetail['data']['booking_property']['property_additional_infos']); + + + //BOOKING ADDON + $bookingAddons = $bookingDetail['data']['booking_addon']; + unset($bookingDetail['data']['booking_addon']); + + $bookingAddonList = []; + foreach ($bookingAddons as $bookingAddon) { + + $bookingAddonAttributeList = []; + $isHasAttribute = false; + $attributeArray = []; + if (!empty($bookingAddon['property_channel_addon']['property_addon']['attributeArray'])) { + $isHasAttribute = true; + $attributeArray = $bookingAddon['property_channel_addon']['property_addon']['attributeArray']; + $bookingAddonAttributes = json_decode($bookingAddon['attribute'], 1); + if (!is_null($bookingAddonAttributes)) { + foreach ($bookingAddonAttributes as $key => $bookingAddonAttribute) { + foreach ($bookingAddonAttribute as $bookingAddonAttributeKey => $bookingAddonAttributeValue) { + + if (isset($bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey])) { + $bookingAddonAttributeList[$key][$bookingAddonAttributeKey] = [ + 'name' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['name'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['language_key'], + 'value' => $bookingAddonAttributeValue, + ]; + } + + } + } + } + } + + $bookingAddonList[] = [ + 'id' => $bookingAddon['id'], + 'booking_id' => $bookingAddon['booking_id'], + 'property_channel_addon_id' => $bookingAddon['property_channel_addon_id'], + 'count' => $bookingAddon['count'], + 'amount' => $bookingAddon['amount'], + 'total' => $bookingAddon['total'], + 'currency_code' => $bookingAddon['currency_code'], + 'name' => $bookingAddon['property_channel_addon']['property_addon']['fact']['name'], + 'title' => $bookingAddon['property_channel_addon']['title'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['fact']['language_key'], + 'icon' => $bookingAddon['property_channel_addon']['property_addon']['fact']['icon'], + 'isHasAttribute' => $isHasAttribute, + 'attributeArray' => $attributeArray, + 'attribute' => $bookingAddonAttributeList + ]; + + } + + $bookingDetail['data']['booking_addon'] = $bookingAddonList; + //BOOKING ADDON + + //DAILY AMOUNT BY ROOM + $hasNonRefundableRoom = false; + foreach ($bookingDetail['data']['booking_room'] as $roomKey => $roomDetail) { + + if (!empty($roomDetail['room_rate_mapping']['property_room'])) { + $bookingDetail['data']['booking_room'][$roomKey]['room_name'] = $roomDetail['room_rate_mapping']['property_room']['name']; + } + + if (!empty($roomDetail['room_rate_mapping']['property_room_rate'])) { + $bookingDetail['data']['booking_room'][$roomKey]['room_rate_name'] = $roomDetail['room_rate_mapping']['property_room_rate']['name']; + } + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + + $roomDailyAmount = []; + if (!empty($roomDetail['daily_amount'])) { + $roomDetailDailyAmount = json_decode($roomDetail['daily_amount'], 1); + if (!empty($roomDetailDailyAmount) && isset($roomDetailDailyAmount)) { + foreach ($roomDetailDailyAmount as $roomRateAmount) { + $roomDailyAmount[] = [ + 'date' => $roomRateAmount['date'], + 'amount' => $roomRateAmount['amount'], + 'currency_code' => $roomRateAmount['currency_code'], + ]; + } + } + } + + if (empty($roomDailyAmount)) { + $roomRateDetail = json_decode($roomDetail['rate_detail'], 1); + if (!empty($roomRateDetail) && isset($roomRateDetail['days'])) { + foreach ($roomRateDetail['days'] as $roomRateDay => $roomRateAmount) { + $roomDailyAmount[] = [ + 'date' => Carbon::parse($roomRateDay)->toDateString(), + 'amount' => $roomRateAmount, + 'currency_code' => $roomDetail['currency_code'], + ]; + } + } + } + + if (empty($roomDailyAmount)) { + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $roomDailyAmount[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily, + 'currency_code' => $roomDetail['currency_code'], + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + } + + $bookingDetail['data']['booking_room'][$roomKey]['daily_amount'] = $roomDailyAmount; + + $extraParam = null; + if (!empty($roomDetail['extra_param'])) { + $extraParamDecode = json_decode($roomDetail['extra_param'], 1); + + foreach ($extraParamDecode as $extraParamKey => $extraParamValue) { + + $extraParamTitle = explode('_', $extraParamKey); + foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) { + $extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue); + } + $extraParamTitle = implode(' ', $extraParamTitle); + + $extraParam[$extraParamKey] = [ + 'title' => $extraParamTitle, + 'value' => $extraParamValue, + ]; + } + + } + + $bookingDetail['data']['booking_room'][$roomKey]['extra_param'] = $extraParam; + $bookingDetail['data']['booking_room'][$roomKey]['occupancyFormatted'] = occupancyCodeFormatted($roomDetail['occupancy_code']); + + $cancellationPolicy = !empty($roomDetail['cancellation_policy']) ? json_decode($roomDetail['cancellation_policy'], 1) : null; + + if (is_array($cancellationPolicy) && isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) { + $hasNonRefundableRoom = true; + } + + + //property_room_bed_group + //unset($bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group']); + $propertyRoomBedGroup = collect($roomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group'); + $propertyRoomBedGroup = $propertyRoomBedGroup ? $propertyRoomBedGroup->toArray() : null; + $bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group'] = $propertyRoomBedGroup; + + + $bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group'] = null; + if(isset($propertyRoomBedGroup[$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group_id']])) { + $bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group'] = $propertyRoomBedGroup[$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group_id']]; + } + + + } + //DAILY AMOUNT BY ROOM + + $bookingChannel = $bookingDetail['data']['booking_channel']; + unset($bookingDetail['data']['booking_channel']); + $bookingDetail['data']['booking_channel'] = [ + 'name' => $bookingChannel['name'], + 'logo' => $bookingChannel['logoUrl'], + 'channel_category_id' => $bookingChannel['channel_category_id'], + ]; + + $bookingContactExtraParam = null; + if (!empty($bookingDetail['data']['booking_contact']['extra_param'])) { + $bookingContactExtraParam = json_decode($bookingDetail['data']['booking_contact']['extra_param'], 1); + } + $bookingDetail['data']['booking_contact']['extra_param'] = $bookingContactExtraParam; + + + $bookingDetail = $bookingDetail['data']; + + $bookingDetail['isOnlineCancellation'] = false; + if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [2]) && !$hasNonRefundableRoom) { + $bookingDetail['isOnlineCancellation'] = false; + } + + if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [3]) && in_array($bookingDetail['booking_property']['country'], ['GE'])) { + $bookingDetail['isOnlineCancellation'] = false; + } + + $payAtHotelCreditCardCheck = collect($bookingDetail['property_channel_mapping']['channel_booking_payment_type'])->where('is_get_payment_data',1)->where('payment_type_id',2)->isNotEmpty(); + $bookingDetail['credit_card_required'] = $payAtHotelCreditCardCheck; + unset($bookingDetail['property_channel_mapping']); + + //Wholesaler MARKUP CALCULATE + $getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $bookingDetail['property_id']); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + $getChannelPropertyDetail = $getChannelPropertyDetail['status'] ? $getChannelPropertyDetail['data'] : null; + + if ($getChannelPropertyDetail && in_array($getChannelPropertyDetail['channel']['channel_category_id'], [7])) { + + $channelCurrencyCode = fillOnUndefined($bookingDetail, 'channel_currency_code', $bookingDetail['currency_code']); + $channelCurrencyExchange = fillOnUndefined($bookingDetail, 'channel_currency_exchange', 1); + + $channelMarkup = 1; + if (!is_null($bookingDetail['channel_markup'])) { + $channelMarkup = (($bookingDetail['channel_markup'] + 100) / 100); + } + + foreach ($bookingDetail['booking_room'] as $roomKey => $room) { + + foreach ($room['daily_amount'] as $dailKey => $dailyAmount) { + $bookingDetail['booking_room'][$roomKey]['daily_amount'][$dailKey]['currency_code'] = $channelCurrencyCode; + $bookingDetail['booking_room'][$roomKey]['daily_amount'][$dailKey]['amount'] = moneyDoubleFormatDecimal($dailyAmount['amount'] * $channelMarkup * $channelCurrencyExchange); + } + + + $bookingDetail['booking_room'][$roomKey]['amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'][$roomKey]['daily_amount'])->sum('amount')); + $bookingDetail['booking_room'][$roomKey]['discount_amount'] = moneyDoubleFormatDecimal($room['discount_amount'] * $channelMarkup * $channelCurrencyExchange); + $bookingDetail['booking_room'][$roomKey]['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'][$roomKey]['daily_amount'])->sum('amount')); + $bookingDetail['booking_room'][$roomKey]['currency_code'] = $channelCurrencyCode; + + + unset($bookingDetail['booking_room'][$roomKey]['rate_detail']); + + } + + $bookingDetail['currency_code'] = $channelCurrencyCode; + $bookingDetail['room_amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('amount')); + $bookingDetail['addon_amount'] = moneyDoubleFormatDecimal($bookingDetail['addon_amount'] * $channelMarkup * $channelCurrencyExchange); + $bookingDetail['discount_amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('discount_amount')); + $bookingDetail['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('amount')); + + + $bookingDetail['booking_payment']['currency_code'] = $channelCurrencyCode; + $bookingDetail['booking_payment']['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('total')); + + + } + //Wholesaler MARKUP CALCULATE + + unset($bookingDetail['channel_markup']); + unset($bookingDetail['channel_currency_code']); + unset($bookingDetail['channel_currency_exchange']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $bookingDetail]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingUpdate(Request $request, $bookingCode) + { + + DB::beginTransaction(); + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode], + ], + 'with' => [ + 'bookingRoom.roomRateMapping.propertyRoom', + 'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', + 'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact', + 'bookingRoom.propertyRoomBed','bookingRoom.smokingFact' + ], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException(lang('Booking not found')); + } + + $bookingDetail = $bookingDetail['data']; + + if(fillOnUndefined($params,'propertyId') != fillOnUndefined($bookingDetail,'property_id')) { + throw new ApiErrorException('PropertyI ID is not matching.'); + } + + $bookingRoomUpdateParam = ['smoking_fact_id','property_room_bed_id','property_room_bed_group_id']; + if(isset($params['booking_room']) && isset($params['booking_room']['id'])) { + + $bookingRoomIds = collect($bookingDetail['booking_room'])->pluck('id'); + $bookingRoomIds = $bookingRoomIds ? $bookingRoomIds->toArray() : null; + + if(empty($bookingRoomIds)) { + throw new ApiErrorException('Booking Room ID not found.'); + } + + if(!in_array($params['booking_room']['id'],$bookingRoomIds )) { + throw new ApiErrorException('Booking Room ID not matching.'); + } + + $bookingRoomDetail = collect($bookingDetail['booking_room'])->where('id',$params['booking_room']['id'])->first(); + + foreach ($bookingRoomUpdateParam as $updateColumn) { + + //smoking_fact_id + if($updateColumn == 'smoking_fact_id' && isset($params['booking_room']['smoking_fact_id'])) { + $smokingPreferenceIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['smoking_preference'])->pluck('fact_id')->toArray(); + if(!in_array($params['booking_room']['smoking_fact_id'],$smokingPreferenceIds)) { + throw new ApiErrorException('smoking_fact_id: ID params not matching.'); + } + $this->bookingRoomService->update($params['booking_room']['id'], ['smoking_fact_id' => $params['booking_room']['smoking_fact_id']]); + } + + //property_room_bed_id + if($updateColumn == 'property_room_bed_id' && isset($params['booking_room']['property_room_bed_id'])) { + $propertyRoomBedGroupIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->pluck('id')->toArray(); + if(!in_array($params['booking_room']['property_room_bed_id'],$propertyRoomBedGroupIds)) { + throw new ApiErrorException('property_room_bed_id: ID params not matching.'); + } + $this->bookingRoomService->update($params['booking_room']['id'], ['property_room_bed_id' => $params['booking_room']['property_room_bed_id']]); + } + + + //property_room_bed_group_id + if($updateColumn == 'property_room_bed_group_id' && isset($params['booking_room']['property_room_bed_group_id'])) { + $propertyRoomBedGroupIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->pluck('bed_group')->toArray(); + + if(!in_array($params['booking_room']['property_room_bed_group_id'],$propertyRoomBedGroupIds)) { + throw new ApiErrorException('property_room_bed_group_id: ID params not matching.'); + } + $this->bookingRoomService->update($params['booking_room']['id'], ['property_room_bed_group_id' => $params['booking_room']['property_room_bed_group_id']]); + } + + + + } + + + } else { + throw new ApiErrorException('Property Room ID not found.'); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + + + public function bookingPaymentInstallment(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $paymentData = []; + + $paymentData['isExchangeAmount'] = false; + + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $propertyId = $this->bookingEnginePropertyId; + $cardBinNumber = $params['cardBinNumber']; + $amount = $params['amount']; + $currency = $params['currency']; + + $paymentData['amount'] = $amount; + $paymentData['currency'] = $currency; + $paymentData['installment'] = []; + + $paymentType = $this->propertyPaymentService->getPaymentTypeMapping($propertyId, $currency, $cardBinNumber); + + if (is_null($paymentType['propertyPaymentMappingId'])) { + throw new ApiErrorException(lang('Payment Type not found')); + } + + if ($params['currency'] != $paymentType['propertyPaymentMappingCurrency']) { + $exchangeRate = $this->propertyPaymentService->getExchangeRates(); + + if (isset($exchangeRate[$params['currency'] . $paymentType['propertyPaymentMappingCurrency']])) { + $exchangeRateValue = $exchangeRate[$params['currency'] . $paymentType['propertyPaymentMappingCurrency']]; + } else { + throw new ApiErrorException(lang('Currency exchange value not found.')); + } + + $paymentData['isExchangeAmount'] = true; + + $paymentData['amount'] = moneyDoubleFormatDecimal($amount * $exchangeRateValue); + $paymentData['currency'] = $paymentType['propertyPaymentMappingCurrency']; + + $paymentData['base_amount'] = $amount; + $paymentData['base_currency'] = $currency; + $paymentData['exchangeRate'] = $exchangeRateValue; + + } + + if (!empty($paymentType['propertyPaymentMappingInstallment'])) { + + $amountBeforeInstallment = $amount; + if ($paymentData['isExchangeAmount']) { + $amountBeforeInstallment = $paymentData['amount']; + } + + foreach ($paymentType['propertyPaymentMappingInstallment'] as $installmentData) { + $paymentData['installment'][$installmentData['installment']] = [ + 'installment' => $installmentData['installment'], + 'commission' => $installmentData['commission'], + 'amount' => moneyDoubleFormatDecimal($amountBeforeInstallment + ($amountBeforeInstallment * $installmentData['commission'] / 100)) + ]; + + } + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $paymentData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function couponCodeCheck(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $couponData = []; + + $channelId = $this->channelId; + $propertyId = $this->bookingEnginePropertyId; + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + $getChannelPropertyDetail = $getChannelPropertyDetail['data']; + + $propertyChannelCouponCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']], + ['field' => 'code', 'condition' => '=', 'value' => $params['code']], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria); + + if ($propertyChannelCoupon['status'] == 'success') { + $propertyChannelCoupon = $propertyChannelCoupon['data']; + } + + if (empty($propertyChannelCoupon)) { + throw new ApiErrorException(lang('Code that has expired or is not available.')); + } + + $codeChecked = fillOnUndefined($propertyChannelCoupon,'checked', 0); $codeChecked++; + $this->propertyChannelCouponService->update($propertyChannelCoupon['id'], ['checked' => $codeChecked]); + + //Reservation Date Check + if (!is_null($propertyChannelCoupon['reservation_start_date']) && !is_null($propertyChannelCoupon['reservation_end_date'])) { + if (isset($params['checkIn']) && isset($params['checkOut'])) { + $reservationDateCheck = Carbon::parse($propertyChannelCoupon['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($params['checkIn'])) + && Carbon::parse($propertyChannelCoupon['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($params['checkOut'])); + if (!$reservationDateCheck) { + throw new ApiErrorException(lang('The code is not within the reservation period entered.')); + } + } + } + + + $couponData = [ + 'code' => $propertyChannelCoupon['code'], + 'type' => $propertyChannelCoupon['type'], + 'value' => $propertyChannelCoupon['value'], + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $couponData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function couponCodeNotify(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $channelId = $this->channelId; + $propertyId = $this->bookingEnginePropertyId; + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + $getChannelPropertyDetail = $getChannelPropertyDetail['data']; + + $propertyChannelCouponCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']], + //['field' => 'code', 'condition' => '=', 'value' => $params['code']], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_notify', 'condition' => '=', 'value' => 1], + ], + "orderBy" => [ + ["field" => "id", "value" => "DESC"] + ], + 'firstRow' => true + ]; + //dd($propertyChannelCouponCriteria); + + $propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria); + + if ($propertyChannelCoupon['status'] == 'success') { + $propertyChannelCoupon = $propertyChannelCoupon['data']; + } + + if (empty($propertyChannelCoupon)) { + throw new ApiErrorException(lang('No active code to notify was found')); + } + + //Reservation Date Check + if (!is_null($propertyChannelCoupon['reservation_start_date']) && !is_null($propertyChannelCoupon['reservation_end_date'])) { + if (isset($params['checkIn']) && isset($params['checkOut'])) { + $reservationDateCheck = Carbon::parse($propertyChannelCoupon['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($params['checkIn'])) + && Carbon::parse($propertyChannelCoupon['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($params['checkOut'])); + if (!$reservationDateCheck) { + throw new ApiErrorException(lang('The code is not within the reservation period entered.')); + } + } + } + + $couponData = [ + 'code' => $propertyChannelCoupon['code'], + 'type' => $propertyChannelCoupon['type'], + 'value' => $propertyChannelCoupon['value'], + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $couponData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingAddonAttribute(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $channelId = $this->channelId; + $propertyId = $this->bookingEnginePropertyId; + $bookingCode = $params['bookingCode']; + $bookingAddonId = $params['bookingAddonId']; + + //TODO: Validator, + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode] + ], + 'with' => ['bookingAddon.propertyChannelAddon.propertyAddon.fact'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) { + throw new ApiErrorException('Booking not found'); + } + + $bookingDetail = $bookingDetail['data']; + + if (empty($bookingDetail['booking_addon'])) { + throw new ApiErrorException('Booking Addon not found'); + } + + $bookingAddonCollect = collect($bookingDetail['booking_addon']); + + $selectedAddon = $bookingAddonCollect->where('id', $bookingAddonId)->first(); + + if (empty($selectedAddon)) { + throw new ApiErrorException('Booking Selected Addon not found'); + } + + $attributeArray = $selectedAddon['property_channel_addon']['property_addon']['attributeArray']; + + + $addonInfoAttribute = null; + if (isset($params['attribute'])) { + foreach ($params['attribute'] as $addonAttribute) { + if (count(array_intersect_key($addonAttribute, $attributeArray)) != count($addonAttribute)) { + throw new ApiErrorException('Additional product attribute values submitted do not match.'); + } + } + $addonInfoAttribute = $params['attribute']; + } + + + if ($selectedAddon['count'] != count($addonInfoAttribute)) { + throw new ApiErrorException('The number of additional items purchased and the number of additional information entered do not match'); + } + + $updateParam['attribute'] = null; + if (!is_null($addonInfoAttribute)) { + $updateParam['attribute'] = json_encode($addonInfoAttribute); + } + + $this->bookingAddonService->update($bookingAddonId, $updateParam); + + $bookingPropertyAddonUpdateMail = [ + 'propertyId' => $bookingDetail['property_id'], + 'bookingCode' => $bookingDetail['booking_code'], + 'addonLanguageKey' => $selectedAddon['property_channel_addon']['property_addon']['fact']['language_key'] + ]; + $this->mailer->onQueue('bookingPropertyAddonUpdateMail', new BookingPropertyAddonUpdateMail($bookingPropertyAddonUpdateMail)); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingCancellation(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $confirmCodeGenerate = null; + $propertyBookingController = \Illuminate\Support\Facades\App::make("App\Http\Controllers\V1\PropertyBookingController"); + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $channelId = $this->channelId; + $propertyId = $this->bookingEnginePropertyId; + $bookingCode = $params['bookingCode']; + $confirmCode = fillOnUndefined($params, 'confirmCode'); + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + $getChannelPropertyDetail = $getChannelPropertyDetail['data']; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode] + ], + 'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty', 'bookingRoom'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || ($bookingDetail['status'] == 'success' && empty($bookingDetail['data']))) { + throw new ApiErrorException('Property and Booking Code are not matched.'); + } + + $bookingDetail = $bookingDetail['data']; + + if ($bookingDetail['status'] != 1) { + throw new ApiErrorException('Reservation status not available.'); + } + + + //Only GE Hotels + if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [3]) && in_array($bookingDetail['booking_property']['country'], ['GE'])) { + + + //Check Cancellation Policy + $isBookingRefundable = false; + foreach ($bookingDetail['booking_room'] as $bookingRoom) { + $cancellationPolicy = json_decode($bookingRoom['cancellation_policy'], 1); + + if (!empty($cancellationPolicy)) { + if ($cancellationPolicy['isNonRefundable']) { + break; + } + if ($cancellationPolicy['isFreeCancellation']) { + if (isset($cancellationPolicy['beforeArrivalDay'])) { + if (Carbon::now()->startOfDay()->lessThan(Carbon::parse($bookingRoom['checkin_date'])->subDays($cancellationPolicy['beforeArrivalDay'])->toDateString())) { + $isBookingRefundable = true; + } + } else { + $isBookingRefundable = true; + } + } + } + } + + if ($isBookingRefundable) { + + //Cancellation Process + $updateBookingParam = [ + 'locale' => $request->getLocale(), + 'property_id' => $bookingDetail['property_id'], + 'booking_id' => $bookingDetail['id'], + 'total' => $bookingDetail['total'], + 'currency_code' => $bookingDetail['currency_code'], + 'status' => 0 + ]; + + $request['requestParams'] = $updateBookingParam; + + $updateBooking = $propertyBookingController->updateBooking($request); + $updateBooking = $updateBooking->getData(); + + if ($updateBooking->status != 200) { + throw new ApiErrorException($updateBooking->message); + } + + $mailParams = ['booking_id' => $bookingDetail['id']]; + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams)); + + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => [ + 'isCancellationRequest' => true + ], + 'message' => __('api-cancellation_confirm-message', [], $request->getLocale()) + ]; + + + } else { + + $mailParams = [ + 'bookingCode' => $bookingCode + ]; + + $this->mailer->send(new BookingCancellationRequestMail($mailParams)); + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => [ + 'isCancellationRequest' => true + ], + 'message' => __('api-cancellation_request-message', [], $request->getLocale()) + ]; + + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + //Just Offline Booking Engines + if (!in_array($bookingDetail['booking_channel']['channel_category_id'], [2, 7])) { + throw new ApiErrorException('Online reservation cancellation is not active for this channel.'); + } + + //TODO: Checkin tarihi geçmemiş olmalı kontrol eklenecek + + $cacheKey = md5('BookingCancellation-' . $bookingDetail['booking_code']); + + if (!empty($confirmCode) || in_array($bookingDetail['booking_channel']['channel_category_id'], [7])) { + + if (!in_array($bookingDetail['booking_channel']['channel_category_id'], [7])) { + + if (!Cache::has($cacheKey)) { + throw new ApiErrorException('Verification code not found, please try again.'); + } + + if ($confirmCode != Cache::get($cacheKey)) { + throw new ApiErrorException('The entered code could not be verified, please enter the updated code sent to your e-mail address.'); + } + + } + + //Cancellation Process + $updateBookingParam = [ + 'locale' => $request->getLocale(), + 'property_id' => $bookingDetail['property_id'], + 'booking_id' => $bookingDetail['id'], + 'total' => $bookingDetail['total'], + 'currency_code' => $bookingDetail['currency_code'], + 'status' => 0 + ]; + + $request['requestParams'] = $updateBookingParam; + + $updateBooking = $propertyBookingController->updateBooking($request); + $updateBooking = $updateBooking->getData(); + + if ($updateBooking->status != 200) { + throw new ApiErrorException($updateBooking->message); + } + + $mailParams = ['booking_id' => $bookingDetail['id']]; + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams)); + + Cache::forget($cacheKey); + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => null, + 'message' => null + ]; + + } else { + + $confirmCodeGenerate = rand(1000, 9999); + Cache::put($cacheKey, $confirmCodeGenerate, 60 * 5);//600 10 dk + + //$confirmCode + $mailParams = [ + 'bookingCode' => $bookingCode, + 'confirmCode' => $confirmCodeGenerate + ]; + + $this->mailer->send(new BookingCancellationConfirmCodeMail($mailParams)); + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => null, + 'message' => 'Please enter the cancellation verification code sent to your e-mail address.' + ]; + + } + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingInvoice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $channelId = $this->channelId; + $propertyId = $this->bookingEnginePropertyId; + $bookingCode = $params['bookingCode']; + + + $getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId); + if (!$getChannelPropertyDetail['status']) { + throw new ApiErrorException(lang('Property and Channel are not matched.')); + } + + $getChannelPropertyDetail = $getChannelPropertyDetail['data']; + + $bookingDetailParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode] + ], + 'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty', 'bookingRoom', 'bookingContact'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($bookingDetailParam); + + if ($bookingDetail['status'] != 'success' || ($bookingDetail['status'] == 'success' && empty($bookingDetail['data']))) { + throw new ApiErrorException('Property and Booking Code are not matched.'); + } + + $bookingDetail = $bookingDetail['data']; + + if ($bookingDetail['status'] != 1) { + throw new ApiErrorException('Reservation status not available.'); + } + + if ($bookingDetail['booking_contact']['invoice_request'] != 1) { + throw new ApiErrorException('Reservation invoice status not available.'); + } + + + $invoiceParam = [ + 'name_surname' => fillOnUndefined($params, 'name_surname'), + 'citizen_number' => fillOnUndefined($params, 'citizen_number'), + 'company' => fillOnUndefined($params, 'company'), + 'tax_number' => fillOnUndefined($params, 'tax_number'), + 'address' => fillOnUndefined($params, 'address'), + ]; + + $bookingInvoiceUpdate = $this->bookingContactService->update($bookingDetail['booking_contact']['id'], ['invoice' => json_encode($invoiceParam)]); + + if ($bookingInvoiceUpdate['status'] != 'success') { + throw new ApiErrorException('Invoice update operation could not be performed.'); + } + + $bookingPropertyAddonUpdateMail = [ + 'bookingCode' => $bookingDetail['booking_code'] + ]; + $this->mailer->onQueue('bookingInvoiceUpdateMail', new BookingInvoiceUpdateMail($bookingPropertyAddonUpdateMail)); + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => null, + 'message' => null + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + public function propertyList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $ipAddress = $request->ip(); + $channelToken = $request->header('channelToken'); + + if (!$channelToken) { + return apiResponse(0, 'Token not provided.', null, 401); + } + + $ipRestriction = [ + //City Travel + '1500c5d5-b55e-4fa0-966b-698f4f168f48' => [ + '127.0.0.1', + '185.137.215.118', + '176.236.59.130', + '176.236.59.131', + '176.236.59.132', + '176.236.59.133', + '176.236.59.134', + '176.236.59.135', + '176.236.59.136', + '176.236.59.137', + '176.236.59.138', + '176.236.59.139', + '54.72.215.85', + '54.77.48.206', + '34.252.23.103', + '52.19.162.59', + '54.72.80.155', + '52.210.166.9', + '54.72.220.60', + '52.17.235.55', + '176.236.59.130', + '54.72.215.85', + '54.77.48.206', + '52.213.250.14', + '34.252.23.103' + ] + ]; + + if (isset($ipRestriction[$channelToken]) && !in_array($ipAddress, $ipRestriction[$channelToken])) { + return apiResponse(0, 'Cannot be accessed via this IP address: ' . $ipAddress, null, 401); + } + + $channelRequest = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $channelToken], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $channelCheck = $this->channelService->select($channelRequest); + + if ($channelCheck['status'] != 'success' || empty($channelCheck['data'])) { + return apiResponse(0, 'Channel Token not found.', null, 401); + } + + $channelCheck = $channelCheck['data']; + + + $propertyBookingEngineParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelCheck['id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property.propertyBookingEngineToken', 'property.propertyType', 'property.propertyContact', 'property.propertyDestination'], + "orderBy" => [ + ["field" => "id", "value" => "DESC"] + ] + ]; + + $propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineParam); + $propertyBookingEngine = $propertyBookingEngine['status'] == 'success' ? $propertyBookingEngine['data'] : []; + + $propertyList = []; + foreach ($propertyBookingEngine as $bookingEngine) { + + $propertyList[] = [ + 'id' => $bookingEngine['property']['id'], + 'name' => $bookingEngine['property']['name'], + 'type' => $bookingEngine['property']['property_type']['name'], + 'country' => $bookingEngine['property']['country'], + 'destination' => $bookingEngine['property']['property_destination']['name'], + 'destination_id' => $bookingEngine['property']['destination_id'], + 'token' => $bookingEngine['token'], + 'mapping' => !empty($bookingEngine['property']['mapping']) ? json_decode($bookingEngine['property']['mapping'], 1) : null, + 'contact' => [ + 'address' => $bookingEngine['property']['property_contact']['address'], + 'phone' => $bookingEngine['property']['property_contact']['view_full_phone'], + 'email' => $bookingEngine['property']['property_contact']['email'], + 'latitude' => $bookingEngine['property']['property_contact']['latitude'], + 'longitude' => $bookingEngine['property']['property_contact']['longitude'], + ], + ]; + + } + + $response = [ + 'status' => 1, + 'statusCode' => 200, + 'data' => $propertyList, + 'message' => null + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} diff --git a/app/Http/Controllers/BookingEngine/V1/BookingEngineBaseController.php b/app/Http/Controllers/BookingEngine/V1/BookingEngineBaseController.php new file mode 100644 index 0000000..582d0a0 --- /dev/null +++ b/app/Http/Controllers/BookingEngine/V1/BookingEngineBaseController.php @@ -0,0 +1,109 @@ +cachePrefix . $searchKey; + Cache::put($searchKeyPrefix, $dataArray, $this->cacheExpireTime * 60);//5 min, 300 ttl, 600 10 dk + + if (Cache::has($searchKeyPrefix)) { + return true; + } else { + return false; + } + + } + + public function getCacheDataWithSearchKey($searchKey) + { + $cacheData = []; + $searchKeyPrefix = $this->cachePrefix . $searchKey; + if (Cache::has($searchKeyPrefix)) { + $cacheData = Cache::get($searchKeyPrefix); + + } + + return $cacheData; + + } + + public function rateKeyCodeDecode($rateKeyCode) + { + $rateKeyCodeExplode = explode('-', $rateKeyCode); + $data = [ + 'propertyId' => $rateKeyCodeExplode[0], + 'channelId' => $rateKeyCodeExplode[1], + 'availabilityTypeId' => $rateKeyCodeExplode[2], + 'roomId' => $rateKeyCodeExplode[3], + 'rateMappingId' => $rateKeyCodeExplode[4], + 'roomOccupancyCode' => $rateKeyCodeExplode[5], + 'checkInDate' => Carbon::parse($rateKeyCodeExplode[6])->format('Y-m-d'), + 'checkOutDate' => Carbon::parse($rateKeyCodeExplode[7])->format('Y-m-d'), + 'cancellationPolicyId' => $rateKeyCodeExplode[8], + 'paymentTypeId' => $rateKeyCodeExplode[9], + ]; + + return $data; + } + + public function getDateByDay($dates = []) + { + + $dateByDay = []; + + $diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut'])); + + for ($i = 0; $i < $diffInDays; $i++) { + $dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d'); + } + + return $dateByDay; + + } + + + public function getRoomsByOccupancies($rooms = []) + { + $roomsByOccupancies = []; + + foreach ($rooms as $roomOrder => $room) { + + $roomKey = []; + $roomKey[] = str_repeat('A', $room['adults']); + if ($room['children'] > 0) { + foreach ($room['age'] as $childAge) { + $roomKey[] = 'C' . $childAge; + } + } + + $roomKey = implode($roomKey, ''); + + $roomsByOccupancies[$roomKey]['rooms'][] = $roomOrder; + $roomsByOccupancies[$roomKey]['roomCount'] = count($roomsByOccupancies[$roomKey]['rooms']); + $roomsByOccupancies[$roomKey]['occupancy'] = intval($room['adults'] + $room['children']); + $roomsByOccupancies[$roomKey]['adultCount'] = $room['adults']; + $roomsByOccupancies[$roomKey]['childCount'] = $room['children']; + $roomsByOccupancies[$roomKey]['childAges'] = fillOnUndefined($room, 'age', []); + $roomsByOccupancies[$roomKey]['occupancyCode'] = str_repeat('A', $room['adults']) . str_repeat('C', $room['children']); + } + + return $roomsByOccupancies; + + } +} diff --git a/app/Http/Controllers/BookingEngine/V1/PaymentLinkController.php b/app/Http/Controllers/BookingEngine/V1/PaymentLinkController.php new file mode 100644 index 0000000..02c4c24 --- /dev/null +++ b/app/Http/Controllers/BookingEngine/V1/PaymentLinkController.php @@ -0,0 +1,489 @@ +request = $request; + $this->propertyPaymentService = $propertyPaymentService; + $this->propertyService = $propertyService; + $this->languageService = $languageService; + $this->manualPaymentMailService = $manualPaymentMailService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + } + + + public function paymentLinkDetail(Request $request, $orderCode) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $paymentDetailParam = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $orderCode], + ['field' => 'transaction_type', 'condition' => '=', 'value' => 'LNK'], + ['field' => 'status', 'condition' => '=', 'value' => 5], + ], + 'with' => ['relatedTransactions', 'paymentTypeMapping.paymentType'], + 'firstRow' => true + ]; + + $paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam); + + if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) { + throw new ApiErrorException(lang('Payment not found')); + } + + $paymentDetail = $paymentDetail['data']; + + if ($paymentDetail['status'] != 5) { + throw new ApiErrorException(lang('Payment not link status')); + } + + $paymentDetail['is_payed'] = false; + if (!empty($paymentDetail['related_transactions'])) { + $relatedTransactions = collect($paymentDetail['related_transactions']); + if ($relatedTransactions->where('status', 1)->count() > 0) { + $paymentDetail['is_payed'] = true; + } + } + + $propertyId = $paymentDetail['property_id']; + + $propertyParam = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['propertyBrand', 'propertyContact'], + 'firstRow' => true + ]; + + $getProperty = $this->propertyService->select($propertyParam); + + if ($getProperty['status'] != "success") { + throw new ApiErrorException($getProperty['message']); + } + + $property = $getProperty['data']; + + $property['property_brand']['logo_url'] = $property['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $property['id'] . "/logo/" . $property['property_brand']['logo_name'] . '_250x250.' . $property['property_brand']['logo_file_ext'] : null; + $property['property_contact']['social_media_addresses'] = json_decode($property['property_contact']['social_media_addresses'], 1); + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all(); + + + //contract_file + $property['contract_file'] = null; + $channelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $property['id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $channelMapping = $this->propertyChannelMappingService->select($channelMappingRequest, ['id', 'contract_file', 'currency_code']); + if ($channelMapping['status'] == 'success' && !empty($channelMapping['data'])) { + $property['contract_file'] = Config::get('app.propertyFilesUrl') . $channelMapping['data']['contract_file']; + } + //contract_file + + $responseData = [ + 'payment_detail' => $paymentDetail, + 'property_detail' => $property, + 'available_languages' => $availableLanguages, + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function paymentLinkInitialize(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $orderCode = $params['orderCode']; + + $paymentDetailParam = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $orderCode], + ['field' => 'transaction_type', 'condition' => '=', 'value' => 'LNK'], + ['field' => 'status', 'condition' => '=', 'value' => 5], + ], + 'firstRow' => true + ]; + + $paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam); + + if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) { + throw new ApiErrorException(lang('Payment not found')); + } + + $paymentDetail = $paymentDetail['data']; + + if ($paymentDetail['status'] != 5) { + throw new ApiErrorException(lang('Payment not link status')); + } + + $paymentStatusCheckParam = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $orderCode], + ['field' => 'transaction_type', 'condition' => '=', 'value' => 'LNK'], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $paymentStatusCheck = $this->propertyPaymentService->selectPaymentTransaction($paymentStatusCheckParam); + + if ($paymentStatusCheck['status'] == 'success' && !empty($paymentStatusCheck['data'])) { + throw new ApiErrorException(lang('Previously paid transaction')); + } + + + DB::beginTransaction(); + + $initializePaymentParam = [ + 'propertyId' => $paymentDetail['property_id'], + 'orderId' => $paymentDetail['order_id'], + 'installment' => 0, + 'amount' => (double)$paymentDetail['amount'], + 'currency' => $paymentDetail['currency'], + 'type' => 'LNK', + 'preferredPaymentTypeId' => $paymentDetail['payment_type_mapping_id'], + 'responseUrl' => $params['responseUrl'], + 'creditCard' => [ + 'name' => $params['creditCard']['cardHolder'], + 'number' => $params['creditCard']['cardNumber'], + 'month' => $params['creditCard']['cardExpireMonth'], + 'year' => $params['creditCard']['cardExpireYear'], + 'cvv' => $params['creditCard']['cardCvv'], + ] + ]; + + $initializePayment = $this->propertyPaymentService->initializePayment($initializePaymentParam); + + if (!$initializePayment['status']) { + throw new ApiErrorException(lang($initializePayment['message'])); + } + + $responseData = [ + 'orderCode' => $paymentDetail['order_id'], + 'paymentCode' => $initializePayment['data']['paymentCode'], + ]; + + if (isset($initializePayment['data']['redirectUrl'])) { + $responseData['redirectUrl'] = $initializePayment['data']['redirectUrl']; + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function paymentLinkConfirm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + $orderCode = $params['orderCode']; + $paymentCode = $params['paymentCode']; + + $paymentDetailParam = [ + 'criteria' => [ + ['field' => 'order_id', 'condition' => '=', 'value' => $orderCode], + ['field' => 'code', 'condition' => '=', 'value' => $paymentCode], + ['field' => 'transaction_type', 'condition' => '=', 'value' => 'LNK'], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam); + + if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) { + throw new ApiErrorException(lang('Payment not confirmed')); + } + + $paymentDetailParam = [ + 'orderCode' => $orderCode, + 'language_code' => isset($params['language_code']) ? $params['language_code'] : 'en' + ]; + $this->manualPaymentMailService->process($paymentDetailParam); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function createManualPaymentForm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $createPaymentLink = $this->propertyPaymentService->createManualPaymentForm($params); + + if ($createPaymentLink['status'] != "success") { + throw new ApiErrorException($createPaymentLink['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createPaymentLink['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createManualPayment(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $params['user_id'] = $request->credentials->user_id; + + $createPaymentLink = $this->propertyPaymentService->createManualPayment($params); + + if ($createPaymentLink['status'] != "success") { + throw new ApiErrorException($createPaymentLink['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createPaymentLink['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function editManualPaymentForm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $createPaymentLink = $this->propertyPaymentService->editManualPaymentForm($params); + + if ($createPaymentLink['status'] != "success") { + throw new ApiErrorException($createPaymentLink['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createPaymentLink['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updateManualPayment(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $createPaymentLink = $this->propertyPaymentService->updateManualPayment($params); + + if ($createPaymentLink['status'] != "success") { + throw new ApiErrorException($createPaymentLink['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createPaymentLink['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getManualPayment(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $createPaymentLink = $this->propertyPaymentService->getManualPayment($params); + + if ($createPaymentLink['status'] != "success") { + throw new ApiErrorException($createPaymentLink['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createPaymentLink['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/BookingEngine/V1/PropertyBookingEngineController.php b/app/Http/Controllers/BookingEngine/V1/PropertyBookingEngineController.php new file mode 100644 index 0000000..5d98d59 --- /dev/null +++ b/app/Http/Controllers/BookingEngine/V1/PropertyBookingEngineController.php @@ -0,0 +1,357 @@ +propertyBookingEngineService = $propertyBookingEngineService; + $this->languageService = $languageService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->currencyService = $currencyService; + $this->propertyGroupService = $propertyGroupService; + $this->findCountryCodeService = $findCountryCodeService; + $this->generalTimezoneService = $generalTimezoneService; + } + + public function checkProperty(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->params; + $propertyRequest = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $params['token']], + ], + 'with' => ['channel', + 'property.propertyBookingEngineGroupMapping.propertyGroup.propertyGroupMapping.property.propertyBookingEngineToken', + 'property.propertyBookingEngineGroupMapping.propertyGroup.propertyGroupMapping.property.propertyWeb', + 'propertyWeb', 'propertyChannelMapping.channelTax', 'propertyWebComponent', + 'property.propertyAdditionalInfos' + ], + 'firstRow' => 1 + ]; + + $propertyBookingEngine = $this->propertyBookingEngineService->select($propertyRequest, ['id', 'property_id', 'channel_id', 'token', 'parameters']); + + if ($propertyBookingEngine['status'] != 'success') { + throw new ApiErrorException($propertyBookingEngine['message']); + } + if (!$propertyBookingEngine['data']) { + throw new ApiErrorException('General error ...'); + } + + $propertyBookingEngine = $propertyBookingEngine['data']; + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ] + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $languageCodes = []; + foreach ($availableLanguages['data'] as $language) { + $languageCodes[$language['code']] = $language; + } + + + $properBookingEngineMapping = []; + if (isset($propertyBookingEngine['parametersArray']['property_group_id'])) { + + $propertyGroupRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'type', 'condition' => '=', 'value' => 'BEN'], + ['field' => 'id', 'condition' => '=', 'value' => $propertyBookingEngine['parametersArray']['property_group_id']] + ], + 'with' => ['propertyGroupMapping'], + 'firstRow' => true, + ]; + + $propertyGroup = $this->propertyGroupService->select($propertyGroupRequest); + $propertyGroup = $propertyGroup['status'] == 'success' && !empty($propertyGroup['data']) ? $propertyGroup['data']['property_group_mapping'] : []; + $propertyGroupPropertyIds = collect($propertyGroup)->pluck('property_id')->toArray(); + + $propertyGroupBookingEngineRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_id', 'condition' => '=', 'value' => $propertyBookingEngine['channel_id']], + ], + 'with' => ['property.propertyBookingEngineGroupMapping.propertyGroup.propertyGroupMapping.property.propertyBookingEngineToken'], + 'whereIn' => [ + ['field' => 'property_id', 'value' => $propertyGroupPropertyIds] + ] + ]; + + $propertyGroupBookingEngine = $this->propertyBookingEngineService->select($propertyGroupBookingEngineRequest); + if ($propertyGroupBookingEngine['status'] == 'success') { + + foreach ($propertyGroupBookingEngine['data'] as $bookingEngine) { + $properBookingEngineMapping[] = [ + 'property_id' => $bookingEngine['property_id'], + 'name' => $bookingEngine['property']['name'], + 'token' => $bookingEngine['token'], + 'order_number' => count($properBookingEngineMapping) + ]; + } + } + + } + + if ($propertyBookingEngine['channel_id'] == 1) { + + $propertyBookingEngineGroupMapping = $propertyBookingEngine['property']['property_booking_engine_group_mapping']; + foreach ($propertyBookingEngineGroupMapping as $beGroupMapping) { + $group = $beGroupMapping['property_group']; + if ($group['type'] == 'MYW') { + $groupProperties = $group['property_group_mapping']; + foreach ($groupProperties as $groupProperty) { + if (isset($groupProperty['property']['property_booking_engine_token'])) { + + $arrayItem = [ + 'property_id' => $groupProperty['property_id'], + 'name' => $groupProperty['property']['name'], + 'token' => $groupProperty['property']['property_booking_engine_token']['token'], + 'order_number' => $groupProperty['order_number'] + ]; + + $arrayItem['web'] = null; + if (!empty($groupProperty['property']['property_web'])) { + if ($groupProperty['property']['property_web']['status'] && $groupProperty['property']['property_web']['is_published']) { + $arrayItem['web'] = $groupProperty['property']['property_web']['webProtocolUrl']; + } + } + + $properBookingEngineMapping[] = $arrayItem; + + } + } + + } + } + } + + if (count($properBookingEngineMapping) > 1) { + array_multisort(array_column($properBookingEngineMapping, 'order_number'), SORT_ASC, $properBookingEngineMapping); + } + + $channelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyBookingEngine['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $propertyBookingEngine['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $channelMapping = $this->propertyChannelMappingService->select($channelMappingRequest, ['id', 'contract_file', 'currency_code']); + if ($channelMapping['status'] != 'success') { + throw new ApiErrorException($channelMapping['message']); + } + + + $channelDefaultCurrencyCode = $channelMapping['data']['currency_code']; + //IP Bases Pricing Channel Manipulation + if (isset($params['ipAddress']) && !empty($params['ipAddress']) && fillOnUndefined($params, 'referrer') != 'google') { + + // Find Country Code with IP + $ipResponse = $this->findCountryCodeService->findCountryWithIpAddress($params['ipAddress']); + + if ($ipResponse['status'] == 'success') { + + $propertyChannelMappingParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyBookingEngine['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'], + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingParam); + + $ipCountryCode = isset($ipResponse['data']['code']) ? $ipResponse['data']['code'] : 'tr'; + + if ($propertyChannelMapping['status'] == 'success') { + + $propertyChannelMappingCollect = collect($propertyChannelMapping['data']); + $countryChannel = $propertyChannelMappingCollect + ->where('channel.channel_category_id', 3) + ->where('channel.country_code', $ipCountryCode) + ->where('channel.parent_id', 1) + ->first(); + + if (!empty($countryChannel)) { + $channelDefaultCurrencyCode = $countryChannel['currency_code']; + } + + //countryCodeGroup + if (empty($countryChannel)) { + $countryChannelGroup = $propertyChannelMappingCollect + ->where('channel.channel_category_id', 3) + ->where('channel.country_code', 'group') + ->where('channel.parent_id', 1) + ->toArray(); + + if (!empty($countryChannelGroup)) { + foreach ($countryChannelGroup as $country) { + if (!empty($country['channel']['country_code_group'])) { + if (in_array($ipCountryCode, $country['channel']['countryCodeGroupArray'])) { + $channelDefaultCurrencyCode = $country['currency_code']; + break; + } + } + } + } + } + //countryCodeGroup + + } + + } + //channelToken Manipulation + + + } + + $exchangeCurrencyRates = $this->currencyService->exchangeCurrencyRates($channelDefaultCurrencyCode); + + $exchangeCurrencyRateList = []; + $exchangeCurrencyAvailable = ['EUR', 'USD', 'TRY', 'GBP', 'GEL', 'MAD', 'AZN']; + if ($exchangeCurrencyRates['status'] == 'success') { + foreach ($exchangeCurrencyRates['data'] as $currencyRate) { + if (!in_array($currencyRate['exc_currency_code'], $exchangeCurrencyAvailable)) { + continue; + } + $currencyKey = $currencyRate['currency_code'] . '-' . $currencyRate['exc_currency_code']; + $exchangeCurrencyRateList[$currencyKey] = [ + 'currency_code' => $currencyRate['currency_code'], + 'exc_currency_code' => $currencyRate['exc_currency_code'], + 'rate' => moneyFourFormatDecimal($currencyRate['rate']), + ]; + } + } + + $contractFileUrl = NULL; + if (!empty($channelMapping['data']['contract_file'])) { + $contractFileUrl = Config::get('app.propertyFilesUrl') . $channelMapping['data']['contract_file']; + } + + $channelTax = null; + $taxOptions = Config::get('app.taxOptions'); + if (!empty($propertyBookingEngine['property_channel_mapping']['channel_tax_id'])) { + $channelTax = [ + 'id' => $propertyBookingEngine['property_channel_mapping']['channel_tax']['id'], + 'code' => $propertyBookingEngine['property_channel_mapping']['channel_tax']['code'], + 'name' => $propertyBookingEngine['property_channel_mapping']['channel_tax']['name'], + 'language_key' => $propertyBookingEngine['property_channel_mapping']['channel_tax']['language_key'], + 'tax' => isset($taxOptions[$propertyBookingEngine['property']['country']]) ? $taxOptions[$propertyBookingEngine['property']['country']] : null + ]; + } + + //PropertyWebComponent + $propertyWebComponent = null; + if ($propertyBookingEngine['property_web_component']) { + + $propertyWebComponentSojernBookingEngine = collect($propertyBookingEngine['property_web_component']) + ->where('component_id', 10) + ->first(); + + if ($propertyWebComponentSojernBookingEngine) { + $propertyWebComponent['sojernbookingengine'] = $propertyWebComponentSojernBookingEngine['parameterArray']; + } + + $propertyWebComponentClarityBookingEngine = collect($propertyBookingEngine['property_web_component']) + ->where('component_id', 14) + ->first(); + + if ($propertyWebComponentClarityBookingEngine) { + $propertyWebComponent['claritybookingengine'] = $propertyWebComponentClarityBookingEngine['parameterArray']; + } + + } + + + $propertyTimeZoneDetail = null; + $timeZoneValue = collect($propertyBookingEngine['property']['property_additional_infos'])->where('additional_info_key_id', '13')->first(); + if ($timeZoneValue) { + $generalTimezoneRepositoryCriteria = ['criteria' => [['field' => 'id', 'condition' => '=', 'value' => $timeZoneValue['value']],], 'firstRow' => true]; + $propertyTimeZoneDetail = $this->generalTimezoneService->select($generalTimezoneRepositoryCriteria, ['location', 'action_type', 'hour', 'minute']); + if ($propertyTimeZoneDetail['status'] == 'success') { + $propertyTimeZoneDetail = $propertyTimeZoneDetail['data']; + } + + } + + $responseData = [ + 'property_id' => $propertyBookingEngine['property_id'], + 'property_name' => $propertyBookingEngine['property']['name'], + 'channel_id' => $propertyBookingEngine['channel_id'], + 'channel_name' => $propertyBookingEngine['channel']['name'], + 'channel_category_id' => $propertyBookingEngine['channel']['channel_category_id'], + 'booking_engine_token' => $propertyBookingEngine['token'], + 'channel_token' => $propertyBookingEngine['channel']['token'], + 'channel_contact' => $propertyBookingEngine['channel']['contact'], + 'default_language' => isset($propertyBookingEngine['property_web']['default_language']) ? $propertyBookingEngine['property_web']['default_language'] : null, + 'default_currency' => $channelDefaultCurrencyCode, + 'available_language_codes' => $languageCodes, + 'property_booking_engine_mapping' => count($properBookingEngineMapping) > 0 ? $properBookingEngineMapping : null, + 'contract_file_url' => $contractFileUrl, + 'exchange_currency_rate' => $exchangeCurrencyRateList, + 'booking_engine_parameters' => $propertyBookingEngine['parametersArray'], + 'channel_tax' => $channelTax, + 'property_web_component' => $propertyWebComponent, + 'property_timezone' => $propertyTimeZoneDetail + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } +} diff --git a/app/Http/Controllers/BookingEngine/V1/SearchController.php b/app/Http/Controllers/BookingEngine/V1/SearchController.php new file mode 100644 index 0000000..fca43f4 --- /dev/null +++ b/app/Http/Controllers/BookingEngine/V1/SearchController.php @@ -0,0 +1,2136 @@ +request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + + $this->channelId = $this->request->channelId; + $this->channelToken = $this->request->channelToken; + $this->bookingEngineToken = $this->request->bookingEngineToken; + $this->bookingEnginePropertyId = $this->request->bookingEnginePropertyId; + $this->findCountryCodeService = $findCountryCodeService; + $this->propertyPromotionService = $propertyPromotionService; + $this->propertyAddonService = $propertyAddonService; + $this->propertyBookingEngineSearchService = $propertyBookingEngineSearchService; + $this->propertyPaymentService = $propertyPaymentService; + $this->currencyService = $currencyService; + + $this->channelConnectedId = null; + + $this->cachePrefix = 'enwAPISearch:'; + $this->cacheExpireTime = 15;//minute + + } + + public function getPropertyRoomAndRoomRateMappingData($channelPropertyRoomRate = []) + { + + $propertyRoomAndRoomRateMappingData = []; + + foreach ($channelPropertyRoomRate as $propertyRoomRate) { + $propertyRoomFacts = []; + foreach ($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_fact_mapping'] as $propertyRoomFact) { + $propertyRoomFacts[$propertyRoomFact['fact_id']] = [ + 'name' => __($propertyRoomFact['property_fact']['language_key']), + 'icon' => $propertyRoomFact['property_fact']['icon'], + 'is_feature' => $propertyRoomFact['is_feature'], + ]; + } + + if (!empty($propertyRoomFacts)) { + unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_fact_mapping']); + $propertyRoomRate['property_room_rate_mapping']['property_room']['attributes'] = $propertyRoomFacts; + + } + + $propertyRoomBedGroups = []; + $propertyRoomBedGroupCollection = collect($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group')->sortBy('bed_group')->toArray(); + foreach ($propertyRoomBedGroupCollection as $propertyRoomBedGroupKey => $propertyRoomBedGroup) { + foreach ($propertyRoomBedGroup as $bedGroup) { + $propertyRoomBedGroups[$propertyRoomBedGroupKey][$bedGroup['id']] = [ + 'count' => $bedGroup['count'], + 'name' => __($bedGroup['property_room_bed_type']['language_key']), + 'icon' => $bedGroup['property_room_bed_type']['bedTypeIcon'], + ]; + } + } + + if (!empty($propertyRoomBedGroups)) { + unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_bed_group']); + $propertyRoomRate['property_room_rate_mapping']['property_room']['bedGroups'] = $propertyRoomBedGroups; + + } + + + $propertyRoomPhotos = []; + foreach ($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_photo_mapping'] as $propertyRoomPhoto) { + $propertyRoomPhotos[$propertyRoomPhoto['property_room_photo']['id']] = [ + 'url' => $propertyRoomPhoto['property_room_photo']['photoUrl'], + 'is_default' => $propertyRoomPhoto['property_room_photo']['is_default'], + 'photo_order' => $propertyRoomPhoto['property_room_photo']['photo_order'], + ]; + } + + $propertyRoomRate['property_room_rate_mapping']['property_room']['photos'] = $propertyRoomPhotos; + if (!empty($propertyRoomPhotos)) { + unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_photo_mapping']); + } + + $propertyRoomAndRoomRateMappingData['room'][$propertyRoomRate['property_room_rate_mapping']['property_room']['id']] = $propertyRoomRate['property_room_rate_mapping']['property_room']; + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']] = $propertyRoomRate['property_room_rate_mapping']; + + + //Child Policy + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingChildPolicy'] = []; + if (!empty($propertyRoomRate['property_room_rate_channel_pricing_child_policy'])) { + + $roomRateMappingChildPolicy = []; + foreach ($propertyRoomRate['property_room_rate_channel_pricing_child_policy'] as $childPolicy) { + $roomRateMappingChildPolicy[$childPolicy['property_pricing_policy_child']['id']] = $childPolicy['property_pricing_policy_child']; + } + + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingChildPolicy'] = $roomRateMappingChildPolicy; + } + + + //Adult Policy + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingAdultPolicy'] = []; + if (!empty($propertyRoomRate['property_room_rate_channel_pricing_adult_policy'])) { + + $roomRateMappingAdultPolicy = []; + foreach ($propertyRoomRate['property_room_rate_channel_pricing_adult_policy'] as $adultPolicy) { + $roomRateMappingAdultPolicy[$adultPolicy['property_pricing_policy_adult']['id']] = $adultPolicy['property_pricing_policy_adult']; + } + + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingAdultPolicy'] = $roomRateMappingAdultPolicy; + } + + + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateDescription'] = $propertyRoomRate['property_room_rate_mapping']['property_room_rate']['descriptionArray']; + + + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingCancellationPolicy'] = []; + if (!empty($propertyRoomRate['property_room_rate_channel_cancellation_policy'])) { + + $roomRateMappingCancellationPolicy = []; + foreach ($propertyRoomRate['property_room_rate_channel_cancellation_policy'] as $cancellationPolicy) { + + if ($cancellationPolicy['property_cancellation_policy']['status'] == 0) { + continue; + } + + $roomRateMappingCancellationPolicy[$cancellationPolicy['property_cancellation_policy']['id']] = [ + 'id' => $cancellationPolicy['cancellation_policy_id'], + 'name' => $cancellationPolicy['property_cancellation_policy']['name'], + 'beforeArrivalDay' => $cancellationPolicy['property_cancellation_policy']['before_arrival'], + 'isNonRefundable' => $cancellationPolicy['property_cancellation_policy']['is_nonrefundable'], + 'isFreeCancellation' => $cancellationPolicy['property_cancellation_policy']['is_free_cancellation'], + 'type' => $cancellationPolicy['property_cancellation_policy']['type'], + 'value' => $cancellationPolicy['property_cancellation_policy']['value'], + 'isAffectedPrice' => $cancellationPolicy['property_cancellation_policy']['is_affected_price'], + 'affectPriceActionType' => $cancellationPolicy['property_cancellation_policy']['affect_price_action_type'], + 'affectPriceType' => $cancellationPolicy['property_cancellation_policy']['affect_price_type'], + 'affectPriceValue' => $cancellationPolicy['property_cancellation_policy']['affect_price_value'], + 'is_date_range' => $cancellationPolicy['property_cancellation_policy']['is_date_range'], + 'start_date' => $cancellationPolicy['property_cancellation_policy']['start_date'], + 'finish_date' => $cancellationPolicy['property_cancellation_policy']['finish_date'], + ]; + } + + $roomRateMappingCancellationPolicy = collect($roomRateMappingCancellationPolicy)->sortByDesc('beforeArrivalDay')->toArray(); + + $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingCancellationPolicy'] = $roomRateMappingCancellationPolicy; + } + + } + + return $propertyRoomAndRoomRateMappingData; + + } + + public function getChannelProperty($property = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['property.propertyBookingEngineToken', 'channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType', 'channelBookingPaymentType.paymentType', 'channel'] + ]; + + if (!empty($property)) { + $requestParam['whereIn'][] = ['field' => 'property_id', 'value' => $property]; + } + + $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); + + if ($getChannelProperty['status'] != 'success' || empty($getChannelProperty['data'])) { + throw new ApiErrorException(lang('Property not found')); + } + + //if (!empty($property)) { + foreach ($getChannelProperty['data'] as $channelPropertyKey => $channelProperty) { + if (!empty($property) && !in_array($channelProperty['property_id'], $property)) { + unset($getChannelProperty['data'][$channelPropertyKey]); + } else { + + $channelBookingPaymentType = []; + foreach ($channelProperty['channel_booking_payment_type'] as $paymentType) { + if ($paymentType['is_selected'] && $paymentType['status']) { + $channelBookingPaymentType[$paymentType['payment_type']['id']] = [ + 'paymentType' => __($paymentType['payment_type']['language_key']), + //'paymentTypeId' => $paymentType['payment_type_id'], + 'paymentTypeCode' => $paymentType['payment_type']['code'], + 'cancellationPolicy' => $paymentType['cancellationPolicyArray'], + 'isAffectedPrice' => $paymentType['is_affected_price'], + 'isGetPaymentData' => $paymentType['is_get_payment_data'], + 'actionType' => $paymentType['action_type'], + 'valueType' => $paymentType['value_type'], + 'value' => $paymentType['value'], + ]; + } + } + + $getChannelProperty['data'][$channelPropertyKey]['channel_booking_payment_type'] = $channelBookingPaymentType; + + + } + } + //} + + $getChannelProperty['data'] = array_values($getChannelProperty['data']); + + $response = [ + 'status' => true, + 'data' => $getChannelProperty['data'], + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function getChannelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $channelId = $this->channelId; + if (!empty($this->channelConnectedId)) { + $channelId = $this->channelConnectedId; + } + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + 'propertyRoomRateMapping.propertyRoom.propertyRoomFactMapping.propertyFact', + 'propertyRoomRateMapping.propertyRoom.propertyRoomPhotoMapping.propertyRoomPhoto', + 'propertyRoomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', + 'propertyRoomRateChannelPricingAdultPolicy.propertyPricingPolicyAdult', + 'propertyRoomRateChannelPricingChildPolicy.propertyPricingPolicyChild', + 'propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy', + //'propertyRoomRateChannelActivePromotion', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException(lang('Property Room Rate not found')); + } + + $getChannelPropertyRoomRateCollect = collect($getChannelPropertyRoomRate['data']); + + + //Date Filtered + $channelPropertyRoomRateCollectNonDateFiltered = $getChannelPropertyRoomRateCollect + ->where('has_date', '=', 0); + + + $channelPropertyRoomRateCollectDateFiltered = $getChannelPropertyRoomRateCollect + ->where('has_date', '=', 1) + ->where('start_date', '<=', Carbon::now()->format('Y-m-d')) + ->where('end_date', '>=', Carbon::now()->format('Y-m-d')); + + $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectNonDateFiltered->merge($channelPropertyRoomRateCollectDateFiltered); + //Date Filtered + + + //Channel Room Rate Active Filtered + $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->where('property_room_rate_mapping.status', 1); + + //Room Rate Filtered + $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->where('property_room_rate_mapping.property_room.status', 1); + + $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->toArray(); + + + $response = [ + 'status' => true, + 'data' => $channelPropertyRoomRateCollectFiltered + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function getPropertyRoomRatePrice($param = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $param['channel_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => $param['checkIn']], + ['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']], + ['field' => 'amount', 'condition' => '<>', 'value' => null], + ['field' => 'amount', 'condition' => '<>', 'value' => 0], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'availability_type_id', 'value' => 'ASC'], + ['field' => 'property_room_id', 'value' => 'ASC'], + ['field' => 'room_rate_mapping_id', 'value' => 'ASC'], + ['field' => 'date', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); + + if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { + throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); + } + + + //dd($getPropertyRoomRatePrice['data']); + + $response = [ + 'status' => true, + 'data' => $getPropertyRoomRatePrice['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function getPropertyRoomAndRoomRateAvailability($param = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], + ['field' => 'availability', 'condition' => '>', 'value' => 0], + ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => $param['checkIn']], + ['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'availability_type_id', 'value' => 'ASC'], + ['field' => 'property_room_id', 'value' => 'ASC'], + ['field' => 'room_rate_mapping_id', 'value' => 'ASC'], + ['field' => 'date', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { + throw new ApiErrorException(lang('PropertyRoomAndRoomRateAvailability not found')); + } + + $response = [ + 'status' => true, + 'data' => $getPropertyRoomAndRoomRateAvailability['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + + public function search(Request $request) + { + + //dd(Cache::get($this->cachePrefix.'4d354fd2-8fc3-0725-38bc-1f2f7e749ea8')); + + $minStayCheckProperty = null; + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500, 'errorCode' => null]; + try { + + $this->channelToken = empty($this->channelToken) ? $request->header('channelToken') : $this->channelToken; + $this->bookingEngineToken = empty($this->bookingEngineToken) ? $request->header('bookingEngineToken') : $this->bookingEngineToken; + $this->channelId = empty($this->channelId) ? $request->header('channelId') : $this->channelId; + $this->bookingEnginePropertyId = empty($this->bookingEnginePropertyId) ? $request->header('bookingEnginePropertyId') : $this->bookingEnginePropertyId; + $this->language = empty($this->language) ? $request->header('language') : $this->language; + + $searchKey = md5(getGuid()); + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(), 1); + + //TODO: Burada validator olacak, date zorunlu, en az 1 oda zorunlu + + if ($params['date']['checkIn'] < Carbon::now()->toDateString()) { + throw new ApiErrorException(lang('Check-in time cannot be earlier than today')); + } + + $isMinStayDisabled = (isset($params['min_stay_disabled']) && $params['min_stay_disabled']) ? true : false; + + if (Carbon::parse($params['date']['checkIn'])->diff(Carbon::parse($params['date']['checkOut']))->days > 60) { + throw new ApiErrorException(lang('You can book up to 60 days')); + } + + + $roomsByOccupancies = $this->getRoomsByOccupancies($params['rooms']); + $this->roomsByOccupancies = $roomsByOccupancies; + + $dateByDay = $this->getDateByDay($params['date']); + $this->dateByDay = $dateByDay; + + $channelAvailabilityType = $this->propertyRoomRateChannelMappingService->selectChannelAvailabilityType([]); + $channelAvailabilityType = $channelAvailabilityType['status'] == 'success' ? $channelAvailabilityType['data'] : []; + $channelAvailabilityType = collect($channelAvailabilityType)->groupBy(['id'])->toArray(); + + $daysLeftForCheckin = Carbon::parse($params['date']['checkIn'])->diff(Carbon::now()->toDateString())->days; + + //Eğer $this->bookingEngineToken var ise bu token a ait prporty çekilip gönderilen veriler ezilcek ve sadece o property için fiyat verieclek + if (!is_null($this->bookingEngineToken) && isset($this->bookingEnginePropertyId)) { + $params['property'] = []; + $params['property'][] = $this->bookingEnginePropertyId; + } + + //Wholesaler + if (in_array($request->bookingEngineChannelCategoryId, [7])) { + //$params['property'] = []; + return $response; + } + + $channelProperty = $this->getChannelProperty($params['property']); + + if (!$channelProperty['status']) { + throw new ApiErrorException($channelProperty['message']); + } + + + $searchPricesCacheWithKey = []; + $calculatedRoomPriceFormatted = []; + + + //Channel ile maplenmiş tüm oteller + foreach ($channelProperty['data'] as $channelProperty) { + + $payAtHotelCreditCardCheck = collect($channelProperty['channel_booking_payment_type'])->where('isGetPaymentData',1)->isNotEmpty(); + + //Wholesaler MARKUP + $channelPropertyMarkup = []; + if (in_array($channelProperty['channel']['channel_category_id'], [7])) { + + if (!is_null($channelProperty['markup']) && !empty($channelProperty['channel']['default_currency'])) { + + $channelPropertyMarkup['markup'] = 1; + if (!is_null($channelProperty['markup'])) { + $channelPropertyMarkup['markup'] = (($channelProperty['markup'] + 100) / 100); + } + + $lastExchangeRate = 1; + if ($channelProperty['currency_code'] != $channelProperty['channel']['default_currency']) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($channelProperty['currency_code'], $channelProperty['channel']['default_currency']); + if ($lastExchangeRate['status'] == 'success') { + $lastExchangeRate = $lastExchangeRate['data']; + } + } + $channelPropertyMarkup['exchange'] = $lastExchangeRate; + $channelPropertyMarkup['currency_code'] = $channelProperty['channel']['default_currency']; + } else { + $channelPropertyMarkup = []; + } + } + //Wholesaler MARKUP + + //Bağlı kanala ait özelliklerin alınması + if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5) { + + $requestConnectedChannelParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelProperty['connected_channel_id']], + ], + 'with' => ['channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType', 'channelBookingPaymentType.paymentType'], + 'firstRow' => true + ]; + + $getConnectedChannel = $this->propertyChannelMappingService->select($requestConnectedChannelParam); + + if ($getConnectedChannel['status'] != 'success' || empty($getConnectedChannel['data'])) { + continue; + } + + $channelProperty['currency_code'] = $getConnectedChannel['data']['currency_code']; + $channelProperty['property_booking_type_id'] = $getConnectedChannel['data']['property_booking_type_id']; + $channelProperty['property_availability_type_id'] = $getConnectedChannel['data']['property_availability_type_id']; + $channelProperty['property_room_pricing_type_id'] = $getConnectedChannel['data']['property_room_pricing_type_id']; + + $channelProperty['channel_availability_type'] = $getConnectedChannel['data']['channel_availability_type']; + $channelProperty['channel_booking_type'] = $getConnectedChannel['data']['channel_booking_type']; + $channelProperty['channel_room_pricing_type'] = $getConnectedChannel['data']['channel_room_pricing_type']; + + + } + + //$channelBookingPaymentTypePolicy + $channelBookingPaymentTypePolicy = []; + if (!empty($channelProperty['channel_booking_payment_type'])) { + + foreach ($channelProperty['channel_booking_payment_type'] as $channelBookingPaymentTypeId => $channelBookingPaymentType) { + + $channelBookingPaymentTypePolicy[$channelBookingPaymentTypeId] = [ + 'name' => $channelBookingPaymentType['paymentType'], + 'code' => $channelBookingPaymentType['paymentTypeCode'], + 'isAffectedPrice' => $channelBookingPaymentType['isAffectedPrice'], + 'isGetPaymentData' => $channelBookingPaymentType['isGetPaymentData'], + 'affectPriceActionType' => $channelBookingPaymentType['actionType'], + 'affectPriceType' => $channelBookingPaymentType['valueType'], + 'affectPriceValue' => $channelBookingPaymentType['value'], + 'cancellationPolicy' => $channelBookingPaymentType['cancellationPolicy'], + 'paymentTypeMapping' => null, + ]; + + if ($channelBookingPaymentType['paymentTypeCode'] == 'CRD') { + $paymentMappingRequest = $this->propertyPaymentService->getPaymentMappingList(['property_id' => $channelProperty['property_id']]); + $paymentMappingRequest = $paymentMappingRequest['status'] == 'success' ? collect($paymentMappingRequest['data'])->pluck('pos_code')->toArray() : null; + $channelBookingPaymentTypePolicy[$channelBookingPaymentTypeId]['paymentTypeMapping'] = $paymentMappingRequest; + } + + } + + } + + + //Eğer bağlı bir kanal ise ve bu kanal acente tipinde ise + if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5 && in_array($channelProperty['channel']['channel_category_id'], [2, 7])) { + $this->channelConnectedId = $channelProperty['connected_channel_id']; + } + + + //Kanala ait otelin aktif olan room rate leri + $getChannelPropertyRoomRate = $this->getChannelPropertyRoomRate($channelProperty['property_id']); + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + continue; + } + + + //Kanala ait otelin aktif olan room rate fiyatları + $propertyRoomRatePriceParam = [ + 'channel_id' => $channelProperty['channel_id'], + 'property_id' => $channelProperty['property_id'], + 'checkIn' => $params['date']['checkIn'], + 'checkOut' => $params['date']['checkOut'], + ]; + + //connected_channel_id manipulation + if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5) { + $propertyRoomRatePriceParam['channel_id'] = $channelProperty['connected_channel_id']; + } + + // if($request->getClientIp() == '185.137.215.118') { + //dd($propertyRoomRatePriceParam); + //} + + $getPropertyRoomRatePrice = $this->getPropertyRoomRatePrice($propertyRoomRatePriceParam); + + if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { + continue; + } + + //connected_channel_id manipulation + if (!is_null($channelProperty['connected_channel_id']) && !is_null($channelProperty['connected_channel_action']) && $channelProperty['connected_channel_id'] != 5) { + + $connectedChannelAction = json_decode($channelProperty['connected_channel_action'], 1); + + foreach ($getPropertyRoomRatePrice['data'] as $roomRatePriceKey => $roomRatePrice) { + + $roomRatePriceAffected = 0; + + if ($connectedChannelAction['type'] == 'PER') { + $roomRatePriceAffected = ($roomRatePrice['amount'] * $connectedChannelAction['value']) / 100; + } elseif ($connectedChannelAction['type'] == 'FIX') { + $roomRatePriceAffected = $connectedChannelAction['value']; + } + + if ($connectedChannelAction['action_type'] == 'INC') { + $getPropertyRoomRatePrice['data'][$roomRatePriceKey]['amount'] = $roomRatePrice['amount'] + $roomRatePriceAffected; + } + + if ($connectedChannelAction['action_type'] == 'DEC') { + $getPropertyRoomRatePrice['data'][$roomRatePriceKey]['amount'] = $roomRatePrice['amount'] - $roomRatePriceAffected; + } + + } + } + //connected_channel_id manipulation + + + $propertyRoomAndRoomRateAvailabilityParam = [ + 'property_id' => $channelProperty['property_id'], + 'checkIn' => $params['date']['checkIn'], + 'checkOut' => $params['date']['checkOut'], + ]; + + $getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam); + + if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { + continue; + } + + + //Room ve Room Date Mapping datası + $propertyRoomAndRoomRateMappingData = $this->getPropertyRoomAndRoomRateMappingData($getChannelPropertyRoomRate['data']); + + + /**** PROMOTION START ****/ + $promotionGroupByDay = []; + $propertyPromotionMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyPromotion.promotionType', 'propertyRoomRateChannelMapping'] + ]; + + + $propertyPromotionMapping = $this->propertyPromotionService->selectPropertyPromotionMapping($propertyPromotionMappingCriteria); + if ($propertyPromotionMapping['status'] == 'success' && !empty($propertyPromotionMapping['data'])) { + $propertyPromotionMapping = $propertyPromotionMapping['data']; + } else { + $propertyPromotionMapping = []; + } + + //Eğer bağlı bir kanal var ise ve booking engine e bağlıysa burada promosyon çalıştırılmaz! + if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] == 1 && !in_array($channelProperty['channel']['channel_category_id'], [2, 3, 7])) { + $propertyPromotionMapping = []; + } + + //Hangi room rate channel datası için komisyon verilecek... + $roomRateChannelMappingIdList = array_values(array_unique(pickItemFromArray('room_rate_channel_mapping_id', $propertyPromotionMapping))); + + $propertyPromotionMapping = collect($propertyPromotionMapping); + $propertyPromotionMappingGrouped = $propertyPromotionMapping->groupBy(['property_promotion.promotion_type.type_code'])->toArray(); + + //dd($propertyPromotionMappingGrouped); + + foreach ($roomRateChannelMappingIdList as $roomRateChannelMappingId) { + foreach ($propertyPromotionMappingGrouped as $promotionType => $promotions) { + + $promotionsCollect = collect($promotions)->sortByDesc('property_promotion.amount'); + + foreach ($dateByDay as $day) { + + $promotionsCollectFiltered = null; + + if ($promotionType == 'PRD') { + + //burada promosyonun işleneceği eşleştirmeinin de oluşturulması lazım gün bazında + //"1-1-1-2021-12-28" + /* + "property_id" => 1 + "room_rate_mapping_id" => 1 + "channel_id" => 1 + "date" => "2021-12-28" + * */ + + $promotionsCollectFiltered = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.start_date', '<=', Carbon::now()->toDateString()) + ->where('property_promotion.end_date', '>=', Carbon::now()->toDateString()) + ->where('property_promotion.reservation_start_date', '<=', $day) + ->where('property_promotion.reservation_end_date', '>=', $day) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + }); + + if (count($promotionsCollectFiltered) > 1) { + if (isset($params['isMobile']) && $params['isMobile'] == 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); + } else { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + + } else { + if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { + if (!isset($params['isMobile']) || $params['isMobile'] != 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + } + } + + $promotionsCollectFiltered = $promotionsCollectFiltered->sortByDesc('property_promotion.min_stay')->first(); + + $promotionHashKey = null; + if (!is_null($promotionsCollectFiltered)) { + + /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; + if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { + continue; + }*/ + + $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . + Carbon::parse($day)->format('Ymd'); + + + if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } + + } + + } + + if ($promotionType == 'BFD') { + + //dd($dateByDay[0], Carbon::now()->toDateString(), Carbon::parse($dateByDay[0])->diff(Carbon::now())->days); + + $promotionsCollectFiltered = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.day_before', '<=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + })->sortByDesc('property_promotion.day_before'); + + if (count($promotionsCollectFiltered) > 1) { + if (isset($params['isMobile']) && $params['isMobile'] == 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); + } else { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + } else { + if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { + if (!isset($params['isMobile']) || $params['isMobile'] != 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + } + } + + $promotionsCollectFiltered = $promotionsCollectFiltered->first(); + + $promotionHashKey = null; + if (!is_null($promotionsCollectFiltered)) { + + /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; + if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { + continue; + }*/ + + //excludeDatesArray + if (isset($promotionsCollectFiltered['property_promotion']['excludeDatesArray']) && in_array($day, $promotionsCollectFiltered['property_promotion']['excludeDatesArray'])) { + continue; + } + + $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . + Carbon::parse($day)->format('Ymd'); + + if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } + } + } + + if ($promotionType == 'LST') { + + //dd($dateByDay[0], Carbon::now()->toDateString(), Carbon::parse($dateByDay[0])->diff(Carbon::now())->days); + $promotionsCollectFiltered = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.day_before', '>=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->where('property_promotion.is_time', null) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + })->sortBy('property_promotion.day_before'); + + if (count($promotionsCollectFiltered) > 1) { + if (isset($params['isMobile']) && $params['isMobile'] == 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); + } else { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + } else { + if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { + if (!isset($params['isMobile']) || $params['isMobile'] != 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + } + } + + //If there is a promotion with a fixed time, it gets priority. + $promotionsCollectFilteredCertainTime = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.day_before', '>=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->where('property_promotion.is_time', 1) + ->where('property_promotion.start_time', '<=', Carbon::now()->format('H:i:s')) + ->where('property_promotion.end_time', '>=', Carbon::now()->format('H:i:s')) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + })->sortByDesc('property_promotion.amount'); + + + if (!is_null($promotionsCollectFilteredCertainTime->first())) { + $promotionsCollectFiltered = $promotionsCollectFilteredCertainTime->first(); + } else { + $promotionsCollectFiltered = $promotionsCollectFiltered->first(); + } + + + $promotionHashKey = null; + if (!is_null($promotionsCollectFiltered)) { + + /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; + if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { + continue; + }*/ + + $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . + Carbon::parse($day)->format('Ymd'); + + if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } + } + + } + + + if ($promotionType == 'DSC') { + + //Default + $defaultPromotionDiscount = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.is_time', null) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + })->sortByDesc('property_promotion.amount'); + + if (isset($params['isMobile']) && $params['isMobile'] == 1) { + $defaultPromotionDiscountMobile = $defaultPromotionDiscount->where('property_promotion.is_mobile', '=', 1); + if ($defaultPromotionDiscountMobile->isNotEmpty()) { + $defaultPromotionDiscount = $defaultPromotionDiscountMobile; + } + } else { + $defaultPromotionDiscount = $defaultPromotionDiscount->where('property_promotion.is_mobile', '!=', 1); + } + + + $promotionsCollectFiltered = $promotionsCollect + ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) + ->where('property_promotion.is_time', 1) + ->where('property_promotion.start_time', '<=', Carbon::now()->format('H:i:s')) + ->where('property_promotion.end_time', '>=', Carbon::now()->format('H:i:s')) + ->where('property_promotion.min_stay', '<=', count($dateByDay)) + ->filter(function ($propertyPromotion) use ($day) { + $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); + if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { + return $propertyPromotion; + } + })->sortByDesc('property_promotion.amount'); + + + if (isset($params['isMobile']) && $params['isMobile'] == 1) { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); + if ($promotionsCollectFiltered->isNotEmpty()) { + $promotionsCollectFiltered = $promotionsCollectFiltered; + } + } else { + $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); + } + + + if ($promotionsCollectFiltered->isEmpty()) { + $promotionsCollectFiltered = $defaultPromotionDiscount; + } + + + $promotionsCollectFiltered = $promotionsCollectFiltered->first(); + + $promotionHashKey = null; + if (!is_null($promotionsCollectFiltered)) { + + /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; + if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { + continue; + }*/ + + //excludeDatesArray + if (isset($promotionsCollectFiltered['property_promotion']['excludeDatesArray']) && in_array($day, $promotionsCollectFiltered['property_promotion']['excludeDatesArray'])) { + continue; + } + + $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . + $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . + Carbon::parse($day)->format('Ymd'); + + if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { + $promotionGroupByDay[$promotionKey] = [ + 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], + 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], + 'id' => $promotionsCollectFiltered['property_promotion']['id'] + ]; + } + } + + } + + //Log::debug($promotionGroupByDay); + + } + + } + } + //dd($promotionGroupByDay, $propertyPromotionMapping); + /**** PROMOTION FINISH ****/ + + //dd($promotionGroupByDay); + + + $getPropertyRoomRatePrice = collect($getPropertyRoomRatePrice['data']); + + + $minStayCheckProperty = $getPropertyRoomRatePrice->sortByDesc('min_stay')->groupBy('min_stay')->keys()->first(); + + //Kanala ait otelin aktif olan room rate lerin gruplanarak gün bazında fiyat var mı hesalanması + // Availability Type - Property Room - Room Rate Mapping + $getPropertyRoomRatePriceGrouped = $getPropertyRoomRatePrice->groupBy(['availability_type_id', 'property_room_id', 'room_rate_mapping_id', 'date'])->toArray(); + + foreach ($getPropertyRoomRatePriceGrouped as $getPropertyRoomRatePriceAvailabilityKey => $getPropertyRoomRatePriceAvailability) { + foreach ($getPropertyRoomRatePriceAvailability as $getPropertyRoomRatePriceAvailabilityRoomKey => $getPropertyRoomRatePriceAvailabilityRoom) { + + foreach ($getPropertyRoomRatePriceAvailabilityRoom as $getPropertyRoomRatePriceAvailabilityRoomRateKey => $getPropertyRoomRatePriceAvailabilityRoomRate) { + + unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); + + if (!empty(array_diff($this->dateByDay, array_keys($getPropertyRoomRatePriceAvailabilityRoomRate)))) { + unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); + } else { + + $getPropertyRoomRatePriceAvailabilityRoomRate = array_map(function ($propertyRoomRatePriceAvailabilityRoomRate) { + return reset($propertyRoomRatePriceAvailabilityRoomRate); + }, $getPropertyRoomRatePriceAvailabilityRoomRate); + + + //MIN_STAY CHECK + $minStayCheckCollect = collect($getPropertyRoomRatePriceAvailabilityRoomRate); + $minStayCheck = $minStayCheckCollect->sortByDesc('min_stay')->first(); + + //$isMinStayDisabled + if ($isMinStayDisabled) { + $minStayCheck['min_stay'] = 0; + } + + if (intval($minStayCheck['min_stay']) > count($this->dateByDay)) { + unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); + } else { + + //PROMOTION CALCULATE + foreach ($getPropertyRoomRatePriceAvailabilityRoomRate as $day => $dailyDetail) { + + $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['baseAmount'] = $dailyDetail['amount']; + $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['discountRate'] = 0; + + //TODO : Delete + /*$dailyDetailPromoCheckKey = $dailyDetail['property_id'] . '-' . + $dailyDetail['room_rate_mapping_id'] . '-' . + $dailyDetail['channel_id'] . '-' . + Carbon::parse($day)->format('Ymd'); + + if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { + $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; + $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['amount'] = moneyDoubleFormatDecimal($dailyDetail['amount'] - ($dailyDetail['amount'] * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); + }*/ + + } + + $getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey] = $getPropertyRoomRatePriceAvailabilityRoomRate; + + } + + } + + } + + if (empty($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey])) { + unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey]); + } + + } + + if (empty($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey])) { + unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey]); + } + } + //Kanala ait otelin aktif olan room rate lerin gruplanarak gün bazında fiyat var mı hesaplanması + + + //Kanalın müsaitlik type ına göre kullanılacak olanların seçilmesi + $selectedPropertyRoomRatePriceGrouped = []; + if (isset($getPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']])) { + $selectedPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']] = $getPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']]; + } + + + if ($channelProperty['channel_availability_type']['code'] == 'GRT') { + if (isset($getPropertyRoomRatePriceGrouped[1])) { + $selectedPropertyRoomRatePriceGrouped[1] = $getPropertyRoomRatePriceGrouped[1]; + } + } + //Kanalın müsaitlik type ına göre kullanılacak olanların seçilmesi + + + if (empty($selectedPropertyRoomRatePriceGrouped)) { + //Hiç fiyat çekilememiş ise diğer proprty ye geç + continue; + } + + + //TODO: burada her istenen oda tipi için fiyat hesaplanacak ve + $calculatedRoomPrice = []; + + // Availability Type - Property Room - Room Rate Mapping + foreach ($selectedPropertyRoomRatePriceGrouped as $propertyAvailabilityKey => $propertyAvailability) { + foreach ($propertyAvailability as $propertyRoomKey => $propertyRoom) { + + //Olmayan bir oda için fiyat gelirse devam et + if (!in_array($propertyRoomKey, array_keys($propertyRoomAndRoomRateMappingData['room']))) { + continue; + } + + foreach ($propertyRoom as $propertyRoomRateKey => $propertyRoomRate) { + + $roomsByOccupancyPrices = []; + foreach ($this->roomsByOccupancies as $roomsByOccupancyKey => $roomsByOccupancy) { + + + if ($roomsByOccupancy['adultCount'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_adult']) { + //Bu oda için istenen yetişkin sayısı kadar kapasite yok + continue; + } + + if ($roomsByOccupancy['childCount'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child']) { + //Bu oda için istenen çocuk sayısı kadar kapasite yok + continue; + } + + if ($roomsByOccupancy['occupancy'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_occupancy']) { + //Bu oda için istenen misafir sayısı kadar kapasite yok + continue; + } + + if (isset($roomsByOccupancy['childAges']) && !is_null($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child_number'])) { + foreach ($roomsByOccupancy['childAges'] as $childAge) { + if ($childAge > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child_number']) { + continue 2; + } + } + } + + + $roomRateExcludeOccupancy = !is_null($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['exclude_occupancy']) ? json_decode($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['exclude_occupancy'], 1) : []; + + if (in_array($roomsByOccupancy['occupancyCode'], $roomRateExcludeOccupancy)) { + //Bu odada istenmeyen bir occupancy grubu olduğu için kullanılmıyor + continue; + } + + + if (!isset($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey])) { + //Mapping olmayan bir rate gelirse devam et + continue 2; + } + + if ($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room']['occupancy_lock']) { + if ($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy'] != $roomsByOccupancy['adultCount']) { + //Occupancy Lock Durumu + continue 1; + } + } + + + //Fiyatlama kısmı baş + $propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']); + + $roomRateDaily = []; + foreach ($propertyRoomRate as $dailyKey => $dailyRoomRate) { + + //Pool için genel kontenjan + if ($propertyAvailabilityKey == 1) { + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $dailyRoomRate['date']) + ->where('property_room_id', $dailyRoomRate['property_room_id']) + ->where('availability_type_id', $dailyRoomRate['availability_type_id']) + ->where('status', 1) + ->first(); + + } else { + $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability + ->where('date', $dailyRoomRate['date']) + ->where('property_room_id', $dailyRoomRate['property_room_id']) + ->where('availability_type_id', $dailyRoomRate['availability_type_id']) + ->where('room_rate_mapping_id', $dailyRoomRate['room_rate_mapping_id']) + ->where('channel_id', $channelProperty['channel_id']) + ->where('status', 1) + ->first(); + } + + + if ($channelProperty['channel_room_pricing_type']['code'] == 'ROM') { + + $dailyRoomRateRackPrice = $dailyRoomRate['amount']; + $propertyRoomRateIncludedOccupancy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']; + $oneAdultRoomRateRackPrice = $dailyRoomRateRackPrice / $propertyRoomRateIncludedOccupancy; + + //NEW Promotoin Affect + $dailyDetailPromoCheckKey = $dailyRoomRate['property_id'] . '-' . + $dailyRoomRate['room_rate_mapping_id'] . '-' . + $dailyRoomRate['channel_id'] . '-' . + Carbon::parse($dailyKey)->format('Ymd'); + + if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { + $dailyRoomRate['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; + $dailyRoomRateRackPrice = moneyDoubleFormatDecimal($dailyRoomRateRackPrice - ($dailyRoomRateRackPrice * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); + } + //NEW Promotoin Affect + + $roomRateDaily[$dailyKey] = [ + 'date' => $dailyKey, + 'amount' => $dailyRoomRateRackPrice, + 'allotment' => fillOnUndefined($roomAndRoomRateAvailability, 'availability', 0), + 'rackRateAmount' => $dailyRoomRateRackPrice, + 'rackRateBaseAmount' => $dailyRoomRate['baseAmount'], + 'discountRate' => $dailyRoomRate['discountRate'], + 'oneAdultRackRateAmount' => $oneAdultRoomRateRackPrice, + 'min_stay' => $dailyRoomRate['min_stay'] + ]; + + } elseif ($channelProperty['channel_room_pricing_type']['code'] == 'PRS') { + + $roomPrice = 0; + $adultPrice = 0; + $childPrice = 0; + + $dailyRoomRateRackPrice = $dailyRoomRate['amount']; + $propertyRoomRateIncludedOccupancy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']; + $oneAdultRoomRateRackPrice = $dailyRoomRateRackPrice / $propertyRoomRateIncludedOccupancy; + + //ADULT, CHILD POLICIES + $roomRateMappingAdultPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingAdultPolicy']; + $roomRateMappingChildPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingChildPolicy']; + + + //ADULT PRICE + $adultPrice = $dailyRoomRateRackPrice; + + if (!empty($roomRateMappingAdultPolicy)) { + + $roomRateMappingAdultPolicyCollect = collect($roomRateMappingAdultPolicy); + + $roomOccupancyAdultActionType = null; + $roomOccupancyAdultActionDiff = null; + if ($roomsByOccupancy['adultCount'] > $propertyRoomRateIncludedOccupancy) { + $roomOccupancyAdultActionType = 'INC'; + $roomOccupancyAdultActionDiff = $roomsByOccupancy['adultCount'] - $propertyRoomRateIncludedOccupancy; + $roomOccupancyAdultActionDiff = ceil($roomOccupancyAdultActionDiff); + } elseif ($roomsByOccupancy['adultCount'] < $propertyRoomRateIncludedOccupancy) { + $roomOccupancyAdultActionType = 'DEC'; + $roomOccupancyAdultActionDiff = $propertyRoomRateIncludedOccupancy - $roomsByOccupancy['adultCount']; + $roomOccupancyAdultActionDiff = floor($roomOccupancyAdultActionDiff); + } + + if (!is_null($roomOccupancyAdultActionType)) { + + $roomOccupancyAdultPolicy = $roomRateMappingAdultPolicyCollect + ->where('adult_action_type', $roomOccupancyAdultActionType) + ->where('adult', $roomOccupancyAdultActionDiff) + ->where('reservation_start_date', null) + ->where('reservation_end_date', null) + ->sortByDesc('id') + ->first(); + + $roomOccupancyAdultPolicyDate = $roomRateMappingAdultPolicyCollect + ->where('adult_action_type', $roomOccupancyAdultActionType) + ->where('adult', $roomOccupancyAdultActionDiff) + ->where('reservation_start_date', '<=', $dailyKey) + ->where('reservation_end_date', '>=', $dailyKey) + ->sortByDesc('id') + ->first(); + + if ($roomOccupancyAdultPolicyDate) { + $roomOccupancyAdultPolicy = $roomOccupancyAdultPolicyDate; + } + + + if (!empty($roomOccupancyAdultPolicy)) { + + if ($roomOccupancyAdultPolicy['type'] == 'PER') { + $roomOccupancyAdultActionDiffAffected = ($dailyRoomRateRackPrice * $roomOccupancyAdultPolicy['value']) / 100; + } elseif ($roomOccupancyAdultPolicy['type'] == 'FIX') { + $roomOccupancyAdultActionDiffAffected = $roomOccupancyAdultPolicy['value']; + } + + if ($roomOccupancyAdultPolicy['action_type'] == 'INC') { + $adultPrice = $dailyRoomRateRackPrice + $roomOccupancyAdultActionDiffAffected; + } + + if ($roomOccupancyAdultPolicy['action_type'] == 'DEC') { + $adultPrice = $dailyRoomRateRackPrice - $roomOccupancyAdultActionDiffAffected; + } + + } + + + } + + + } + + + //dd($adultPrice); + + + if ($adultPrice <= 0) { + //Eğer günlük fiyat 0 ya da - ye düşerse bu rate için hesaplama yapmayacak + continue 2; + } + + //CHILD PRICE + $childPriceRaw = []; + $roomRateMappingChildPolicyCollect = collect($roomRateMappingChildPolicy); + + //dd($roomRateMappingChildPolicyCollect); + + $childOrder = 1; + for ($i = 0; $i < $roomsByOccupancy['childCount']; $i++) { + + $childPriceRaw[$i] = $oneAdultRoomRateRackPrice; + + + if (!empty($roomRateMappingChildPolicy)) { + + $childAgePolicyAffected = $oneAdultRoomRateRackPrice; + + $childAgePolicy = $roomRateMappingChildPolicyCollect + ->where('adult', 0) + ->where('child_order', $childOrder) + ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) + ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) + ->where('reservation_start_date', null) + ->where('reservation_end_date', null) + ->sortByDesc('id') + ->first(); + + $childAgePolicyPeriod = $roomRateMappingChildPolicyCollect + ->where('adult', 0) + ->where('child_order', $childOrder) + ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) + ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) + ->where('reservation_start_date', '<=', $dailyKey) + ->where('reservation_end_date', '>=', $dailyKey) + ->sortByDesc('id') + ->first(); + + if ($childAgePolicyPeriod) { + $childAgePolicy = $childAgePolicyPeriod; + } + + $childAgePolicyAdult = $roomRateMappingChildPolicyCollect + ->where('adult', $roomsByOccupancy['adultCount']) + ->where('child_order', $childOrder) + ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) + ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) + ->where('reservation_start_date', null) + ->where('reservation_end_date', null) + ->sortByDesc('id') + ->first(); + + if ($childAgePolicyAdult) { + $childAgePolicy = $childAgePolicyAdult; + } + + $childAgePolicyDate = $roomRateMappingChildPolicyCollect + ->where('adult', $roomsByOccupancy['adultCount']) + ->where('child_order', $childOrder) + ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) + ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) + ->where('reservation_start_date', '<=', $dailyKey) + ->where('reservation_end_date', '>=', $dailyKey) + ->sortByDesc('id') + ->first(); + + if ($childAgePolicyDate) { + $childAgePolicy = $childAgePolicyDate; + } + + if (!empty($childAgePolicy)) { + if ($childAgePolicy['type'] == 'PER') { + $childAgePolicyAffected = ($oneAdultRoomRateRackPrice * $childAgePolicy['value']) / 100; + } elseif ($childAgePolicy['type'] == 'FIX') { + $childAgePolicyAffected = $childAgePolicy['value']; + } + + $childOrder++; + } + + $childPriceRaw[$i] = $childAgePolicyAffected; + + } + + + } + + + $childPrice = array_sum($childPriceRaw); + + $roomPrice = $adultPrice + $childPrice; + + + //NEW Promotoin Affect + $dailyDetailPromoCheckKey = $dailyRoomRate['property_id'] . '-' . + $dailyRoomRate['room_rate_mapping_id'] . '-' . + $dailyRoomRate['channel_id'] . '-' . + Carbon::parse($dailyKey)->format('Ymd'); + + if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { + $dailyRoomRate['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; + $roomPrice = moneyDoubleFormatDecimal($roomPrice - ($roomPrice * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); + } + //NEW Promotoin Affect + + + $roomRateDaily[$dailyKey] = [ + 'date' => $dailyKey, + 'amount' => $roomPrice, + 'allotment' => fillOnUndefined($roomAndRoomRateAvailability, 'availability', 0), + 'rackRateAmount' => $dailyRoomRateRackPrice, + 'rackRateBaseAmount' => $dailyRoomRate['baseAmount'], + 'discountRate' => $dailyRoomRate['discountRate'], + 'oneAdultRackRateAmount' => $oneAdultRoomRateRackPrice, + 'min_stay' => $dailyRoomRate['min_stay'] + ]; + + } + + } + + + //Eğer günlere ait kontenjanlardan olmadığı bir gün gelir ise + $dailyRoomRateAvailabilityCheck = collect($roomRateDaily)->where('allotment', '<=', '0')->toArray(); + if (!empty($dailyRoomRateAvailabilityCheck)) { + continue; + } + + //Günler için de minimum doluluk oranına göre müsaitliğin alınması + $dailyRoomRateAvailabilityMin = collect($roomRateDaily)->sortBy('allotment')->first(); + $dailyRoomRateAllotment = $dailyRoomRateAvailabilityMin['allotment']; + + + //POLICY PRICES + $baseTotalPrice = array_sum(array_column($roomRateDaily, 'amount')); + $dailyAverageDiscount = floatval(array_sum(array_column($roomRateDaily, 'discountRate')) / count($roomRateDaily)); + $roomRateMappingCancellationPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingCancellationPolicy']; + + if (!empty($roomRateMappingCancellationPolicy)) { + foreach ($roomRateMappingCancellationPolicy as $roomRateMappingCancellationPolicyKey => $roomRateMappingCancellationPolicyValue) { + //Do not take into account if the number of rule days is greater than the remaining days. + /*if ($roomRateMappingCancellationPolicyValue['beforeArrivalDay'] > $daysLeftForCheckin && $roomRateMappingCancellationPolicyValue['isNonRefundable'] == 0) { + unset($roomRateMappingCancellationPolicy[$roomRateMappingCancellationPolicyKey]); + }*/ + + if ($roomRateMappingCancellationPolicyValue['is_date_range']) { + + $isDateInCancellationPolicyRange = false; + foreach ($this->dateByDay as $date) { + if ($date >= $roomRateMappingCancellationPolicyValue['start_date'] && $date <= $roomRateMappingCancellationPolicyValue['finish_date']) { + $isDateInCancellationPolicyRange = true; + break; + } + } + + if (!$isDateInCancellationPolicyRange) { + unset($roomRateMappingCancellationPolicy[$roomRateMappingCancellationPolicyKey]); + } + } + + } + } + + if (empty($roomRateMappingCancellationPolicy)) { + $roomRateMappingCancellationPolicy[] = [ + 'isAffectedPrice' => false, + 'isFreeCancellation' => true, + 'isNonRefundable' => false + ]; + } + + //Wholesalers can only use CHN payment type + if (in_array($channelProperty['channel']['channel_category_id'], [7])) { + + if (empty($channelBookingPaymentTypePolicy)) { + $channelBookingPaymentTypePolicy[2] = [ + 'name' => 'Channel Manager', + 'code' => 'CHN', + 'isAffectedPrice' => false + ]; + } + + } else { + + if (empty($channelBookingPaymentTypePolicy)) { + $channelBookingPaymentTypePolicy[2] = [ + 'name' => 'Pay at Hotel', + 'code' => 'HTL', + 'isAffectedPrice' => false + ]; + } + + } + + + //dd($roomRateMappingCancellationPolicy, $channelBookingPaymentTypePolicy); + + $policyPrices = []; + foreach ($roomRateMappingCancellationPolicy as $roomRateMappingCancellationPolicyKey => $roomRateMappingCancellationPolicy) { + foreach ($channelBookingPaymentTypePolicy as $channelBookingPaymentTypeKey => $channelBookingPaymentType) { + + //dd($channelBookingPaymentType['cancellationPolicy'], $roomRateMappingCancellationPolicyKey); + + + if (!empty($channelBookingPaymentType['cancellationPolicy'])) { + if (!in_array($roomRateMappingCancellationPolicyKey, $channelBookingPaymentType['cancellationPolicy'])) { + continue; + } + } + + + $cancellationPolicyAffectPrice = 0; + if ($roomRateMappingCancellationPolicy['isAffectedPrice']) { + + if ($roomRateMappingCancellationPolicy['affectPriceType'] == 'PER') { + $cancellationPolicyAffectPrice = ($baseTotalPrice * $roomRateMappingCancellationPolicy['affectPriceValue']) / 100; + } elseif ($roomRateMappingCancellationPolicy['affectPriceType'] == 'FIX') { + $cancellationPolicyAffectPrice = $roomRateMappingCancellationPolicy['affectPriceValue']; + } + + $cancellationPolicyAffectPrice = $roomRateMappingCancellationPolicy['affectPriceActionType'] == 'DEC' ? (-1 * $cancellationPolicyAffectPrice) : $cancellationPolicyAffectPrice; + + } + + $cancellationPolicyAffectPriceName = fillOnUndefined($roomRateMappingCancellationPolicy, 'name'); + if ($roomRateMappingCancellationPolicy['isNonRefundable']) { + $cancellationPolicyAffectPriceName = 'NonRefundable'; + } elseif ($roomRateMappingCancellationPolicy['isFreeCancellation']) { + $cancellationPolicyAffectPriceName = 'FreeCancellation'; + } + + $bookingPaymentTypeAffectPrice = 0; + if ($channelBookingPaymentType['isAffectedPrice']) { + + if ($channelBookingPaymentType['affectPriceType'] == 'PER') { + $bookingPaymentTypeAffectPrice = ($baseTotalPrice * $channelBookingPaymentType['affectPriceValue']) / 100; + } elseif ($channelBookingPaymentType['affectPriceType'] == 'FIX') { + $bookingPaymentTypeAffectPrice = $channelBookingPaymentType['affectPriceValue']; + } + + $bookingPaymentTypeAffectPrice = $channelBookingPaymentType['affectPriceActionType'] == 'DEC' ? (-1 * $bookingPaymentTypeAffectPrice) : $bookingPaymentTypeAffectPrice; + + } + + $bookingPaymentTypeAffectPriceName = fillOnUndefined($channelBookingPaymentType, 'name'); + + + //Bu dataları 10dk lık cache de tutacaksın, search_id ve $policyPriceKeyHashed bazında + $policyPriceKey = $channelProperty['property_id'] . '-' . $channelProperty['channel_id'] . '-' . $propertyAvailabilityKey . '-' . $propertyRoomKey . '-' . $propertyRoomRateKey . '-' . $roomsByOccupancyKey . '-' . Carbon::parse($params['date']['checkIn'])->format('Ymd') . '-' . Carbon::parse($params['date']['checkOut'])->format('Ymd') . '-' . $roomRateMappingCancellationPolicyKey . '-' . $channelBookingPaymentTypeKey; + $policyPriceKeyHashed = md5($policyPriceKey); + $policyPriceTotal = $baseTotalPrice + $cancellationPolicyAffectPrice + $bookingPaymentTypeAffectPrice; + + $policyPriceDaily = []; + $policyPriceRate = ($policyPriceTotal / $baseTotalPrice); + + foreach ($roomRateDaily as $daily) { + $policyPriceDaily[] = [ + 'date' => $daily['date'], + 'amount' => moneyDoubleFormatDecimal($daily['amount'] * $policyPriceRate), + 'currency_code' => $channelProperty['currency_code'], + 'min_stay' => fillOnUndefined($daily, 'min_stay', 0), + ]; + } + + $policyPrices[$policyPriceKeyHashed] = [ + 'rateKey' => $policyPriceKeyHashed, + 'rateKeyCode' => $policyPriceKey, + 'occupancyCode' => $roomsByOccupancyKey, + 'name' => $cancellationPolicyAffectPriceName . ' - ' . $bookingPaymentTypeAffectPriceName, + 'total' => moneyDoubleFormatDecimal($policyPriceTotal), + 'currency' => $channelProperty['currency_code'], + 'availability' => [ + 'name' => __($channelAvailabilityType[$propertyAvailabilityKey][0]['language_key']), + 'code' => $channelAvailabilityType[$propertyAvailabilityKey][0]['code'], + ], + 'room' => [ + 'name' => $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['name'], + 'type' => __($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['property_room_type']['language_key']), + 'allotment' => ($propertyAvailabilityKey == 1) ? $dailyRoomRateAllotment : null, + ], + 'rate' => [ + 'name' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['name'], + 'boardCode' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['id'], + 'boardName' => __($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['language_key']), + 'accommodationCode' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['id'], + 'allotment' => ($propertyAvailabilityKey != 1) ? $dailyRoomRateAllotment : null, + ], + 'cancellationPolicy' => $roomRateMappingCancellationPolicy, + 'bookingPaymentType' => $channelBookingPaymentType, + 'policyPriceRate' => $policyPriceRate, + 'policyPriceDaily' => $policyPriceDaily, + ]; + + //Add to Cache + $searchPricesCacheWithKey['requestParams'] = $params; + $searchPricesCacheWithKey['roomPrices'][$policyPriceKeyHashed] = $policyPrices[$policyPriceKeyHashed]; + + } + + } + + $policyPrices = collect($policyPrices)->sortBy('total')->toArray(); + //POLICY PRICES + + $dailyCalculatedPrices = [ + 'prices' => $policyPrices, + 'baseTotalPrice' => $baseTotalPrice, + 'dailyAverageDiscount' => number_format($dailyAverageDiscount, 0, '', ''), + 'allotment' => $dailyRoomRateAllotment, + 'room' => [ + 'adults' => $roomsByOccupancy['adultCount'], + 'children' => $roomsByOccupancy['childCount'], + 'childAges' => $roomsByOccupancy['childAges'], + ], + 'daily' => $roomRateDaily, + ]; + + $calculatedRoomPrice + [$propertyAvailabilityKey] + [$propertyRoomKey] + [$propertyRoomRateKey] + [$roomsByOccupancyKey] = $dailyCalculatedPrices; + + //Fiyatlama kısmı son + + + } + + //dd($roomsByOccupancy, $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']); + + } + } + } + + + //TODO: Burayı taşıyabilirz')); + foreach ($calculatedRoomPrice as $propertyAvailabilityKey => $propertyAvailability) { + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['name'] = $channelProperty['property']['name']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['currency'] = $channelProperty['currency_code']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['token'] = $channelProperty['token']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['booking_engine_token'] = $channelProperty['property']['property_booking_engine_token']['token']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['credit_card_required'] = $payAtHotelCreditCardCheck; + + + + //Wholesaler Currency SET + if (!empty($channelPropertyMarkup)) { + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['currency'] = $channelPropertyMarkup['currency_code']; + } + //Wholesaler Currency SET + + + //$calculatedRoomPriceFormatted[$channelProperty['property']['id']]['paymentType'] = $channelProperty['channel_booking_payment_type']; + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['name'] = __($channelAvailabilityType[$propertyAvailabilityKey][0]['language_key']); + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['code'] = $channelAvailabilityType[$propertyAvailabilityKey][0]['code']; + + + //En düşük fiyata göre sıralama + $propertyAvailability = collect($propertyAvailability); + $propertyAvailabilitySorted = $propertyAvailability->sortBy(function ($room, $roomKey) { + $firstRate = reset($room); + $firstRateOccupancy = reset($firstRate); + return $firstRateOccupancy['baseTotalPrice']; + }); + + $propertyAvailability = $propertyAvailabilitySorted->toArray(); + + + foreach ($propertyAvailability as $propertyRoomKey => $propertyRoom) { + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['name'] = $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['name']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['type'] = __($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['property_room_type']['language_key']); + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['attributes'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'attributes', []); + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['bedGroups'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'bedGroups', []); + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['photos'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'photos', []); + + //Wholesaler + if (in_array($channelProperty['channel']['channel_category_id'], [7]) && empty($this->bookingEngineToken) || fillOnUndefined($params, 'justPriceValues')) { + unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['attributes']); + unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['bedGroups']); + unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['photos']); + } + + foreach ($propertyRoom as $propertyRoomRateKey => $propertyRoomRate) { + + + if ($propertyAvailabilityKey == 1) { + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['allotment'] = reset($propertyRoomRate)['allotment']; + } + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['name'] = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['name']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['boardCode'] = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['id']; + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['boardName'] = __($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['language_key']); + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['rateDescription'] = isset($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['descriptionArray'][$this->language]) ? $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['descriptionArray'][$this->language]: null; + + if ($propertyAvailabilityKey != 1) { + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['allotment'] = reset($propertyRoomRate)['allotment']; + } + + foreach ($propertyRoomRate as $propertyRoomOccupancyKey => $propertyRoomOccupancy) { + + $propertyRoomOccupancy['baseTotalPrice'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['baseTotalPrice']); + foreach ($propertyRoomOccupancy['daily'] as $dailyKey => $daily) { + $propertyRoomOccupancy['daily'][$dailyKey]['amount'] = moneyDoubleFormatDecimal($daily['amount']); + $propertyRoomOccupancy['daily'][$dailyKey]['rackRateAmount'] = moneyDoubleFormatDecimal($daily['rackRateAmount']); + $propertyRoomOccupancy['daily'][$dailyKey]['oneAdultRackRateAmount'] = moneyDoubleFormatDecimal($daily['oneAdultRackRateAmount']); + } + + + //Wholesaler MARKUP CALCULATE + if (!empty($channelPropertyMarkup)) { + + foreach ($propertyRoomOccupancy['prices'] as $rateKey => $propertyRoomOccupancyPrice) { + + $currency = $channelPropertyMarkup['currency_code']; + $propertyRoomOccupancy['prices'][$rateKey]['currency'] = $currency; + + foreach ($propertyRoomOccupancyPrice['policyPriceDaily'] as $policyPriceDailyKey => $policyPriceDaily) { + + $policyPriceDailyAmount = moneyDoubleFormatDecimal($policyPriceDaily['amount'] * $channelPropertyMarkup['markup'] * $channelPropertyMarkup['exchange']); + + $propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'][$policyPriceDailyKey]['amount'] = $policyPriceDailyAmount; + $propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'][$policyPriceDailyKey]['currency_code'] = $currency; + + } + + $propertyRoomOccupancy['prices'][$rateKey]['total'] = collect($propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'])->sum('amount'); + $propertyRoomOccupancy['prices'][$rateKey]['total'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['prices'][$rateKey]['total']); + + + } + + foreach ($propertyRoomOccupancy['daily'] as $propertyRoomOccupancyDateKey => $propertyRoomOccupancyDate) { + + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] = $propertyRoomOccupancyDate['amount'] * $channelPropertyMarkup['markup']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] *= $channelPropertyMarkup['exchange']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount']); + + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] = $propertyRoomOccupancyDate['rackRateAmount'] * $channelPropertyMarkup['markup']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] *= $channelPropertyMarkup['exchange']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount']); + + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] = $propertyRoomOccupancyDate['rackRateBaseAmount'] * $channelPropertyMarkup['markup']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] *= $channelPropertyMarkup['exchange']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount']); + + + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] = $propertyRoomOccupancyDate['oneAdultRackRateAmount'] * $channelPropertyMarkup['markup']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] *= $channelPropertyMarkup['exchange']; + $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount']); + + } + + $propertyRoomOccupancy['baseTotalPrice'] = collect($propertyRoomOccupancy['daily'])->sum('amount'); + $propertyRoomOccupancy['baseTotalPrice'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['baseTotalPrice']); + + } + //Wholesaler MARKUP CALCULATE + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['requestedRoomPrice'][$propertyRoomOccupancyKey] = $propertyRoomOccupancy; + + } + } + } + } + + + //ADDON Setup + if (!empty($calculatedRoomPriceFormatted)) { + $propertyChannelAddonCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelProperty['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyAddon.fact'] + ]; + $columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'amount', 'type', 'title', 'description', 'min_stay']; + $selectPropertyChannelAddon = $this->propertyAddonService->selectPropertyChannelAddon($propertyChannelAddonCriteria, $columns); + + $nightOfStay = Carbon::parse($params['date']['checkIn'])->diff(Carbon::parse($params['date']['checkOut']))->days; + + $propertyChannelAddon = []; + if ($selectPropertyChannelAddon['status'] == 'success') { + $propertyChannelAddon = $selectPropertyChannelAddon['data']; + } + + $propertyChannelAddonList = []; + foreach ($propertyChannelAddon as $addon) { + + + if (!is_null($addon['min_stay']) && $addon['min_stay'] <= $nightOfStay) { + $addon['amount'] = 0; + } + + $propertyChannelAddonList[$addon['property_addon_id']][] = [ + 'id' => $addon['id'], + 'property_addon_id' => $addon['property_addon_id'], + 'property_channel_addon_id' => $addon['id'], + 'title' => $addon['title'], + 'description' => $addon['description'], + 'descriptionArray' => $addon['descriptionArray'], + 'amount' => $addon['amount'], + 'currency_code' => $channelProperty['currency_code'], + 'name' => $addon['property_addon']['title'], + 'language_key' => $addon['property_addon']['fact']['language_key'], + 'icon' => $addon['property_addon']['fact']['icon'], + 'attribute' => $addon['property_addon']['attribute'], + 'attributeArray' => $addon['property_addon']['attributeArray'], + 'type' => $addon['type'], + 'count' => $addon['type'] == 'ONT' ? 1 : 10, + 'min_stay' => $addon['min_stay'], + ]; + } + + $propertyChannelAddonList = array_values($propertyChannelAddonList); + + $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['addon'] = $propertyChannelAddonList; + } + //ADDON Setup + + + } + + //Add Prices to Cache With SearchKey + //If this parameter (noneCacheSearch) exists, it is not cached. + if (!isset($params['noneCacheSearch'])) { + $this->setCacheDataWithSearchKey($searchKey, $searchPricesCacheWithKey); + } + + + $ip = isset($params['ipAddress']) ? $params['ipAddress'] : config("app.myIP"); + $countryCodeWithIP = $this->findCountryCodeService->findCountryWithIpAddress($ip); + + $responseData = [ + 'searchKey' => $searchKey, + 'properties' => $calculatedRoomPriceFormatted, + 'requestParams' => $params, + 'countryCodeWithIP' => isset($countryCodeWithIP['data']['code']) ? $countryCodeWithIP['data']['code'] : '' + ]; + + if (empty($calculatedRoomPriceFormatted) && (integer)$minStayCheckProperty > 1 && count($dateByDay) < (integer)$minStayCheckProperty) { + throw new ApiErrorException(__('be-minstay-warning', ['minStay' => $minStayCheckProperty], $this->language), 201); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'errorCode' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + $response['errorCode'] = $e->getCode(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + //201: be-minstay-warning + + //For Booking Engine + if (isset($channelProperty['channel']['channel_category_id']) && in_array($channelProperty['channel']['channel_category_id'], [3, 7])) { + + $createSearchStatus = 0; + if (isset($response['data']['properties'])) { + $calculatedRoomPriceFormattedReset = reset($calculatedRoomPriceFormatted); + if (isset($calculatedRoomPriceFormattedReset['name'])) { + $createSearchStatus = 1; + } + } + + $createSearchExcludeIps = ['127.0.0.1', '185.137.215.118']; + if ((isset($params['ipAddress']) && !in_array($params['ipAddress'], $createSearchExcludeIps)) || in_array($channelProperty['channel_id'], [393])) { + + $isRobot = fillOnUndefined($params, 'isRobot'); + + if (isset($params['noneCacheSearch'])) { + $isRobot = true; + } + + if (!$isRobot) { + + $createSearchParam = [ + 'search_key' => $searchKey, + 'property_id' => fillOnUndefined($channelProperty, 'property_id'), + 'channel_id' => fillOnUndefined($channelProperty, 'channel_id', 1), + 'checkin_date' => $params['date']['checkIn'], + 'checkout_date' => $params['date']['checkOut'], + 'pax' => array_key_first($this->roomsByOccupancies), + 'rooms' => json_encode($params['rooms']), + 'booking_code' => fillOnUndefined($params, 'booking_code'), + 'best_amount' => fillOnUndefined($params, 'best_amount'), + 'currency_code' => fillOnUndefined($channelProperty, 'currency_code'), + 'ip_address' => fillOnUndefined($params, 'ipAddress'), + 'country_code' => isset($countryCodeWithIP['data']['code']) ? $countryCodeWithIP['data']['code'] : null, + 'language_code' => $this->language, + 'detail' => json_encode($params), + 'referrer' => fillOnUndefined($params, 'referrer'), + 'status' => $createSearchStatus, + ]; + + if (in_array($channelProperty['channel_id'], [393])) { + $createSearchParam['property_id'] = null; + } + + + $createSearch = $this->propertyBookingEngineSearchService->create($createSearchParam); + } + + } + + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode'], $response['errorCode']); + + + } + + + public function bestAvailableRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $excludePropertyIds = [643,644,645,738,163,164,165,166,236,366]; + + $this->channelToken = empty($this->channelToken) ? $request->header('channelToken') : $this->channelToken; + $this->bookingEngineToken = empty($this->bookingEngineToken) ? $request->header('bookingEngineToken') : $this->bookingEngineToken; + $this->channelId = empty($this->channelId) ? $request->header('channelId') : $this->channelId; + $this->bookingEnginePropertyId = empty($this->bookingEnginePropertyId) ? $request->header('bookingEnginePropertyId') : $this->bookingEnginePropertyId; + $this->language = empty($this->language) ? $request->header('language') : $this->language; + + $params = json_decode($request->getContent(), 1); + + $cacheKeyParam[] = $this->bookingEnginePropertyId; + $cacheKeyParam[] = $params['period']; + $cacheKey = 'CRR:' . md5(implode(',', $cacheKeyParam)); + + if(in_array($this->bookingEnginePropertyId, $excludePropertyIds)) { + throw new ApiErrorException('Property Channel not found'); + } + + //Cache::forget($cacheKey); + if (Cache::has($cacheKey)) { + $responseData = Cache::get($cacheKey); + } else { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $this->bookingEnginePropertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['currency'], + 'firstRow' => true + ]; + + $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); + $getChannelProperty = $getChannelProperty['status'] == 'success' && !empty($getChannelProperty['data']) ? $getChannelProperty['data'] : null; + + if (!$getChannelProperty) { + throw new ApiErrorException('Property Channel not found'); + } + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => 5], + ['field' => 'property_id', 'condition' => '=', 'value' => $this->bookingEnginePropertyId], + ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => Carbon::parse($params['period'])->format('Y-m-d')], + ['field' => 'date', 'condition' => '<', 'value' => Carbon::parse($params['period'])->addMonth()->format('Y-m-d')], + ['field' => 'amount', 'condition' => '<>', 'value' => null], + ['field' => 'amount', 'condition' => '<>', 'value' => 0], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'roomRateMapping.propertyRoomRate' + ], + 'orderBy' => [ + ['field' => 'date', 'value' => 'ASC'], + ['field' => 'amount', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); + + + if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { + throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); + } + + $getPropertyRoomRatePrice = $getPropertyRoomRatePrice['status'] == 'success' && !empty($getPropertyRoomRatePrice['data']) ? $getPropertyRoomRatePrice['data'] : []; + + $firstDate = Carbon::parse($params['period'])->format('Y-m-d'); + $lastDate = Carbon::parse($params['period'])->addMonth()->format('Y-m-d'); + $dateDiff = Carbon::parse($firstDate)->diffInDays(Carbon::parse($lastDate)); + + $rateAndAvailability = []; + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($firstDate)->addDays($i)->toDateString(); + + $bestPrice = collect($getPropertyRoomRatePrice) + ->where('date', $date) + ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate') + ->sortBy('amount')->first(); + $bestPrice = $bestPrice ? $bestPrice['amount'] : null; + + $rateAndAvailability[$date] = [ + 'rate' => round($bestPrice), + 'available' => $bestPrice ? true : false, + ]; + + } + + $responseData = [ + 'currency' => $getChannelProperty['currency']['code'], + 'currency_icon' => $getChannelProperty['currency']['symbol'], + 'date' => $rateAndAvailability + ]; + + if (count($rateAndAvailability) == collect($rateAndAvailability)->where('available', false)->count()) { + $responseData = null; + } + + Cache::put($cacheKey, $responseData, 60 * 60);//1h 60 * 60 + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/Athena/v1/AthenaController.php b/app/Http/Controllers/ChannelManager/Athena/v1/AthenaController.php new file mode 100644 index 0000000..e93de45 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/Athena/v1/AthenaController.php @@ -0,0 +1,488 @@ +username = 'athena'; + $this->password = 'AU3EUmA9LChTzAzv'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 5; //Athena + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'response' => null, + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + //['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + if($roomRate['status'] == 0) { + continue; + } + + if(empty($roomRate['property_room_rate_mapping'])) { + continue; + } + + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function channel(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $propertyChannelCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel','propertyChannelCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + ]; + + $propertyChannel = $this->propertyChannelService->select($propertyChannelCriteria); + if (!$propertyChannel['status']) { + throw new ApiErrorException($propertyChannel['message']); + } + + $propertyChannel = $propertyChannel['data']; + + $response = []; + + $response['channels'] = []; + foreach ($propertyChannel as $channel) { + + $response['channels'][] = [ + 'id' => $channel['id'], + 'name' => $channel['name'], + 'category_id' => $channel['property_channel_category']['id'], + 'category_name' => $channel['property_channel_category']['name'], + ]; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/Channex/v1/ChannexController.php b/app/Http/Controllers/ChannelManager/Channex/v1/ChannexController.php new file mode 100644 index 0000000..3962525 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/Channex/v1/ChannexController.php @@ -0,0 +1,228 @@ +username = 'channex'; + $this->password = 'AU3EUmA9LChTzAzv'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->mailer = $mailer; + $this->channexService = $channexService; + + $payloadJson = $this->request->all(); + $this->param = $payloadJson; + + Log::debug($payloadJson); + + $this->channelManagerId = 2; //Channex + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + + public function channelManagerProperty($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'with' => ['property'], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property mapping not found'); + } + + + $response = [ + 'status' => true, + 'data' => $channelManagerPropertyMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function notification(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['property_id']; + + $propertyChannelMapping = $this->channelManagerProperty($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $channelDetails = $this->channexService->getChannelDetails($this->param['payload']['channel_id']); + if (!$channelDetails['status']) { + throw new ApiErrorException($channelDetails['message']); + } + $channelDetails = $channelDetails['data']; + + + $mailParams = [ + 'propertyId' => $propertyChannelMapping['property']['id'], + 'propertyName' => $propertyChannelMapping['property']['name'], + 'channelName' => $channelDetails['attributes']['channel'] + ]; + + $this->mailer->onQueue('channelManagerNotificationMail', new ChannelManagerNotificationMail($mailParams)); + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + +} diff --git a/app/Http/Controllers/ChannelManager/ElektraWeb/v1/ElektraWebController.php b/app/Http/Controllers/ChannelManager/ElektraWeb/v1/ElektraWebController.php new file mode 100644 index 0000000..a58d101 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/ElektraWeb/v1/ElektraWebController.php @@ -0,0 +1,893 @@ +username = 'elektraweb'; + $this->password = 'XGgK2BSYCERDaVAx'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 4; //ElektraWeb + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'ip_address' => $this->request->ip(), + 'response' => null, + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray(); + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + //TODO: burada otelinde kendisine bakmak lazım status + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'max_adult' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'max_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + 'max_occupancy' => $roomRate['property_room_rate_mapping']['property_room']['max_occupancy'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + 'included_occupancy' => $roomRate['property_room_rate_mapping']['included_occupancy'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + 'max_adult' => $roomRate['room']['max_adult'], + 'max_child' => $roomRate['room']['max_child'], + 'max_occupancy' => $roomRate['room']['max_occupancy'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + 'included_occupancy' => floor($rateData['included_occupancy']), + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomAvailability(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomAvailabilities = $this->param['rooms']; + + // Merge consecutive dates with same availability and stop_sell + usort($roomAvailabilities, function ($a, $b) { + if ($a['room_id'] === $b['room_id']) { + return strcmp($a['start_date'], $b['start_date']); + } + return $a['room_id'] <=> $b['room_id']; + }); + + $mergedAvailabilities = []; + $currentAvailability = null; + + foreach ($roomAvailabilities as $availability) { + if ($currentAvailability === null) { + $currentAvailability = $availability; + continue; + } + + $currentEnd = Carbon::parse($currentAvailability['end_date']); + $nextStart = Carbon::parse($availability['start_date']); + + $isConsecutive = $currentEnd->addDay()->toDateString() === $nextStart->toDateString(); + + $sameRoomId = ($currentAvailability['room_id'] === $availability['room_id']); + $sameAvailability = (isset($currentAvailability['availability']) && isset($availability['availability']) && $currentAvailability['availability'] === $availability['availability']) || (!isset($currentAvailability['availability']) && !isset($availability['availability'])); + $sameStopSell = (isset($currentAvailability['stop_sell']) && isset($availability['stop_sell']) && $currentAvailability['stop_sell'] === $availability['stop_sell']) || (!isset($currentAvailability['stop_sell']) && !isset($availability['stop_sell'])); + + if ($isConsecutive && $sameRoomId && $sameAvailability && $sameStopSell) { + $currentAvailability['end_date'] = $availability['end_date']; + } else { + $mergedAvailabilities[] = $currentAvailability; + $currentAvailability = $availability; + } + } + + if ($currentAvailability !== null) { + $mergedAvailabilities[] = $currentAvailability; + } + + $roomAvailabilities = $mergedAvailabilities; + $roomAvailabilitiesCollect = collect($roomAvailabilities); + + DB::beginTransaction(); + + $startDate = $roomAvailabilitiesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomAvailabilitiesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomAvailabilities as $availability) { + + $roomId = $availability['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $totalInventoryAvailable = null; + if (isset($availability['availability'])) { + $totalInventoryAvailable = $availability['availability']; + } + + $startDate = Carbon::parse($availability['start_date'])->toDateString(); + $endDate = Carbon::parse($availability['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + if (isset($availability['stop_sell']) && !is_null($availability['stop_sell'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'room_stop_sell'; + $requestParams['value'] = $availability['stop_sell']; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + } + + DB::commit(); + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomRates = $this->param['rooms']; + $roomRatesCollect = collect($roomRates); + + $paramsListChannel = []; + $paramsListChannel[] = $this->channelId; + + //CONNECTED CHANNEL RATE UPDATE + /*$propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + }*/ + //CONNECTED CHANNEL RATE UPDATE + + + DB::beginTransaction(); + + foreach ($roomRates as $roomRate) { + + $roomId = $roomRate['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + //throw new ApiErrorException('Undefined or inactive room accommodation'); + continue; + } + + $rates = $roomRate['rates']; + if (empty($rates)) { + continue; + } + + // Sort by rate_id and then start_date to ensure we process them in order for each rate_id + usort($rates, function ($a, $b) { + if ($a['rate_id'] === $b['rate_id']) { + return strcmp($a['start_date'], $b['start_date']); + } + return strcmp($a['rate_id'], $b['rate_id']); + }); + + $mergedRates = []; + $currentRate = null; + + foreach ($rates as $rate) { + if ($currentRate === null) { + $currentRate = $rate; + continue; + } + + $currentEnd = Carbon::parse($currentRate['end_date']); + $nextStart = Carbon::parse($rate['start_date']); + + $isConsecutive = $currentEnd->addDay()->toDateString() === $nextStart->toDateString(); + + $sameRateId = ($currentRate['rate_id'] === $rate['rate_id']); + $sameAmount = (isset($currentRate['amount']) && isset($rate['amount']) && (float)$currentRate['amount'] === (float)$rate['amount']) || (!isset($currentRate['amount']) && !isset($rate['amount'])); + $sameStopSell = (isset($currentRate['stop_sell']) && isset($rate['stop_sell']) && $currentRate['stop_sell'] === $rate['stop_sell']) || (!isset($currentRate['stop_sell']) && !isset($rate['stop_sell'])); + $sameMinStay = (isset($currentRate['min_stay']) && isset($rate['min_stay']) && $currentRate['min_stay'] === $rate['min_stay']) || (!isset($currentRate['min_stay']) && !isset($rate['min_stay'])); + + if ($isConsecutive && $sameRateId && $sameAmount && $sameStopSell && $sameMinStay) { + $currentRate['end_date'] = $rate['end_date']; + } else { + $mergedRates[] = $currentRate; + $currentRate = $rate; + } + } + + if ($currentRate !== null) { + $mergedRates[] = $currentRate; + } + + + $roomRatesCollect = collect($mergedRates); + + $startDate = $roomRatesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomRatesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($mergedRates as $rate) { + + $startDate = Carbon::parse($rate['start_date'])->toDateString(); + $endDate = Carbon::parse($rate['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + $roomRateMappingId = $rate['rate_id']; + + $isCloseRoomRateMappingSale = null; + if (isset($rate['stop_sell'])) { + $isCloseRoomRateMappingSale = $rate['stop_sell'] == 1 ? true : false; + } + + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + //throw new ApiErrorException('Undefined or inactive room accommodation'); + continue; + } + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + foreach ($paramsListChannel as $paramChannelId) { + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($rate['amount'])) { + + $currency = $this->param['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Exchange rate that does not match the channel exchange rate, channel exchange rate: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $rate['amount']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Kısıtlamalar var ise min los + if (isset($rate['min_stay'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($rate['min_stay'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $rate['min_stay']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + } + + } + + + } + } + + DB::commit(); + + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/ElektraWeb/v1/_ElektraWebController.php b/app/Http/Controllers/ChannelManager/ElektraWeb/v1/_ElektraWebController.php new file mode 100644 index 0000000..b4c83f4 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/ElektraWeb/v1/_ElektraWebController.php @@ -0,0 +1,809 @@ +username = 'elektraweb'; + $this->password = 'XGgK2BSYCERDaVAx'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 4; //ElektraWeb + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'ip_address' => $this->request->ip(), + 'response' => null, + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray(); + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + //TODO: burada otelinde kendisine bakmak lazım status + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'max_adult' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'max_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + 'max_occupancy' => $roomRate['property_room_rate_mapping']['property_room']['max_occupancy'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + 'included_occupancy' => $roomRate['property_room_rate_mapping']['included_occupancy'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + 'max_adult' => $roomRate['room']['max_adult'], + 'max_child' => $roomRate['room']['max_child'], + 'max_occupancy' => $roomRate['room']['max_occupancy'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + 'included_occupancy' => floor($rateData['included_occupancy']), + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomAvailability(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomAvailabilities = $this->param['rooms']; + $roomAvailabilitiesCollect = collect($roomAvailabilities); + + DB::beginTransaction(); + + $startDate = $roomAvailabilitiesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomAvailabilitiesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomAvailabilities as $availability) { + + $roomId = $availability['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $totalInventoryAvailable = null; + if (isset($availability['availability'])) { + $totalInventoryAvailable = $availability['availability']; + } + + $startDate = Carbon::parse($availability['start_date'])->toDateString(); + $endDate = Carbon::parse($availability['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + if (isset($availability['stop_sell']) && !is_null($availability['stop_sell'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'room_stop_sell'; + $requestParams['value'] = $availability['stop_sell']; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + } + + DB::commit(); + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomRates = $this->param['rooms']; + $roomRatesCollect = collect($roomRates); + + $paramsListChannel = []; + $paramsListChannel[] = $this->channelId; + + //CONNECTED CHANNEL RATE UPDATE + /*$propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + }*/ + //CONNECTED CHANNEL RATE UPDATE + + + DB::beginTransaction(); + + foreach ($roomRates as $roomRate) { + + $roomId = $roomRate['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + //throw new ApiErrorException('Undefined or inactive room accommodation'); + continue; + } + + + $roomRatesCollect = collect($roomRate['rates']); + + $startDate = $roomRatesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomRatesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomRate['rates'] as $rate) { + + $startDate = Carbon::parse($rate['start_date'])->toDateString(); + $endDate = Carbon::parse($rate['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + $roomRateMappingId = $rate['rate_id']; + + $isCloseRoomRateMappingSale = null; + if (isset($rate['stop_sell'])) { + $isCloseRoomRateMappingSale = $rate['stop_sell'] == 1 ? true : false; + } + + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + //throw new ApiErrorException('Undefined or inactive room accommodation'); + continue; + } + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + foreach ($paramsListChannel as $paramChannelId) { + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($rate['amount'])) { + + $currency = $this->param['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Exchange rate that does not match the channel exchange rate, channel exchange rate: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $rate['amount']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Kısıtlamalar var ise min los + if (isset($rate['min_stay'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($rate['min_stay'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $rate['min_stay']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + $requestParams['ip_address'] = $this->request->ip(); + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + } + + } + + + } + } + + DB::commit(); + + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/Fina/v1/FinaController.php b/app/Http/Controllers/ChannelManager/Fina/v1/FinaController.php new file mode 100644 index 0000000..8302dc5 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/Fina/v1/FinaController.php @@ -0,0 +1,488 @@ +username = 'fina'; + $this->password = '6T3VpfsNvLwWFY2gtXjz8y'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 8; //Fina + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'response' => null, + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + //['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + if($roomRate['status'] == 0) { + continue; + } + + if(empty($roomRate['property_room_rate_mapping'])) { + continue; + } + + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function channel(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $propertyChannelCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel','propertyChannelCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + ]; + + $propertyChannel = $this->propertyChannelService->select($propertyChannelCriteria); + if (!$propertyChannel['status']) { + throw new ApiErrorException($propertyChannel['message']); + } + + $propertyChannel = $propertyChannel['data']; + + $response = []; + + $response['channels'] = []; + foreach ($propertyChannel as $channel) { + + $response['channels'][] = [ + 'id' => $channel['id'], + 'name' => $channel['name'], + 'category_id' => $channel['property_channel_category']['id'], + 'category_name' => $channel['property_channel_category']['name'], + ]; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/HotelRunner/v1/HotelRunnerController.php b/app/Http/Controllers/ChannelManager/HotelRunner/v1/HotelRunnerController.php new file mode 100644 index 0000000..c1747ca --- /dev/null +++ b/app/Http/Controllers/ChannelManager/HotelRunner/v1/HotelRunnerController.php @@ -0,0 +1,825 @@ +username = 'hotelrunner'; + $this->password = '2otNDLCgJz9Tgdga'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadXML = simplexml_load_string($payload); + $payloadParam = json_decode(json_encode($payloadXML), 1); + + $this->param = $payloadParam; + + $this->channelId = 1; + $this->channelManagerId = 3; //HotelRunner + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + + //channelManagerLogService + $logArray = ['room-inventory-update']; + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => $payload, + 'response' => null, + 'ip_address' => $this->request->ip(), + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + + //Authentication + $errors = []; + if ($this->username != $payloadParam['username'] || $this->password != $payloadParam['password']) { + $errors[] = [ + //'code' => 100, + 'message' => 'Your username or password is incorrect.' + ]; + } + + if (!empty($errors)) { + $this->responseError($errors); + } + + + } + + + public function responseError($errors) + { + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addChild('status', -1); + + foreach ($errors as $error) { + $xmlResponseError = $xmlResponse->addChild('message', $error['message']); + if (isset($error['code'])) { + $xmlResponseError->addAttribute('code', $error['code']); + } + } + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => $xmlResponse->asXML(), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + header('Content-type: text/xml'); + echo $xmlResponse->asXML(); + + die(); + } + + public function responseSuccess($xmlPayload) + { + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => $xmlPayload->asXML(), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + header('Content-type: text/xml'); + //echo $xmlPayload->asXML(); + echo html_entity_decode($xmlPayload->asXML()); + + die(); + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray(); + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $xmlResponse = new \SimpleXMLElement(''); + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + 'included_occupancy' => $roomRate['property_room_rate_mapping']['included_occupancy'], + ]; + + } + + foreach ($roomRates as $roomId => $roomRate) { + + $room = $xmlResponse->addChild('room'); + $room->addAttribute('id', $roomId); + $room->addAttribute('room_name', $roomRate['room']['name']); + + + $rates = $room->addChild('rates'); + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + $rate = $rates->addChild('rate'); + $rate->addAttribute('id', $roomRateMappingId); + $rate->addAttribute('board_id', $rateData['accommodationId']); + $rate->addAttribute('rate_name', $rateData['name'] . ' - ' . $rateData['rate'].' - '. $rateData['included_occupancy'].' Person'); + $rate->addAttribute('allocation_group', $roomId); + $rate->addAttribute('stop_sale_group', $roomId . ':' . $roomRateMappingId); + $rate->addAttribute('min_stay_group', $roomId . ':' . $roomRateMappingId); + $rate->addAttribute('included_occupancy', $rateData['included_occupancy']); + } + + } + + + $this->responseSuccess($xmlResponse); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + public function availabilityRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $startDate = $this->param['start_date']; + $finishDate = $this->param['end_date']; + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $requestParams = [ + 'property_id' => $propertyId, + 'room_id' => null, + 'room_rate_mapping_id' => null, + 'channel_id' => $this->channelId, + 'start_date' => $startDate, + 'end_date' => $finishDate, + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams); + if ($propertyRoomType['status'] != 'success') { + throw new ApiErrorException($propertyRoomType['message']); + } + + $propertyRoomType = $propertyRoomType['data']; + $propertyRoomRateAvailability = collect($propertyRoomType); + + + $roomRates = []; + foreach ($propertyRoomRateAvailability as $room) { + + foreach ($room['property_room_rate_mapping'] as $roomRateMapping) { + + + foreach ($room['room_availability'] as $date => $roomAvailability) { + $roomRates[$room['id']]['availability'][$date] = $roomAvailability['value']; + } + + $roomRates[$room['id']]['rate'][$roomRateMapping['id']] = [ + 'roomName' => $room['name'], + 'roomRateName' => $roomRateMapping['name'], + //'minStay' => $roomRateMapping['min_stay'], + //'maxStay' => $roomRateMapping['max_stay'], + 'currencyCode' => $roomRateMapping['currency_code'], + ]; + + + $roomRatePrices = reset($roomRateMapping['prices']); + foreach ($roomRatePrices['price'] as $date => $roomRatePrice) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['price'][$date] = $roomRatePrice['value']; + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $roomRatePrice['stop_sell']; + } + + foreach ($roomRatePrices['stop_sell'] as $date => $stopSell) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $stopSell['value']; + } + + foreach ($roomRatePrices['min_stay'] as $date => $minStay) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['minstay'][$date] = $minStay['value']; + } + + } + } + + + $xmlResponse = new \SimpleXMLElement(''); + + $diffInDays = Carbon::parse($startDate)->diffInDays(Carbon::parse($finishDate)); + + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + + $currentDate = $startDate; + for ($i = 0; $i <= $diffInDays; $i++) { + + + foreach ($roomRates as $roomId => $roomRateMapping) { + + foreach ($roomRateMapping['rate'] as $roomRateMappingId => $roomRate) { + + $inventory = $xmlResponse->addChild('inventory'); + + $inventory->addAttribute('room_id', $roomId); + $inventory->addAttribute('rate_id', $roomRateMappingId); + $inventory->addAttribute('date', $currentDate); + $inventory->addAttribute('price', $roomRate['price'][$currentDate]); + $inventory->addAttribute('allocation', $roomRateMapping['availability'][$currentDate]); + $inventory->addAttribute('stop_sale', $roomRate['stopSell'][$currentDate] == 1 ? 1 : 0); + $inventory->addAttribute('min_stay', $roomRate['minstay'][$currentDate]); + } + } + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + + } + + + $this->responseSuccess($xmlResponse); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + public function availabilityRateUpdate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $availRateUpdates = singleElementXMLArray($this->param['inventories']['inventory']); + + DB::beginTransaction(); + + $dateRange = []; + $dateRange['startDate'] = $this->param['start_date']; + $dateRange['finishDate'] = $this->param['end_date']; + + if (Carbon::parse($dateRange['startDate'])->isBefore(Carbon::now()->toDateString()) || Carbon::parse($dateRange['finishDate'])->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($availRateUpdates as $availRateUpdate) { + + $roomId = $availRateUpdate['@attributes']['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $totalInventoryAvailable = null; + if (isset($availRateUpdate['@attributes']['allocation'])) { + $totalInventoryAvailable = $availRateUpdate['@attributes']['allocation']; + } + + $currentDate = Carbon::parse($availRateUpdate['@attributes']['date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $currentDate, + 'end_date' => $currentDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + $roomRateMappingId = $availRateUpdate['@attributes']['rate_id']; + + $isCloseRoomRateMappingSale = null; + if (isset($availRateUpdate['@attributes']['stop_sale'])) { + $isCloseRoomRateMappingSale = $availRateUpdate['@attributes']['stop_sale'] == 1 ? true : false; + } + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + + $paramsListChannel = []; + $paramsListChannel[] = $this->channelId; + + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + + foreach ($paramsListChannel as $paramChannelId) { + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($availRateUpdate['@attributes']['price'])) { + + $currency = $this->param['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Exchange rate that does not match the channel exchange rate, channel exchange rate: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + $amountPerDay = $availRateUpdate['@attributes']['price']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $amountPerDay; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Kısıtlamalar var ise min los + if (isset($availRateUpdate['@attributes']['min_stay'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($availRateUpdate['@attributes']['min_stay'])) { + + $minStay = $availRateUpdate['@attributes']['min_stay']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $minStay; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + } + + } + + + } + + DB::commit(); + + $xmlResponse = new \SimpleXMLElement(''); + + $xmlResponse->addChild('status', 0); + $xmlResponse->addChild('message', 'success'); + $xmlResponse->addChild('ConfirmCode', $this->channelManagerLogId); + + $this->responseSuccess($xmlResponse); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/HyperGuest/v1/HyperGuestController.php b/app/Http/Controllers/ChannelManager/HyperGuest/v1/HyperGuestController.php new file mode 100644 index 0000000..194a3c9 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/HyperGuest/v1/HyperGuestController.php @@ -0,0 +1,635 @@ +request = $request; + $this->restClient = $restClient; + $this->mailer = $mailer; + $this->param = $this->request->all(); + + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + if (App::environment() == 'production') { + $this->url = 'https://pdm.hyperguest.io/api/'; + $this->urlstatic = 'https://hg-static.hyperguest.com/'; + $this->bearerToken = '63d51938dc3749788ac3e88ea6d58950'; + } else { + $this->url = 'https://pdm.hyperguest.com/api/'; + $this->urlstatic = 'https://hg-static.hyperguest.com/'; + $this->bearerToken = '63d51938dc3749788ac3e88ea6d58950'; + } + + + $this->channelId = 1; + $this->channelManagerId = 10; + $this->channelManagerName = 'HyperGuest'; + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['room-inventory-update']; + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + if (in_array($serviceRequestName, $logArray)) { + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($this->param['propertyId']); + + if ($channelManagerPropertyCheck['status']) { + $insertDataLog = [ + 'property_id' => $channelManagerPropertyCheck['data']['property_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($this->param), + 'response' => null, + 'ip_address' => $this->request->ip(), + 'status' => null + ]; + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + + } + //channelManagerLogService + + } + + public function request($type, $method, $jsonPayload) + { + $response = ['status' => false, 'message' => '']; + + try { + $this->restClient = new Client(['http_errors' => false]); + + if ($type == 'POST') { + + $parameter = [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $this->bearerToken + ] + ]; + + if (!empty($jsonPayload)) { + $parameter['body'] = $jsonPayload; + } + + $res = $this->restClient->request('POST', $this->url . $method, $parameter); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + } else if ($type == 'GET') { + + + $res = $this->restClient->request('GET', $this->url . $method, + [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $this->bearerToken + ], + 'query' => $jsonPayload + ] + ); + + $getResponseBody = $res->getBody(); + $getResponse = $getResponseBody->getContents(); + $getResponse = json_decode($getResponse, 1); + + + } + + if ($res->getStatusCode() != 200) { + $errors = singleElementArray($getResponse['errors']); + $firstError = reset($errors); + throw new Exception($firstError['code'] . ': ' . $firstError['title']); + } + + + $response = ["status" => true, 'message' => '', "data" => fillOnUndefined($getResponse, 'data', [])]; + + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + return $response; + + } + + public function responseError($errors) + { + + $response = ['success' => false, 'message' => null]; + $response['message'] = implode(',', $errors); + + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + return response()->json($response); + } + + public function responseSuccess($data = []) + { + + $response = ['success' => true, 'message' => null]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'with' => ['channelManagerRoomRate.propertyRoomRateMapping'], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + $response = [ + 'status' => true, + 'data' => $channelManagerPropertyMapping + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function availabilityRateUpdate(Request $request) + { + + $errors = []; + $response = ['status' => false, 'message' => '']; + + try { + + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($this->param['propertyId']); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelManagerPropertyCheck = $channelManagerPropertyCheck['data']; + $channelManagerPropertyRoomRateCollect = collect($channelManagerPropertyCheck['channel_manager_room_rate']); + + $propertyId = $channelManagerPropertyCheck['property_id']; + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $availRateUpdates = $this->param['ARIUpdate']; + + DB::beginTransaction(); + + /*$dateRange = []; + $dateRange['startDate'] = $this->param['start_date']; + $dateRange['finishDate'] = $this->param['end_date']; + + if (Carbon::parse($dateRange['startDate'])->isBefore(Carbon::now()->toDateString()) || Carbon::parse($dateRange['finishDate'])->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + }*/ + + foreach ($availRateUpdates as $availRateUpdate) { + + $roomIdCheck = $channelManagerPropertyRoomRateCollect->where('channel_manager_room_id', $availRateUpdate['roomTypeCode'])->first(); + if (empty($roomIdCheck)) { + continue; + } + + $roomId = $roomIdCheck['property_room_rate_mapping']['room_id']; + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + continue; + } + + $totalInventoryAvailable = null; + if (isset($availRateUpdate['numberOfAvailableRooms'])) { + $totalInventoryAvailable = $availRateUpdate['numberOfAvailableRooms']; + } + + + $currentDate = Carbon::parse($availRateUpdate['date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $currentDate, + 'end_date' => $currentDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + foreach ($availRateUpdate['ratePlans'] as $ratePlan) { + + + $roomRateMappingIdCheck = $channelManagerPropertyRoomRateCollect->where('channel_manager_room_id', $availRateUpdate['roomTypeCode'])->where('channel_manager_room_rate_id', $ratePlan['ratePlanCode'])->first(); + if (empty($roomRateMappingIdCheck)) { + continue; + } + + $roomRateMappingId = $roomRateMappingIdCheck['property_room_rate_mapping_id']; + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + continue; + } + + + $includedOccupancy = (int)$roomRateMappingIdCheck['included_occupancy']; + $ratePlanPrice = collect($ratePlan['prices'])->where('numberOfGuests.adults', $includedOccupancy) + ->where('numberOfGuests.adults', $includedOccupancy) + ->where('numberOfGuests.children', 0) + ->where('numberOfGuests.infants', 0) + ->first(); + + + if (empty($ratePlanPrice)) { + continue; + } + + $ratePlanPrice = $ratePlanPrice['price']; + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + + $paramsListChannel = []; + $paramsListChannel[] = $this->channelId; + + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + + foreach ($paramsListChannel as $paramChannelId) { + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($ratePlanPrice)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $ratePlanPrice; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + $isCloseRoomRateMappingSale = null; + if (isset($ratePlan['isOpen'])) { + $isCloseRoomRateMappingSale = $ratePlan['isOpen'] == 1 ? false : true; + } + + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Minimum Konaklama Gün Sayısı + if (isset($ratePlan['minLOS'])) { + + $minStay = $ratePlan['minLOS']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $minStay; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + + } + + + } + + + } + + DB::commit(); + + + //$this->channelManagerLogId + + return $this->responseSuccess(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + $errors[] = $response['message']; + + return $this->responseError($errors); + + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/OneC/v1/OneCController.php b/app/Http/Controllers/ChannelManager/OneC/v1/OneCController.php new file mode 100644 index 0000000..9289892 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/OneC/v1/OneCController.php @@ -0,0 +1,640 @@ +username = '1CHotel'; + $this->password = 'w2Dffb9EGXPZfiUDxWKZqB'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 9; //1C Hotels + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'response' => null, + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + //['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + if($roomRate['status'] == 0) { + continue; + } + + if(empty($roomRate['property_room_rate_mapping'])) { + continue; + } + + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function channel(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $propertyChannelCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel','propertyChannelCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + ]; + + $propertyChannel = $this->propertyChannelService->select($propertyChannelCriteria); + if (!$propertyChannel['status']) { + throw new ApiErrorException($propertyChannel['message']); + } + + $propertyChannel = $propertyChannel['data']; + + $response = []; + + $response['channels'] = []; + foreach ($propertyChannel as $channel) { + + $response['channels'][] = [ + 'id' => $channel['id'], + 'name' => $channel['name'], + 'category_id' => $channel['property_channel_category']['id'], + 'category_name' => $channel['property_channel_category']['name'], + ]; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomAvailability(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomAvailabilities = $this->param['rooms']; + $roomAvailabilitiesCollect = collect($roomAvailabilities); + + DB::beginTransaction(); + + $startDate = $roomAvailabilitiesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomAvailabilitiesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomAvailabilities as $availability) { + + $roomId = $availability['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $totalInventoryAvailable = null; + if (isset($availability['availability'])) { + $totalInventoryAvailable = $availability['availability']; + } + + $startDate = Carbon::parse($availability['start_date'])->toDateString(); + $endDate = Carbon::parse($availability['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + //Days Filter + if (isset($availability['days']) && !empty($availability['days']) && is_array($availability['days']) && count($availability['days']) <= 7) { + + $requestParams = [ + 'days' => $availability['days'] + ]; + + $validator = Validator::make($requestParams, ['days' => 'required|array|in:Mon,Tue,Wed,Thu,Fri,Sat,Sun']);//Mon,Tue,Wed,Thu,Fri,Sat,Sun + if (empty($validator->errors()->messages())) { + $requestParamBase['include_days'] = $availability['days']; + } + + } + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + if (isset($availability['stop_sell']) && !is_null($availability['stop_sell'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'room_stop_sell'; + $requestParams['value'] = $availability['stop_sell']; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + } + + DB::commit(); + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/Reseliva/v1/ReselivaController.php b/app/Http/Controllers/ChannelManager/Reseliva/v1/ReselivaController.php new file mode 100644 index 0000000..a018d06 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/Reseliva/v1/ReselivaController.php @@ -0,0 +1,1069 @@ +username = 'reseliva'; + $this->password = 'e3HYUTUSGcPwIRzV'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadXML = simplexml_load_string($payload); + $payloadParam = json_decode(json_encode($payloadXML), 1); + + $serviceRequestName = str_replace('RQ', '', $payloadXML->getName()); + $this->serviceRequestName = $serviceRequestName; + + $this->param = $payloadParam; + + $this->channelId = 1; + $this->channelManagerId = 1; //Reseliva, TODO: burada mapping yapılmış mı yapılmamış mı kontrol edilmeli, her şey verilmemeli + + + //channelManagerLogService + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + $insertDataLog = [ + 'property_id' => $this->param['Hotel']['@attributes']['id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => $payload, + 'response' => null, + 'ip_address' => $this->request->ip(), + 'status' => null + ]; + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + //channelManagerLogService + + + //Authentication + $errors = []; + if ($this->username != $payloadParam['Authentication']['@attributes']['username'] || $this->password != $payloadParam['Authentication']['@attributes']['password']) { + $errors[] = [ + //'code' => 100, + 'message' => 'Your username or password is incorrect.' + ]; + } + + if (!empty($errors)) { + $this->responseError($errors); + } + + + } + + + public function responseError($errors) + { + + $serviceRequestName = $this->serviceRequestName; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + foreach ($errors as $error) { + $xmlResponseError = $xmlResponse->addChild('Error', $error['message']); + if (isset($error['code'])) { + $xmlResponseError->addAttribute('code', $error['code']); + } + } + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => $xmlResponse->asXML(), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + echo $xmlResponse->asXML(); + + die(); + } + + public function responseSuccess($xmlPayload) + { + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => $xmlPayload->asXML(), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + echo $xmlPayload->asXML(); + + die(); + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray(); + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['Hotel']['@attributes']['id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $serviceRequestName = $this->serviceRequestName; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + $ProductList = $xmlResponse->addChild('ProductList'); + + $ProductListHotel = $ProductList->addChild('Hotel'); + $ProductListHotel->addAttribute('id', $propertyId); + $ProductListHotel->addAttribute('currency', $propertyChannelMapping['currency_code']); + $ProductListHotel->addAttribute('child_age_group_number', 1); //TODO: + + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if ($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'] + ]; + + } + + foreach ($roomRates as $roomId => $roomRate) { + + $RoomType = $ProductList->addChild('RoomType'); + $RoomType->addAttribute('id', $roomId); + $RoomType->addAttribute('name', $roomRate['room']['name']); + $RoomType->addAttribute('status', $roomRate['room']['status']); + $RoomType->addAttribute('capacity', $roomRate['room']['capacity']); + $RoomType->addAttribute('capacity_child', $roomRate['room']['capacity_child']); + + foreach ($roomRate['rate'] as $roomRateMappingId => $rate) { + $RatePlan = $RoomType->addChild('RatePlan'); + $RatePlan->addAttribute('id', $roomRateMappingId); + $RatePlan->addAttribute('name', $rate['name'] . ' - ' . $rate['rate']); + } + + } + + $this->responseSuccess($xmlResponse); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + public function availabilityRateUpdate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['Hotel']['@attributes']['id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $availRateUpdates = singleElementXMLArray($this->param['AvailRateUpdate']); + + + DB::beginTransaction(); + + + foreach ($availRateUpdates as $availRateUpdate) { + + $dateRange = []; + $dateRange['startDate'] = $availRateUpdate['DateRange']['@attributes']['from']; + $dateRange['finishDate'] = $availRateUpdate['DateRange']['@attributes']['to']; + + if (Carbon::parse($dateRange['startDate'])->isBefore(Carbon::now()->toDateString()) || Carbon::parse($dateRange['finishDate'])->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + $roomTypes = singleElementXMLArray($availRateUpdate['RoomType']); + + foreach ($roomTypes as $roomType) { + + $roomId = $roomType['@attributes']['id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Tanımlı ya da aktif olmayan oda'); + } + + + $totalInventoryAvailable = null; + if (isset($roomType['Inventory']['@attributes']['totalInventoryAvailable'])) { + $totalInventoryAvailable = $roomType['Inventory']['@attributes']['totalInventoryAvailable']; + } + + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $dateRange['startDate'], + 'end_date' => $dateRange['finishDate'], + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + if (isset($roomType['RatePlan'])) { + + $ratePlans = singleElementXMLArray($roomType['RatePlan']); + + foreach ($ratePlans as $ratePlan) { + + $roomRateMappingId = $ratePlan['@attributes']['id']; + + $isCloseRoomRateMappingSale = null; + if (isset($ratePlan['@attributes']['closed'])) { + $isCloseRoomRateMappingSale = $ratePlan['@attributes']['closed'] == 'true' ? true : false; + } + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + throw new ApiErrorException('Tanımlı ya da aktif olmayan oda konaklama'); + } + + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + + $paramsListChannel = []; + $paramsListChannel[] = 1; + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + + foreach ($paramsListChannel as $paramChannelId) { + + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($ratePlan['Rate'])) { + + $currency = $ratePlan['Rate']['@attributes']['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Kanal döviz kuru ile eşleşmeyen döviz kuru, kanal döviz kuru: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + + $amountPerDay = $ratePlan['Rate']['PerDay']['@attributes']['rate']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $amountPerDay; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Kısıtlamalar var ise min los + if (isset($ratePlan['Restrictions'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($ratePlan['Restrictions']['@attributes']['minLOS'])) { + + $minStay = $ratePlan['Restrictions']['@attributes']['minLOS']; + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $minStay; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + } + + } + + + } + + } + + + } + + } + + DB::commit(); + + $serviceRequestName = $this->serviceRequestName; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + $xmlResponse->addChild('Success'); + $xmlResponse->addChild('ConfirmCode', $this->channelManagerLogId); + + $this->responseSuccess($xmlResponse); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + public function availabilityRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['Hotel']['@attributes']['id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $startDate = $this->param['ParamSet']['AvailRateRetrieval']['@attributes']['from']; + $finishDate = $this->param['ParamSet']['AvailRateRetrieval']['@attributes']['to']; + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $requestParams = [ + 'property_id' => $propertyId, + 'room_id' => null, + 'room_rate_mapping_id' => null, + 'channel_id' => $this->channelId, + 'start_date' => $startDate, + 'end_date' => $finishDate, + + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams); + if ($propertyRoomType['status'] != 'success') { + throw new ApiErrorException($propertyRoomType['message']); + } + + $propertyRoomType = $propertyRoomType['data']; + $propertyRoomRateAvailability = collect($propertyRoomType); + + + $roomRates = []; + foreach ($propertyRoomRateAvailability as $room) { + + foreach ($room['property_room_rate_mapping'] as $roomRateMapping) { + + + foreach ($room['room_availability'] as $date => $roomAvailability) { + $roomRates[$room['id']]['availability'][$date] = $roomAvailability['value']; + } + + $roomRates[$room['id']]['rate'][$roomRateMapping['id']] = [ + 'roomName' => $room['name'], + 'roomRateName' => $roomRateMapping['name'], + //'minStay' => $roomRateMapping['min_stay'], + //'maxStay' => $roomRateMapping['max_stay'], + 'currencyCode' => $roomRateMapping['currency_code'], + ]; + + + $roomRatePrices = reset($roomRateMapping['prices']); + foreach ($roomRatePrices['price'] as $date => $roomRatePrice) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['price'][$date] = $roomRatePrice['value']; + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $roomRatePrice['stop_sell']; + } + + foreach ($roomRatePrices['stop_sell'] as $date => $stopSell) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $stopSell['value']; + } + + foreach ($roomRatePrices['min_stay'] as $date => $minStay) { + $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['minstay'][$date] = $minStay['value']; + } + + } + } + + $serviceRequestName = $this->serviceRequestName; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + $AvailRateList = $xmlResponse->addChild('AvailRateList'); + + $AvailRateListHotel = $AvailRateList->addChild('Hotel'); + $AvailRateListHotel->addAttribute('id', $propertyId); + + + $diffInDays = Carbon::parse($startDate)->diffInDays(Carbon::parse($finishDate)); + + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + + $currentDate = $startDate; + for ($i = 0; $i <= $diffInDays; $i++) { + + //Burada her roomid, roomratemappingid, availability, stopsell, kur, fiyat hepsi var ise kayda girece + + $AvailRate = $AvailRateList->addChild('AvailRate'); + $AvailRate->addAttribute('date', $currentDate); + + + foreach ($roomRates as $roomId => $roomRateMapping) { + + $RoomType = $AvailRate->addChild('RoomType'); + $RoomType->addAttribute('id', $roomId); + + $Inventory = $RoomType->addChild('Inventory'); + $Inventory->addAttribute('totalInventoryAvailable', $roomRateMapping['availability'][$currentDate]); + + foreach ($roomRateMapping['rate'] as $roomRateMappingId => $roomRate) { + + + $RatePlan = $RoomType->addChild('RatePlan'); + $RatePlan->addAttribute('id', $roomRateMappingId); + $RatePlan->addAttribute('closed', $roomRate['stopSell'][$currentDate] == 1 ? 'true' : 'false'); + + + $Rate = $RatePlan->addChild('Rate'); + $Rate->addAttribute('currency', $roomRate['currencyCode']); + + $PerDay = $Rate->addChild('PerDay'); + $PerDay->addAttribute('rate', $roomRate['price'][$currentDate]); + + $Restrictions = $RatePlan->addChild('Restrictions'); + $Restrictions->addAttribute('minLOS', $roomRate['minstay'][$currentDate]); + + + } + + + } + + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + + + } + + + $this->responseSuccess($xmlResponse); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + + public function booking(Request $request, $param = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyId = $this->param['Hotel']['@attributes']['id']; + $bookingId = $this->param['Booking']['@attributes']['id']; + $type = $this->param['Booking']['@attributes']['type']; + + if (!in_array($type, ['Book', 'Modify', 'Cancel'])) { + throw new ApiErrorException('Unknown process type:' . $type); + } + + + $this->serviceRequestName = 'BookingRetrieval'; + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $requestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $bookingId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ], + 'with' => ['bookingContact', 'bookingChannel', 'bookingPayment', 'bookingPaymentType', 'bookingStatus', 'bookingRoom.roomPax.paxCountry'], + 'firstRow' => true + ]; + + $bookingDetail = $this->bookingService->select($requestData); + + if ($bookingDetail['status'] != 'success') { + throw new ApiErrorException('Property Booking Data not found'); + } + + $bookingDetail = $bookingDetail['data']; + + $serviceRequestName = 'BookingRetrieval'; + $xmlResponse = new \SimpleXMLElement('<' . $serviceRequestName . 'RS>'); + + + if (in_array($bookingDetail['status'], [0, 3])) { + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + $Booking->addAttribute('id', $bookingDetail['id']); + $Booking->addAttribute('type', 'Cancel'); + $Booking->addAttribute('cancelDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + } + + } else { + + + $Bookings = $xmlResponse->addChild('Bookings'); + $Booking = $Bookings->addChild('Booking'); + + $Booking->addAttribute('id', $bookingDetail['id']); + + //Book ve Modify Aynı olacak, Cancel + if ($type == 'Book') { + $Booking->addAttribute('type', 'Book'); + $Booking->addAttribute('createDateTime', Carbon::createFromTimestamp($bookingDetail['created_at'])->toISOString()); + } + + if ($type == 'Modify') { + $Booking->addAttribute('type', 'Modify'); + $Booking->addAttribute('modifyDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString()); + } + + $Hotel = $Booking->addChild('Hotel'); + $Hotel->addAttribute('id', $bookingDetail['property_id']); + + + foreach ($bookingDetail['booking_room'] as $room) { + + $RoomStay = $Booking->addChild('RoomStay'); + $RoomStay->addAttribute('roomTypeID', $room['room_id']); + $RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']); + + $StayDate = $RoomStay->addChild('StayDate'); + $StayDate->addAttribute('arrival', $room['checkin_date']); + $StayDate->addAttribute('departure', $room['checkout_date']); + + + $roomPaxCollect = collect($room['room_pax']); + + $GuestCount = $RoomStay->addChild('GuestCount'); + $GuestCount->addAttribute('adult', $roomPaxCollect->where('type', 'ADT')->count()); + + $diffInDays = Carbon::parse($room['checkin_date'])->diffInDays(Carbon::parse($room['checkout_date'])); + + //dd($room['total'], $diffInDays, $room); + + $PerDayRates = $RoomStay->addChild('PerDayRates'); + $PerDayRates->addAttribute('currency', $room['currency_code']); + + $baseRateDaily = moneyDoubleFormatDecimal($room['total'] / $diffInDays); + + $currentDate = $room['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $PerDayRate = $PerDayRates->addChild('PerDayRate'); + $PerDayRate->addAttribute('stayDate', $currentDate); + $PerDayRate->addAttribute('baseRate', $baseRateDaily); + $PerDayRate->addAttribute('hotelServiceFees', 0); + + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + + $Total = $RoomStay->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $room['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $room['currency_code']); + + $RoomStay->addChild('RoomNotes', $bookingDetail['booking_contact']['note']); + + } + + + $PrimaryGuest = $Booking->addChild('PrimaryGuest'); + + $Name = $PrimaryGuest->addChild('Name'); + $Name->addAttribute('givenName', $bookingDetail['booking_contact']['name']); + $Name->addAttribute('surname', $bookingDetail['booking_contact']['surname']); + + $Phone = $PrimaryGuest->addChild('Phone'); + $Phone->addAttribute('countryCode', $bookingDetail['booking_contact']['phone_code']); + //$Phone->addAttribute('cityAreaCode'); + $Phone->addAttribute('number', $bookingDetail['booking_contact']['phone_number']); + + $PrimaryGuest->addChild('Email', $bookingDetail['booking_contact']['email']); + + + $Total = $Booking->addChild('Total'); + $Total->addAttribute('amountAfterTaxes', $bookingDetail['total']); + $Total->addAttribute('amountOfTaxes', 0); + $Total->addAttribute('currency', $bookingDetail['currency_code']); + + + $Booking->addChild('SpecialRequest'); + $Booking->addChild('BookingNotes', $bookingDetail['booking_contact']['note']); + + + } + + + $this->responseSuccess($xmlResponse); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $errors[] = [ + 'message' => $response['message'] + ]; + + $this->responseError($errors); + + } + + } + + +} diff --git a/app/Http/Controllers/ChannelManager/SistemOtel/v1/SistemOtelController.php b/app/Http/Controllers/ChannelManager/SistemOtel/v1/SistemOtelController.php new file mode 100644 index 0000000..a2da5a9 --- /dev/null +++ b/app/Http/Controllers/ChannelManager/SistemOtel/v1/SistemOtelController.php @@ -0,0 +1,827 @@ +username = 'sistemotel'; + $this->password = 'ys6paYBmEWa5q7Mt'; + + $this->request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyRoomService = $propertyRoomService; + $this->bookingService = $bookingService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerLogService = $channelManagerLogService; + + $payload = $this->request->getContent(); + $payloadJson = json_decode($payload, 1); + $this->param = $payloadJson; + + $this->channelId = 1; + $this->channelManagerId = 6; //SistemOtel + + $getRequestUri = $request->getRequestUri(); + $getRequestUriExplode = explode('/', $getRequestUri); + $serviceRequestName = last($getRequestUriExplode); + + //channelManagerLogService + $logArray = ['update-room-availability', 'update-room-rate']; + $this->channelManagerLogId = null; + $this->channelManagerRequestTime = microtime(true); + if (in_array($serviceRequestName, $logArray)) { + $insertDataLog = [ + 'property_id' => $this->param['hotel_id'], + 'channel_manager_id' => $this->channelManagerId, + 'type' => 'C2E', + 'service' => $serviceRequestName, + 'request' => json_encode($payloadJson), + 'response' => null, + 'ip_address' => $this->request->ip(), + 'status' => null + ]; + + + $channelManagerLog = $this->channelManagerLogService->create($insertDataLog); + if ($channelManagerLog['status'] == 'success') { + $this->channelManagerLogId = $channelManagerLog['data']['id']; + } + } + //channelManagerLogService + + + } + + public function checkAuthentication($username, $password) + { + + $response = ['status' => false, 'message' => '']; + + if ($this->username != $username || $this->password != $password) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function responseSuccess($responseData = null) + { + + $response = [ + 'status' => true, + 'message' => null, + 'data' => $responseData, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 1 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + return response()->json($response); + + } + + public function propertyChannelMapping($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = [ + 'status' => true, + 'data' => $propertyChannelMapping['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelPropertyRoomRate($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType', + ] + ]; + + $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); + + if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray(); + + $response = [ + 'status' => true, + 'data' => $getChannelPropertyRoomRate['data'] + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function channelManagerPropertyCheck($propertyId) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $requestParam = + [ + 'criteria' => + [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam); + + + if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) { + throw new ApiErrorException('Property Room Rate not found'); + } + + $channelManagerPropertyMapping = $channelManagerPropertyMapping['data']; + + if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) { + throw new ApiErrorException('This hotel can only be updated by ENW'); + } + + $response = [ + 'status' => true + ]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + + public function roomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + try { + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + $response = []; + + $roomRates = []; + foreach ($channelPropertyRoomRate as $roomRate) { + + if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [ + 'id' => $roomRate['property_room_rate_mapping']['property_room']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room']['name'], + 'status' => 'Active', + 'capacity' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'], + 'capacity_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'], + ]; + + $roomRates[$roomRate['property_room_rate_mapping']['room_id']] + ['rate'][$roomRate['property_room_rate_mapping']['id']] = [ + 'id' => $roomRate['property_room_rate_mapping']['id'], + 'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'], + 'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'], + 'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'], + ]; + + } + + $roomKey = 0; + $response['rooms'] = []; + foreach ($roomRates as $roomId => $roomRate) { + + $response['rooms'][$roomKey] = [ + 'id' => $roomId, + 'room_name' => $roomRate['room']['name'], + ]; + + $roomRateKey = 0; + $response['rooms'][$roomKey]['rates'] = []; + foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) { + + $response['rooms'][$roomKey]['rates'][$roomRateKey] = [ + 'id' => $roomRateMappingId, + 'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'], + 'board_id' => $rateData['accommodationId'], + 'board_name' => $rateData['name'], + ]; + + $roomRateKey++; + + } + + $roomKey++; + } + + return $this->responseSuccess($response); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomAvailability(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomAvailabilities = $this->param['rooms']; + $roomAvailabilitiesCollect = collect($roomAvailabilities); + + DB::beginTransaction(); + + $startDate = $roomAvailabilitiesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomAvailabilitiesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomAvailabilities as $availability) { + + $roomId = $availability['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $totalInventoryAvailable = null; + if (isset($availability['availability'])) { + $totalInventoryAvailable = $availability['availability']; + } + + $startDate = Carbon::parse($availability['start_date'])->toDateString(); + $endDate = Carbon::parse($availability['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + //Days Filter + if (isset($availability['days']) && !empty($availability['days']) && is_array($availability['days']) && count($availability['days']) <= 7) { + + $requestParams = [ + 'days' => $availability['days'] + ]; + + $validator = Validator::make($requestParams, ['days' => 'required|array|in:Mon,Tue,Wed,Thu,Fri,Sat,Sun']);//Mon,Tue,Wed,Thu,Fri,Sat,Sun + if (empty($validator->errors()->messages())) { + $requestParamBase['include_days'] = $availability['days']; + } + + } + + + if (!is_null($totalInventoryAvailable)) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'availability'; + $requestParams['value'] = $totalInventoryAvailable; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + if (isset($availability['stop_sell']) && !is_null($availability['stop_sell'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'room_stop_sell'; + $requestParams['value'] = $availability['stop_sell']; + $requestParams['room_rates'] = [ + ['room_id' => $roomId] + ]; + + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + } + + DB::commit(); + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + public function updateRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '']; + + try { + + //checkAuthentication + $checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $propertyId = $this->param['hotel_id']; + + $channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId); + if (!$channelManagerPropertyCheck['status']) { + throw new ApiErrorException($channelManagerPropertyCheck['message']); + } + + $channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId); + if (!$channelPropertyRoomRate['status']) { + throw new ApiErrorException($channelPropertyRoomRate['message']); + } + + $channelPropertyRoomRate = $channelPropertyRoomRate['data']; + $channelPropertyRoomRateCollect = collect($channelPropertyRoomRate); + + + $propertyChannelMapping = $this->propertyChannelMapping($propertyId); + if (!$propertyChannelMapping['status']) { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + $roomRates = $this->param['rooms']; + $roomRatesCollect = collect($roomRates); + + + DB::beginTransaction(); + + foreach ($roomRates as $roomRate) { + + $roomId = $roomRate['room_id']; + + $roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty(); + if ($roomCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + + $roomRatesCollect = collect($roomRate['rates']); + + $startDate = $roomRatesCollect->sortBy('start_date')->first(); + $startDate = $startDate['start_date']; + + $endDate = $roomRatesCollect->sortByDesc('end_date')->first(); + $endDate = $endDate['end_date']; + + if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Dates to be updated cannot be earlier than today'); + } + + foreach ($roomRate['rates'] as $rate) { + + $startDate = Carbon::parse($rate['start_date'])->toDateString(); + $endDate = Carbon::parse($rate['end_date'])->toDateString(); + + $requestParamBase = [ + 'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'), + 'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'), + 'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + ]; + + //Days Filter + if (isset($rate['days']) && !empty($rate['days']) && is_array($rate['days']) && count($rate['days']) <= 7) { + + $requestParams = [ + 'days' => $rate['days'] + ]; + + $validator = Validator::make($requestParams, ['days' => 'required|array|in:Mon,Tue,Wed,Thu,Fri,Sat,Sun']); + if (empty($validator->errors()->messages())) { + $requestParamBase['include_days'] = $rate['days']; + } + + } + + + $roomRateMappingId = $rate['rate_id']; + + $isCloseRoomRateMappingSale = null; + if (isset($rate['stop_sell'])) { + $isCloseRoomRateMappingSale = $rate['stop_sell'] == 1 ? true : false; + } + + + $channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty(); + if ($channelRoomRateMappingCheck) { + throw new ApiErrorException('Undefined or inactive room accommodation'); + } + + $roomRates = []; + $roomRates[] = [ + 'room_id' => $roomId, + 'room_rate_mapping_id' => [ + $roomRateMappingId + ] + ]; + + + $paramsListChannel = []; + $paramsListChannel[] = $this->channelId; + + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria); + if ($propertyChannelMappingConnected['status'] == 'success') { + + foreach ($propertyChannelMappingConnected['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = $channel['channel_id']; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + + foreach ($paramsListChannel as $paramChannelId) { + + //Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri + if (isset($rate['amount'])) { + + $currency = $this->param['currency']; + + $currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false; + + if (!$currencyCheck) { + throw new ApiErrorException('Exchange rate that does not match the channel exchange rate, channel exchange rate: ' . $propertyChannelMapping['currency_code']); + } + + $channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first(); + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate'; + $requestParams['value'] = $rate['amount']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + + //Room Rate Stop Sale + if (!is_null($isCloseRoomRateMappingSale)) { + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'rate_stop_sell'; + $requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + + + //Kısıtlamalar var ise min los + if (isset($rate['min_stay'])) { + + //Minimum Konaklama Gün Sayısı + if (isset($rate['min_stay'])) { + + $requestParams = []; + $requestParams = $requestParamBase; + $requestParams['update_type'] = 'min_stay'; + $requestParams['value'] = $rate['min_stay']; + $requestParams['room_rates'] = $roomRates; + + $requestParams['channel_id'] = $paramChannelId; + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + } + + } + + + } + } + + DB::commit(); + + + return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + DB::rollBack(); + + if (!$response['status']) { + return $this->responseError($response['message']); + } + + } + + +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..0a7059f --- /dev/null +++ b/app/Http/Controllers/Controller.php @@ -0,0 +1,12 @@ +username = 'google'; + $this->password = 'P8MUQtNP6TkKMz3E'; + + $this->channelManagerId = 14;//Google + + $this->request = $request; + $this->currencyService = $currencyService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + + $payload = $this->request->getContent(); + parse_str(urldecode($payload), $payloadDecode); + $this->param = $payloadDecode; + + $this->authorization = $request->header('authorization'); + + $this->tax = 10; + + + $this->mealCodeMapping = [ + 10 => 'AI', + 11 => 'BB', + 13 => 'RO', + 14 => 'FB', + 15 => 'HB', + ]; + + $this->paymentTypeMapping = [ + 'CRD' => 'prepaid', + 'HTL' => 'postpaid' + ]; + + + } + + + public function checkAuthentication($authorization) + { + + $response = ['status' => false, 'message' => '']; + + $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password); + + if ($authorization != $basicAuth) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + return response()->json($response); + + } + + public function requestParamConverter($requestParam = []) + { + + $searchRequestJson = []; + + $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['Checkin'])->toDateString(); + $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['Checkin'])->addDays($requestParam['Nights'])->toDateString(); + + + $rooms = []; + $rooms[0]['adults'] = (integer)$requestParam['Context']['OccupancyDetails']['NumAdults']; + $rooms[0]['children'] = (integer)($requestParam['Context']['Occupancy'] - $requestParam['Context']['OccupancyDetails']['NumAdults']); + + $rooms[0]['age'] = []; + if (isset($requestParam['Context']['OccupancyDetails']['Children']['Child'])) { + $requestParam['Context']['OccupancyDetails']['Children']['Child'] = singleElementXMLArray($requestParam['Context']['OccupancyDetails']['Children']['Child']); + } else { + $requestParam['Context']['OccupancyDetails']['Children']['Child'] = []; + } + + foreach ($requestParam['Context']['OccupancyDetails']['Children']['Child'] as $child) { + $rooms[0]['age'][] = $child['@attributes']['age']; + } + + $searchRequestJson['rooms'] = $rooms; + + if (isset($requestParam['PropertyList']['Property'])) { + $requestParam['PropertyList']['Property'] = singleElementXMLArray($requestParam['PropertyList']['Property']); + } else { + $requestParam['PropertyList']['Property'] = []; + } + + + $searchRequestJson['property'] = $requestParam['PropertyList']['Property']; + + return $searchRequestJson; + + } + + public function deepLinkGenerator($token, $requestParam = []) + { + + $deepLink = 'https://be.extranetwork.com/' . $token . '/' . fillOnUndefined($requestParam, 'locale', 'en') . '/search/'; + + + $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/'; + $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/'; + + + $roomOccupancy = $this->roomOccupancy($requestParam['rooms']); + + $deepLink .= implode(',', $roomOccupancy);; + + $deepLink .= '?utm_source=google'; + + return $deepLink; + + } + + + public function hotel(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + + $listings = new \SimpleXMLElement(''); + + $listings->addChild('language', 'en'); + + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country', + 'property.propertyRooms', 'property.propertyPhotos', 'property.propertyAdditionalInfos', 'property.propertyBrand' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + if ($propertyMapping['status'] != 1) { + continue; + } + + $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1); + + $listing = $listings->addChild('listing'); + + $listing->addChild('id', $propertyMapping['property']['id']); + $listing->addChild('name', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8')); + + $address = $listing->addChild('address'); + $address->addAttribute('format', 'simple'); + + $component = $address->addChild('component', htmlspecialchars(fillOnUndefined($metaAddress, 'street'), ENT_XML1, 'UTF-8')); + $component->addAttribute('name', 'addr1'); + + //$component = $address->addChild('component'); + //$component->addAttribute('name', 'addr2'); + + $component = $address->addChild('component', fillOnUndefined($metaAddress, 'city')); + $component->addAttribute('name', 'city'); + + //$component = $address->addChild('component', $propertyMapping['property']['country']['name']); + //$component->addAttribute('name','region'); + + $component = $address->addChild('component', fillOnUndefined($metaAddress, 'zip_code')); + $component->addAttribute('name', 'postal_code'); + + $listing->addChild('country', $propertyMapping['property']['country']['country_code']); + $listing->addChild('latitude', $propertyMapping['property']['property_contact']['latitude']); + $listing->addChild('longitude', $propertyMapping['property']['property_contact']['longitude']); + + if (!empty($propertyMapping['property']['property_contact']['view_full_phone'])) { + $phone = $listing->addChild('phone'); + $phone->addAttribute('number', $propertyMapping['property']['property_contact']['view_full_phone']); + } + + $listing->addChild('category', 'hotel'); + + if (!empty($propertyMapping['property']['property_brand']['name'])) { + $listing->addChild('brand', htmlspecialchars($propertyMapping['property']['property_brand']['name'], ENT_XML1, 'UTF-8')); + } + + if (!empty($propertyMapping['property']['property_web']['webProtocolUrl'])) { + $listing->addChild('website', $propertyMapping['property']['property_web']['webProtocolUrl']); + } + + $content = $listing->addChild('content'); + + $text = $content->addChild('text'); + $text->addAttribute('type', 'description'); + $text->addChild('body', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8')); + + $attributes = $content->addChild('attributes'); + $clientAttrCountry = $attributes->addChild('client_attr', $propertyMapping['property']['country']['country_code']); + $clientAttrCountry->addAttribute('name', 'country'); + + $clientAttrMaxNightStay = $attributes->addChild('client_attr', '0'); + $clientAttrMaxNightStay->addAttribute('name', 'max_night_stay'); + + $clientAttrMinNightStay = $attributes->addChild('client_attr', '1'); + $clientAttrMinNightStay->addAttribute('name', 'minimum_night_stay'); + + $roomCountTotal = 0; + if (!empty($propertyMapping['property']['property_additional_infos'])) { + foreach ($propertyMapping['property']['property_additional_infos'] as $info) { + if ($info['additional_info_key_id'] == 3) { + $roomCountTotal = $info['value']; + break; + } + } + } + + $clientAttrRooms = $attributes->addChild('client_attr', $roomCountTotal); + $clientAttrRooms->addAttribute('name', 'number_of_rooms'); + + $clientAttrLatLong = $attributes->addChild('client_attr', $propertyMapping['property']['property_contact']['latitude'] . ', ' . $propertyMapping['property']['property_contact']['longitude']); + $clientAttrLatLong->addAttribute('name', 'latlong'); + + if (!empty($propertyMapping['property']['property_photos'])) { + $photos = $propertyMapping['property']['property_photos']; + + // Filter photos with status 1 + $photos = array_filter($photos, function ($p) { + return isset($p['status']) && $p['status'] == 1; + }); + + // Sort photos by is_default (desc), photo_order (asc), and created_at (desc) + usort($photos, function ($a, $b) { + return ($b['is_default'] ?? 0) <=> ($a['is_default'] ?? 0) + ?: ($a['photo_order'] ?? 0) <=> ($b['photo_order'] ?? 0) + ?: ($b['created_at'] ?? 0) <=> ($a['created_at'] ?? 0); + }); + + // Limit to first 10 photos + $photos = array_slice($photos, 0, 10); + + foreach ($photos as $photo) { + $imageUrl = $photo['photoUrl']['default'] ?? $photo['photo_url']['default'] ?? null; + + if ($imageUrl) { + $image = $content->addChild('image'); + $image->addAttribute('type', 'ad'); + $image->addAttribute('url', $imageUrl); + + $width = '1440'; + $height = '959'; + + if (!empty($photo['photo_resolution'])) { + $resolution = explode('x', $photo['photo_resolution']); + if (count($resolution) == 2) { + $width = trim($resolution[0]); + $height = trim($resolution[1]); + } + } + + $image->addAttribute('width', $width); + $image->addAttribute('height', $height); + + $image->addChild('link', $imageUrl); + $image->addChild('title', 'Unknown title'); + + $date = $image->addChild('date'); + if (!empty($photo['created_at'])) { + $photoCreatedAt = Carbon::createFromTimestamp($photo['created_at']); + } else { + $photoCreatedAt = Carbon::now(); + } + + $date->addAttribute('day', $photoCreatedAt->day); + $date->addAttribute('month', $photoCreatedAt->month); + $date->addAttribute('year', $photoCreatedAt->year); + } + } + } + + + } + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + header('Content-Type: application/xml; charset=UTF-8'); + echo $listings->asXML(); + exit; + + + } + +} diff --git a/app/Http/Controllers/MetaSearch/Trivago/v1/TrivagoController.php b/app/Http/Controllers/MetaSearch/Trivago/v1/TrivagoController.php new file mode 100644 index 0000000..441a09f --- /dev/null +++ b/app/Http/Controllers/MetaSearch/Trivago/v1/TrivagoController.php @@ -0,0 +1,872 @@ +username = 'trivago'; + $this->password = 'P8MUQtNP6TkKMz3E'; + + $this->channelManagerId = 11;//Trivago + + $this->request = $request; + $this->currencyService = $currencyService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + + $payload = $this->request->getContent(); + parse_str(urldecode($payload), $payloadDecode); + $this->param = $payloadDecode; + + $this->authorization = $request->header('authorization'); + + $this->tax = 10; + $this->cityTax = 2; + + + $this->mealCodeMapping = [ + 10 => 'AI', + 11 => 'BB', + 13 => 'RO', + 14 => 'FB', + 15 => 'HB', + ]; + + $this->paymentTypeMapping = [ + 'CRD' => 'prepaid', + 'HTL' => 'postpaid' + ]; + + $this->CPA['TR'] = ["1" => 9.60, "2" => 10.80, "3" => 11.00, "4" => 11.20, "5" => 11.40, "6" => 11.60, "7" => 11.80, "8" => 12.00]; + $this->CPA['DE'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + $this->CPA['UK'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + $this->CPA['US'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + + $this->countryCodeCampaign = [ + 'DE' => [ + 'code' => 'DE', + 'campaignCode' => 7 + ], + 'TR' => [ + 'code' => 'TR', + 'campaignCode' => 8 + ], + 'US' => [ + 'code' => 'US', + 'campaignCode' => 7 + ], + 'UK' => [ + 'code' => 'UK', + 'campaignCode' => 7 + ] + ]; + + } + + + public function checkAuthentication($authorization) + { + + $response = ['status' => false, 'message' => '']; + + $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password); + + if ($authorization != $basicAuth) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + return response()->json($response); + + } + + public function requestParamConverter($requestParam = []) + { + + $searchRequestJson = []; + + $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['start_date'])->toDateString(); + $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['end_date'])->toDateString(); + + $rooms = []; + for ($i = 0; $i < $requestParam['num_rooms']; $i++) { + + $roomCounter = ($i + 1); + + if (isset($requestParam['room_adults_' . $roomCounter])) { + $rooms[$i]['adults'] = $requestParam['room_adults_' . $roomCounter]; + } + + + $rooms[$i]['children'] = 0; + $rooms[$i]['age'] = null; + if (isset($requestParam['room_childs_' . $roomCounter])) { + + $childAges = json_decode($requestParam['room_childs_' . $roomCounter]); + + $rooms[$i]['children'] = count($childAges); + $rooms[$i]['age'] = $childAges; + } + + } + + $searchRequestJson['rooms'] = $rooms; + $searchRequestJson['property'] = json_decode($requestParam['hotels']); + + return $searchRequestJson; + + } + + public function roomOccupancy($requestParam) + { + + $roomOccupancy = []; + foreach ($requestParam as $room) { + $adults = str_repeat('A', $room['adults']); + + $children = []; + if ($room['children'] > 0 && !empty($room['age'])) { + foreach ($room['age'] as $child) { + $children[] = 'C' . $child; + } + } + + $roomOccupancy[] = $adults . implode('', $children); + + } + + return $roomOccupancy; + } + + public function deepLinkGenerator($token, $requestParam = []) + { + + $deepLink = 'https://be.extranetwork.com/' . $token . '/en/search/'; + + + $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/'; + $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/'; + + + $roomOccupancy = $this->roomOccupancy($requestParam['rooms']); + + $deepLink .= implode(',', $roomOccupancy);; + + $deepLink .= '?utm_medium=trivago&utm_source=trivago&locale=' . $requestParam['locale']; + + return $deepLink; + + } + + public function couponCodeCheck($propertyId, $checkIn, $checkOut) + { + //$propertyChannelCoupon + $propertyChannelCouponsCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ], + ]; + + $propertyChannelCoupons = $this->propertyChannelCouponService->select($propertyChannelCouponsCriteria); + + if ($propertyChannelCoupons['status'] == 'success') { + $propertyChannelCoupons = $propertyChannelCoupons['data']; + + foreach ($propertyChannelCoupons as $propertyChannelCouponKey => $propertyChannelCouponData) { + + //Reservation Date Check + if (!is_null($propertyChannelCouponData['reservation_start_date']) && !is_null($propertyChannelCouponData['reservation_end_date'])) { + $reservationDateCheck = Carbon::parse($propertyChannelCouponData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($checkIn)) + && Carbon::parse($propertyChannelCouponData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($checkOut)); + if (!$reservationDateCheck) { + unset($propertyChannelCoupons[$propertyChannelCouponKey]); + } + + } + } + + } else { + $propertyChannelCoupons = []; + } + + $propertyChannelCoupon = !empty($propertyChannelCoupons) ? reset($propertyChannelCoupons) : null; + + return $propertyChannelCoupon; + + } + + public function availability(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + $checkAuthentication = $this->checkAuthentication($this->authorization); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController"); + + $requestTime = microtime(true); + + + $hotelList['root'] = $this->param; + unset($hotelList['root']['hotels']); + $hotelList['root']['hotel_ids'] = json_decode($this->param['hotels']); + $hotelList['root']['hotels'] = []; + + $hotelList['root']['api_version'] = (integer)$hotelList['root']['api_version']; + $hotelList['root']['num_rooms'] = (integer)$hotelList['root']['num_rooms']; + + for ($i = 0; $i < $hotelList['root']['num_rooms']; $i++) { + $roomCounter = ($i + 1); + if (isset($hotelList['root']['room_adults_' . $roomCounter])) { + $hotelList['root']['room_adults_' . $roomCounter] = (integer)$hotelList['root']['room_adults_' . $roomCounter]; + } + } + + $requestCurrency = $this->param['currency']; + + try { + + + //Hotels Check + $channelManagerPropertyList = []; + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + $channelManagerPropertyList = pickItemFromArray('property_id', $channelManagerPropertyMapping['data']); + } + + $availableHotelIds = array_intersect($hotelList['root']['hotel_ids'], $channelManagerPropertyList); + + if (empty($availableHotelIds)) { + throw new ApiErrorException('Hotel not found'); + } + + $this->param['hotels'] = json_encode($availableHotelIds); + //Hotels Check + + + $searchRequestJson = $this->requestParamConverter($this->param); + + $searchRequestJson['ipAddress'] = $request->getClientIp(); + $searchRequestJson['isMobile'] = null; + $searchRequestJson['noneCacheSearch'] = true; + $searchRequestJson['ipAddress'] = $request->getClientIp(); + $searchRequestJson['justPriceValues'] = true; + + + $cacheKeyParam = $this->param; + unset($cacheKeyParam['currency']); + unset($cacheKeyParam['rate_model']); + unset($cacheKeyParam['lang']); + $cacheKey = 'TRV:' . md5(implode(',', $cacheKeyParam)); + + //Cache::forget($cacheKey); + + if (Cache::has($cacheKey)) { + $search = Cache::get($cacheKey); + } else { + $requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson)); + $requestCreate->headers->set('channelId', '1'); + //$requestCreate->headers->set('bookingEnginePropertyId', null); + $requestCreate->headers->set('channelToken', 'ece3ef02-42e7-92b7-f379-08226ed7a0f3');//TODO: from DB + $requestCreate->headers->set('bookingEngineToken', null); + $search = $searchController->search($requestCreate); + + Cache::put($cacheKey, $search, 60 * 60);//1 Day 24 * 60 * 60 + } + + $search = json_decode(json_encode($search), 1); + + if ($search['original']['status'] != 200) { + throw new ApiErrorException('Hotel not found'); + } + + $properties = $search['original']['data']['properties']; + + if (empty($properties)) { + throw new ApiErrorException('Hotel not found'); + } + + $hotelCounter = 0; + $numberOfStay = Carbon::parse($searchRequestJson['date']['checkIn'])->diffInDays(Carbon::parse($searchRequestJson['date']['checkOut'])); + + foreach ($properties as $propertyId => $property) { + + if (!isset($property['currency'])) { + continue; + } + + $currencyExchangeRate = 1; + if ($requestCurrency != $property['currency']) { + $currencyExchangeRate = $this->currencyService->lastExchangeRate($property['currency'], $requestCurrency); + if ($currencyExchangeRate['status'] == 'success') { + $currencyExchangeRate = $currencyExchangeRate['data']; + } + } + + + $languageLocale = explode('_', $this->param['lang'], 2); + $searchRequestJson['locale'] = $languageLocale[1]; + + $token = $property['booking_engine_token']; + $deepLinkGenerator = $this->deepLinkGenerator($token, $searchRequestJson); + + $property = reset($property['availabilities']); + $propertyRooms = $property['rooms']; + + //Standard Room Room Only FreeCancellation - Pay at Hotel + + $requestedRoomPriceGroup = []; + foreach ($propertyRooms as $propertyRoomId => $propertyRoom) { + + foreach ($propertyRoom['rates'] as $propertyRoomRateId => $propertyRoomRate) { + + foreach ($propertyRoomRate['requestedRoomPrice'] as $occupancyCode => $requestedRoomPrices) { + + foreach ($requestedRoomPrices['prices'] as $requestedRoomPriceKey => $requestedRoomPrice) { + + $roomRateKeyName = $occupancyCode . ' ' . $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name']; + + $roomRateKeycode = $requestedRoomPrice['rate']['accommodationCode'] . '|' . (isset($requestedRoomPrice['cancellationPolicy']['id']) ? $requestedRoomPrice['cancellationPolicy']['id'] : 0) . '|' . $requestedRoomPrice['bookingPaymentType']['code']; + + //$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $roomRateKeyName . '-' . $requestedRoomPrice['rateKeyCode']; + $requestedRoomPrice['dailyAverageDiscount'] = $requestedRoomPrices['dailyAverageDiscount']; + $requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $requestedRoomPrice; + + } + + + } + + } + } + + $roomOccupancy = $this->roomOccupancy($searchRequestJson['rooms']); + + + $roomRateBoardGroup = []; + foreach ($requestedRoomPriceGroup as $groupKey => $groupValue) { + + $counter = 0; + + foreach ($groupValue as $groupValueOccupancyCode => $groupValueOccupancy) { + foreach ($groupValueOccupancy as $groupValueOccupancyCodeX => $groupValueOccupancyVal) { + + foreach ($roomOccupancy as $occupancyOrder => $occupancy) { + + $occupancyCheckKey = $occupancy . '-' . $occupancyOrder; + + if ($groupValueOccupancyCode == $occupancy && !isset($roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey])) { + $roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey] = $groupValueOccupancyVal; + if (count($roomRateBoardGroup[$groupKey][$counter]) == count($roomOccupancy)) { + $counter++; + } + } + + } + + } + } + } + + + $roomRateTypes = []; + foreach ($roomRateBoardGroup as $boardGroups) { + + foreach ($boardGroups as $boardGroups) { + + + $roomRateTypesGroup = []; + foreach ($boardGroups as $requestedRoomPrice) { + + $roomRateKeyName = $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name']; + + $total = $requestedRoomPrice['total']; + $totalBeforeDiscount = $requestedRoomPrice['total']; + $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay); + + $discounts = []; + if ($requestedRoomPrice['dailyAverageDiscount'] > 0) { + + $totalBeforeDiscount = ($total / (100 - (double)$requestedRoomPrice['dailyAverageDiscount'])) * 100; + $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay); + $totalDiscount = $totalBeforeDiscount - $total; + $dailyDiscountAverage = ($totalDiscount / $numberOfStay); + + + $netRate = $dailyDiscountAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100)); + $vat = $netRate * ($this->tax / 100); + $localTax = $netRate * ($this->cityTax / 100); + + + $finalRateDiscount = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate); + + $discounts[] = [ + 'booking_fee' => 0, + 'final_rate' => moneyDoubleFormatDecimal($finalRateDiscount), //moneyDoubleFormatDecimal($dailyDiscountAverage * $currencyExchangeRate), + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate), + 'marketing_text' => $requestedRoomPrice['dailyAverageDiscount'] . '% Special Discount', + 'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate), + 'resort_fee' => 0, + 'service_charge' => 0, + 'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate), + ]; + + } + + $netRate = $totalBeforeDiscountDailyAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100)); + $vat = $netRate * ($this->tax / 100); + $localTax = $netRate * ($this->cityTax / 100); + + + $finalRate = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate); + + $roomRateTypesGroup[][$roomRateKeyName] = [ + 'booking_fee' => 0, + 'breakfast_included' => in_array($requestedRoomPrice['rate']['accommodationCode'], [10, 11, 14, 15]) ? true : false, + 'currency' => $requestCurrency, + 'discounts' => $discounts, + 'final_rate' => moneyDoubleFormatDecimal($finalRate),//moneyDoubleFormatDecimal($totalBeforeDiscountDailyAverage * $currencyExchangeRate), + 'free_cancellation' => $requestedRoomPrice['cancellationPolicy']['isFreeCancellation'] ? true : false, + //'free_cancellation_deadline' => '2018-04-25T16:00:00+00:00', + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate), + 'meal_code' => isset($this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']]) ? $this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']] : 'RO', + 'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate), + 'payment_type' => isset($this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']]) ? $this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']] : 'postpaid', + 'resort_fee' => 0, + 'room_code' => $requestedRoomPrice['room']['name'], + 'service_charge' => 0, + 'url' => $deepLinkGenerator, + //'mobileURL' => null', + 'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate), + 'rate_type' => 'DEFAULT', + //'rateKeyCode' => $requestedRoomPrice['rateKeyCode'], + //'dailyAverageDiscount' => $requestedRoomPrice['dailyAverageDiscount'], + ]; + + + } + + $roomRateTypes[] = $roomRateTypesGroup; + + + } + } + + if (!empty($roomRateTypes)) { + + //if (in_array($propertyId, [1275,1325])) { + + $propertyCouponCodeCheck = $this->couponCodeCheck($propertyId, $searchRequestJson['date']['checkIn'], $searchRequestJson['date']['checkOut']); + + if (!empty($propertyCouponCodeCheck)) { + $roomRateTypesWithCoupon = []; + foreach ($roomRateTypes as $roomRateTypeKey => $roomRateType) { + foreach ($roomRateType as $roomRateTypeDetailKey => $roomRateTypeDetails) { + + //dd($roomRateTypeKey, $roomRateTypeDetailKey, $propertyCouponCodeCheck, $roomRateTypeDetail, key($roomRateTypeDetail)); + + $roomRateTypeDetail = reset($roomRateTypeDetails); + + $couponPercentageValue = (100 - $propertyCouponCodeCheck['value']) / 100; + + $finalRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('final_rate'); + $localTaxDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('local_tax'); + $netRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('net_rate'); + $vatDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('vat'); + + $finalRateDiscountReward = ($roomRateTypeDetail['final_rate'] - $finalRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $localTaxDiscountReward = ($roomRateTypeDetail['local_tax'] - $localTaxDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $netRateDiscountReward = ($roomRateTypeDetail['net_rate'] - $netRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $vatDiscountReward = ($roomRateTypeDetail['vat'] - $vatDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + + $discountReward = [ + 'booking_fee' => 0, + 'final_rate' => moneyDoubleFormatDecimal($finalRateDiscountBeforeReward + $finalRateDiscountReward), + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTaxDiscountBeforeReward + $localTaxDiscountReward), + 'marketing_text' => 'Special REWARD Discount', + 'net_rate' => moneyDoubleFormatDecimal($netRateDiscountBeforeReward + $netRateDiscountReward), + 'resort_fee' => 0, + 'service_charge' => 0, + 'vat' => moneyDoubleFormatDecimal($vatDiscountBeforeReward + $vatDiscountReward), + ]; + + $discountReward['marketing_text'] = number_format($discountReward['final_rate'] / $roomRateTypeDetail['final_rate'] * 100) . '% Special Popup Discount'; + + unset($roomRateTypeDetail['discounts']); + + $roomRateTypeDetail['discounts'][] = $discountReward; + + //$roomRateTypeDetail['rate_type'] = 'REWARD'; + $roomRateTypeDetail['rate_type'] = 'DEFAULT'; + + + $roomRateTypesWithCoupon[$roomRateTypeKey][$roomRateTypeDetailKey][key($roomRateTypeDetails)] = $roomRateTypeDetail; + + } + + unset($roomRateTypes[$roomRateTypeKey]); + + } + + $roomRateTypes = array_merge($roomRateTypes, $roomRateTypesWithCoupon); + } + + //} + + + $hotelList['root']['hotels'][$hotelCounter] = [ + 'hotel_id' => $propertyId, + 'room_types' => $roomRateTypes + ]; + + $hotelCounter++; + + } + + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $hotelList['root']['hotels'] = []; + } + + $responseTime = microtime(true) - $requestTime; + + + //Log::debug(json_encode($this->param) . ' - Response Time: ' . number_format($responseTime, 2) . ' - Status: ' . count($hotelList['root']['hotels'])); + + + return response()->json($hotelList); + + } + + public function hotel(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + + $hotelList = []; + + $hotelList['api_version'] = 4; + $hotelList['lang'] = 'en_GB'; + $hotelList['hotels'] = []; + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + if ($propertyMapping['status'] != 1) { + continue; + } + + $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1); + + + $hotelList['hotels'][] = [ + 'partner_reference' => $propertyMapping['property']['id'], + 'name' => $propertyMapping['property']['name'], + 'street' => fillOnUndefined($metaAddress, 'street'), + 'city' => fillOnUndefined($metaAddress, 'city'), + 'postal_code' => fillOnUndefined($metaAddress, 'zip_code'), + //'state' => null, + 'country' => $propertyMapping['property']['country']['name'], + 'latitude' => $propertyMapping['property']['property_contact']['latitude'], + 'longitude' => $propertyMapping['property']['property_contact']['longitude'], + 'desc' => $propertyMapping['property']['name'], + 'amenities' => null,//['Beauty Center', 'Business Center', 'Café/ Bistro', 'Sauna'], + 'url' => $propertyMapping['property']['property_web']['webProtocolUrl'], + 'email' => $propertyMapping['property']['property_contact']['email'], + 'phone' => $propertyMapping['property']['property_contact']['phone'], + 'fax' => $propertyMapping['property']['property_contact']['fax'] + ]; + + //dd(json_decode($propertyMapping['property']['property_contact']['meta'],1)); + + $addressExplode = explode('/', $propertyMapping['property']['property_contact']['address'], 2); + $street = isset($addressExplode[0]) ? $addressExplode[0] : $propertyMapping['property']['property_contact']['address']; + $cityExplode = isset($addressExplode[1]) ? explode(',', $addressExplode[1]) : (isset($addressExplode[0]) ? explode(',', $addressExplode[0]) : null); + $city = isset($cityExplode[0]) ? $cityExplode[0] : null; + + $streetExplode = explode(', ', $street); + unset($streetExplode[count($streetExplode) - 1]); + $street = implode(', ', $streetExplode); + + $metaUpdate = [ + 'street' => $street, + 'city' => $city, + 'zip_code' => $propertyMapping['property']['property_contact']['zip_code'], + ]; + + if (empty($propertyMapping['property']['property_contact']['meta'])) { + PropertyContact::where('id', $propertyMapping['property']['property_contact']['id'])->update(['meta' => json_encode($metaUpdate)]); + } + + + //dd($propertyMapping['property']['property_contact']['id'],$metaUpdate); + + } + + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $hotelList['root']['hotels'] = []; + } + + + return response()->json($hotelList); + + } + + public function campaign(Request $request) + { + + + $hotelList = []; + + $hotelExcludeList = []; + $hotelExcludeList['TR'] = [721, 729]; + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $hotelList[] = [ + 'partner_reference' => 'partner_reference', + 'locale' => 'locale', + 'campaign' => 'campaign' + ]; + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + foreach ($this->CPA as $countryCode => $countryValue) { + foreach ($countryValue as $campaignId => $campaignValue) { + + if (isset($this->countryCodeCampaign[$countryCode]) && $this->countryCodeCampaign[$countryCode]['campaignCode'] == $campaignId) { + + if (isset($hotelExcludeList[$countryCode])) { + if (in_array($propertyMapping['property_id'], $hotelExcludeList[$countryCode])) { + continue; + } + } + + $hotelList[] = [ + 'partner_reference' => $propertyMapping['property']['id'], + 'locale' => $countryCode, + 'campaign' => $campaignId + ]; + } + + } + } + + + } + + + } + + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + $out = ""; + foreach ($hotelList as $hotel) { + $out .= implode(",", $hotel) . PHP_EOL; + + } + + header("Content-Type: application/csv"); + header("Content-Disposition: attachment; filename=Extranetwork-Campaign.csv"); + header('Pragma: no-cache'); + header("Expires: 0"); + + echo $out; + die(); + + //return response()->json($hotelList); + + } + + public function cpa(Request $request) + { + + + $cpaList[] = [ + 'locale' => 'locale', + 'campaign' => 'campaign', + 'cpa_value' => 'cpa_value' + ]; + + + try { + + foreach ($this->CPA as $countryCode => $countryValue) { + foreach ($countryValue as $campaignId => $campaignValue) { + + $cpaList[] = [ + 'locale' => $countryCode, + 'campaign' => $campaignId, + 'cpa_value' => $campaignValue + ]; + + } + + } + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + + $out = ""; + foreach ($cpaList as $cpa) { + $out .= implode(",", $cpa) . PHP_EOL; + + } + + header("Content-Type: application/csv"); + header("Content-Disposition: attachment; filename=Extranetwork-CPA.csv"); + header('Pragma: no-cache'); + header("Expires: 0"); + + echo $out; + die(); + + //return response()->json($hotelList); + + } + + +} diff --git a/app/Http/Controllers/MetaSearch/Trivago/v1/_TrivagoController.php b/app/Http/Controllers/MetaSearch/Trivago/v1/_TrivagoController.php new file mode 100644 index 0000000..af70e8a --- /dev/null +++ b/app/Http/Controllers/MetaSearch/Trivago/v1/_TrivagoController.php @@ -0,0 +1,884 @@ +username = 'trivago'; + $this->password = 'P8MUQtNP6TkKMz3E'; + + $this->channelManagerId = 11;//Trivago + + $this->request = $request; + $this->currencyService = $currencyService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + + $payload = $this->request->getContent(); + parse_str(urldecode($payload), $payloadDecode); + $this->param = $payloadDecode; + + $this->authorization = $request->header('authorization'); + + $this->tax = 10; + $this->cityTax = 2; + + + $this->mealCodeMapping = [ + 10 => 'AI', + 11 => 'BB', + 13 => 'RO', + 14 => 'FB', + 15 => 'HB', + ]; + + $this->paymentTypeMapping = [ + 'CRD' => 'prepaid', + 'HTL' => 'postpaid' + ]; + + $this->CPA['TR'] = ["1" => 9.60, "2" => 10.80, "3" => 11.00, "4" => 11.20, "5" => 11.40, "6" => 11.60, "7" => 11.80, "8" => 12.00]; + $this->CPA['DE'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + $this->CPA['UK'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + $this->CPA['US'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20]; + + $this->countryCodeCampaign = [ + 'DE' => [ + 'code' => 'DE', + 'campaignCode' => 7 + ], + 'TR' => [ + 'code' => 'TR', + 'campaignCode' => 8 + ], + 'US' => [ + 'code' => 'US', + 'campaignCode' => 7 + ], + 'UK' => [ + 'code' => 'UK', + 'campaignCode' => 7 + ] + ]; + + } + + + public function checkAuthentication($authorization) + { + + $response = ['status' => false, 'message' => '']; + + $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password); + + if ($authorization != $basicAuth) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + return response()->json($response); + + } + + public function requestParamConverter($requestParam = []) + { + + $searchRequestJson = []; + + $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['start_date'])->toDateString(); + $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['end_date'])->toDateString(); + + $rooms = []; + for ($i = 0; $i < $requestParam['num_rooms']; $i++) { + + $roomCounter = ($i + 1); + + if (isset($requestParam['room_adults_' . $roomCounter])) { + $rooms[$i]['adults'] = $requestParam['room_adults_' . $roomCounter]; + } + + + $rooms[$i]['children'] = 0; + $rooms[$i]['age'] = null; + if (isset($requestParam['room_childs_' . $roomCounter])) { + + $childAges = json_decode($requestParam['room_childs_' . $roomCounter]); + + $rooms[$i]['children'] = count($childAges); + $rooms[$i]['age'] = $childAges; + } + + } + + $searchRequestJson['rooms'] = $rooms; + $searchRequestJson['property'] = json_decode($requestParam['hotels']); + + return $searchRequestJson; + + } + + public function roomOccupancy($requestParam) + { + + $roomOccupancy = []; + foreach ($requestParam as $room) { + $adults = str_repeat('A', $room['adults']); + + $children = []; + if ($room['children'] > 0 && !empty($room['age'])) { + foreach ($room['age'] as $child) { + $children[] = 'C' . $child; + } + } + + $roomOccupancy[] = $adults . implode('', $children); + + } + + return $roomOccupancy; + } + + public function deepLinkGenerator($token, $requestParam = []) + { + + $deepLink = 'https://be.extranetwork.com/' . $token . '/en/search/'; + + + $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/'; + $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/'; + + + $roomOccupancy = $this->roomOccupancy($requestParam['rooms']); + + $deepLink .= implode(',', $roomOccupancy);; + + $deepLink .= '?utm_medium=trivago&utm_source=trivago&locale=' . $requestParam['locale']; + + return $deepLink; + + } + + public function couponCodeCheck($propertyId, $checkIn, $checkOut) + { + //$propertyChannelCoupon + $propertyChannelCouponsCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ], + ]; + + $propertyChannelCoupons = $this->propertyChannelCouponService->select($propertyChannelCouponsCriteria); + + if ($propertyChannelCoupons['status'] == 'success') { + $propertyChannelCoupons = $propertyChannelCoupons['data']; + + foreach ($propertyChannelCoupons as $propertyChannelCouponKey => $propertyChannelCouponData) { + + //Reservation Date Check + if (!is_null($propertyChannelCouponData['reservation_start_date']) && !is_null($propertyChannelCouponData['reservation_end_date'])) { + $reservationDateCheck = Carbon::parse($propertyChannelCouponData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($checkIn)) + && Carbon::parse($propertyChannelCouponData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($checkOut)); + if (!$reservationDateCheck) { + unset($propertyChannelCoupons[$propertyChannelCouponKey]); + } + + } + } + + } else { + $propertyChannelCoupons = []; + } + + $propertyChannelCoupon = !empty($propertyChannelCoupons) ? reset($propertyChannelCoupons) : null; + + return $propertyChannelCoupon; + + } + + public function availability(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + $checkAuthentication = $this->checkAuthentication($this->authorization); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController"); + + $requestTime = microtime(true); + + + $hotelList['root'] = $this->param; + unset($hotelList['root']['hotels']); + $hotelList['root']['hotel_ids'] = json_decode($this->param['hotels']); + $hotelList['root']['hotels'] = []; + + $hotelList['root']['api_version'] = (integer)$hotelList['root']['api_version']; + $hotelList['root']['num_rooms'] = (integer)$hotelList['root']['num_rooms']; + + for ($i = 0; $i < $hotelList['root']['num_rooms']; $i++) { + $roomCounter = ($i + 1); + if (isset($hotelList['root']['room_adults_' . $roomCounter])) { + $hotelList['root']['room_adults_' . $roomCounter] = (integer)$hotelList['root']['room_adults_' . $roomCounter]; + } + } + + $requestCurrency = $this->param['currency']; + + try { + + + //Hotels Check + $channelManagerPropertyList = []; + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + $channelManagerPropertyList = pickItemFromArray('property_id', $channelManagerPropertyMapping['data']); + } + + $availableHotelIds = array_intersect($hotelList['root']['hotel_ids'], $channelManagerPropertyList); + + if (empty($availableHotelIds)) { + throw new ApiErrorException('Hotel not found'); + } + + $this->param['hotels'] = json_encode($availableHotelIds); + //Hotels Check + + + $searchRequestJson = $this->requestParamConverter($this->param); + + $searchRequestJson['ipAddress'] = $request->getClientIp(); + $searchRequestJson['isMobile'] = null; + $searchRequestJson['noneCacheSearch'] = true; + $searchRequestJson['ipAddress'] = $request->getClientIp(); + $searchRequestJson['justPriceValues'] = true; + + + $cacheKeyParam = $this->param; + unset($cacheKeyParam['currency']); + unset($cacheKeyParam['rate_model']); + unset($cacheKeyParam['lang']); + $cacheKey = 'TRV:' . md5(implode(',', $cacheKeyParam)); + + //Cache::forget($cacheKey); + + if (Cache::has($cacheKey)) { + $search = Cache::get($cacheKey); + } else { + $requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson)); + $requestCreate->headers->set('channelId', '1'); + //$requestCreate->headers->set('bookingEnginePropertyId', null); + $requestCreate->headers->set('channelToken', 'ece3ef02-42e7-92b7-f379-08226ed7a0f3');//TODO: from DB + $requestCreate->headers->set('bookingEngineToken', null); + $search = $searchController->search($requestCreate); + + Cache::put($cacheKey, $search, 60 * 60);//1 Day 24 * 60 * 60 + } + + $search = json_decode(json_encode($search), 1); + + if ($search['original']['status'] != 200) { + throw new ApiErrorException('Hotel not found'); + } + + $properties = $search['original']['data']['properties']; + + if (empty($properties)) { + throw new ApiErrorException('Hotel not found'); + } + + $hotelCounter = 0; + $numberOfStay = Carbon::parse($searchRequestJson['date']['checkIn'])->diffInDays(Carbon::parse($searchRequestJson['date']['checkOut'])); + + foreach ($properties as $propertyId => $property) { + + if (!isset($property['currency'])) { + continue; + } + + $currencyExchangeRate = 1; + if ($requestCurrency != $property['currency']) { + $currencyExchangeRate = $this->currencyService->lastExchangeRate($property['currency'], $requestCurrency); + if ($currencyExchangeRate['status'] == 'success') { + $currencyExchangeRate = $currencyExchangeRate['data']; + } + } + + + $languageLocale = explode('_', $this->param['lang'], 2); + $searchRequestJson['locale'] = $languageLocale[1]; + + $token = $property['booking_engine_token']; + $deepLinkGenerator = $this->deepLinkGenerator($token, $searchRequestJson); + + $property = reset($property['availabilities']); + $propertyRooms = $property['rooms']; + + //Standard Room Room Only FreeCancellation - Pay at Hotel + + $requestedRoomPriceGroup = []; + foreach ($propertyRooms as $propertyRoomId => $propertyRoom) { + + foreach ($propertyRoom['rates'] as $propertyRoomRateId => $propertyRoomRate) { + + foreach ($propertyRoomRate['requestedRoomPrice'] as $occupancyCode => $requestedRoomPrices) { + + foreach ($requestedRoomPrices['prices'] as $requestedRoomPriceKey => $requestedRoomPrice) { + + $roomRateKeyName = $occupancyCode . ' ' . $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name']; + + $roomRateKeycode = $requestedRoomPrice['rate']['accommodationCode'] . '|' . (isset($requestedRoomPrice['cancellationPolicy']['id']) ? $requestedRoomPrice['cancellationPolicy']['id'] : 0) . '|' . $requestedRoomPrice['bookingPaymentType']['code']; + + //$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $roomRateKeyName . '-' . $requestedRoomPrice['rateKeyCode']; + $requestedRoomPrice['dailyAverageDiscount'] = $requestedRoomPrices['dailyAverageDiscount']; + $requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $requestedRoomPrice; + + } + + + } + + } + } + + $roomOccupancy = $this->roomOccupancy($searchRequestJson['rooms']); + + + $roomRateBoardGroup = []; + foreach ($requestedRoomPriceGroup as $groupKey => $groupValue) { + + $counter = 0; + + foreach ($groupValue as $groupValueOccupancyCode => $groupValueOccupancy) { + foreach ($groupValueOccupancy as $groupValueOccupancyCodeX => $groupValueOccupancyVal) { + + foreach ($roomOccupancy as $occupancyOrder => $occupancy) { + + $occupancyCheckKey = $occupancy . '-' . $occupancyOrder; + + if ($groupValueOccupancyCode == $occupancy && !isset($roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey])) { + $roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey] = $groupValueOccupancyVal; + if (count($roomRateBoardGroup[$groupKey][$counter]) == count($roomOccupancy)) { + $counter++; + } + } + + } + + } + } + } + + + $roomRateTypes = []; + foreach ($roomRateBoardGroup as $boardGroups) { + + foreach ($boardGroups as $boardGroups) { + + + $roomRateTypesGroup = []; + foreach ($boardGroups as $requestedRoomPrice) { + + $roomRateKeyName = $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name']; + + $total = $requestedRoomPrice['total']; + $totalBeforeDiscount = $requestedRoomPrice['total']; + $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay); + + $discounts = []; + if ($requestedRoomPrice['dailyAverageDiscount'] > 0) { + + $totalBeforeDiscount = ($total / (100 - (double)$requestedRoomPrice['dailyAverageDiscount'])) * 100; + $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay); + $totalDiscount = $totalBeforeDiscount - $total; + $dailyDiscountAverage = ($totalDiscount / $numberOfStay); + + + $netRate = $dailyDiscountAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100)); + $vat = $netRate * ($this->tax / 100); + $localTax = $netRate * ($this->cityTax / 100); + + + $finalRateDiscount = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate); + + $discounts[] = [ + 'booking_fee' => 0, + 'final_rate' => moneyDoubleFormatDecimal($finalRateDiscount), //moneyDoubleFormatDecimal($dailyDiscountAverage * $currencyExchangeRate), + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate), + 'marketing_text' => $requestedRoomPrice['dailyAverageDiscount'] . '% Special Discount', + 'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate), + 'resort_fee' => 0, + 'service_charge' => 0, + 'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate), + ]; + + } + + $netRate = $totalBeforeDiscountDailyAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100)); + $vat = $netRate * ($this->tax / 100); + $localTax = $netRate * ($this->cityTax / 100); + + + $finalRate = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate); + + $roomRateTypesGroup[][$roomRateKeyName] = [ + 'booking_fee' => 0, + 'breakfast_included' => in_array($requestedRoomPrice['rate']['accommodationCode'], [10, 11, 14, 15]) ? true : false, + 'currency' => $requestCurrency, + 'discounts' => $discounts, + 'final_rate' => moneyDoubleFormatDecimal($finalRate),//moneyDoubleFormatDecimal($totalBeforeDiscountDailyAverage * $currencyExchangeRate), + 'free_cancellation' => $requestedRoomPrice['cancellationPolicy']['isFreeCancellation'] ? true : false, + //'free_cancellation_deadline' => '2018-04-25T16:00:00+00:00', + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate), + 'meal_code' => isset($this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']]) ? $this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']] : 'RO', + 'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate), + 'payment_type' => isset($this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']]) ? $this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']] : 'postpaid', + 'resort_fee' => 0, + 'room_code' => $requestedRoomPrice['room']['name'], + 'service_charge' => 0, + 'url' => $deepLinkGenerator, + //'mobileURL' => null', + 'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate), + 'rate_type' => 'DEFAULT', + //'rateKeyCode' => $requestedRoomPrice['rateKeyCode'], + //'dailyAverageDiscount' => $requestedRoomPrice['dailyAverageDiscount'], + ]; + + + } + + $roomRateTypes[] = $roomRateTypesGroup; + + + } + } + + if (!empty($roomRateTypes)) { + + //if (in_array($propertyId, [1275,1325])) { + + $propertyCouponCodeCheck = $this->couponCodeCheck($propertyId, $searchRequestJson['date']['checkIn'], $searchRequestJson['date']['checkOut']); + + if (!empty($propertyCouponCodeCheck)) { + $roomRateTypesWithCoupon = []; + foreach ($roomRateTypes as $roomRateTypeKey => $roomRateType) { + foreach ($roomRateType as $roomRateTypeDetailKey => $roomRateTypeDetails) { + + //dd($roomRateTypeKey, $roomRateTypeDetailKey, $propertyCouponCodeCheck, $roomRateTypeDetail, key($roomRateTypeDetail)); + + $roomRateTypeDetail = reset($roomRateTypeDetails); + + $couponPercentageValue = (100 - $propertyCouponCodeCheck['value']) / 100; + + $finalRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('final_rate'); + $localTaxDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('local_tax'); + $netRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('net_rate'); + $vatDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('vat'); + + $finalRateDiscountReward = ($roomRateTypeDetail['final_rate'] - $finalRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $localTaxDiscountReward = ($roomRateTypeDetail['local_tax'] - $localTaxDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $netRateDiscountReward = ($roomRateTypeDetail['net_rate'] - $netRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + $vatDiscountReward = ($roomRateTypeDetail['vat'] - $vatDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100; + + $discountReward = [ + 'booking_fee' => 0, + 'final_rate' => moneyDoubleFormatDecimal($finalRateDiscountBeforeReward + $finalRateDiscountReward), + 'hotel_fee' => 0, + 'local_tax' => moneyDoubleFormatDecimal($localTaxDiscountBeforeReward + $localTaxDiscountReward), + 'marketing_text' => 'Special REWARD Discount', + 'net_rate' => moneyDoubleFormatDecimal($netRateDiscountBeforeReward + $netRateDiscountReward), + 'resort_fee' => 0, + 'service_charge' => 0, + 'vat' => moneyDoubleFormatDecimal($vatDiscountBeforeReward + $vatDiscountReward), + ]; + + + /*foreach ($roomRateTypeDetail['discounts'] as $discountKey => $discount) { + + $discount['vat'] = moneyDoubleFormatDecimal($discount['vat'] * $couponPercentageValue); + $discount['net_rate'] = moneyDoubleFormatDecimal($discount['net_rate'] * $couponPercentageValue); + $discount['local_tax'] = moneyDoubleFormatDecimal($discount['local_tax'] * $couponPercentageValue); + $discount['final_rate'] = moneyDoubleFormatDecimal($discount['net_rate'] + $discount['vat'] + $discount['local_tax']); + + $roomRateTypeDetail['discounts'][$discountKey] = $discount; + + } + + + $roomRateTypeDetail['vat'] = moneyDoubleFormatDecimal($roomRateTypeDetail['vat'] * $couponPercentageValue); + $roomRateTypeDetail['net_rate'] = moneyDoubleFormatDecimal($roomRateTypeDetail['net_rate'] * $couponPercentageValue); + $roomRateTypeDetail['local_tax'] = moneyDoubleFormatDecimal($roomRateTypeDetail['local_tax'] * $couponPercentageValue); + $roomRateTypeDetail['final_rate'] = moneyDoubleFormatDecimal($roomRateTypeDetail['net_rate'] + $roomRateTypeDetail['vat'] + $roomRateTypeDetail['local_tax']);*/ + + unset($roomRateTypeDetail['discounts']); + + $roomRateTypeDetail['discounts'][] = $discountReward; + + $roomRateTypeDetail['rate_type'] = 'REWARD'; + + $roomRateTypesWithCoupon[$roomRateTypeKey][$roomRateTypeDetailKey][key($roomRateTypeDetails)] = $roomRateTypeDetail; + + } + + } + + $roomRateTypes = array_merge($roomRateTypes, $roomRateTypesWithCoupon); + } + + //} + + + $hotelList['root']['hotels'][$hotelCounter] = [ + 'hotel_id' => $propertyId, + 'room_types' => $roomRateTypes + ]; + + $hotelCounter++; + + } + + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $hotelList['root']['hotels'] = []; + } + + $responseTime = microtime(true) - $requestTime; + + + //Log::debug(json_encode($this->param) . ' - Response Time: ' . number_format($responseTime, 2) . ' - Status: ' . count($hotelList['root']['hotels'])); + + + return response()->json($hotelList); + + } + + public function hotel(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + + $hotelList = []; + + $hotelList['api_version'] = 4; + $hotelList['lang'] = 'en_GB'; + $hotelList['hotels'] = []; + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + if ($propertyMapping['status'] != 1) { + continue; + } + + $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1); + + + $hotelList['hotels'][] = [ + 'partner_reference' => $propertyMapping['property']['id'], + 'name' => $propertyMapping['property']['name'], + 'street' => fillOnUndefined($metaAddress, 'street'), + 'city' => fillOnUndefined($metaAddress, 'city'), + 'postal_code' => fillOnUndefined($metaAddress, 'zip_code'), + //'state' => null, + 'country' => $propertyMapping['property']['country']['name'], + 'latitude' => $propertyMapping['property']['property_contact']['latitude'], + 'longitude' => $propertyMapping['property']['property_contact']['longitude'], + 'desc' => $propertyMapping['property']['name'], + 'amenities' => null,//['Beauty Center', 'Business Center', 'Café/ Bistro', 'Sauna'], + 'url' => $propertyMapping['property']['property_web']['webProtocolUrl'], + 'email' => $propertyMapping['property']['property_contact']['email'], + 'phone' => $propertyMapping['property']['property_contact']['phone'], + 'fax' => $propertyMapping['property']['property_contact']['fax'] + ]; + + //dd(json_decode($propertyMapping['property']['property_contact']['meta'],1)); + + $addressExplode = explode('/', $propertyMapping['property']['property_contact']['address'], 2); + $street = isset($addressExplode[0]) ? $addressExplode[0] : $propertyMapping['property']['property_contact']['address']; + $cityExplode = isset($addressExplode[1]) ? explode(',', $addressExplode[1]) : (isset($addressExplode[0]) ? explode(',', $addressExplode[0]) : null); + $city = isset($cityExplode[0]) ? $cityExplode[0] : null; + + $streetExplode = explode(', ', $street); + unset($streetExplode[count($streetExplode) - 1]); + $street = implode(', ', $streetExplode); + + $metaUpdate = [ + 'street' => $street, + 'city' => $city, + 'zip_code' => $propertyMapping['property']['property_contact']['zip_code'], + ]; + + if (empty($propertyMapping['property']['property_contact']['meta'])) { + PropertyContact::where('id', $propertyMapping['property']['property_contact']['id'])->update(['meta' => json_encode($metaUpdate)]); + } + + + //dd($propertyMapping['property']['property_contact']['id'],$metaUpdate); + + } + + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!$response['status']) { + $hotelList['root']['hotels'] = []; + } + + + return response()->json($hotelList); + + } + + public function campaign(Request $request) + { + + + $hotelList = []; + + $hotelExcludeList = []; + $hotelExcludeList['TR'] = [721, 729]; + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + $hotelList[] = [ + 'partner_reference' => 'partner_reference', + 'locale' => 'locale', + 'campaign' => 'campaign' + ]; + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + foreach ($this->CPA as $countryCode => $countryValue) { + foreach ($countryValue as $campaignId => $campaignValue) { + + if (isset($this->countryCodeCampaign[$countryCode]) && $this->countryCodeCampaign[$countryCode]['campaignCode'] == $campaignId) { + + if (isset($hotelExcludeList[$countryCode])) { + if (in_array($propertyMapping['property_id'], $hotelExcludeList[$countryCode])) { + continue; + } + } + + $hotelList[] = [ + 'partner_reference' => $propertyMapping['property']['id'], + 'locale' => $countryCode, + 'campaign' => $campaignId + ]; + } + + } + } + + + } + + + } + + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + $out = ""; + foreach ($hotelList as $hotel) { + $out .= implode(",", $hotel) . PHP_EOL; + + } + + header("Content-Type: application/csv"); + header("Content-Disposition: attachment; filename=Extranetwork-Campaign.csv"); + header('Pragma: no-cache'); + header("Expires: 0"); + + echo $out; + die(); + + //return response()->json($hotelList); + + } + + public function cpa(Request $request) + { + + + $cpaList[] = [ + 'locale' => 'locale', + 'campaign' => 'campaign', + 'cpa_value' => 'cpa_value' + ]; + + + try { + + foreach ($this->CPA as $countryCode => $countryValue) { + foreach ($countryValue as $campaignId => $campaignValue) { + + $cpaList[] = [ + 'locale' => $countryCode, + 'campaign' => $campaignId, + 'cpa_value' => $campaignValue + ]; + + } + + } + + } catch (ApiErrorException | Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + } + + + $out = ""; + foreach ($cpaList as $cpa) { + $out .= implode(",", $cpa) . PHP_EOL; + + } + + header("Content-Type: application/csv"); + header("Content-Disposition: attachment; filename=Extranetwork-CPA.csv"); + header('Pragma: no-cache'); + header("Expires: 0"); + + echo $out; + die(); + + //return response()->json($hotelList); + + } + + +} diff --git a/app/Http/Controllers/MetaSearch/Yandex/v1/YandexController.php b/app/Http/Controllers/MetaSearch/Yandex/v1/YandexController.php new file mode 100644 index 0000000..2d845b7 --- /dev/null +++ b/app/Http/Controllers/MetaSearch/Yandex/v1/YandexController.php @@ -0,0 +1,541 @@ +username = 'yandex'; + $this->password = 'P8MUQtNP6TkKMz3E'; + + $this->channelManagerId = 13;//Yandex + + $this->request = $request; + $this->currencyService = $currencyService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + + $payload = $this->request->getContent(); + parse_str(urldecode($payload), $payloadDecode); + $this->param = $payloadDecode; + + $this->authorization = $request->header('authorization'); + + $this->tax = 10; + + + $this->mealCodeMapping = [ + 10 => 'AI', + 11 => 'BB', + 13 => 'RO', + 14 => 'FB', + 15 => 'HB', + ]; + + $this->paymentTypeMapping = [ + 'CRD' => 'prepaid', + 'HTL' => 'postpaid' + ]; + + + } + + + public function checkAuthentication($authorization) + { + + $response = ['status' => false, 'message' => '']; + + $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password); + + if ($authorization != $basicAuth) { + $response['message'] = 'Your username or password is incorrect.'; + } else { + $response['status'] = true; + } + + return $response; + + } + + + public function responseError($errorMessage) + { + + $response = [ + 'status' => false, + 'message' => $errorMessage, + ]; + + //channelManagerLogService + if (!is_null($this->channelManagerLogId)) { + $updateDataLog = [ + 'response' => json_encode($response), + 'status' => 0 + ]; + + if (!is_null($this->channelManagerRequestTime)) { + $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; + } + + $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); + } + //channelManagerLogService + + + return response()->json($response); + + } + + public function requestParamConverter($requestParam = []) + { + + $searchRequestJson = []; + + $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['Checkin'])->toDateString(); + $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['Checkin'])->addDays($requestParam['Nights'])->toDateString(); + + + $rooms = []; + $rooms[0]['adults'] = (integer)$requestParam['Context']['OccupancyDetails']['NumAdults']; + $rooms[0]['children'] = (integer)($requestParam['Context']['Occupancy'] - $requestParam['Context']['OccupancyDetails']['NumAdults']); + + $rooms[0]['age'] = []; + if (isset($requestParam['Context']['OccupancyDetails']['Children']['Child'])) { + $requestParam['Context']['OccupancyDetails']['Children']['Child'] = singleElementXMLArray($requestParam['Context']['OccupancyDetails']['Children']['Child']); + } else { + $requestParam['Context']['OccupancyDetails']['Children']['Child'] = []; + } + + foreach ($requestParam['Context']['OccupancyDetails']['Children']['Child'] as $child) { + $rooms[0]['age'][] = $child['@attributes']['age']; + } + + $searchRequestJson['rooms'] = $rooms; + + if (isset($requestParam['PropertyList']['Property'])) { + $requestParam['PropertyList']['Property'] = singleElementXMLArray($requestParam['PropertyList']['Property']); + } else { + $requestParam['PropertyList']['Property'] = []; + } + + + $searchRequestJson['property'] = $requestParam['PropertyList']['Property']; + + return $searchRequestJson; + + } + + public function roomOccupancy($requestParam) + { + + $roomOccupancy = []; + foreach ($requestParam as $room) { + $adults = str_repeat('A', $room['adults']); + + $children = []; + if ($room['children'] > 0 && !empty($room['age'])) { + foreach ($room['age'] as $child) { + $children[] = 'C' . $child; + } + } + + $roomOccupancy[] = $adults . implode('', $children); + + } + + return $roomOccupancy; + } + + public function deepLinkGenerator($token, $requestParam = []) + { + + $deepLink = 'https://be.extranetwork.com/' . $token . '/' . fillOnUndefined($requestParam, 'locale', 'en') . '/search/'; + + + $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/'; + $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/'; + + + $roomOccupancy = $this->roomOccupancy($requestParam['rooms']); + + $deepLink .= implode(',', $roomOccupancy);; + + $deepLink .= '?utm_source=yandex'; + + return $deepLink; + + } + + public function couponCodeCheck($propertyId, $checkIn, $checkOut) + { + //$propertyChannelCoupon + $propertyChannelCouponsCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ], + ]; + + $propertyChannelCoupons = $this->propertyChannelCouponService->select($propertyChannelCouponsCriteria); + + if ($propertyChannelCoupons['status'] == 'success') { + $propertyChannelCoupons = $propertyChannelCoupons['data']; + + foreach ($propertyChannelCoupons as $propertyChannelCouponKey => $propertyChannelCouponData) { + + //Reservation Date Check + if (!is_null($propertyChannelCouponData['reservation_start_date']) && !is_null($propertyChannelCouponData['reservation_end_date'])) { + $reservationDateCheck = Carbon::parse($propertyChannelCouponData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($checkIn)) + && Carbon::parse($propertyChannelCouponData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($checkOut)); + if (!$reservationDateCheck) { + unset($propertyChannelCoupons[$propertyChannelCouponKey]); + } + + } + } + + } else { + $propertyChannelCoupons = []; + } + + $propertyChannelCoupon = !empty($propertyChannelCoupons) ? reset($propertyChannelCoupons) : null; + + return $propertyChannelCoupon; + + } + + + public function hotel(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + + $listings = new \SimpleXMLElement(''); + + $listings->addChild('language', 'tr'); + + + try { + + + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMappingCriteria['with'] = [ + 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country' + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { + + if ($propertyMapping['status'] != 1) { + continue; + } + + $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1); + + $listing = $listings->addChild('listing'); + + $listing->addChild('id', $propertyMapping['property']['id']); + $listing->addChild('name', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8')); + + $address = $listing->addChild('address'); + $address->addAttribute('format', 'simple'); + + $component = $address->addChild('component', htmlspecialchars(fillOnUndefined($metaAddress, 'street'), ENT_XML1, 'UTF-8')); + $component->addAttribute('name', 'addr1'); + + //$component = $address->addChild('component'); + //$component->addAttribute('name', 'addr2'); + + $component = $address->addChild('component', fillOnUndefined($metaAddress, 'city')); + $component->addAttribute('name', 'city'); + + //$component = $address->addChild('component', $propertyMapping['property']['country']['name']); + //$component->addAttribute('name','region'); + + $component = $address->addChild('component', fillOnUndefined($metaAddress, 'zip_code')); + $component->addAttribute('name', 'postal_code'); + + $listing->addChild('country', $propertyMapping['property']['country']['country_code']); + $listing->addChild('latitude', $propertyMapping['property']['property_contact']['latitude']); + $listing->addChild('longitude', $propertyMapping['property']['property_contact']['longitude']); + $listing->addChild('category', 'hotel'); + + } + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + header('Content-Type: application/xml; charset=UTF-8'); + echo $listings->asXML(); + exit; + + + } + + public function availability(Request $request) + { + + $response = ['status' => true, 'message' => '']; + + $checkAuthentication = $this->checkAuthentication($this->authorization); + if (!$checkAuthentication['status']) { + return $this->responseError($checkAuthentication['message']); + } + + $searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController"); + + $requestTime = microtime(true); + + + $param = $this->request->getContent(); + $paramXML = simplexml_load_string($param); + $requestParam = json_decode(json_encode($paramXML), 1); + + $hotelIdList = collect($requestParam['PropertyList']['Property'])->values(); + $hotelIdList = $hotelIdList ? $hotelIdList->toArray() : []; + + $transaction = new \SimpleXMLElement(''); + + try { + + + //Hotels Check + $channelManagerPropertyList = []; + $channelManagerPropertyMappingCriteria['criteria'] = [ + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ]; + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + $channelManagerPropertyList = pickItemFromArray('property_id', $channelManagerPropertyMapping['data']); + } + + $availableHotelIds = array_intersect($hotelIdList, $channelManagerPropertyList); + + if (empty($availableHotelIds)) { + throw new ApiErrorException('Hotel not found'); + } + //Hotels Check + + $searchRequestJson = $this->requestParamConverter($requestParam); + + + $searchRequestJson['isMobile'] = null; + $searchRequestJson['noneCacheSearch'] = true; + $searchRequestJson['ipAddress'] = $request->getClientIp(); + $searchRequestJson['justPriceValues'] = true; + $searchRequestJson['locale'] = fillOnUndefined($requestParam, 'Locale') ?? 'tr'; + + $roomOccupancy = $this->roomOccupancy($searchRequestJson['rooms']); + $roomOccupancy = implode(',', $roomOccupancy); + + + $requestCurrency = fillOnUndefined($requestParam, 'Currency') ?? 'TRY'; + + + $cacheKeyParam = $requestCurrency . ':' . $searchRequestJson['date']['checkIn'] . ':' . $searchRequestJson['date']['checkOut'] . ':' . implode(',', $searchRequestJson['property']) . ':' . $roomOccupancy; + $cacheKey = 'YND:' . md5($cacheKeyParam); + + //Cache::forget($cacheKey); + + if (Cache::has($cacheKey)) { + $search = Cache::get($cacheKey); + } else { + $requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson)); + $requestCreate->headers->set('channelId', '1'); + //$requestCreate->headers->set('bookingEnginePropertyId', null); + $requestCreate->headers->set('channelToken', 'ece3ef02-42e7-92b7-f379-08226ed7a0f3');//TODO: from DB + $requestCreate->headers->set('bookingEngineToken', null); + $search = $searchController->search($requestCreate); + + Cache::put($cacheKey, $search, 60 * 60);//1 Day 24 * 60 * 60 + } + + $search = json_decode(json_encode($search), 1); + + if ($search['original']['status'] != 200) { + throw new ApiErrorException('Hotel not found'); + } + + $properties = $search['original']['data']['properties']; + + if (empty($properties)) { + throw new ApiErrorException('Hotel not found'); + } + + $hotelCounter = 0; + $numberOfStay = Carbon::parse($searchRequestJson['date']['checkIn'])->diffInDays(Carbon::parse($searchRequestJson['date']['checkOut'])); + + foreach ($properties as $propertyId => $property) { + + $propertyName = $property['name']; + + if (!isset($property['currency'])) { + continue; + } + + $currencyExchangeRate = 1; + if ($requestCurrency != $property['currency']) { + $currencyExchangeRate = $this->currencyService->lastExchangeRate($property['currency'], $requestCurrency); + if ($currencyExchangeRate['status'] == 'success') { + $currencyExchangeRate = $currencyExchangeRate['data']; + } + } + + $token = $property['booking_engine_token']; + $deepLinkGenerator = $this->deepLinkGenerator($token, $searchRequestJson); + + + $property = reset($property['availabilities']); + $propertyRooms = $property['rooms']; + + //Standard Room Room Only FreeCancellation - Pay at Hotel + + + $requestedRoomPriceGroup = []; + foreach ($propertyRooms as $propertyRoomId => $propertyRoom) { + + foreach ($propertyRoom['rates'] as $propertyRoomRateId => $propertyRoomRate) { + + foreach ($propertyRoomRate['requestedRoomPrice'] as $occupancyCode => $requestedRoomPrices) { + + foreach ($requestedRoomPrices['prices'] as $requestedRoomPriceKey => $requestedRoomPrice) { + + $roomRateKeyName = $occupancyCode . ' ' . $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name']; + $roomRateKeycode = $requestedRoomPrice['rate']['accommodationCode'] . '|' . (isset($requestedRoomPrice['cancellationPolicy']['id']) ? $requestedRoomPrice['cancellationPolicy']['id'] : 0) . '|' . $requestedRoomPrice['bookingPaymentType']['code']; + + //$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $roomRateKeyName . '-' . $requestedRoomPrice['rateKeyCode']; + $requestedRoomPrice['dailyAverageDiscount'] = $requestedRoomPrices['dailyAverageDiscount']; + $requestedRoomPriceGroup[] = $requestedRoomPrice; + + } + + } + + } + } + + if (!empty($requestedRoomPriceGroup)) { + $requestedRoomPriceGroup = collect($requestedRoomPriceGroup)->sortBy('total')->toArray(); + } + + $requestedRoomPrice = reset($requestedRoomPriceGroup); + + + $propertyCouponCodeCheck = $this->couponCodeCheck($propertyId, $searchRequestJson['date']['checkIn'], $searchRequestJson['date']['checkOut']); + if ($propertyCouponCodeCheck) { + + $requestedRoomPrice['totalWithoutPopup'] = $requestedRoomPrice['total']; + + $couponPercentageValue = (100 - $propertyCouponCodeCheck['value']) / 100; + $requestedRoomPrice['total'] = moneyDoubleFormatDecimal($requestedRoomPrice['total'] * $couponPercentageValue); + + } + + + $transactionResult = $transaction->addChild('Result'); + + $transactionResult->addChild('Property', $propertyId); + $transactionResult->addChild('Checkin', $searchRequestJson['date']['checkIn']); + $transactionResult->addChild('Nights', $numberOfStay); + + + $taxValue = $requestedRoomPrice['total'] * ($this->tax / 100); + $baseTotalValue = $requestedRoomPrice['total'] - $taxValue; + $netTotalValue = ($taxValue + $baseTotalValue); + + $baseRate = $transactionResult->addChild('Baserate', moneyDoubleFormatDecimal($baseTotalValue * $currencyExchangeRate)); + $baseRate->addAttribute('currency', $requestCurrency); + + $tax = $transactionResult->addChild('Tax', moneyDoubleFormatDecimal($taxValue * $currencyExchangeRate)); + $tax->addAttribute('currency', $requestCurrency); + + $otherFees = $transactionResult->addChild('OtherFees', 0); + $otherFees->addAttribute('currency', $requestCurrency); + + $transactionResult->addChild('Custom1', htmlspecialchars($propertyName, ENT_XML1, 'UTF-8')); + + $allowablePointsOfSale = $transactionResult->addChild('AllowablePointsOfSale'); + $pointOfSale = $allowablePointsOfSale->addChild('PointOfSale'); + $pointOfSale->addAttribute('id', 'default'); + + $pointOfSale->addChild('URL', htmlspecialchars($deepLinkGenerator, ENT_XML1, 'UTF-8')); + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + header('Content-Type: application/xml; charset=UTF-8'); + echo $transaction->asXML(); + exit; + + + } + + +} diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php new file mode 100644 index 0000000..9463ac3 --- /dev/null +++ b/app/Http/Controllers/PaymentController.php @@ -0,0 +1,257 @@ +propertyPaymentService = $propertyPaymentService; + $this->mailer = $mailer; + } + + public function initializePayment(Request $request) + { + + /* + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($this->request->getContent(), 1); + + + dd($params); + + + $responseData = [ + 'bookingCode' => $bookingCode, + 'total' => $totalRoomsPrice, + 'currency' => $currencyCode + ]; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + */ + + + } + + public function paymentRedirect(Request $request, $paymentCode) + { + + $response = ['status' => false, 'message' => '']; + + try { + + $paymentTransaction = $this->propertyPaymentService->getPaymentTransactionDetail($paymentCode); + + if (!$paymentTransaction['status']) { + throw new ApiErrorException($paymentTransaction['message']); + } + + $paymentTransaction = $paymentTransaction['data']; + + if ($paymentTransaction['status'] == 1) { + return redirect()->to($paymentTransaction['paramsArray']['responseUrl']); + } + + //Set Redirect Status + $this->propertyPaymentService->updatePaymentTransaction($paymentTransaction['id'], ['status' => 3]); + + if ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'POS') { + + + //TODO: Burada PAN replace edilecek + //$this->propertyPaymentService->updatePaymentTransaction($paymentTransaction['id'], ['status' => 3]); + + $formData = $paymentTransaction['extraParamsArray']; + return view('threeDSecureForm', compact('formData')); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'STR') { + + if (isset($paymentTransaction['extraParamsArray']['redirect']['url'])) { + return redirect()->to($paymentTransaction['extraParamsArray']['redirect']['url']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'ENW') { + + if (isset($paymentTransaction['extraParamsArray']['redirect']['url'])) { + return redirect()->to($paymentTransaction['extraParamsArray']['redirect']['url']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'SPY') { + + $formData = $paymentTransaction['extraParamsArray']; + return view('threeDSecureForm', compact('formData')); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'MOK') { + + if (isset($paymentTransaction['extraParamsArray'])) { + return redirect()->to($paymentTransaction['extraParamsArray']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'BOG') { + + $redirectUrl = collect($paymentTransaction['extraParamsArray']['links'])->where('method', 'REDIRECT')->first(); + + if (isset($redirectUrl['href'])) { + return redirect()->to($redirectUrl['href']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'TBC') { + + $redirectUrl = collect($paymentTransaction['extraParamsArray']['links'])->where('method', 'REDIRECT')->first(); + + if (isset($redirectUrl['uri'])) { + return redirect()->to($redirectUrl['uri']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'QNB') { + + $formData = $paymentTransaction['extraParamsArray']; + return view('threeDSecureForm', compact('formData')); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'WEE') { + + if (isset($paymentTransaction['extraParamsArray']['threeDSecureUrl'])) { + return redirect()->to($paymentTransaction['extraParamsArray']['threeDSecureUrl']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'HLK') { + + $formData = $paymentTransaction['extraParamsArray']; + return view('threeDSecureForm', compact('formData')); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'ESN') { + + if (isset($paymentTransaction['extraParamsArray']['URL_3DS'])) { + return redirect()->to($paymentTransaction['extraParamsArray']['URL_3DS']); + } + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'KVY') { + + $formData = $paymentTransaction['extra_params']; + echo $formData; die(); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'RTL') { + + $extraParams = json_decode($paymentTransaction['extra_params'],1); + echo $extraParams['form3d_html']; die(); + + } elseif ($paymentTransaction['payment_type_mapping']['payment_type']['pos_code'] == 'PYR') { + + $redirectUrl = $paymentTransaction['extraParamsArray']['payload']; + + if (isset($redirectUrl['paymentUrl'])) { + return redirect()->to($redirectUrl['paymentUrl']); + } + + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + + //TODO: Burada bir yere yönlendirilmeli + dd($response); + + + } + + public function paymentCheck(Request $request, $paymentCode) + { + + $responseData = ['status' => false]; + + try { + + $checkPayment = $this->propertyPaymentService->checkPayment($paymentCode, $request->all()); + + $responseData['paymentCode'] = $checkPayment['data']['paymentCode']; + + if ($checkPayment['status']) { + $responseData['status'] = true; + $responseData['bankOrderId'] = $checkPayment['data']['bankOrderId']; + } else { + $responseData['message'] = $checkPayment['message']; + } + + if (isset($checkPayment['data']['paymentTransactionDetail']['property'])) { + $responseData['paymentTransactionDetail']['amount'] = $checkPayment['data']['paymentTransactionDetail']['amount']; + $responseData['paymentTransactionDetail']['currency'] = $checkPayment['data']['paymentTransactionDetail']['currency']; + $responseData['paymentTransactionDetail']['message'] = $checkPayment['data']['paymentTransactionDetail']['message']; + $responseData['property'] = $checkPayment['data']['paymentTransactionDetail']['property']; + } + + //$logMessage + $mailParams = [ + 'title' => 'PaymentCheck', + 'logMessage' => '
' . print_r($responseData, true) . '
' + ]; + + $this->mailer->onQueue( + 'logMail', + new LogMail($mailParams) + ); + //$logMessage + + } catch (ApiErrorException $e) { + $responseData['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $responseData['message'] = $e->getMessage(); + } + + return redirect()->to($checkPayment['data']['responseUrl']); + + + } + + +} diff --git a/app/Http/Controllers/TestController.php b/app/Http/Controllers/TestController.php new file mode 100644 index 0000000..779bbb3 --- /dev/null +++ b/app/Http/Controllers/TestController.php @@ -0,0 +1,491 @@ +exampleValidator = $exampleValidator; + $this->propertyFactAttributeRepository = $propertyFactAttributeRepository; + $this->propertyUnitRepository = $propertyUnitRepository; + + $this->propertyPaymentService = $propertyPaymentService; + $this->newBookingMailService = $newBookingMailService; + $this->mailer = $mailer; + + $this->notificationService = $notificationService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + + $this->manualPaymentMailService = $manualPaymentMailService; + } + + + public function testResponse(Request $request) + { + + $inputAll = $request->input(); + + dd($inputAll); + + Log::debug(json_encode($inputAll)); + + $response = [ + 'success' => true + ]; + + return response()->json($response); + + dd($inputAll); + + + $publishableKey = 'pk_test_51HuYHvEa9cmPdLq3cIxkIJ2y6EtTL1mSuPKKbtSJuMemCaLW49h8lPhVINB0ju8MvYDwM45cxk1oFpz8EoMpVpum00Rw3qKohb'; + $secretKey = 'sk_test_51HuYHvEa9cmPdLq3ANG7ZYaGB9zMuhQZlwH19axJRauZsMnnpnuGBN1h8iAfr9kNVWe4FWcEcvZiMjn3hhBELHHx00hiBgjO41'; + + try { + + //Secret key + $stripe = new \Stripe\StripeClient($secretKey); + + + $charge = $stripe->charges->create([ + 'currency' => 'EUR', + 'amount' => 120,//10.20 + 'source' => $inputAll['source'] + ]); + + dd($inputAll, $charge); + + if ($charge['status'] == 'succeeded') { + + } + + } catch (\Exception $e) { + dd($e->getMessage()); + } + + dd($inputAll); + + + $account = [ + 'bank' => 'akbank', + 'model' => '3d_pay', + 'client_id' => '100200000', + 'store_key' => '123456', + 'env' => 'test', // test veya production. test ise; API Test Url, production ise; API Production URL kullanılır. + ]; + + + $pos = new \App\Core\Payment\Pos\Pos($account); + + $orderParams = Cache::get($request->input('oid')); + + + $pos->prepare($orderParams); + $payment = $pos->payment(); + + dd($payment, $payment->response, $payment->response->status, $payment->response->code); + + $response = $payment->response; + + dd($response, $request->input()); + + + } + + public function test(Request $request) + { + + $inputAll = $request->input(); + + + try { + + + /*$path = resource_path('data/data.json'); + $json = file_get_contents($path); + $summaryReportData = json_decode($json, true); + + $this->mailer->onQueue('dailyReportMail', new DailyReportMail($summaryReportData)); + + die();*/ + + //$mailParams = ['booking_id' => 72027]; + //$this->newBookingMailService->process($mailParams); + + die(); + + $initializePaymentParam = [ + 'propertyId' => 1, + 'orderId' => getCodeGenerate(), + 'installment' => 0, + 'amount' => (double)1.25, + 'currency' => 'AZN', + 'responseUrl' => 'http://api.extranetwork.local/testResponse', + 'preferredPaymentTypeId' => 606, + 'ipAddress' => $request->getClientIp(), + /*'creditCard' => [ + 'name' => 'Test Card', + 'number' => '4000007546012078', + 'month' => '04', + 'year' => '2028', + 'cvv' => '236', + ]*/ + ]; + + //dd($initializePaymentParam); + + //4938460158754205 2024/11 715 123456 + //4119790155203496 2024/04 579 + + $initializePayment = $this->propertyPaymentService->initializePayment($initializePaymentParam); + + dd($initializePayment); + + die(); + + $param = [ + 'property_id' => 1805, + 'subject' => '🛎️ ' . __('notification-new_booking', [], 'en'), + 'message' => __('notification-new_booking_desc', ['hotel_name' => 'Seres Hotel', 'amount' => 198.45, 'currency' => 'EUR'], 'en'), + ]; + + Notification::route('OneSignal', null)->notify(new PushNotificationPropertyUser($param)); + + die(); + + $mailParams = ['booking_id' => 71740]; + $this->newBookingMailService->process($mailParams); + + + $propertyProductOfferMail = [ + 'offerKey' => '6c0d6ee7-c378-4859-9603-7967ede0e120' + ]; + + $this->mailer->onQueue('propertyProductOfferMail', new PropertyProductOfferMail($propertyProductOfferMail)); + + + // + + + //$newBookingNotificationParam = ['booking_id' => 63012]; + //$this->notificationService->sendNewBookingNotification($newBookingNotificationParam); + //PUSH NOTIFICATION + + die(); + + + /*$report = json_decode('{"name":"Cemile Ays\u0131n ARIKAN","email":"cemile@extranetwork.com","daily":{"data":{"1258":{"id":1258,"name":"Rayelin Hotel Istanbul Old City","count":3,"total":1504.2399999999998,"commission":225.63599999999997},"580":{"id":580,"name":"\u00d6zkaymak Falez Hotel","count":1,"total":1054.7,"commission":158.205},"1007":{"id":1007,"name":"T\u00fcrkay Hotel","count":1,"total":226.59912,"commission":27.191894400000002}},"title":"Daily Report","type":"daily","period":"20.01.2025","summary":{"count":5,"total":2785.5391199999995,"commission":411.03289440000003}},"monthly":{"data":{"1258":{"id":1258,"name":"Rayelin Hotel Istanbul Old City","count":13,"total":8061.37,"commission":1209.2054999999998},"580":{"id":580,"name":"\u00d6zkaymak Falez Hotel","count":6,"total":3558.55,"commission":533.7825},"1007":{"id":1007,"name":"T\u00fcrkay Hotel","count":3,"total":1301.88312,"commission":156.2259744},"1205":{"id":1205,"name":"Duck Otel","count":7,"total":386.2046399999999,"commission":57.93069599999999}},"title":"Monthly Report","type":"monthly","period":"01.2025","summary":{"count":29,"total":13308.00776,"commission":1957.1446703999998}},"annually":{"data":{"1258":{"id":1258,"name":"Rayelin Hotel Istanbul Old City","count":13,"total":8061.37,"commission":1209.2054999999998},"580":{"id":580,"name":"\u00d6zkaymak Falez Hotel","count":6,"total":3558.55,"commission":533.7825},"1007":{"id":1007,"name":"T\u00fcrkay Hotel","count":3,"total":1301.88312,"commission":156.2259744},"1205":{"id":1205,"name":"Duck Otel","count":7,"total":386.2046399999999,"commission":57.93069599999999}},"title":"Annually Report","type":"annually","period":"2025","summary":{"count":29,"total":13308.00776,"commission":1957.1446703999998}},"activeProperty":[{"id":1258,"name":"Rayelin Hotel Istanbul Old City","commission":15,"year":"2024","month":"2024-12","contract_user_id":22},{"id":1205,"name":"Duck Otel","commission":15,"year":"2024","month":"2024-08","contract_user_id":22},{"id":1007,"name":"T\u00fcrkay Hotel","commission":12,"year":"2024","month":"2024-02","contract_user_id":22},{"id":580,"name":"\u00d6zkaymak Falez Hotel","commission":15,"year":"2022","month":"2022-11","contract_user_id":22}]}',1); + $this->mailer->onQueue('dailyReportSalesMail', new DailyReportMailSales($report)); + + die();*/ + + + } catch (Exception $e) { + dd($e->getMessage()); + Log::debug($e->getMessage()); + } + + + die(); + + //$summaryReportData = json_decode('{"daily":{"data":{"EUR":{"count":9,"total":2080.9900000000002,"commission":240.5208},"GEL":{"count":4,"total":958.6600000000001,"commission":24.5828},"TRY":{"count":1,"total":27000,"commission":4050}},"title":"Daily Report","period":"11.12.2024","summary":{"count":14,"total":3140.391492,"commission":359.35053736000003}},"monthly":{"data":{"EUR":{"count":98,"total":32560.43,"commission":3690.2600999999995},"GEL":{"count":81,"total":39810.82000000001,"commission":1132.786},"TRY":{"count":24,"total":151606.96,"commission":21772.044}},"title":"Monthly Report","period":"12.2024","summary":{"count":203,"total":50083.697692,"commission":4665.479554399999},"summaryCheckoutData":{"EUR":{"count":202,"total":59142.93000000001,"commission":5871.0608},"GEL":{"count":101,"total":41661.039999999986,"commission":1358.6717999999996},"TRY":{"count":31,"total":257321.56,"commission":38041.734000000004},"USD":{"count":2,"total":120,"commission":14.4}},"summaryCheckout":{"count":336,"total":80288.454236,"commission":7380.090077360001}},"annually":{"data":{"EUR":{"count":3711,"total":1805925.850000003,"commission":197665.67849999937},"GEL":{"count":1841,"total":1037083.2200000021,"commission":30233.390399999997},"TRY":{"count":335,"total":2973705.5399999996,"commission":387296.1086999998},"USD":{"count":37,"total":5649.07,"commission":677.8884000000002},"GBP":{"count":20,"total":18908.2,"commission":2268.9840000000004}},"title":"Annually Report","period":"2024","summary":{"count":5944,"total":2264081.583865003,"commission":221800.07140706936}},"activeProperty":{"count":145,"groupByMonth":{"2024-12":[{"id":1310,"name":"Hope Sapanca Tiny House","commission":15,"year":"2024","month":"2024-12"},{"id":1216,"name":"Hub Inn Pera ","commission":15,"year":"2024","month":"2024-12"},{"id":1224,"name":"Aria Claros Beach & Spa Resort","commission":15,"year":"2024","month":"2024-12"},{"id":1258,"name":"Rayelin Hotel Istanbul Old City","commission":15,"year":"2024","month":"2024-12"},{"id":1218,"name":"StayHub","commission":15,"year":"2024","month":"2024-12"},{"id":1242,"name":"Tusan Beach Resort","commission":15,"year":"2024","month":"2024-12"},{"id":1304,"name":"Litros Hotel & Spa","commission":15,"year":"2024","month":"2024-12"},{"id":1308,"name":"Rayelin Hotel Old Town","commission":15,"year":"2024","month":"2024-12"}],"2024-11":[{"id":1281,"name":"Hotel Atina Budva","commission":15,"year":"2024","month":"2024-11"},{"id":1277,"name":"Villa La Barba","commission":15,"year":"2024","month":"2024-11"},{"id":1275,"name":"S\u00f6\u011f\u00fct Hotel Old City","commission":15,"year":"2024","month":"2024-11"},{"id":1273,"name":"The Riada Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1269,"name":"Hotel Del Lago Luxury by Sara\u00e7o\u011flu","commission":15,"year":"2024","month":"2024-11"},{"id":1293,"name":"Blue Ottoman Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1303,"name":"Zelve Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1276,"name":"Grand S Hotel","commission":15,"year":"2024","month":"2024-11"}],"2024-10":[{"id":1244,"name":"B Hotel Bishkek","commission":15,"year":"2024","month":"2024-10"},{"id":1247,"name":"Keten Suites Taksim","commission":15,"year":"2024","month":"2024-10"},{"id":1246,"name":"Ankara Santral Otel","commission":15,"year":"2024","month":"2024-10"},{"id":1253,"name":"Kazda\u011flar\u0131 Allia Thermal Health & Spa","commission":12,"year":"2024","month":"2024-10"},{"id":1249,"name":"Cartoon Hotel","commission":15,"year":"2024","month":"2024-10"},{"id":1267,"name":"Ottoman Hotel Sakarya","commission":15,"year":"2024","month":"2024-10"},{"id":1260,"name":"Monark Hotel Cappadocia","commission":12,"year":"2024","month":"2024-10"}],"2024-09":[{"id":1215,"name":"Hub Suite \u0130stanbul","commission":15,"year":"2024","month":"2024-09"},{"id":1229,"name":"Qlus\u0131ve Hotel","commission":15,"year":"2024","month":"2024-09"},{"id":1231,"name":"Credo Hotel Kotor","commission":15,"year":"2024","month":"2024-09"}],"2024-08":[{"id":1208,"name":"Vicolo Otel","commission":15,"year":"2024","month":"2024-08"},{"id":1205,"name":"Duck Otel","commission":15,"year":"2024","month":"2024-08"},{"id":1203,"name":"Expo Park Hotel","commission":15,"year":"2024","month":"2024-08"},{"id":1200,"name":"Sierra Cave Cappadocia Hotel","commission":15,"year":"2024","month":"2024-08"},{"id":1196,"name":"Lubberona Cave Cappadocia","commission":15,"year":"2024","month":"2024-08"},{"id":1184,"name":"Elephant In The Room Hotel","commission":15,"year":"2024","month":"2024-08"}],"2024-07":[{"id":1166,"name":"Alice Hotel Antalya","commission":15,"year":"2024","month":"2024-07"},{"id":1180,"name":"Keremk\u00f6y Ya\u015fam Platosu","commission":10,"year":"2024","month":"2024-07"},{"id":1170,"name":"Hotel Berke Ranch & Nature","commission":15,"year":"2024","month":"2024-07"}],"2024-06":[{"id":1150,"name":"Konyaalt\u0131 Furkan Family","commission":15,"year":"2024","month":"2024-06"}],"2024-05":[{"id":1125,"name":"Petra Hotel Trabzon","commission":15,"year":"2024","month":"2024-05"}],"2024-04":[{"id":1103,"name":"New Wave 2 Apart-Hotel","commission":12,"year":"2024","month":"2024-04"},{"id":1102,"name":"Cappadocia Villa Comfort Hotel","commission":15,"year":"2024","month":"2024-04"},{"id":1098,"name":"Batumi Palm Hotel","commission":12,"year":"2024","month":"2024-04"},{"id":1091,"name":"Nehir Suit Hotel","commission":15,"year":"2024","month":"2024-04"},{"id":1090,"name":"Mera Park Otel","commission":15,"year":"2024","month":"2024-04"},{"id":1082,"name":"Very Peri Cappadocia ","commission":12,"year":"2024","month":"2024-04"},{"id":1081,"name":"La Vie Cappadocia Cave Hotel","commission":12,"year":"2024","month":"2024-04"}],"2024-03":[{"id":1048,"name":"Side Crown Serenity","commission":15,"year":"2024","month":"2024-03"},{"id":1047,"name":"Side Crown Palace","commission":15,"year":"2024","month":"2024-03"},{"id":1076,"name":"Alia Cave Hotel","commission":9,"year":"2024","month":"2024-03"},{"id":1073,"name":"Mithra Cave Hotel","commission":9,"year":"2024","month":"2024-03"},{"id":1075,"name":"Misty Cave Hotel","commission":9,"year":"2024","month":"2024-03"}],"2024-02":[{"id":1020,"name":"Gamirasu Junior","commission":15,"year":"2024","month":"2024-02"},{"id":1007,"name":"T\u00fcrkay Hotel","commission":12,"year":"2024","month":"2024-02"},{"id":1008,"name":"Tamara Business Antalya","commission":12,"year":"2024","month":"2024-02"},{"id":1010,"name":"Tamara Business Hotel Van","commission":12,"year":"2024","month":"2024-02"},{"id":1011,"name":"Utopia Cave Cappadocia","commission":15,"year":"2024","month":"2024-02"},{"id":1025,"name":"Hotel Monarch Batumi","commission":12,"year":"2024","month":"2024-02"},{"id":1031,"name":"La Perla Cave Cappadocia","commission":15,"year":"2024","month":"2024-02"},{"id":1024,"name":"Hotel Mandalin","commission":15,"year":"2024","month":"2024-02"},{"id":1033,"name":"Saliche Cave Suits","commission":15,"year":"2024","month":"2024-02"},{"id":1034,"name":"Cappadocia Hobbit House","commission":15,"year":"2024","month":"2024-02"},{"id":1035,"name":"Hotel Salvador","commission":12,"year":"2024","month":"2024-02"}],"2024-01":[{"id":1006,"name":"Can Adalya Palace Hotel","commission":12,"year":"2024","month":"2024-01"},{"id":989,"name":"Tantan Cappadocia House","commission":15,"year":"2024","month":"2024-01"},{"id":984,"name":"Cappanar Cave","commission":15,"year":"2024","month":"2024-01"},{"id":983,"name":"Yunak Evleri","commission":9,"year":"2024","month":"2024-01"},{"id":982,"name":"Enjoy Stone House","commission":12,"year":"2024","month":"2024-01"},{"id":981,"name":"Sabiha Sultan Hotel","commission":12,"year":"2024","month":"2024-01"}],"2023-12":[{"id":955,"name":"My Adress Ala\u00e7at\u0131 Otel","commission":15,"year":"2023","month":"2023-12"},{"id":966,"name":"Arya Apart Kundu","commission":15,"year":"2023","month":"2023-12"},{"id":961,"name":"Lorem Hotel","commission":15,"year":"2023","month":"2023-12"},{"id":956,"name":"Alt\u0131noluk Lambada Otel","commission":15,"year":"2023","month":"2023-12"}],"2023-11":[{"id":934,"name":"Transatlantik Hotel & SPA","commission":15,"year":"2023","month":"2023-11"},{"id":944,"name":"Transatlantik Beach Hotel","commission":15,"year":"2023","month":"2023-11"},{"id":928,"name":"Daima Biz Hotel","commission":12,"year":"2023","month":"2023-11"}],"2023-10":[{"id":911,"name":"All Seasons Suites","commission":10,"year":"2023","month":"2023-10"},{"id":909,"name":"All Seasons Hotel","commission":10,"year":"2023","month":"2023-10"},{"id":907,"name":"Grand Hotel G\u00fclsoy","commission":15,"year":"2023","month":"2023-10"},{"id":901,"name":"Emerald Hotel","commission":12,"year":"2023","month":"2023-10"},{"id":912,"name":"Grand Ons Hotel","commission":15,"year":"2023","month":"2023-10"}],"2023-09":[{"id":872,"name":"La Rezidans Hotel","commission":15,"year":"2023","month":"2023-09"}],"2023-08":[{"id":848,"name":"Green Glass Hotel","commission":12,"year":"2023","month":"2023-08"}],"2023-07":[{"id":808,"name":"Nok \u0130stanbul Suites","commission":15,"year":"2023","month":"2023-07"}],"2023-06":[{"id":772,"name":"Cronton Design Hotel","commission":15,"year":"2023","month":"2023-06"},{"id":790,"name":"New Wave Hotel ","commission":12,"year":"2023","month":"2023-06"}],"2023-05":[{"id":738,"name":"VONRESORT Abant","commission":15,"year":"2023","month":"2023-05"},{"id":729,"name":"\u00d6zkaymak Select Resort Hotel","commission":15,"year":"2023","month":"2023-05"},{"id":728,"name":"Lara Din\u00e7 Hotel","commission":15,"year":"2023","month":"2023-05"},{"id":743,"name":"Hotel Luna Antalya","commission":12,"year":"2023","month":"2023-05"},{"id":755,"name":"Hotel Chao","commission":12,"year":"2023","month":"2023-05"},{"id":759,"name":"The Nest Hotel","commission":15,"year":"2023","month":"2023-05"}],"2023-04":[{"id":692,"name":"Orka Royal Hotel & Spa","commission":12,"year":"2023","month":"2023-04"},{"id":696,"name":"Mielo Lara Hotel","commission":15,"year":"2023","month":"2023-04"},{"id":693,"name":"Orient Express & Spa by Orka Hotels","commission":12,"year":"2023","month":"2023-04"},{"id":694,"name":"Pianoforte by Febor Hotels&Spa","commission":12,"year":"2023","month":"2023-04"},{"id":695,"name":"Orka Taksim Suites & Hotel","commission":12,"year":"2023","month":"2023-04"},{"id":726,"name":"\u00d6zkaymak Otem Hotel","commission":15,"year":"2023","month":"2023-04"},{"id":698,"name":"Febor Park Hotel","commission":12,"year":"2023","month":"2023-04"},{"id":699,"name":"Lara Kapris Otel","commission":15,"year":"2023","month":"2023-04"},{"id":712,"name":"G Hotels Skopje","commission":15,"year":"2023","month":"2023-04"},{"id":721,"name":"\u00d6zkaymak \u0130ncekum Hotel","commission":15,"year":"2023","month":"2023-04"},{"id":724,"name":"\u00d6zkaymak Marina Hotel","commission":15,"year":"2023","month":"2023-04"}],"2023-03":[{"id":684,"name":"Alfa Cave Hotel","commission":15,"year":"2023","month":"2023-03"},{"id":681,"name":"The Calypso Cave","commission":15,"year":"2023","month":"2023-03"}],"2023-02":[{"id":665,"name":"Endless Flats","commission":12,"year":"2023","month":"2023-02"},{"id":671,"name":"Bilgehan Hotel","commission":9,"year":"2023","month":"2023-02"},{"id":668,"name":"Sim Hotel","commission":12,"year":"2023","month":"2023-02"}],"2023-01":[{"id":629,"name":"Endless Comfort Hotel","commission":10,"year":"2023","month":"2023-01"},{"id":628,"name":"Endless Suites Taksim","commission":10,"year":"2023","month":"2023-01"},{"id":644,"name":"VONRESORT Golden Coast","commission":15,"year":"2023","month":"2023-01"},{"id":643,"name":"VONRESORT Elite","commission":15,"year":"2023","month":"2023-01"},{"id":645,"name":"VONRESORT Golden Beach","commission":15,"year":"2023","month":"2023-01"}],"2022-12":[{"id":623,"name":"WOW Airport Hotel","commission":15,"year":"2022","month":"2022-12"},{"id":605,"name":"Oksijen Zone Hotel & Spa","commission":15,"year":"2022","month":"2022-12"},{"id":591,"name":"WOW \u0130stanbul Hotel","commission":15,"year":"2022","month":"2022-12"}],"2022-11":[{"id":580,"name":"\u00d6zkaymak Falez Hotel","commission":15,"year":"2022","month":"2022-11"},{"id":529,"name":"Green Nature Resort & Spa Otel","commission":12,"year":"2022","month":"2022-11"}],"2022-10":[{"id":506,"name":"Green Nature Diamond Hotel","commission":12,"year":"2022","month":"2022-10"},{"id":503,"name":"Elegance Hotels International","commission":12,"year":"2022","month":"2022-10"}],"2022-08":[{"id":450,"name":"Bilem Hotel Beach & Spa","commission":15,"year":"2022","month":"2022-08"}],"2022-07":[{"id":430,"name":"Invite Hotel Corner Trabzon","commission":15,"year":"2022","month":"2022-07"}],"2022-05":[{"id":400,"name":"Elanaz Hotel","commission":12,"year":"2022","month":"2022-05"}],"2022-04":[{"id":384,"name":"Albinas Hotel Old City","commission":12,"year":"2022","month":"2022-04"}],"2022-03":[{"id":366,"name":"Sealife Royal Suites","commission":10,"year":"2022","month":"2022-03"},{"id":368,"name":"Sultan Hostel & Guesthouse","commission":12,"year":"2022","month":"2022-03"}],"2022-02":[{"id":362,"name":"Bar\u0131n Hotel","commission":12,"year":"2022","month":"2022-02"}],"2022-01":[{"id":346,"name":"G\u00fcner Business Hotel","commission":12,"year":"2022","month":"2022-01"}],"2021-12":[{"id":317,"name":"Lalahan Hotel","commission":12,"year":"2021","month":"2021-12"},{"id":343,"name":"CitrusLuna Suite Hotel","commission":15,"year":"2021","month":"2021-12"},{"id":341,"name":"Harbiye Residence","commission":12,"year":"2021","month":"2021-12"},{"id":330,"name":"Radar Hotel","commission":12,"year":"2021","month":"2021-12"},{"id":326,"name":"Yavuz Otel","commission":12,"year":"2021","month":"2021-12"},{"id":319,"name":"\u0130lkay Hotel","commission":12,"year":"2021","month":"2021-12"},{"id":318,"name":"Hotellino","commission":12,"year":"2021","month":"2021-12"},{"id":316,"name":"Sirkeci Mansion Hotel","commission":9,"year":"2021","month":"2021-12"},{"id":314,"name":"Hotel \u015eahinler","commission":12,"year":"2021","month":"2021-12"},{"id":313,"name":"Levni Plus Hotel","commission":12,"year":"2021","month":"2021-12"}],"2021-10":[{"id":278,"name":"Gorrion Hotel Istanbul","commission":8,"year":"2021","month":"2021-10"}],"2021-08":[{"id":252,"name":"Tut Hotel","commission":12,"year":"2021","month":"2021-08"}],"2021-07":[{"id":249,"name":"Grand Ant Hotel","commission":12,"year":"2021","month":"2021-07"}],"2021-04":[{"id":236,"name":"Sealife Kemer Resort Hotel","commission":10,"year":"2021","month":"2021-04"}],"2020-11":[{"id":165,"name":"Sealife Lounge Hotel","commission":10,"year":"2020","month":"2020-11"},{"id":164,"name":"SeaLife Family Resort Hotel","commission":10,"year":"2020","month":"2020-11"},{"id":163,"name":"Porto Bello Hotel Resort & Spa","commission":10,"year":"2020","month":"2020-11"},{"id":166,"name":"Sealife Buket Beach & Resort","commission":10,"year":"2020","month":"2020-11"},{"id":168,"name":"Endless Art Hotel Special Category","commission":10,"year":"2020","month":"2020-11"}],"2020-08":[{"id":71,"name":"Grand Yavuz Hotel","commission":15,"year":"2020","month":"2020-08"}]},"lastMonth":{"2024-12":[{"id":1310,"name":"Hope Sapanca Tiny House","commission":15,"year":"2024","month":"2024-12"},{"id":1216,"name":"Hub Inn Pera ","commission":15,"year":"2024","month":"2024-12"},{"id":1224,"name":"Aria Claros Beach & Spa Resort","commission":15,"year":"2024","month":"2024-12"},{"id":1258,"name":"Rayelin Hotel Istanbul Old City","commission":15,"year":"2024","month":"2024-12"},{"id":1218,"name":"StayHub","commission":15,"year":"2024","month":"2024-12"},{"id":1242,"name":"Tusan Beach Resort","commission":15,"year":"2024","month":"2024-12"},{"id":1304,"name":"Litros Hotel & Spa","commission":15,"year":"2024","month":"2024-12"},{"id":1308,"name":"Rayelin Hotel Old Town","commission":15,"year":"2024","month":"2024-12"}],"2024-11":[{"id":1281,"name":"Hotel Atina Budva","commission":15,"year":"2024","month":"2024-11"},{"id":1277,"name":"Villa La Barba","commission":15,"year":"2024","month":"2024-11"},{"id":1275,"name":"S\u00f6\u011f\u00fct Hotel Old City","commission":15,"year":"2024","month":"2024-11"},{"id":1273,"name":"The Riada Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1269,"name":"Hotel Del Lago Luxury by Sara\u00e7o\u011flu","commission":15,"year":"2024","month":"2024-11"},{"id":1293,"name":"Blue Ottoman Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1303,"name":"Zelve Hotel","commission":15,"year":"2024","month":"2024-11"},{"id":1276,"name":"Grand S Hotel","commission":15,"year":"2024","month":"2024-11"}],"2024-10":[{"id":1244,"name":"B Hotel Bishkek","commission":15,"year":"2024","month":"2024-10"},{"id":1247,"name":"Keten Suites Taksim","commission":15,"year":"2024","month":"2024-10"},{"id":1246,"name":"Ankara Santral Otel","commission":15,"year":"2024","month":"2024-10"},{"id":1253,"name":"Kazda\u011flar\u0131 Allia Thermal Health & Spa","commission":12,"year":"2024","month":"2024-10"},{"id":1249,"name":"Cartoon Hotel","commission":15,"year":"2024","month":"2024-10"},{"id":1267,"name":"Ottoman Hotel Sakarya","commission":15,"year":"2024","month":"2024-10"},{"id":1260,"name":"Monark Hotel Cappadocia","commission":12,"year":"2024","month":"2024-10"}]}}}',1); + //$this->mailer->onQueue('dailyReportMail', new DailyReportMail($summaryReportData)); + + //dd($summaryReportData); + + + //Log::debug($inputAll); + + + /*$newBookingNotificationParam = ['property_id' => 1]; + $this->notificationService->sendLogNotification($newBookingNotificationParam);*/ + + + /*$bookingPropertyAddonUpdateMail = [ + 'bookingCode' => 'BKG240814-OYS9A8DG' + ]; + $this->mailer->onQueue('bookingInvoiceUpdateMail', new BookingInvoiceUpdateMail($bookingPropertyAddonUpdateMail));*/ + + + /*$paymentDetailParam = [ + 'orderCode' => 'LNK230913-ALAXEATT', + 'language_code' => isset($params['language_code']) ? $params['language_code'] : 'en' + ]; + $this->manualPaymentMailService->process($paymentDetailParam);*/ + + + //$mailParams = ['booking_id' => 44264]; + //$this->newBookingMailService->process($mailParams); + //$this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($mailParams)); + //$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams)); + //dd('ds'); + + + //F5k8GvBkLQ22414131 + //Lucpc736tlh2414127 + //w9wAo95tftA2414111 - Success + + try { + + $initializePaymentParam = [ + 'propertyId' => 1, + 'orderId' => getCodeGenerate(), + 'installment' => 0, + 'amount' => (double)868.3199999999999, + 'currency' => 'TRY', + 'responseUrl' => 'http://api.extranetwork.local/testResponse', + 'preferredPaymentTypeId' => 325, + 'ipAddress' => $request->getClientIp(), + 'creditCard' => [ + 'name' => 'Burhan Yumak', + 'number' => '4938460158754205', + 'month' => '11', + 'year' => '2024', + 'cvv' => '715', + ] + ]; + + //4938460158754205 2024/11 715 123456 + //4119790155203496 2024/04 579 + + $initializePayment = $this->propertyPaymentService->initializePayment($initializePaymentParam); + + dd($initializePayment); + + + die(); + + //BookingPaymentDataCode + /*$mailParams = [ + 'user_id' => 1, + 'booking_id' => 978, + 'unlock_code' => 'KEOSXS', + //'locale' => 'en' + ]; + return new BookingPaymentDataCodeMail($mailParams); + die(); + $this->mailer->onQueue('bookingPaymentDataCode', new BookingPaymentDataCodeMail($mailParams));*/ + + + $paymentInfo = [ + "creditCard" => [ + "cardHolder" => "John Doe", + "cardNumber" => "5127541122223332", + "cardExpireMonth" => "12", + "cardExpireYear" => "2022", + "cardCvv" => "000", + "installment" => 0 + ] + ]; + + $cardNumber = $paymentInfo['creditCard']['cardNumber']; + $cardLengthSize = ceil(strlen($cardNumber) / 4); + + $cardNumberParse = []; + for ($i = 0; $i < $cardLengthSize; $i++) { + $cardNumberParse['cc'][] = Crypt::encrypt(mb_substr($cardNumber, $i * 4, 4)); + } + + $cardNumberParse['cm'] = Crypt::encrypt($paymentInfo['creditCard']['cardExpireMonth']); + $cardNumberParse['cy'] = Crypt::encrypt(mb_substr($paymentInfo['creditCard']['cardExpireYear'], -2, 2)); + $cardNumberParse['cv'] = Crypt::encrypt($paymentInfo['creditCard']['cardCvv']); + + dd($cardNumberParse, Crypt::decrypt($cardNumberParse['cm'])); + + dd(ceil(strlen($paymentInfo['creditCard']['cardNumber']) / 4)); + + $param = "3441"; + $x = Crypt::encrypt($param); + + dd($x, strlen($x), Crypt::decrypt($x)); + + die(); + $mailParams = ['booking_id' => 10117]; + $this->newBookingMailService->process($mailParams); + + die(); + + + $mailParams = []; + + $today = '2022-02-25'; + + + $report['daily']['data'] = []; + $report['daily']['title'] = 'Daily Report'; + $report['daily']['period'] = Carbon::parse($today)->format('d.m.Y'); + $daily = vwBookingSummary::where('time', '>', Carbon::parse($today)->toDateString()) + ->where('time', '<', Carbon::parse($today)->addDay()->toDateString()) + ->get()->toArray(); + + if ($daily) { + $dataCollect = collect($daily); + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['daily']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['daily']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + } + } + + + $report['monthly']['data'] = []; + $report['monthly']['title'] = 'Monthly Report'; + $report['monthly']['period'] = Carbon::parse($today)->firstOfMonth()->format('m.Y'); + $monthly = vwBookingSummary::where('time', '>', Carbon::parse($today)->firstOfMonth()->toDateString()) + ->where('time', '<', Carbon::parse($today)->addMonth()->firstOfMonth()->toDateString()) + ->get()->toArray(); + + if ($monthly) { + $dataCollect = collect($monthly); + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['monthly']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['monthly']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + } + } + + + $report['annually']['data'] = []; + $report['annually']['title'] = 'Annually Report'; + $report['annually']['period'] = Carbon::parse($today)->firstOfYear()->format('Y'); + $annually = vwBookingSummary::where('time', '>', Carbon::parse($today)->firstOfYear()->toDateString()) + ->where('time', '<', Carbon::parse($today)->addYear()->firstOfYear()->toDateString()) + ->get()->toArray(); + + if ($annually) { + $dataCollect = collect($annually); + $dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray(); + foreach ($dataCollectGroup as $currencyCode => $currencyGroup) { + $report['annually']['data'][$currencyCode]['count'] = count($currencyGroup); + $report['annually']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup)); + } + } + + + $this->mailer->onQueue('dailyReportMail', new DailyReportMail($report)); + + + die(); + + //Secret key + $secretKey = 'sk_test_51HuYHvEa9cmPdLq3ANG7ZYaGB9zMuhQZlwH19axJRauZsMnnpnuGBN1h8iAfr9kNVWe4FWcEcvZiMjn3hhBELHHx00hiBgjO41'; + $stripe = new \Stripe\StripeClient($secretKey); + + //$balance = $stripe->balance->retrieve(); + $balanceTransactions = $stripe->balanceTransactions->all(['limit' => 10]); + + + dd($balanceTransactions->toArray()); + + $token = $stripe->tokens->create([ + 'card' => [ + 'number' => $params['creditCard']['number'], + 'exp_month' => $params['creditCard']['month'], + 'exp_year' => $params['creditCard']['year'], + 'cvc' => $params['creditCard']['cvv'] + ], + ]); + + + die(); + + + //Bunu bookin sonrası ve booking iptali kısmına koyucaz + + //Connected Room Case + $roomAvailabilityUpdateForConnectedRoomParams = [ + 'property_id' => 1, + 'channel_id' => 1, + 'availability_type_id' => [1], + 'startDate' => '2022-01-18', + 'endDate' => '2022-01-25', + ]; + + $this->propertyRoomAvailabilityService->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams); + //Connected Room Case + + dd('ok'); + + $mailParams = ['booking_id' => 1134]; + $this->newBookingMailService->process($mailParams); + + throw new Exception('api-unknown_error'); + + + } catch (Exception $e) { + dd($e->getMessage()); + Log::debug($e->getMessage()); + } + + die(); + + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..6364665 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,845 @@ +request = $request; + $this->userService = $userService; + $this->tempPropertyService = $tempPropertyService; + $this->propertyService = $propertyService; + $this->userPropertyMappingService = $userPropertyMappingService; + $this->jwtService = $jwtService; + $this->applicationCacheService = $applicationCacheService; + $this->mailer = $mailer; + $this->apiAccessTokenService = $apiAccessTokenService; + $this->languageService = $languageService; + $this->productService = $productService; + $this->mondayService = $mondayService; + } + + public function getUserList() + { + + + /*$userListCriteria['criteria'] = []; + $userListCriteria['criteria'][] = ['field' => 'idate', 'condition' => '=', 'value' => 0]; + //$userListCriteria['firstRow'] = true; + $userListCriteria['skip'] = 0; //take *2 + $userListCriteria['take'] = 3; + $userListCriteria['orderBy'][] = ['field' => 'id', 'value' => 'DESC'];*/ + + if (is_null($this->request->params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + + $userListCriteria = $this->request->params; + $userList = $this->userService->select($userListCriteria, fillOnUndefined($userListCriteria, 'select', ['*'])); + + if ($userList['status'] == 'success') { + return apiResponse(1, null, $userList['data'], 200); + } else { + return apiResponse(0, $userList['message'], null, 400); + } + } + + public function userCreate(Request $request) + { + + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + + $params = $this->request->params; + $userId = $request->credentials->user_id; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $userCreateParams = $params; + $userCreateParams['user_id'] = $userId; + $return = []; + $userCreate = $this->userService->create($userCreateParams); + + if ($userCreate['status'] != 'success') { + throw new ApiErrorException($userCreate['message']); + } + $return['user'] = $userCreate['data']; + + $mailParams = [ + 'name_surname' => $return['user']['name'] . ' ' . $return['user']['surname'], + 'email' => $return['user']['email'], + 'hash_key' => $return['user']['hash_key'], + 'activation_link' => Config::get('app.client_server') . '/activate-user?email=' . $return['user']['email'] . '&key=' . $return['user']['hash_key'], + + ]; + + $this->mailer->onQueue( + 'userCreateMail', + new UserCreateMail($mailParams) + ); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function checkUserKey(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + $params = $this->request->params; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $checkUserParams = $params; + $return = []; + $checkUserKey = $this->userService->checkUserKey($checkUserParams); + + if ($checkUserKey['status'] != 'success') { + throw new ApiErrorException($checkUserKey['message']); + } + $return['user'] = $checkUserKey['data']; + unset($return['user']['id']); + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function newPassword(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + $params = $this->request->params; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $checkUserParams = $params; + $return = []; + $checkUserKey = $this->userService->checkUserKey($checkUserParams); + + if ($checkUserKey['status'] != 'success') { + throw new Exception($checkUserKey['message']); + } + + $checkUserKey = $checkUserKey['data']; + $newPasswordParams = [ + 'email' => fillOnUndefined($params, 'email'), + 'hash_key' => fillOnUndefined($params, 'key'), + 'password' => fillOnUndefined($params, 'password'), + 'password_confirmation' => fillOnUndefined($params, 'password_confirmation'), + 'user_id' => $checkUserKey['id'], + + ]; + + $newPassword = $this->userService->newPassword($newPasswordParams); + if ($newPassword['status'] != 'success') { + throw new Exception($newPassword['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function changePassword(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + $params = $this->request->params; + $userId = $request->credentials->user_id; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $return = []; + + $changePasswordParams = [ + 'user_id' => $userId, + 'old_password' => fillOnUndefined($params, 'old_password'), + 'password' => fillOnUndefined($params, 'password'), + 'password_confirmation' => fillOnUndefined($params, 'password_confirmation'), + ]; + + $changePassword = $this->userService->changePassword($changePasswordParams); + if ($changePassword['status'] != 'success') { + throw new Exception($changePassword['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function forgotPassword(Request $request) + { + + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $params = $this->request->params; + + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + + + $language = "en"; + if ($request->headers->get('language')) { + $language = $request->headers->get('language'); + } + + $userUpdateParams = [ + 'email' => fillOnUndefined($params, 'email'), + ]; + $return = []; + + $userUpdate = $this->userService->forgotPassword($userUpdateParams); + if ($userUpdate['status'] != 'success') { + throw new Exception($userUpdate['message']); + } + $userUpdate = $userUpdate['data']; + $mailParams = [ + 'name_surname' => $userUpdate['name'] . ' ' . $userUpdate['surname'], + 'email' => $userUpdate['email'], + 'hash_key' => $userUpdate['hash_key'], + 'activation_link' => Config::get('app.client_server') . '/reset-password?email=' . $userUpdate['email'] . '&key=' . $userUpdate['hash_key'], + 'language' => $language, + + ]; + + $this->mailer->onQueue( + 'UserForgotPassword', + new UserForgotPassword($mailParams) + ); + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function resetPassword(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $params = $this->request->params; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $userUpdateParams = [ + 'email' => fillOnUndefined($params, 'email'), + 'hash_key' => fillOnUndefined($params, 'key'), + 'password' => fillOnUndefined($params, 'password'), + 'password_confirmation' => fillOnUndefined($params, 'password_confirmation'), + ]; + $return = []; + + $userUpdate = $this->userService->resetPassword($userUpdateParams); + if ($userUpdate['status'] != 'success') { + throw new Exception($userUpdate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => 'Your password updated successfuly', 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function userUpdate(Request $request) + { + + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $params = $this->request->params; + + $userId = $request->credentials->user_id; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $userUpdateParams = [ + 'user_update_data' => fillOnUndefined($params, 'user_update_data'), + 'update_user_id' => fillOnUndefined($params, 'update_user_id'), + 'user_id' => $userId + + + ]; + + $return = []; + $userCreate = $this->userService->update($userUpdateParams); + if ($userCreate['status'] != 'success') { + throw new Exception($userCreate['message']); + } + $return['user'] = $userCreate['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function addUserProperty(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + + $params = $this->request->params; + + $userId = $request->credentials->user_id; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + + $userPropertyParams = [ + 'add_user_id' => fillOnUndefined($params, 'add_user_id'), + 'add_property_id' => fillOnUndefined($params, 'add_property_id'), + 'user_id' => $userId + ]; + $return = []; + + $addUserProperty = $this->userPropertyMappingService->addUserProperty($userPropertyParams); + + if ($addUserProperty['status'] != 'success') { + throw new Exception($addUserProperty['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function removeUserProperty(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + + $params = $this->request->params; + + $userId = $request->credentials->user_id; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + + $userPropertyParams = [ + 'remove_user_id' => fillOnUndefined($params, 'remove_user_id'), + 'remove_property_id' => fillOnUndefined($params, 'remove_property_id'), + 'user_id' => $userId + ]; + $return = []; + + $addUserProperty = $this->userPropertyMappingService->removeUserProperty($userPropertyParams); + if ($addUserProperty['status'] != 'success') { + throw new Exception($addUserProperty['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function userRegister() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + $params = $this->request->params; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $userCreateParams = $params; + $return = []; + $userCreate = $this->userService->create($userCreateParams); + if ($userCreate['status'] != 'success') { + throw new Exception($userCreate['message']); + } + $return['user'] = $userCreate['data']; + + $jwtData = $this->jwtService->jwtCreate(['user_id' => $return['user']['id']]); + + if ($jwtData['status'] != 'success') { + throw new Exception($userCreate['message']); + } + + $return['token'] = $jwtData['data']; + + if ($params['temp_hotel_id']) { + $propertySearchCriteria = [ + 'criteria' => [ + ["field" => "id", "condition" => "=", "value" => $params['temp_hotel_id']] + ], + 'firstRow' => true + ]; + $tempPropertyData = $this->tempPropertyService->select($propertySearchCriteria, ['id', 'name', 'giata_id', 'destination_id']); + if ($tempPropertyData['status'] == 'success') { + $tempProperty = $tempPropertyData['data']; + $propertyInsertData = [ + 'name' => $tempProperty['name'], + 'destination_id' => $tempProperty['destination_id'], + 'giata_id' => $tempProperty['destination_id'], + 'currency_type' => 'TRY', + 'created_at' => time(), + 'updated_at' => time(), + ]; + $propertyCreate = $this->propertyService->create($propertyInsertData); + if ($propertyCreate['status'] == 'success') { + $return['property'] = $propertyCreate['data']; + $userPropertyMappingData = [ + 'user_id' => $userCreate['data']['id'], + 'property_id' => $propertyCreate['data']['id'], + ]; + $userPropertyMappingCreate = $this->userPropertyMappingService->create($userPropertyMappingData); + if ($userPropertyMappingCreate['status'] == 'success') { + // $return['user_property_mapping'] = $userPropertyMappingCreate['data'] ; + } + } + } + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function setProperty() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + + $request = $this->request->params; + $checkUserPropertyCriteria = [ + 'criteria' => [ + ['field' => 'user_id', 'condition' => '=', 'value' => $this->request->credentials->user_id], + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($request, 'property_id')], + ], + 'with' => ['property'], + 'firstRow' => true, + ]; + $checkUserProperty = $this->userPropertyMappingService->select($checkUserPropertyCriteria); + + if ($checkUserProperty['status'] != 'success') { + throw new Exception(lang('An unknown error occurred')); + } + + if (!$checkUserProperty['data']) { + throw new ApiErrorException(lang('Mapping data not found')); + } + $cacheParams = [ + + 'token' => $this->request->header('authToken'), + 'property_id' => $checkUserProperty['data']['property_id'] + + ]; + $applicationCache = $this->applicationCacheService->applicationCacheCreate($cacheParams); + $return['hotel_user_mapping'] = $checkUserProperty['data']; + $return['application_cache'] = $applicationCache['data']; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function userRegisterWithProperty() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + DB::beginTransaction(); + + $params = $this->request->params; + if (is_null($params)) { + return apiResponse(0, 'Parameter Error.', null, 400); + } + $language = "en"; + if ($this->request->headers->get('language')) { + $language = $this->request->headers->get('language'); + } + $userCreateParams = $params; + $return = []; + $userCreateParams['status'] = 1; + $userCreateParams['user_type'] = 1; + + $userCreate = $this->userService->create($userCreateParams); + if ($userCreate['status'] != 'success') { + throw new ApiErrorException($userCreate['message']); + } + $return['user'] = $userCreate['data']; + + $propertyInsertData = [ + 'name' => $userCreateParams['property_name'], + 'status' => 1, + 'created_by' => $return['user']['id'], + 'updated_by' => $return['user']['id'], + 'created_at' => time(), + 'updated_at' => time(), + ]; + $propertyCreate = $this->propertyService->create($propertyInsertData); + if ($propertyCreate['status'] != 'success') { + throw new ApiErrorException($propertyCreate['message']); + } + $return['property_list'] = [ + [ + 'id' => $propertyCreate['data']['id'], + 'name' => $propertyCreate['data']['name'], + 'default_photo' => "/assets/img/placeholder.png", + ] + ]; + $userPropertyMappingData = [ + 'user_id' => $userCreate['data']['id'], + 'status' => 1, + 'property_id' => $propertyCreate['data']['id'], + 'created_by' => $return['user']['id'], + 'updated_by' => $return['user']['id'], + 'created_at' => time(), + 'updated_at' => time(), + ]; + $userPropertyMappingCreate = $this->userPropertyMappingService->create($userPropertyMappingData); + if ($userPropertyMappingCreate['status'] != 'success') { + throw new ApiErrorException($userPropertyMappingCreate['message']); + } + + $propertyProducts = $this->productService->setDefaultPropertyProducts($userPropertyMappingData); + if ($propertyProducts['status'] != 'success') { + throw new ApiErrorException($propertyProducts['message']); + } + + $jwtToken = $this->jwtService->jwtCreate(['user_id' => $return['user']['id']]); + if ($jwtToken['status'] != 'success') { + throw new ApiErrorException(lang('An unknown error occurred.')); + } + $jwtToken = $jwtToken['data']; + $saveToken = [ + "token" => md5(fillOnUndefined($jwtToken, "token")), + "expire_date" => fillOnUndefined($jwtToken, "exp"), + "user_id" => fillOnUndefined($return['user'], "id"), + "invalidate" => fillOnUndefined($jwtToken, "invalidate", 0), + ]; + + $saveTokenTo = $this->apiAccessTokenService->create($saveToken); + if ($saveTokenTo['status'] != 'success') { + throw new ApiErrorException(lang('General error')); + } + + + $return['token'] = $jwtToken['token']; + $return['expire_time'] = $saveTokenTo['data']['expire_time']; + $return['locale'] = null; + + + $mailParams = [ + 'name_surname' => $return['user']['name'] . ' ' . $return['user']['surname'], + 'email' => $return['user']['email'], + "password" => $return['user']['userPassword'], + 'language' => $language, + ]; + + $this->mailer->onQueue( + 'userCreateMail', + new UserCreateMail($mailParams) + ); + + $return['user'] = [ + 'name' => $userCreate['data']['name'], + 'surname' => $userCreate['data']['surname'], + + ]; + + + $notificationParam = $userCreateParams; + Notification::route('mail', ['sales@extranetwork.com' => 'Extranetwork Sales'])->notify(new NewUserNotification($notificationParam)); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + DB::commit(); + + //Monday.com contact items + //$createBoardItems = $this->mondayService->createBoardItems($userCreateParams); + + //Kommo integration + $kommoPropertyParam = [ + 'name_surname' => $notificationParam['name'] . ' ' . $notificationParam['surname'], + 'phone_number' => $notificationParam['phone'], + 'email' => $notificationParam['email'], + 'property' => $notificationParam['property_name'], + 'web' => fillOnUndefined($notificationParam, 'web', 'www.extranetwork.com') + ]; + + $this->propertyService->kommoCreateLead($kommoPropertyParam); + + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getProfile(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $requestParams = [ + 'user_id' => $request->credentials->user_id, + 'status' => 1 + ]; + + $profileFields = ['id', 'email', 'name', 'surname', 'gender', 'language', 'phone']; + + $profile = $this->userService->getProfile($requestParams, $profileFields); + + if ($profile['status'] != 'success') { + throw new Exception($profile['message']); + } + $return['profile'] = $profile['data']; + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $languages = $this->languageService->getAllLanguages($languageCriteria, ['id', 'code', 'name', 'status', 'language_key']); + + if ($languages['status'] != 'success') { + throw new Exception($languages['message']); + } + $return['languages'] = $languages['data']; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function updateProfile(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $requestParams = [ + 'name' => fillOnUndefined($params, 'name'), + 'surname' => fillOnUndefined($params, 'surname'), + 'gender' => fillOnUndefined($params, 'gender'), + 'language' => fillOnUndefined($params, 'language'), + 'phone' => fillOnUndefined($params, 'phone'), + 'user_id' => $request->credentials->user_id, + ]; + + $profile = $this->userService->profileUpdate($requestParams); + + if ($profile['status'] != 'success') { + + throw new ApiErrorException($profile['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $profile['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } +} diff --git a/app/Http/Controllers/V1/AIController.php b/app/Http/Controllers/V1/AIController.php new file mode 100644 index 0000000..4b10142 --- /dev/null +++ b/app/Http/Controllers/V1/AIController.php @@ -0,0 +1,84 @@ + false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $client = new \GuzzleHttp\Client([ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['https'], + 'timeout' => 30, + 'headers' => [ + 'Authorization' => 'Bearer ' . config('app.openAISecretKey'), + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache', + 'Connection' => 'keep-alive', + 'Accept-Encoding' => 'gzip' + ] + ] + ); + + + $result = $client->post('https://api.openai.com/v1/chat/completions', [ + 'body' => json_encode($params['query']) + ]); + + $result = $result->getBody()->getContents(); + $result = json_decode($result, 1); + + $choiceMessage = reset($result['choices']); + + if (isset($choiceMessage['message']['content'])) { + $choiceMessage = json_decode($choiceMessage['message']['content'], 1); + $data = $choiceMessage; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $data]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + +} + diff --git a/app/Http/Controllers/V1/CompetitorPriceAnalysisController.php b/app/Http/Controllers/V1/CompetitorPriceAnalysisController.php new file mode 100644 index 0000000..565a0f1 --- /dev/null +++ b/app/Http/Controllers/V1/CompetitorPriceAnalysisController.php @@ -0,0 +1,1235 @@ +tripAdvisorCookie = 'TADCID=X6AlsdAQPb0JGrWnABQCFdpBzzOuRA-9xvCxaMyI12kGsGqfJg45fcvAP84z1sQ0l6BdP8fUu-L4qe5Zh7uINoyb1usbZKS8xpY; ak_bmsc=1D49AF2E3BEE0E197E48F537CB620AA3~000000000000000000000000000000~YAAQTLOvw+g4QVN8AQAARPc0rQ3fR0x3SZUbtbLJX5hS76gF80zdg9dmKzmyonlGUQ5dyEnGt6odg1kTQUj74Xg3FeuvUX3RZZ0Oqg/HiEAMSuEbC9QgS6fugmOZLJDsJ0Vyt29BuAOYMPf/OX7lt7pCPCgfb6iQClwqh1L5ZfsjPwLrd8B9KjIKMY9hjOdpjTacei9gZoM7eR0Q3Xe2r5BoIoV4CDpM8kde/BD6rKcZbRjfNAc0KTUpHUawTS3unZ9y145u8H/99xxZCbjqrUW25g+x+hpBdI7IBr6FTXw5sljsl5V7iwfNob0NGTJF4y/37RA5KBqGatwkeMp/qdMUPBK76TyDx0q6hIwBiVxTm3y0Hq999VUmrl7Kg2IEvrACcDQNM4gKo+zjxnse+g=='; + //$this->tripAdvisorCookie = 'TNI1625!AC8GutJQ28ZxO8jorf9FRDmeZ1UQdBgLItfITy8i77flGfQpI+UIoZd+cEfErXSR8VMnvDTKEW1MdkNx2GdRoJdWitJp5OC+ZjGozmfw/z8AfgvQ/IPIym57VSEZN06vcVmQulCtCPaM/q+OdmNYoEc7A3kcekslH9yl2sBLchIS'; + $this->tripAdvisorCookie = '4c4b806c8afc9ae6f0d9f62e0951c53c17d4d7964446a664f74de11087849ec3'; + + $this->restClient = new Client([ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['https'], + 'track_redirects' => false, + 'allow_redirects' => false, + 'timeout' => 5 + ] + ); + + $this->params = Input::all(); + $this->currencyService = $currencyService; + $this->competitorPriceAnalysisService = $competitorPriceAnalysisService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyChannelCouponService = $propertyChannelCouponService; + $this->propertyPromotionService = $propertyPromotionService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->maxCompetitorPropertyAdd = 5; + } + + public function property(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $this->restClientFroTripadvisr = new Client([ + 'max' => 5, + 'verify' => false, + 'http_errors' => false + ] + ); + + $query[] = [ + 'query' => '84b17ed122fbdbd4', + 'variables' => [ + 'request' => [ + 'query' => $this->params['keyword'], + 'limit' => 10, + 'scope' => 'WORLDWIDE', + 'locale' => 'tr-TR', + 'scopeGeoId' => 1, + 'searchCenter' => null, + 'types' => ['LOCATION'], + 'locationTypes' => [ + 'ACCOMMODATION' + ], + 'userId' => null, + 'context' => [ + 'listResultType' => 'HOTEL' + ], + 'articleCategories' => [ + 'default', + 'love_your_local', + 'insurance_lander' + ], + 'enabledFeatures' => [ + 'typeahead-q' + ] + ] + ], + "extensions" => [ + "preRegisteredQueryId" => "5ddff5cef01e3cfd" + ] + ]; + + $result = $this->restClientFroTripadvisr->post('https://www.tripadvisor.com/data/graphql/ids', [ + 'headers' => [ + 'accept-encoding' => 'gzip, deflate', + 'content-type' => 'application/json', + 'origin' => 'https://www.tripadvisor.com', + 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', + 'x-requested-by' => $this->tripAdvisorCookie, + 'Cookie' => 'TAUnique=%1%enc%3AB8gsSVzcYv%2Fy%2FQcUCC8NkwTAxw1PuWKMN7hDUF0uFMBsFY3v8WCw%2B6S4L8prdRoSNox8JbUSTxk%3D; TATrkConsent=eyJvdXQiOiIiLCJpbiI6IkFMTCJ9; TASSK=enc%3AAGWI%2Fjlo8Bi8BIsq9syl2j66bc48e82FdKzTyCz99EMkiPVMHbfZ6ngS%2F%2FZ%2FLHG6rhp8Sul%2BflsMdGktQml1d%2Fv7%2BwaYcOfHfgNDsKFC%2FJK4vpvZ5AbBpyN8zPlNHh5kAQ%3D%3D; _lc2_fpi=eb26cb8958b8--01kg7mzmk5gj81kjyacda52m8t; _lc2_fpi_meta=%7B%22w%22%3A1769783415397%7D; _gcl_au=1.1.656612842.1769783416; _ga=GA1.1.959970588.1769783416; PMC=V2*MS.44*MD.20260130*LD.20260130; CM=%1%mds%2C1769783421921%2C1769869821%7C; _ga_QX0Q50ZC9P=GS2.1.s1769783415$o1$g1$t1769784141$j57$l0$h0; TASID=2CE514F9A73746734B5866FC46F2C79C; TADCID=JXGuyvNjCnVXf8NBABQChrLCR-aOT_K5vlfY_RXuc4v8CctrMv3z7OyJhtqOIyA2jOwugGFgO4oUe5amkFV2bF3B1pi0-C11DE0; TASession=V2ID.2CE514F9A73746734B5866FC46F2C79C*SQ.1*LS.Hotel_Review*HS.recommended*ES.popularity*DS.5*SAS.popularity*FPS.oldFirst*FA.1*DF.0*TRA.true; PAC=AJfQGZeJqolH8Hzh3aZ4aFh_W2_NwTyw1iLgJX-tGmLLLPZwnNUwZE10W5UpsGahNGHg2Ks3ir6Z_6VMT-2nePlhd0jEjv2wl51LQbZqgAxsvoqWpjsPObiKX0VGg8bLCCUuPQCm1PWMu6iQhRW8tlJasIUq89-o5gswGEJueIGjz6bk-Ugzm1MP8oxQBgQcCaCNPMtS5PvVLfz2craf2Xs%3D; SRT=TART_SYNC; TART=%1%enc%3Aego6iAgRUncSBJJBqhWUc6MS72Gdmrlbyt6LsE1hcOb28uizb4wsXf5kB4qidaAdxJICaUS3Vk4%3D; OptanonConsent=isGpcEnabled=0&datestamp=Mon+Mar+02+2026+15%3A44%3A46+GMT%2B0300+(GMT%2B03%3A00)&version=202601.2.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=65f573db-6363-4747-9874-4ef7843acd7e&interactionCount=1&isAnonUser=1&landingPath=https%3A%2F%2Fwww.tripadvisor.de%2FHotel_Review-g293974-d295165-Reviews-Grand_Yavuz_Hotel-Istanbul.html&groups=C0001%3A1%2CC0002%3A1%2CC0003%3A1%2CC0004%3A1&prevHadToken=0; _li_dcdm_c=.tripadvisor.de; pbjs_sharedId=04024d25-0c58-462b-a8df-f66362c4dfa8; pbjs_sharedId_cst=zix7LPQsHA%3D%3D; _lr_retry_request=true; _lr_env_src_ats=false; _gcl_aw=GCL.1772455489.null; pbjs_unifiedID=%7B%22TDID_LOOKUP%22%3A%22FALSE%22%2C%22TDID_CREATED_AT%22%3A%222026-03-02T12%3A44%3A48%22%7D; pbjs_unifiedID_cst=zix7LPQsHA%3D%3D; pbjs_li_nonid=%7B%7D; pbjs_li_nonid_cst=zix7LPQsHA%3D%3D; __gads=ID=1cd3edce1a02a3a9:T=1769783416:RT=1772455490:S=ALNI_MZw9YE9xOBfuT3GptcwBZz1kk9y8A; __gpi=UID=000012ed05a9c113:T=1769783416:RT=1772455490:S=ALNI_MZjriFWmZQ4byU9h5qi7PxTySAUPA; __eoi=ID=5e090e36e225d6f3:T=1769783416:RT=1772455490:S=AA-AfjaO0smbZgTBvQkXOeDLsC_b; _lr_sampling_rate=100; datadome=jUF6V7MInCDT_e60vxsoUawgoBJ~kcHXw8wWQdbdAkpYR1DUqrYEcBuA9knMvbo2Q67tacHuwfJkQIk9aIeMFP5dfkY4ZQhZyeNyekXYunHAxxhaJ19q4AqV0_oha73O; __vt=y16Z4GVTSrBGH8EoABQCT24E-H_BQo6gx1APGQJPtzvZqhsLjxQLo2PGhRdDojXJUj-NQn9d3uXlRiKs37Gm9slng8tYN5Ykvbhr99p9t0D5jo3uHrNEzrIfiJ_F87BCZBZZH0h1u-4d1B0A0JmN31zUaQ', + ], + 'body' => json_encode($query), + 'decode_content' => true + ] + ); + + $result = $result->getBody()->getContents(); + $result = json_decode($result, 1); + + $dataResults = $result[0]['data']['Typeahead_autocomplete']['results']; + + $dataHotels = []; + foreach ($dataResults as $dataResult) { + + $hotelKeyRegex = '/Hotel_Review-(.*)-Reviews/m'; + preg_match_all($hotelKeyRegex, $dataResult['details']['url'], $hotelKeyMatch, PREG_SET_ORDER, 0); + $hotelKey = $hotelKeyMatch[0][1]; + + $dataHotels[] = [ + 'name' => $dataResult['details']['localizedName'], + 'location' => $dataResult['details']['localizedAdditionalNames']['longOnlyHierarchy'], + 'key' => $hotelKey + ]; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $dataHotels]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPropertyCompetitorPrice($params = []) + { + + $response = ['status' => false, 'message' => '']; + + try { + + + $currency = 'USD'; + $currencyRequest = fillOnUndefined($params, 'currency', 'USD'); + $competitorPropertyKey = $params['competitor_property_key']; + $startDate = $params['date'];//$params['startDate']; + $hotelIdExplode = explode('-d', $competitorPropertyKey, 2); + $hotelId = $hotelIdExplode[1]; + + + $dailyPrices = []; + $dailyPricesCache = []; + + $timeStartOverall = Carbon::now(); + + $date = Carbon::parse($startDate)->toDateString(); + + //$cacheKey = 'competitorPropertyHash-' . md5($competitorPropertyKey . '-' . $day . '-' . $currencyRequest); + $cacheKey = 'competitorPropertyHash-' . md5($competitorPropertyKey . '-' . $currencyRequest); + + //Cache::forget($cacheKey); + + if (Cache::has($cacheKey)) { + $dailyPricesCache = Cache::get($cacheKey); + } + + if (isset($dailyPricesCache[$competitorPropertyKey]) && isset($dailyPricesCache[$competitorPropertyKey][$date])) { + + $dailyPrices = $dailyPricesCache[$competitorPropertyKey][$date]; + + } else { + + $lastExchangeRate = $this->currencyService->lastExchangeRate($currency, $currencyRequest); + $currencyList = $this->currencyService->getCurrencyList(); + if ($currencyList['status'] != 'success') { + throw new ApiErrorException($currencyList['message']); + } + + $currencyList = pickItemFromArray('code', $currencyList['data']); + if (!in_array($currencyRequest, $currencyList)) { + throw new ApiErrorException('Invalid currency code'); + } + + + $dailyPrices['date'] = $date; + $dailyPrices['competitorPropertyKey'] = $competitorPropertyKey; + $dailyPrices['amount'] = null; + $dailyPrices['currency'] = null; + $dailyPrices['provider'] = null; + + $timeStart = Carbon::now(); + try { + + $query = [ + "detailId" => (integer)$hotelId, + "checkIn" => $date, + "checkOut" => Carbon::parse($date)->addDay()->toDateString(), + "rooms" => [ + [ + "adults" => 2, + "childrenAges" => [] + ] + ] + ]; + + $client = new \GuzzleHttp\Client([ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['https'], + 'timeout' => 5, + 'headers' => [ + 'X-RapidAPI-Host' => 'travel-advisor.p.rapidapi.com', + 'X-RapidAPI-Key' => 'baad80dc1cmsha3959d133378f89p1c7844jsnd2bbb8c1b529', + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache', + 'Connection' => 'keep-alive', + 'Accept-Encoding' => 'gzip', + //'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' + ] + ] + ); + + $result = $client->post('https://travel-advisor.p.rapidapi.com/hotels/v2/get-offers?currency=USD', [ + 'body' => json_encode($query) + ]); + + $result = $result->getBody()->getContents(); + $result = json_decode($result, 1); + + //$result = json_decode('{"data":{"AppPresentation_queryHotelCommerceV2":{"__typename":"AppPresentation_HotelCommerceResponseV2","impressions":[{"__typename":"AppPresentation_ImpressionLog","data":"noClientLog"}],"sections":[{"__typename":"AppPresentation_HotelCommerceOfferList","trackingKey":"{\"ik\":\"031acedb-8ad1-4e60-83b7-f420f74270d2_0\",\"lid\":295165,\"hlk\":\"d933245d-57cc-41bb-abe7-65c56de1dbd4\",\"sn\":\"HotelCommerceDeals\",\"haik\":\"2b2dd3584c074bf1aa0fd27e0515ee34\",\"login\":false,\"plus\":false,\"hbfk\":\"a952489d18264e5dadc24707d6e912e7\"}","trackingTitle":"HotelOfferListSection_HOTEL_COMMERCE_OFFERS","stableDiffingType":"HotelOfferListSection_HOTEL_COMMERCE_OFFERS","isComplete":false,"clusterId":"HOTEL_COMMERCE_OFFERS","offersV2":[{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=BookingCom&src=32477061&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=1&matchID=1&oos=0&cnt=13&silo=10500&bucket=903023&nrank=1&crank=1&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=8odt39lfF_8t2Lfd3qE3zpQ0bxS-DfXQEVCGCu56GjFwnVeP40ut1Q002MbPq6-GJ6vB_j_RINgMP7TOHy-KvSCdi6d4Z8La-qnaZPCa-GEiuUaN_QJF7VccooTGz6JmhU8LApaUfO047k4rSkKAbSnSXPyL7p4B7_t3niacNpO2A0QC9DiwQuNiQC8EQLE_tDRUphklFjaKlLCkmWspYTT4-PvHv3rN5yphvdPwOS3NkNHYdexTPEJU7pHbjPOzsXI_bXJoAOHM2nApL3ce2g&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.7700&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_637ab6e45797e5e16d5d775b08bcb864&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=19aaa73e178a8f07cd8f023359c51db95&ik=a952489d18264e5dadc24707d6e912e7&aok=ca2e78acd4e24a049ddd6ec13becaa79&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus0_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":"img2/branding/hotels/Booking_Com_v2_384x164_Blue.png","providerName":"Booking.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=HotelsCom2&src=34516980&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=2&matchID=1&oos=0&cnt=13&silo=6103&bucket=901739&nrank=2&crank=2&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=3hpVWWn59hLMfGrDq-0PCWG0EYNU_kg7POsPF6ThFAsDLVIH9gwfrcn3KKhOJ77Hs9AhHIzsICyJ0mI3s8HKXpv7jGezH5fXhsJqGmqdraP3tSka3ZDOkJoU7EIJ70o5dfkzgxFaWMjETOgqmxodjD1lXD1fYejoKeMUXnsa3xIWLHmXb6IRJ4xhf-0yHS8BVJTNTk4sr1oaCXYVIZq4lELuOzeOFUU6d4EYfZ4AxRhyztoG3Eb2AOJCs0ZKWt6hRj9B443Hfn2gtB2jjrSYxtg2QAMYK-T84MC4H3H0X3M&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8200&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_24b0d2a6ed870a6180e189a001b79dd5&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=12cc54312b2eb45f0ce07e66a5c1c33f6&ik=a952489d18264e5dadc24707d6e912e7&aok=c2783e8f360947db94f58e9d83893781&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus1_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Hotels.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$63","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=Destinia&src=38799788&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=3&matchID=1&oos=0&cnt=13&silo=17847&bucket=941214&nrank=13&crank=13&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=swfzbqjFSX7gVvosEdYcyYIGyfWsITpUvJQf-vEJqDHm9NwKePRSjyIPgYDOS3Zu3lVB4dzt7cLJszgYOeRqxckOHll06lzUQrVe3cN6hK12F3yN-JD5PgYUe25vWygGqyUJllLEK0WqQnKNdJYH_ZPUgiXvFP7XXyp0h7lT9ou0NFSmGSUWNoqUsKSZaylhNPj4-8e_es3nKmG90_A5Lc2Q0dh17FM8QlTukduM87Oxcj9tcmgA4czacCkvdx7a&priceShown=63&pm=AIWE&hac=AVAILABLE&mbl=BEAT&mbldelta=0&rq=P&rate=56.4000&fees=7.5700&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_463dd3f7e09ddac3184dd5e74ad235d4&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=1b6dc44a7278cc8c32567e3a520bb93b6&ik=a952489d18264e5dadc24707d6e912e7&aok=97efe91fd2da40e78e184ad7b9c8b7e9&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$63","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus2_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Destinia.com","strikeThroughPrice":{"__typename":"AppPresentation_LocalizedString","string":"$74","debugValueKey":null},"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=Expedia&src=32697091&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=4&matchID=1&oos=0&cnt=13&silo=4310&bucket=910482&nrank=3&crank=3&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=A9XDoEHOyR8iEoOswVX8y-cW5J59D7A7N0XHbUPeLv66diINev9wjgAObbDdrO6yX5d0Q1ez6ijY2HLxwIX5W9XpaS5zSbmuZK_8Gu7vLuTAD9SGrijsQAT4286JgdpRReQPdO0gi8p8HjzLpSV7beb1PKJh4qVLBTlLxU6LEb1krsYnSBNbM8o5e0dlEj_EjuMEKK-PIa-Wjo5kGgO767Q0VKYZJRY2ipSwpJlrKWE0-Pj7x796zecqYb3T8DktzZDR2HXsUzxCVO6R24zzs7FyP21yaADhzNpwKS93Hto&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8200&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_75d1f38b85875ca0bf26dcc0945b80d7&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=13cf902d80cadc2e02215c3661782bd91&ik=a952489d18264e5dadc24707d6e912e7&aok=cc924d45a89847e890676c53a4749cce&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus3_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Expedia.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":null,"commerceLink":null,"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"otelz.com","strikeThroughPrice":null,"status":"IN_PROGRESS","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=TravelocityEWS&src=54221039&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=6&matchID=1&oos=0&cnt=13&silo=11456&bucket=860112&nrank=5&crank=5&clt=M&ttype=MobileCR&tm=286615964&managed=true&capped=false&gosox=MahhiGPAvYM26fgM1Fs4y0LVZilal8soQAd2MInZ40In_xelT2u3Ixjgz2DgbhROuqk_NPFo6jTPJtKMwVpV-CMX2PFFS0t0R3BGfZbK-b9Y1Jq0QYdwPNWnPIX2GiSyMqshHc50jde-NsAl4bH3ts_GhD0pIqyi4lT55BblhQcYWrVvWWB70uU03PUBEl4af9tWrpjsJHFaPzLyh2ldrULuOzeOFUU6d4EYfZ4AxRhyztoG3Eb2AOJCs0ZKWt6hRj9B443Hfn2gtB2jjrSYxtg2QAMYK-T84MC4H3H0X3M&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8200&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=16948884fd24b04e1043a4fb842aa97be&ik=a952489d18264e5dadc24707d6e912e7&aok=82abbe08c2104f3e80985e9b18d71158&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus5_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Travelocity","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=Agoda&src=48793666&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=7&matchID=1&oos=0&cnt=13&silo=5122&bucket=895087&nrank=6&crank=6&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=AVPDU6RbcFVwDmbzu1YYBtZP2QUi_h128CKV_kPJuS07F_gMAdHJfUdZc8AvnTrys1pvQMRoQTuIgA976JCaSbt03vCzSlET_r8sQ_dNDrbRg9T-G1NQPHxYQ_TbM2jw-UtdbO2VUIE_TgNh3iknx_9MM4l1otBv9IETF1TlsG1h_2lMxYV4LzkEOncYyHUB0LI9QnHjhVUlnK50nbopfWyJVyDQFH6wPS4euHOGtm6Hz1FMFNk3jN9MF76vIS3C&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8200&fees=7.5300&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_6977b14032c41291e33b975570bcb286&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=1ce3884332c82f010606b95510eb54183&ik=a952489d18264e5dadc24707d6e912e7&aok=60e8134067604ba487e187f96f906c5a&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus6_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Agoda.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=CtripTA&src=79214115&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=8&matchID=1&oos=0&cnt=13&silo=13669&bucket=899272&nrank=7&crank=7&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=lsSswv72QfbQgHuBbiLSFYE96DuL8ibgqcCcE_kHNN_Km9dkuLDm3L_m7RS8TJ3HivMyOCtiFJw9AfjfwuKpbEVsJk90QOwx9LCM4T2yPAJh7pkq6NTEKg0WDZ-hQs8lqb4uKT8BvbntHGMsxczemosM8iUgx9LuUm4EROAIHrXC9Gj0-zlbhNnfi4QogBrlrJpHfyCEDtt94CM_z-5cGGHhfsgOsRiGcJYkNnQrWhC3R27nhgsncVtnNAe50s6W&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8100&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_596afd5c88483c206cc4318df651709e&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=18f2d4afbf696d011dbe4059cc42ee964&ik=a952489d18264e5dadc24707d6e912e7&aok=12a5b5ad33374d5dbf7c1ee6c3d83798&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus7_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Trip.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$74","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=Mirai&src=255621478&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=9&matchID=1&oos=0&cnt=13&silo=26106&bucket=979000&nrank=8&crank=8&clt=M&ttype=MobileCR&tm=286615964&managed=true&capped=false&gosox=sb95c4IBPXymK172SEJwTOq17gLqU_oE5TJLTjytnMaxAedRBBXUYoekoR-d9PMVNvrpLlBCaSTqtFK0EoJ2boOmn7uhCcmC2KGSJKrEybT4gR0orTS2T-AArDVYrR6dYi4oq6NjBVtyuYK5lmWSSKlSNP1ISAz8UxD3Fybyaf0M96yboyeG0iMId70TR_Fd28BM-yClSZkKZcUCt5Qj4mfpsweKUIlmCaDUaTygVHxh4X7IDrEYhnCWJDZ0K1oQt0du54YLJ3FbZzQHudLOlg&priceShown=74&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=1100&rq=P&rate=67.0700&fees=6.7100&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_1b7639ec01898e034557cc27443ed58d&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=17098edcf450ce800b98a43c64c737828&ik=a952489d18264e5dadc24707d6e912e7&aok=dddc0118d4ec4025b3bd3a8c56cd61f0&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$74","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus8_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Official website","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$67","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=StayForLong&src=143811959&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=10&matchID=1&oos=0&cnt=13&silo=40511&bucket=944068&nrank=9&crank=9&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=iU3wCxpEHfKz1_yraLhvgLECmoIxDl97J66m2TgHHDHBaXRNIPUumERknooRzmLhEf1P3JKVjztLN-P06N6ZoJs7YuP0twV4ttX9T7P2xCVP6M-JfITK9FzYFiRtslp_bNXI4HjtY-enzYzJfOrNNoE1QjUcqgXJchXu2mYd5xM21Y_InGFgm4ssJnJCe_hHYf9pTMWFeC85BDp3GMh1AdCyPUJx44VVJZyudJ26KX1siVcg0BR-sD0uHrhzhrZuh89RTBTZN4zfTBe-ryEtwg&priceShown=67&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=400&rq=P&rate=66.0100&fees=0.9900&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_1a2c43030be33dc2825829366987f63a&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=18f8f91cf2b981d48d9a18cd57013d982&ik=a952489d18264e5dadc24707d6e912e7&aok=ced593da26634a0d99b705e4a8d92827&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$67","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus9_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"StayForLong","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=Vio&src=256849928&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=11&matchID=1&oos=0&cnt=13&silo=47493&bucket=997319&nrank=10&crank=10&clt=M&ttype=MobileCR&tm=286615964&managed=false&capped=false&gosox=qi8Pk1Rxoc1dwj6TlSgFnDHmTstrv7hj9b7zE8y_bU1UhxfB0tE_98RArd2AGTDUfqleSf3zWjw73eZ_KKqYWhD2WpKqmjNXuuKaHjmd90ShD8E-GDEqX0YFTdRe7DHJnw-aMYVFolfl6BPtHd2VDX3OrZqMMJuXF4BjH4EnXAghnAXWcstQ_ATM_czA23uMxrvsCe2kVfhGH30bQ8AVpnzO-4h0JzsHHOAlD7-2zqL5HNWwqmBPMFSYFlkr7Hpm9lTNXFfW_xzFOmhEb7yupJBLokGIyXFrxUiGNMxHAZU&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.7800&fees=7.5300&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_1db480d711ee619f011e9cb65cc805d7&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=184590a69616cbf405d1409a6ec8a78b8&ik=a952489d18264e5dadc24707d6e912e7&aok=fa05ea300e294464b826633eae70aa87&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus10_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Vio.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=BookingeDreamsWL&src=60220887&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=12&matchID=1&oos=0&cnt=13&silo=35404&bucket=914257&nrank=11&crank=11&clt=M&ttype=MobileCR&tm=286615964&managed=true&capped=false&gosox=wAYrrGjW7Bydo3kUpJXG9x-_rTT4xfM27ciwH-8l-DFHQoXiw53-HkoXH2woreUgPEQGNzWoU0UWdeapcHF6TC2ZZTDzaMEmDVNA1Ju9Ksf3PkgqLsaIz3LZAuwdMtNPvqhfyhXVqIaPY00bJD0LJE-0Cn622zDgb7Kfys-XrUCA00kLdR6Ct3D621MI2FwsqpyEGSk8F_hZm79XabgIE9lfMxamOainLytCpOUDBa13BFhBr8Q51Y0eTw8h_GtuOIcjIhb4Huqemyr-_eDENA&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.7700&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=1780cec9318b617c63e6e6c6e2f041d05&ik=a952489d18264e5dadc24707d6e912e7&aok=e4d17c75ad2a42529ce22b377ebafcea&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus11_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"eDreams","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]},{"__typename":"AppPresentation_HotelCommerceOfferDeal","displayPrice":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"commerceLink":{"__typename":"AppPresentation_ExternalLink","externalUrl":"/Commerce?p=OrbitzEWS&src=78874101&geo=295165&from=HotelDateSearch_HotelCommerceDeals&slot=13&matchID=1&oos=0&cnt=13&silo=20728&bucket=862895&nrank=11&crank=12&clt=M&ttype=MobileCR&tm=286615964&managed=true&capped=false&gosox=duEJfdKRjSaUExDPyWiVTxfzxv14vo3_X57IHuv-PENZzSU0u_qCcSugyEI21SUpyTdJYppCoBfhowdBz1tytuSVcY2ctKopxjdDSR4zUA8bk_9BDHix8tffG7gOF9URKgwSVrp1OniloXJJ3ME0EJzucmES6J8quJoqj2ReWepGgoURtfMoOFl-stDivIvoQmMxR6jRfSXd2WGXNXtHBnzO-4h0JzsHHOAlD7-2zqL5HNWwqmBPMFSYFlkr7Hpm9lTNXFfW_xzFOmhEb7yupJBLokGIyXFrxUiGNMxHAZU&priceShown=70&pm=AIWE&hac=AVAILABLE&mbl=LOSE&mbldelta=700&rq=P&rate=62.8200&fees=7.5400&cur=USD&adults=2&child_rm_ages=&inDay=18&outDay=19&rdex=RDEX_445cc1f599f38d72d456f6729697e683&rooms=1&inMonth=3&inYear=2024&outMonth=3&outYear=2024&auid=a087cf4c-7eeb-4052-9492-74e1ec4dc0d4&def_d=false&bld=L_1,D_47,G_2,W_1,U_0,C_240318,T_15&bh=true&cs=10084d859975c54482a6a57bb7df14f32&ik=a952489d18264e5dadc24707d6e912e7&aok=c3ebd3b4b4534b04b485a5d5ebfa84d3&tp=APS-HotelCommerceDeals&pageLocId=295165","text":{"__typename":"AppPresentation_LocalizedString","string":"$70","debugValueKey":null},"accessibilityString":null,"trackingContext":"server_nonPlus12_hotelCommerceLink"},"details":[{"__typename":"AppPresentation_LocalizedString","string":"Free breakfast included","debugValueKey":null}],"providerLogoUrl":null,"providerName":"Orbitz.com","strikeThroughPrice":null,"status":"AVAILABLE","roomUrgencyMessage":null,"labels":[]}]},{"__typename":"AppPresentation_LogicalBreak","stableDiffingType":"LogicalBreakSection","spacing":"spacing-03","clusterId":null,"divider":null,"background":null},{"__typename":"AppPresentation_OmnibusDisclosure","link":null,"contentText":{"__typename":"AppPresentation_HtmlString","htmlString":"Prices are provided by our partners, and reflect average nightly room rates, including taxes and fees that are fixed, known to our partners, and due at time of booking. Other miscellaneous taxes and hotel fees which are not fixed or due at time of booking may be payable at the property at time of stay. Please see our partners for more details."},"trackingTitle":"HotelDealsDisclaimerSection","trackingKey":"{\"dt\":\"HOTEL_DEALS\",\"ik\":\"031acedb-8ad1-4e60-83b7-f420f74270d2_1\",\"sn\":\"HotelCommerceDeals\"}","stableDiffingType":"HotelDealsDisclaimerSection","clusterId":null},{"__typename":"AppPresentation_LogicalBreak","stableDiffingType":"LogicalBreakSection_1","spacing":"spacing-03","clusterId":null,"divider":null,"background":null}],"statusV2":{"__typename":"AppPresentation_SuccessQueryResponseStatus","partial":false,"pollingStatus":{"__typename":"AppPresentation_QueryResponsePollingStatus","delayForNextPollInMillis":10,"updateToken":"eyJ2ZXIiOiJ2MiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2IiwidmVyc2lvbiI6IjEifQ.eyJvYmplY3QiOiJ7XCJAY1wiOlwiLlVwZGF0ZVRva2VuXCIsXCJ0eXBlXCI6XCJQT0xMSU5HXCIsXCJjbHVzdGVySWRzXCI6W1wiSE9URUxfQ09NTUVSQ0VfT0ZGRVJTXCJdLFwicHJvdmlkZXJVcGRhdGVUb2tlbnNcIjp7XCJIT1RFTF9ERVRBSUxfUFJPVklERVJcIjp7XCJAY1wiOlwiLlN0cmluZ1ZhbHVlUHJvdmlkZXJVcGRhdGVUb2tlblwiLFwidmFsdWVcIjpudWxsfX0sXCJwb2xsaW5nU2VxdWVuY2VOdW1cIjoxfSJ9.MjRlNTU4MmItMGIyNS00YTI1LTk4NDUtYTY0YjFiNzYxODc0Lk1FVUNJRVNiQlU2bWIxTjlvYV80VWx3eEwtTXY4UmZRal9fMGFvOXB1WGMtRG5rVUFpRUFsUDJPVUdMYzBHY2NpRTlXLVJOUXBtT3FLNlZKSHpfV3NmSFZmNlpjaFhV"}},"updatedClusterIds":[]}}}', 1); + + if (isset($result['data']['AppPresentation_queryHotelCommerceV2']['sections'][0]['offersV2'])) { + + $dataResults = $result['data']['AppPresentation_queryHotelCommerceV2']['sections'][0]['offersV2']; + + $dailyPricesByProvider = []; + foreach ($dataResults as $dataResult) { + + if ($dataResult['displayPrice']) { + $priceText = str_replace('$', '', $dataResult['displayPrice']['string']); + $provider = $dataResult['providerName']; + + if ($priceText) { + + $taxesAndFeesText = empty($taxesAndFeesText) ? 0 : $taxesAndFeesText; + $dailyPricesByProvider[] = [ + 'amount' => round(moneyDoubleFormatDecimal((($priceText + $taxesAndFeesText)) * $lastExchangeRate['data'])), + 'currencyCode' => $currencyRequest, + 'provider' => $provider, + 'logo' => config('app.url') . '/img/channel-icons/' . mb_strtolower(str_replace('.', '', $provider)) . '.png', + ]; + + } + } + + } + + if (!empty($dailyPricesByProvider)) { + + $rateCollect = collect($dailyPricesByProvider); + $rateCollect = $rateCollect->sortBy('amount')->toArray(); + $minRate = reset($rateCollect); + + $dailyPrices['amount'] = $minRate['amount']; + $dailyPrices['currency'] = $currencyRequest; + $dailyPrices['provider'] = $minRate['provider']; + $dailyPrices['all'] = array_values($rateCollect); + + if (Cache::has($cacheKey)) { + $dailyPricesCache = Cache::get($cacheKey); + } + + $dailyPrices['cacheTime'] = Carbon::now()->toDateTimeString(); + + $dailyPricesCache[$dailyPrices['competitorPropertyKey']][$dailyPrices['date']] = $dailyPrices; + + Cache::put($cacheKey, $dailyPricesCache, 60 * 5);//600 10 dk + } + + + } + + + } catch (Exception $e) { + Log::debug($e->getMessage()); + //dd($e->getMessage()); + } + + $timeEnd = Carbon::now(); + $timeDiff = Carbon::parse($timeStart)->floatDiffInRealSeconds(Carbon::parse($timeEnd)); + //$dailyPrices[$hotelKey][$day]['time'] = $timeDiff; + $dailyPrices['time'] = $timeDiff; + + } + + $timeEndOverall = Carbon::now(); + $timeDiffOverall = Carbon::parse($timeStartOverall)->floatDiffInRealSeconds(Carbon::parse($timeEndOverall)); + + //$dailyPrices['responseTime'] = $timeDiffOverall; + + $response = ['status' => true, 'message' => null, 'data' => $dailyPrices]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + return $response; + + } + + public function propertyCompetitorPrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $request->all(); + + + if (isset($params['property_id'])) { + + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_manager_id', 'condition' => '=', 'value' => 12], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + $params['competitor_property_key'] = $channelManagerPropertyMapping['data']['channel_manager_property_id']; + } else { + throw new ApiErrorException('Mapping not found.'); + } + + + } + + $paramCompetitorPrice = [ + 'date' => $params['date'], + 'competitor_property_key' => $params['competitor_property_key'], + 'currency' => $params['currency'], + ]; + + $propertyCompetitorPrice = $this->getPropertyCompetitorPrice($paramCompetitorPrice); + + if (!$propertyCompetitorPrice['status']) { + throw new ApiErrorException($propertyCompetitorPrice['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyCompetitorPrice['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function createPropertyCompetitor(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ] + ]; + + + $requestSelectResult = $this->competitorPriceAnalysisService->selectPropertyCompetitorMapping($requestSelectCriteria); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + if (count($requestSelectResult['data']) >= $this->maxCompetitorPropertyAdd) { + //throw new ApiErrorException('Up to 5 records can be added.'); + } + + + $requestParam = [ + 'property_id' => $this->params['params']['property_id'], + 'competitor_property_name' => $this->params['params']['competitor_property_name'], + 'competitor_property_key' => $this->params['params']['competitor_property_key'], + 'created_by' => $request->auth->id, + 'updated_by' => $request->auth->id, + ]; + + $requestResult = $this->competitorPriceAnalysisService->createPropertyCompetitorMapping($requestParam); + + if ($requestResult['status'] != 'success') { + throw new ApiErrorException($requestResult['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncPropertyCompetitor(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ] + ]; + + + $requestSelectResult = $this->competitorPriceAnalysisService->selectPropertyCompetitorMapping($requestSelectCriteria); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + DB::beginTransaction(); + + if (!empty($requestSelectResult['data'])) { + $deleteIds = pickItemFromArray('id', $requestSelectResult['data']); + $deletePropertyCompetitorMapping = $this->competitorPriceAnalysisService->deletePropertyCompetitorMapping($deleteIds); + if ($deletePropertyCompetitorMapping['status'] != 'success') { + throw new ApiErrorException($deletePropertyCompetitorMapping['message']); + } + } + + + $competitorProperty = $this->params['params']['competitor']; + + + if (count($competitorProperty) > $this->maxCompetitorPropertyAdd) { + //throw new ApiErrorException('Up to 5 records can be added.'); + } + + $requestResultData = []; + foreach ($competitorProperty as $property) { + + $requestParam = [ + 'property_id' => $this->params['params']['property_id'], + 'competitor_property_name' => $property['name'], + "competitor_property_source" => fillOnUndefined($property, "competitor_property_source"), + 'competitor_property_key' => $property['key'], + 'created_by' => $request->auth->id, + 'updated_by' => $request->auth->id, + ]; + + $requestResult = $this->competitorPriceAnalysisService->createPropertyCompetitorMapping($requestParam); + + if ($requestResult['status'] != 'success') { + throw new ApiErrorException($requestResult['message']); + } + + $requestResultData[] = $requestResult['data']; + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestResultData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPropertyCompetitor(Request $request) + { + + $params = $request->all(); + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['params']['property_id']], + ] + ]; + + $columns = ['id', 'property_id', 'competitor_property_name', 'competitor_property_key','competitor_property_source']; + $requestSelectResult = $this->competitorPriceAnalysisService->selectPropertyCompetitorMapping($requestSelectCriteria, $columns); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + if (empty($requestSelectResult['data'])) { + throw new ApiErrorException(lang('Mapping data not found')); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestSelectResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function deletePropertyCompetitor(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'id', 'condition' => '=', 'value' => $this->params['params']['property_competitor_mapping_id']] + ], 'firstRow' => true + ]; + + + $requestSelectResult = $this->competitorPriceAnalysisService->selectPropertyCompetitorMapping($requestSelectCriteria); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + if (empty($requestSelectResult['data'])) { + throw new ApiErrorException(lang('Mapping data not found')); + } + + $deletePropertyCompetitorMapping = $this->competitorPriceAnalysisService->deletePropertyCompetitorMapping($requestSelectResult['data']['id']); + + if ($deletePropertyCompetitorMapping['status'] != 'success') { + throw new ApiErrorException($deletePropertyCompetitorMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function propertyCompetitorExcel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->params['params']; + + if (Carbon::parse($params['start_date'])->isBefore(Carbon::now()) && !Carbon::parse($params['start_date'])->isToday()) { + throw new ApiErrorException('Comparison possible for today and next days.'); + } + + if (Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])) > 14) { + throw new ApiErrorException('A maximum of 14 days of data can be retrieved.'); + } + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ] + ]; + + $columns = ['id', 'property_id', 'competitor_property_name', 'competitor_property_key','competitor_property_source']; + $propertyCompetitor = $this->competitorPriceAnalysisService->selectPropertyCompetitorMapping($requestSelectCriteria, $columns); + + if ($propertyCompetitor['status'] != 'success') { + throw new ApiErrorException($propertyCompetitor['message']); + } + + if (empty($propertyCompetitor['data'])) { + throw new ApiErrorException(lang('Mapping data not found')); + } + + $dataTableData = []; + + $dateFirst = $params['start_date']; + $dateDiff = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + foreach ($propertyCompetitor['data'] as $property) { + for ($i = 0; $i <= $dateDiff; $i++) { + + $date = Carbon::parse($dateFirst)->addDays($i)->toDateString(); + + + $propertyCompetitorPrice = [ + 'status' => false, + 'data' => [] + ]; + + $cacheKey = 'competitorPropertyHash-' . md5($property['key'] . '-' . $params['currency']); + + if (Cache::has($cacheKey)) { + $dailyPricesCache = Cache::get($cacheKey); + + if (isset($dailyPricesCache[$property['key']][$date])) { + $propertyCompetitorPrice = [ + 'status' => true, + 'data' => $dailyPricesCache[$property['key']][$date] + ]; + } + } + + /*if(empty($propertyCompetitorPrice)) { + $paramCompetitorPrice = [ + 'date' => $date, + 'competitor_property_key' => $property['key'], + 'currency' => $params['currency'], + ]; + + $propertyCompetitorPrice = $this->getPropertyCompetitorPrice($paramCompetitorPrice); + }*/ + + $dailyAmount = null; + if ($propertyCompetitorPrice['status']) { + $dailyAmount = $propertyCompetitorPrice['data']['amount']; + } + + $dataTableData['value'][$property['key']][$date] = [ + 'amount' => $dailyAmount, + 'currency' => $params['currency'] + ]; + + $dataTableData['property'][$property['key']] = $property['name']; + $dataTableData['date'][$date] = Carbon::parse($date)->format('d.m.Y'); + + } + + } + + + $fileName = 'PropertyCompetitorExport-' . md5(implode('-', $params)) . '.xlsx'; + $fileNamePath = 'excel/' . $fileName; + $fileNamePublic = config('app.url') . '/' . $fileNamePath; + + $excelStore = Excel::store(new PropertyCompetitorExport($dataTableData), $fileNamePath, 'public'); + + if (!$excelStore) { + throw new ApiErrorException(lang('Mapping data not found')); + } + + $data = [ + 'url' => $fileNamePublic + ]; + + //Delete files older than 1 hours + $excelFileDir = public_path('excel'); + foreach (glob($excelFileDir . '/' . "*") as $file) { + if (filemtime($file) < time() - 3600) { // 6 hours 21600 + unlink($file); + } + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $data]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + public function bestAvailablePrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = json_decode($request->getContent(), 1); + $params = $this->params['params']; + + $params['type'] = fillOnUndefined($params, 'type', 'range'); + $bookingEnginePropertyId = $params['property_id']; + + $cacheKeyParam[] = $params['type']; + $cacheKeyParam[] = $bookingEnginePropertyId; + if ($params['type'] == 'range') { + + if (Carbon::parse($params['start_date'])->isBefore(Carbon::now()) && !Carbon::parse($params['start_date'])->isToday()) { + throw new ApiErrorException('Comparison possible for today and next days.'); + } + + if (Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])) > 14) { + throw new ApiErrorException('A maximum of 14 days of data can be retrieved.'); + } + + $cacheKeyParam[] = $params['start_date'] . '|' . $params['finish_date']; + } else if ($params['type'] == 'date') { + $cacheKeyParam[] = $params['date'] . '|' . $params['currency']; + } + + $cacheKey = 'CRR:' . md5(implode(',', $cacheKeyParam)); + + + //Cache::forget($cacheKey); + if (Cache::has($cacheKey)) { + $responseData = Cache::get($cacheKey); + } else { + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => 5], + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingEnginePropertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['currency'], + 'firstRow' => true + ]; + + $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); + $getChannelProperty = $getChannelProperty['status'] == 'success' && !empty($getChannelProperty['data']) ? $getChannelProperty['data'] : null; + + if (!$getChannelProperty) { + throw new ApiErrorException('Property Channel not found'); + } + + + switch ($params['type']) { + + case 'range' : + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => 5], + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingEnginePropertyId], + ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], + ['field' => 'date', 'condition' => '>=', 'value' => \Carbon\Carbon::parse($params['start_date'])->format('Y-m-d')], + ['field' => 'date', 'condition' => '<', 'value' => Carbon::parse($params['finish_date'])->addDay()->format('Y-m-d')], + ['field' => 'amount', 'condition' => '<>', 'value' => null], + ['field' => 'amount', 'condition' => '<>', 'value' => 0], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'roomRateMapping.propertyRoomRate' + ], + 'orderBy' => [ + ['field' => 'date', 'value' => 'ASC'], + ['field' => 'amount', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); + + if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { + throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); + } + + $getPropertyRoomRatePrice = $getPropertyRoomRatePrice['status'] == 'success' && !empty($getPropertyRoomRatePrice['data']) ? $getPropertyRoomRatePrice['data'] : []; + + $firstDate = Carbon::parse($params['start_date'])->format('Y-m-d'); + $lastDate = Carbon::parse($params['finish_date'])->addDay()->format('Y-m-d'); + $dateDiff = Carbon::parse($firstDate)->diffInDays(Carbon::parse($lastDate)); + + $rateAndAvailability = []; + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($firstDate)->addDays($i)->toDateString(); + + $bestPrice = collect($getPropertyRoomRatePrice) + ->where('date', $date) + ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate') + ->sortBy('amount')->first(); + $bestPrice = $bestPrice ? $bestPrice['amount'] : null; + + $rateAndAvailability[$date] = [ + 'rate' => round($bestPrice), + 'available' => $bestPrice ? true : false, + ]; + + } + + $responseData = [ + 'currency' => $getChannelProperty['currency']['code'], + 'currency_icon' => $getChannelProperty['currency']['symbol'], + 'date' => $rateAndAvailability + ]; + + + if (count($rateAndAvailability) == collect($rateAndAvailability)->where('available', false)->count()) { + $responseData = null; + } + + Cache::put($cacheKey, $responseData, 60 * 60);//1h 60 * 60 + + break; + + case 'date' : + + $requestParam = [ + 'criteria' => [ + ['field' => 'channel_id', 'condition' => '=', 'value' => 5], + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingEnginePropertyId], + ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], + ['field' => 'date', 'condition' => '=', 'value' => Carbon::parse($params['date'])->format('Y-m-d')], + ['field' => 'amount', 'condition' => '<>', 'value' => null], + ['field' => 'amount', 'condition' => '<>', 'value' => 0], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'roomRateMapping.propertyRoomRate' + ], + 'orderBy' => [ + ['field' => 'date', 'value' => 'ASC'], + ['field' => 'amount', 'value' => 'ASC'] + ], + ]; + + $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); + + if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { + throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); + } + + $getPropertyRoomRatePrice = $getPropertyRoomRatePrice['status'] == 'success' && !empty($getPropertyRoomRatePrice['data']) ? $getPropertyRoomRatePrice['data'] : []; + + + $rateAndAvailability = []; + $bestPriceSelect = collect($getPropertyRoomRatePrice) + ->where('date', $params['date']) + ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate') + ->sortBy('amount')->first(); + + $bestPrice = $bestPriceSelect ? $bestPriceSelect['amount'] : null; + + if ($params['currency'] != $bestPriceSelect['currency']) { + $lastExchangeRate = $this->currencyService->lastExchangeRate($bestPriceSelect['currency'], $params['currency']); + $bestPrice = $bestPrice * $lastExchangeRate['data']; + + } + + $rateAndAvailability[$params['date']] = [ + 'rate' => round($bestPrice), + 'available' => $bestPrice ? true : false, + ]; + + $responseData = [ + 'currency' => $params['currency'], + 'date' => $rateAndAvailability + ]; + + if (count($rateAndAvailability) == collect($rateAndAvailability)->where('available', false)->count()) { + $responseData = null; + } + + Cache::put($cacheKey, $responseData, 60 * 60);//1h 60 * 60 + + break; + + } + + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch + (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + public function propertyCompetitorAnalysis(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $data = null; + $params = $this->params['params']; + + $openAiToken = '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'; + + $client = new \GuzzleHttp\Client([ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['https'], + 'timeout' => 30, + 'headers' => [ + 'Authorization' => 'Bearer ' . $openAiToken, + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache', + 'Connection' => 'keep-alive', + 'Accept-Encoding' => 'gzip' + ] + ] + ); + + + $query = [ + 'model' => 'gpt-4o', + 'response_format' => [ + 'type' => 'json_object' + ], + 'messages' => [ + [ + 'role' => 'system', + 'content' => 'Sen bir otel gelir yönetimi (revenue management) uzmanısın. Görev: 1. Verilen fiyatları analiz et. 2. İstenen dilde yorum ve öneri üret. Cevap alanları: {"property": "string", "currency": "string", "average_price": "float", "average_difference": "float (10,2)", "price_position": "string", "competitor_average_price": "float (10,2)", "highest_difference_day": "string (format: d.m.Y)", "highest_difference_percent": "float", "language": "string", "comment": "string", "recommendation": "string"}. price_position değeri higher, lower veya similar olabilir. highest_difference_day ve highest_difference_percent rakiplere göre en yüksek kalan güne göre, format: float(10.2). price_position, average_difference ve competitor_average_price, rakiplerin ortalamalarına göre, format: float. Sadece geçerli JSON döndür, başka açıklama veya metin ekleme.' + ], + [ + 'role' => 'user', + 'content' => json_encode($params) + ] + ] + + ]; + + $result = $client->post('https://api.openai.com/v1/chat/completions', [ + 'body' => json_encode($query) + ]); + + $result = $result->getBody()->getContents(); + $result = json_decode($result, 1); + + $choiceMessage = reset($result['choices']); + + if (isset($choiceMessage['message']['content'])) { + $choiceMessage = json_decode($choiceMessage['message']['content'], 1); + $data = $choiceMessage; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $data]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function promotionAvailable(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + $promotionAvailableData = []; + + try { + + $data = null; + $params = $this->params['params']; + + + //property_channel_coupon + $propertyChannelCouponData = null; + $propertyChannelCouponCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => 1], + ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::parse($params['date'])->toDateString()], + ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::parse($params['date'])->toDateString()], + ['field' => 'is_notify', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'value', 'value' => 'DESC'] + ], + ]; + + $propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria); + + if ($propertyChannelCoupon['status'] == 'success') { + foreach ($propertyChannelCoupon['data'] as $coupon) { + if (!empty($coupon['reservation_start_date']) && !empty($coupon['reservation_end_date'])) { + if (Carbon::parse($params['date'])->betweenIncluded(Carbon::parse($coupon['reservation_start_date']), Carbon::parse($coupon['reservation_end_date']))) { + $propertyChannelCouponData = [ + 'type' => $coupon['type'], + 'value' => $coupon['value'], + ]; + break; + } else { + continue; + } + } else { + $propertyChannelCouponData = [ + 'type' => $coupon['type'], + 'value' => $coupon['value'], + ]; + } + } + } + $promotionAvailableData['popup'] = $propertyChannelCouponData; + //property_channel_coupon + + + //property_promotion + + + //property_promotion + $propertyPromotionData = null; + $promotionTypes = ['PRD', 'BFD', 'LST', 'DSC']; + $propertyPromotionCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['promotionType'], + 'orderBy' => [ + ['field' => 'promotion_type_id', 'value' => 'ASC'] + ], + ]; + + $propertyPromotions = $this->propertyPromotionService->select($propertyPromotionCriteria); + + $propertyPromotionGroup = null; + if ($propertyPromotions['status'] == 'success') { + + foreach ($propertyPromotions['data'] as $propertyPromotion) { + $propertyPromotionGroup[$propertyPromotion['promotion_type']['type_code']][$propertyPromotion['id']] = $propertyPromotion; + } + + + foreach ($promotionTypes as $promotionType) { + + $propertyPromotionData[$promotionType] = null; + if (isset($propertyPromotionGroup[$promotionType])) { + + switch ($promotionType) { + + case 'PRD': + + $propertyPromotionSelected = collect($propertyPromotionGroup[$promotionType]) + ->where('start_date', '<=', Carbon::parse($params['date'])->toDateString()) + ->where('end_date', '>=', Carbon::parse($params['date'])->toDateString()) + ->where('reservation_start_date', '<=', Carbon::parse($params['date'])->toDateString()) + ->where('reservation_end_date', '>=', Carbon::parse($params['date'])->toDateString()) + ->sortByDesc('amount') + ->first(); + + if ($propertyPromotionSelected) { + + $propertyPromotionData[$promotionType] = [ + 'type' => 'PER', + 'value' => $propertyPromotionSelected['amount'], + 'is_mobile' => $propertyPromotionSelected['is_mobile'], + ]; + + } + + + break; + + case 'BFD' || 'LST': + + + $propertyPromotionSelected = collect($propertyPromotionGroup[$promotionType]) + ->sortByDesc('amount') + ->toArray(); + + if ($propertyPromotionSelected) { + + foreach ($propertyPromotionSelected as $perPromotion) { + + if (Carbon::parse($params['date'])->subDays($perPromotion['day_before'])->lessThanOrEqualTo(Carbon::now())) { + $propertyPromotionData[$promotionType] = [ + 'type' => 'PER', + 'value' => $perPromotion['amount'], + 'is_mobile' => $perPromotion['is_mobile'], + ]; + break; + } + + } + } + + break; + case 'DSC': + + + $propertyPromotionSelected = collect($propertyPromotionGroup[$promotionType]) + ->sortByDesc('amount') + ->first(); + + if ($propertyPromotionSelected) { + $propertyPromotionData[$promotionType] = [ + 'type' => 'PER', + 'value' => $propertyPromotionSelected['amount'], + 'is_mobile' => $propertyPromotionSelected['is_mobile'], + ]; + } + + + break; + + } + + } + + } + + //dd($propertyPromotionGroup); + + $promotionAvailableData['promotion'] = $propertyPromotionData; + + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $promotionAvailableData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/CurrencyController.php b/app/Http/Controllers/V1/CurrencyController.php new file mode 100644 index 0000000..ce70cbe --- /dev/null +++ b/app/Http/Controllers/V1/CurrencyController.php @@ -0,0 +1,49 @@ +currencyService = $currencyService; + } + public function getListCurrency(){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $currencyList = $this->currencyService->getCurrencyList(); + + if($currencyList['status'] != 'success'){ + throw new Exception($currencyList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $currencyList['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } +} + diff --git a/app/Http/Controllers/V1/DestinationController.php b/app/Http/Controllers/V1/DestinationController.php new file mode 100644 index 0000000..e16b97e --- /dev/null +++ b/app/Http/Controllers/V1/DestinationController.php @@ -0,0 +1,75 @@ +request = $request; + $this->destinationService = $destinationService; + + } + + + + public function searchDestination(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'search_term' => fillOnUndefined($params, 'search_term'), + 'user_id' => $request->credentials->user_id, + ]; + + $destinationSearch = $this->destinationService->searchDestination($requestParams); + + if($destinationSearch['status'] != 'success'){ + throw new ApiErrorException($destinationSearch['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $destinationSearch['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/EnwContactFormController.php b/app/Http/Controllers/V1/EnwContactFormController.php new file mode 100644 index 0000000..44dd1aa --- /dev/null +++ b/app/Http/Controllers/V1/EnwContactFormController.php @@ -0,0 +1,74 @@ +enwContactFormService = $enwContactFormService; + } + + public function sendEmail(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $language = "en"; + if($request->headers->get('language')){ + $language = $request->headers->get('language'); + app('translator')->setLocale($language); + } + + $params = $request->params; + + $requestParams = [ + 'language' => $language, + 'name' => fillOnUndefined($params, 'name'), + 'surname' => fillOnUndefined($params, 'surname'), + 'email' => fillOnUndefined($params, 'email'), + 'subject' => fillOnUndefined($params, 'subject') + ]; + + $contactForm = $this->enwContactFormService->sendEmail($requestParams); + + if ($contactForm['status'] != 'success') { + throw new ApiErrorException($contactForm['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $contactForm['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/ExportPdfController.php b/app/Http/Controllers/V1/ExportPdfController.php new file mode 100644 index 0000000..8fa698f --- /dev/null +++ b/app/Http/Controllers/V1/ExportPdfController.php @@ -0,0 +1,741 @@ +pdf = $pdf; + $this->pdfContentService = $pdfContentService; + $this->propertyRoomService = $propertyRoomService; + $this->mailer = $mailer; + + } + + + public function pdf(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(), 1); + $params = current($params); + + + if (isset($params['dataExport']) && $params['dataExport'] == 'json') { + + $pdfDataRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id', null), + 'locale' => app('translator')->getLocale() + ]; + $factSheetDataResponse = $this->pdfContentService->factSheetData($pdfDataRequest); + if ($factSheetDataResponse['status'] != 'success') { + throw new Exception($factSheetDataResponse['message']); + } + $factSheetData = $factSheetDataResponse['data']; + + return apiResponse(1, null, $factSheetData, 200); + } + + + if (isset($params['dataExport']) && $params['dataExport'] == 'catalog') { + + /*$pdfDataRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id', null), + 'locale' => fillOnUndefined($params, 'language', 'en'), + ]; + $factSheetDataResponse = $this->pdfContentService->factSheetData($pdfDataRequest); + if ($factSheetDataResponse['status'] != 'success') { + throw new Exception($factSheetDataResponse['message']); + } + + $pageContent = $factSheetDataResponse['data']; + $pdfLanguage = $pdfDataRequest['locale']; + + app('translator')->setLocale($pdfLanguage); + $pdfService = $this->pdf->loadView('pdf.propertyCatalog', compact('pageContent'), [], 'UTF8'); + //$pdfService->setOptions(['dpi' => 100, 'isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]); + $hotelName = Str::slug($pageContent['name'], '_', 'en') . '_' . $pdfLanguage; + + return $pdfService->download($hotelName . '.pdf');*/ + + + dispatch(new PropertyCatalogServiceJob( + fillOnUndefined($params, 'property_id', null), + fillOnUndefined($params, 'language', app('translator')->getLocale()), + fillOnUndefined($params, 'email', null) + )); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + $pdfDataRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id', null), + 'locale' => app('translator')->getLocale() + ]; + $pdfDataResponse = $this->pdfContentService->pdfData($pdfDataRequest); + if ($pdfDataResponse['status'] != 'success') { + throw new Exception($pdfDataResponse['message']); + } + + $pdfData = $pdfDataResponse['data']; + $pdfLanguage = upperCase(app('translator')->getLocale()); + + $logoBase64 = null; + if ($pdfData['property_brand']) { + if ($pdfData['property_brand']['logo_name']) { + $logoFile = Config::get('app.imageUrl') . '/property-photos/' . $pdfData['property_brand']['property_id'] . '/logo/' . $pdfData['property_brand']['logo_name'] . '_250x250.' . $pdfData['property_brand']['logo_file_ext']; + $logoBase64 = 'data:image/' . $pdfData['property_brand']['logo_file_ext'] . ';base64,' . base64_encode(file_get_contents($logoFile)); + } + } + + $ip = $request->ip(); + + $pdf = $this->pdf->loadView('pdf.hotelContent', compact('pdfData', 'logoBase64', 'ip'), [], 'UTF8'); + $hotelName = Str::slug($pdfData['name'], '_', 'en') . '_' . $pdfLanguage; + + return $pdf->download($hotelName . '.pdf'); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (\Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + // return $pdf->stream(); + } + + public function getPropertyPdfInventory(Request $request, $token) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $requestParams = [ + 'token' => $token + ]; + + $params = $this->propertyRoomService->getParamsForPdfInvenyory($requestParams); + $params = $params['data']; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + + ]; + + $inventoryData = $this->propertyRoomService->getPropertyRoomInventory($requestParams); + if ($inventoryData['status'] != 'success') { + throw new ApiErrorException($inventoryData['message']); + } + + $data = $inventoryData['data']; + + foreach ($data as $dataKey => $dataVal) { + + + //room_availability + $i = 0; + $monthKey = null; + foreach ($dataVal['room_availability'] as $key => $val) { + + $keyArr = explode('-', $key); + if ($monthKey != $keyArr[1]) { + $monthKey = $keyArr[1]; + $i++; + } + + if ($i > 6) { + continue; + } + + $data[$dataKey]['monthly_room_availability'][$i][$key] = $val; + } + + //room_stop_sell + $i = 0; + $monthKey = null; + foreach ($dataVal['room_stop_sell'] as $key => $val) { + + $keyArr = explode('-', $key); + if ($monthKey != $keyArr[1]) { + $monthKey = $keyArr[1]; + $i++; + } + + if ($i > 6) { + continue; + } + + $data[$dataKey]['monthly_room_stop_sell'][$i][$key] = $val; + } + + + foreach ($dataVal['property_room_rate_mapping'] as $propertyRoomRateMappingKey => $propertyRoomRateMappingVal) { + + foreach ($propertyRoomRateMappingVal['prices'] as $pricesKey => $pricesVal) { + + //price + $i = 0; + $monthKey = null; + foreach ($pricesVal['price'] as $key => $val) { + + $keyArr = explode('-', $key); + if ($monthKey != $keyArr[1]) { + $monthKey = $keyArr[1]; + $i++; + } + + if ($i > 6) { + continue; + } + + $data[$dataKey]['property_room_rate_mapping'][$propertyRoomRateMappingKey]['prices'][$pricesKey]['monthly_price'][$i][$key] = $val; + } + + //stop_sell + $i = 0; + $monthKey = null; + foreach ($pricesVal['stop_sell'] as $key => $val) { + + $keyArr = explode('-', $key); + if ($monthKey != $keyArr[1]) { + $monthKey = $keyArr[1]; + $i++; + } + + if ($i > 6) { + continue; + } + + $data[$dataKey]['property_room_rate_mapping'][$propertyRoomRateMappingKey]['prices'][$pricesKey]['monthly_stop_sell'][$i][$key] = $val; + } + + //min_stay + $i = 0; + $monthKey = null; + foreach ($pricesVal['min_stay'] as $key => $val) { + + $keyArr = explode('-', $key); + if ($monthKey != $keyArr[1]) { + $monthKey = $keyArr[1]; + $i++; + } + + if ($i > 6) { + continue; + } + + $data[$dataKey]['property_room_rate_mapping'][$propertyRoomRateMappingKey]['prices'][$pricesKey]['monthly_min_stay'][$i][$key] = $val; + } + + + } + + } + } + + $propertyDataRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id', null) + ]; + $propertyDataResponse = $this->pdfContentService->propertyBaseData($propertyDataRequest); + if ($propertyDataResponse['status'] != 'success') { + throw new Exception($propertyDataResponse['message']); + } + + $propertyData = $propertyDataResponse['data']; + + $logoBase64 = null; + if ($propertyData['property_brand']) { + if ($propertyData['property_brand']['logo_name']) { + $logoFile = Config::get('app.imageUrl') . '/property-photos/' . $propertyData['property_brand']['property_id'] . '/logo/' . $propertyData['property_brand']['logo_name'] . '_250x250.' . $propertyData['property_brand']['logo_file_ext']; + $logoBase64 = 'data:image/' . $propertyData['property_brand']['logo_file_ext'] . ';base64,' . base64_encode(file_get_contents($logoFile)); + } + } + + /*$pdf = $this->pdf->loadView('pdf.inventory', compact('data','propertyData','logoFile','logoBase64'), [], 'UTF8' )->setPaper('a4', 'landscape'); + $pdfLanguage = upperCase(app('translator')->getLocale()); + $fileName = Str::slug('inventory', '_','en').'_'.$pdfLanguage;*/ + + return view('pdf.inventory', compact('data', 'propertyData', 'logoFile', 'logoBase64')); + /*return $pdf->download($fileName.'.pdf');*/ + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + public function propertyProductOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(), 1); + $params = current($params); + + if (fillOnUndefined($params, 'version') == 'v2') { + + $offerKey = []; + $offerKey[] = $params['propertyName']; + $offerKey[] = $params['executiveName']; + $offerKey[] = $params['executiveEmail']; + $offerKey[] = $params['executivePhone']; + $offerKey[] = $params['accountManager']; + $offerKey[] = hash('sha256', json_encode($params['detail'], JSON_UNESCAPED_UNICODE)); + + $offerKey = md5(implode('-', $offerKey)); + + } else { + $offerKey = md5($params['propertyName'] . '-' . $params['executiveName'] . '-' . $params['package'] . '-' . $params['numberOfRooms'] . '-' . $params['promotionCode']); + + if ($offerKey != fillOnUndefined($params, 'hashKey')) { + throw new ApiErrorException('HASH verification error!'); + } + } + + + $createParam = [ + 'offer_key' => $offerKey, + 'property_name' => $params['propertyName'], + 'executive_name' => $params['executiveName'], + 'executive_email' => $params['executiveEmail'], + 'executive_phone' => $params['executivePhone'], + 'account_manager_name' => fillOnUndefined($params, 'accountManagerName'), + 'account_manager_email' => fillOnUndefined($params, 'accountManagerEmail'), + 'confirm' => fillOnUndefined($params, 'confirm'), + 'offer_date' => Carbon::now()->toDateTimeString(), + 'offer_expire_date' => Carbon::now()->addDays(2)->toDateTimeString(), + 'package' => $params['package'], + 'promotion_code' => $params['promotionCode'], + 'detail' => fillOnUndefined($params, 'detail') ? json_encode($params['detail']) : json_encode($params), + 'version' => fillOnUndefined($params, 'version', 'v1'), + 'ip_address' => $params['ipAddress'], + 'status' => 1, + 'created_at' => time(), + 'updated_at' => time() + ]; + + + $propertyProductOfferCheck = PropertyProductOffer::where('offer_key', $offerKey)->first(); + if ($propertyProductOfferCheck) { + $propertyProductOfferSync = PropertyProductOffer::where('offer_key', $offerKey)->update($createParam); + } else { + $propertyProductOfferSync = PropertyProductOffer::insert($createParam); + } + + if (!$propertyProductOfferSync) { + throw new ApiErrorException('Your offer could not be generated. Please try again.'); + } + + if(fillOnUndefined($params, 'sendEmail')) { + $propertyProductOfferMail = ['offerKey' => $offerKey]; + $this->mailer->onQueue('propertyProductOfferMail', new PropertyProductOfferMail($propertyProductOfferMail)); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['offer_key' => $offerKey]]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + //$response['message'] = $e->getMessage(); + $response['message'] = 'Your offer could not be generated. Please try again.'; + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + public function propertyProductOfferExport(Request $request, $offerKey) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + $package = [ + 'LRG' => [ + 'commission' => 15, + 'minFee' => 2, + 'name' => 'Paket A', + 'creditRange' => [ + '25-50' => [ + 'min' => 25, + 'max' => 50, + 'monthly' => 250, + 'annually' => 3000, + ], + '51-75' => [ + 'min' => 51, + 'max' => 75, + 'monthly' => 500, + 'annually' => 6000, + ], + '76-100' => [ + 'min' => 76, + 'max' => 100, + 'monthly' => 750, + 'annually' => 9000, + ], + '101-150' => [ + 'min' => 101, + 'max' => 150, + 'monthly' => 1000, + 'annually' => 12000, + ], + '151-200' => [ + 'min' => 151, + 'max' => 200, + 'monthly' => 1500, + 'annually' => 18000, + ], + '201-250' => [ + 'min' => 201, + 'max' => 250, + 'monthly' => 2000, + 'annually' => 24000, + ], + '250+' => [ + 'min' => 251, + 'max' => null, + 'monthly' => 2500, + 'annually' => 30000, + ], + ] + ], + 'MED' => [ + 'commission' => 10, + 'minFee' => 3, + 'name' => 'Paket B', + 'creditRange' => [ + '25-50' => [ + 'min' => 25, + 'max' => 50, + 'monthly' => 375, + 'annually' => 4500, + ], + '51-75' => [ + 'min' => 51, + 'max' => 75, + 'monthly' => 750, + 'annually' => 9000, + ], + '76-100' => [ + 'min' => 76, + 'max' => 100, + 'monthly' => 1125, + 'annually' => 13500, + ], + '101-150' => [ + 'min' => 101, + 'max' => 150, + 'monthly' => 1500, + 'annually' => 18000, + ], + '151-200' => [ + 'min' => 151, + 'max' => 200, + 'monthly' => 2250, + 'annually' => 27000, + ], + '201-250' => [ + 'min' => 201, + 'max' => 250, + 'monthly' => 3000, + 'annually' => 36000, + ], + '250+' => [ + 'min' => 251, + 'max' => null, + 'monthly' => 3750, + 'annually' => 45000, + ], + ] + ], + 'SML' => [ + 'commission' => 5, + 'minFee' => 4, + 'name' => 'Paket C', + 'creditRange' => [ + '25-50' => [ + 'min' => 25, + 'max' => 50, + 'monthly' => 750, + 'annually' => 9000, + ], + '51-75' => [ + 'min' => 51, + 'max' => 75, + 'monthly' => 1500, + 'annually' => 18000, + ], + '76-100' => [ + 'min' => 76, + 'max' => 100, + 'monthly' => 2250, + 'annually' => 27000, + ], + '101-150' => [ + 'min' => 101, + 'max' => 150, + 'monthly' => 3000, + 'annually' => 36000, + ], + '151-200' => [ + 'min' => 151, + 'max' => 200, + 'monthly' => 4500, + 'annually' => 54000, + ], + '201-250' => [ + 'min' => 201, + 'max' => 250, + 'monthly' => 6000, + 'annually' => 72000, + ], + '250+' => [ + 'min' => 251, + 'max' => null, + 'monthly' => 7500, + 'annually' => 90000, + ], + ], + ] + ]; + + $campaign = [ + 'promotion' => [ + 'code' => [/*'ITF2025','ATF2025','TTI2025'*/], + 'percentage' => 50 + ], + 'oneYearAnnually' => [ + 'percentage' => 10 + ], + 'twoYearAnnually' => [ + 'percentage' => 20 + ] + ]; + + + $userListIds = [904, 941, 1485];//22-41 + + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + + $userList = User::whereIn('id', $userListIds)->get()->toArray(); + + $offerDetail = PropertyProductOffer::where('offer_key', $offerKey)->first(); + $offerDetail = $offerDetail ? $offerDetail->toArray() : null; + + if (empty($offerDetail)) { + return redirect()->to(config('app.url')); + } + + $pageContent = [ + 'name' => $offerDetail['property_name'], + 'executiveName' => $offerDetail['executive_name'], + 'executiveEmail' => $offerDetail['executive_email'], + 'executivePhone' => $offerDetail['detailArray']['executivePhone'], + 'offerTime' => $offerDetail['offer_date'], + 'offerExpireTime' => $offerDetail['offer_expire_date'], + 'offerTimeFormatted' => $offerDetail['offerTimeFormatted'], + 'offerExpireTimeFormatted' => $offerDetail['offerExpireTimeFormatted'], + 'numberOfRooms' => $offerDetail['detailArray']['numberOfRooms'], + 'package' => $offerDetail['package'], + 'promotionCode' => $offerDetail['promotion_code'], + ]; + + + $pageContent['package'] = !empty($request->get('package')) ? $request->get('package') : $pageContent['package']; + $pageContent['numberOfRooms'] = !empty($request->get('numberOfRooms')) ? $request->get('numberOfRooms') : $pageContent['numberOfRooms']; + + + $creditPackage = []; + if ((int)$pageContent['numberOfRooms'] < 25) { + $creditPackage = $package[$pageContent['package']]['creditRange']['25-50']; + } elseif ((int)$pageContent['numberOfRooms'] > 250) { + $creditPackage = $package[$pageContent['package']]['creditRange']['250+']; + } else { + $creditPackage = collect($package[$pageContent['package']]['creditRange']) + ->where('min', '<=', (int)$pageContent['numberOfRooms']) + ->where('max', '>=', (int)$pageContent['numberOfRooms']) + ->first(); + } + + + $pricing = []; + + $pricing['minFee'] = $package[$pageContent['package']]['minFee']; + $pricing['minFeeBeforeDiscount'] = $package[$pageContent['package']]['minFee']; + + if (in_array($pageContent['promotionCode'], $campaign['promotion']['code'])) { + $pricing['minFee'] = (int)($pricing['minFee'] * (1 - ($campaign['promotion']['percentage'] / 100))); + } + + $pricing['commission'] = $package[$pageContent['package']]['commission']; + $pricing['minFee'] = $pricing['minFee']; + $pricing['minFeeBeforeDiscount'] = $pricing['minFeeBeforeDiscount']; + + + $pricing['monthly']['minFee'] = (int)$pricing['minFee'] * (int)$pageContent['numberOfRooms']; + $pricing['monthly']['minFeeBeforePromotion'] = (int)$pricing['minFeeBeforeDiscount'] * (int)$pageContent['numberOfRooms']; + $pricing['monthly']['commission'] = $package[$pageContent['package']]['commission']; + //$pricing['monthly']['minReservationTotal'] = number_format(((int)$pricing['monthly']['minFee'] * 100) / $package[$pageContent['package']]['commission'], 0, '', '.'); + $pricing['monthly']['minReservationTotal'] = number_format(fillOnUndefined($creditPackage, 'monthly', 0), 0, '', '.'); + + + $pricing['annually']['minFee'] = (int)$pricing['monthly']['minFee'] * 12; + $pricing['annually']['minFeeBeforePromotion'] = (int)$pricing['monthly']['minFeeBeforePromotion'] * 12; + $pricing['annually']['commission'] = $package[$pageContent['package']]['commission']; + + $pricing['annually']['minFeeDiscount'] = (int)$pricing['annually']['minFee'] * (1 - ($campaign['oneYearAnnually']['percentage'] / 100));//%10 + + //$pricing['annually']['minReservationTotal'] = number_format(((int)$pricing['annually']['minFeeDiscount'] * 100) / $package[$pageContent['package']]['commission'], 0, '', '.'); + $pricing['annually']['minReservationTotal'] = number_format(fillOnUndefined($creditPackage, 'annually', 0), 0, '', '.'); + + + if ($pricing['minFee'] == $pricing['minFeeBeforeDiscount']) { + $pricing['monthly']['minFeeBeforePromotion'] = null; + $pricing['annually']['minFeeBeforePromotion'] = null; + } + + $pageContent['packageName'] = $package[$pageContent['package']]['name']; + $pageContent['pricing'] = $pricing; + + + $accountUserDetail = collect($userList)->where('email', $offerDetail['detailArray']['accountManager'])->first(); + $pageContent['accountManagerName'] = fillOnUndefined($accountUserDetail, 'nameSurname'); + $pageContent['accountManagerEmail'] = fillOnUndefined($accountUserDetail, 'email'); + $pageContent['accountManagerPhone'] = fillOnUndefined($accountUserDetail, 'phone'); + + + $pdfService = $this->pdf->loadView('pdf.propertyProductOffer', compact('pageContent'), [], 'UTF8'); + $pdfService->setOptions(['dpi' => 100, 'isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]); + $hotelName = Str::slug($pageContent['name'], '_', 'en'); + return $pdfService->stream($hotelName . '.pdf'); + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function propertyProductOfferData(Request $request, $offerKey) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + + $userListIds = [904, 941, 1485];//22-41 + + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + + $userList = User::whereIn('id', $userListIds)->get()->toArray(); + + $offerDetail = PropertyProductOffer::where('offer_key', $offerKey)->first(); + $offerDetail = $offerDetail ? $offerDetail->toArray() : null; + + if (empty($offerDetail)) { + return redirect()->to(config('app.url')); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $offerDetail]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} diff --git a/app/Http/Controllers/V1/LanguageController.php b/app/Http/Controllers/V1/LanguageController.php new file mode 100644 index 0000000..24dbdfe --- /dev/null +++ b/app/Http/Controllers/V1/LanguageController.php @@ -0,0 +1,138 @@ +languageService = $languageService; + $this->languageBaseService = $languageBaseService ; + } + + public function getAllLanguages($param) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500 ]; + try { + + if($param === "all"){ + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status' , 'condition' => '=', 'value' => 1 ] + ] , + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + }elseif ($param === "app"){ + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status' , 'condition' => '=', 'value' => 1 ], + ['field' => 'is_application' , 'condition' => '=', 'value' => 1 ], + ['field' => 'is_published' , 'condition' => '=', 'value' => 1 ] + ] , + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + }else{ + throw new ApiErrorException(lang('Parameter Error.')); + } + + $languages = $this->languageService->getAllLanguages($languageCriteria, ['id','code','name','status', 'language_key']); + + if ($languages['status'] != 'success') { + throw new ApiErrorException($languages['message']); + } + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null,'data' => $languages['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createApplicationLanguageFiles() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500 ]; + try { + $languageBaseResponse = $this->languageBaseService->createApplicationLanguageFiles() ; + if ($languageBaseResponse['status'] != 'success') { + throw new ApiErrorException($languageBaseResponse['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null,'data' => null ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getNullDescriptions() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500 ]; + try { + $applicationLanguages = $this->languageService->getApplicationLanguages(); + $applicationLanguages = $applicationLanguages['data']; + $responseLangTitle = [] ; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangTitle[] = [ + 'language_code' => $langKey, + 'description' => isset($titleLangContents[$langKey]) ? $titleLangContents[$langKey] : null + ]; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null,'data' => $responseLangTitle ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/MyWebContentController.php b/app/Http/Controllers/V1/MyWebContentController.php new file mode 100644 index 0000000..301dd4a --- /dev/null +++ b/app/Http/Controllers/V1/MyWebContentController.php @@ -0,0 +1,1277 @@ +request = $request; + $this->pdf = $pdf; + $this->myWebContentService = $myWebContentService; + $this->pdfContentService = $pdfContentService; + $this->languageService = $languageService; + $this->propertyWebPhotoMappingService = $propertyWebPhotoMappingService; + $this->propertyRoomPhotoMappingService = $propertyRoomPhotoMappingService; + $this->propertyPlaceService = $propertyPlaceService; + $this->propertyWebLogService = $propertyWebLogService; + $this->findCountryCodeService = $findCountryCodeService; + $this->propertyWebMetaService = $propertyWebMetaService; + + $this->languageCode = $request->headers->get('language'); + + } + + + public function webMetaTag($propertyId, $propertyWebMetaId, $code = null) + { + + $webMetaTag = null; + $webMetaTagCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'property_web_meta_id', 'condition' => '=', 'value' => $propertyWebMetaId] + ], + ]; + + if ($code) { + $webMetaTagCriteria['criteria'][] = ['field' => 'code', 'condition' => '=', 'value' => $code]; + } + + $webMetaTagRequest = $this->propertyWebMetaService->selectMapping($webMetaTagCriteria); + $webMetaTagRequest = $webMetaTagRequest['status'] == 'success' && !empty($webMetaTagRequest['status']) ? $webMetaTagRequest['data'] : []; + + foreach ($webMetaTagRequest as $webMetaTagData) { + + $webMetaTag[$webMetaTagData['property_web_meta_tag']['name']] = [ + 'property_web_meta' => $webMetaTagData['property_web_meta']['name'], + 'property_web_meta_tag' => $webMetaTagData['property_web_meta_tag']['name'], + 'content' => collect($webMetaTagData['textArray'])->where('language_code', $this->languageCode)->first()['content'] ?? null + ]; + + } + + return $webMetaTag; + + } + + public function home(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->home($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $agentIp = isset($params['agentInfo']['ip']) ? $params['agentInfo']['ip'] : null; + if ($agentIp !== null) { + // Find Country Code with IP + $ipResponse = $this->findCountryCodeService->findCountryWithIpAddress($agentIp); + if ($ipResponse['status'] !== 'success') { + //throw new ApiErrorException('IP Not Found'); + } + + // Create or Update Web Log + if (!empty($params['agentInfo']) && !empty($ipResponse['data']) && !empty($ipResponse['data']['code']) && $ipResponse['status']) { + + $agentParams = [ + 'web_id' => $params['property_web_id'], + 'ip' => $agentIp, + 'country_code' => $ipResponse['data'] ? $ipResponse['data']['code'] : null, + 'isRobot' => $params['agentInfo']['isRobot'] === true ? $params['agentInfo']['isRobot'] : false, + 'isDesktop' => $params['agentInfo']['isDesktop'] === true ? $params['agentInfo']['isDesktop'] : false, + 'isPhone' => $params['agentInfo']['isPhone'] === true ? $params['agentInfo']['isPhone'] : false + ]; + + if ($agentParams['isRobot'] === false) { + $webLogResponse = $this->propertyWebLogService->createPropertyWebLog($agentParams); + } + + } + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 1); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function aboutUs(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->aboutUs($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 2); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function gallery(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->gallery($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 9); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function rooms(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->rooms($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 17); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function roomDetail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + if (!isset($params['room_id'])) { + throw new ApiErrorException('room_id required'); + } + + $responseData = $this->myWebContentService->roomDetail($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 18, $params['room_id']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function contact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->contact($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 5); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function executiveDetail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->executiveDetail($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function contactForm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + + if ($request->headers->get('language')) { + $language = $request->headers->get('language'); + app('translator')->setLocale($language); + } + + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->contactForm($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => $responseData['message'], 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function placeCategoryPlaces(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + if (!isset($params['place_category_id'])) { + throw new ApiErrorException('place_category_id required'); + } + + $responseData = $this->myWebContentService->placeCategoryPlaces($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 12); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPlace(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + if (!isset($params['place_id'])) { + throw new ApiErrorException('place_id required'); + } + + $responseData = $this->myWebContentService->getPlace($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 13, $params['place_id']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function kvkk(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->kvkk($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 10); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function multimedia(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->multimedia($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + + $contentCodeConfirmToken = fillOnUndefined($params, 'contentCodeConfirmToken'); + $contentCodeConfirmTokenCache = Cache::get($contentCodeConfirmToken); + + + $multimedia = []; + if ($responseData['data']['id'] == $contentCodeConfirmTokenCache['propertyId']) { + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + + + $factSheetParam = [ + 'contentCodeConfirmToken' => fillOnUndefined($params, 'contentCodeConfirmToken'), + 'language' => [] + ]; + + foreach ($availableLanguages['data'] as $availableLanguage) { + $factSheetParam['language'][$availableLanguage['code']] = $availableLanguage; + $factSheetParam['language'][$availableLanguage['code']]['url'] = Config::get('app.url') . '/multimedia/fact/' . $availableLanguage['code'] . '/' . $contentCodeConfirmToken; + } + + + $photoParam = []; + + //Gallery + $propertyWebPhotoMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $responseData['data']['id']] + ], + 'with' => ['propertyPhoto'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $propertyWebPhotoMapping = $this->propertyWebPhotoMappingService->select($propertyWebPhotoMappingCriteria); + + if ($propertyWebPhotoMapping['status'] == 'success' && !empty($propertyWebPhotoMapping['data'])) { + + $propertyWebPhotoMapping = $propertyWebPhotoMapping['data']; + $firstPhoto = reset($propertyWebPhotoMapping); + + $photoParam['gallery']['all'] = [ + 'id' => 'all', + 'title' => 'Galeri', + 'language_key' => 'myweb-menu-gallery', + 'url' => Config::get('app.url') . '/multimedia/photo/gallery/all/' . $contentCodeConfirmToken, + 'photoUrl' => $firstPhoto['property_photo']['photoUrl'] + ]; + + } + + + //Room + $propertyRoomPhotoMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $responseData['data']['id']] + ], + 'with' => ['propertyRoomPhoto', 'propertyRoom'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $propertyRoomPhotoMapping = $this->propertyRoomPhotoMappingService->select($propertyRoomPhotoMappingCriteria); + + if ($propertyRoomPhotoMapping['status'] == 'success' && !empty($propertyRoomPhotoMapping['data'])) { + + $propertyRoomPhotoMapping = $propertyRoomPhotoMapping['data']; + $firstPhoto = reset($propertyWebPhotoMapping); + + $photoParam['room']['all'] = [ + 'id' => 'all', + 'title' => 'Tüm Odalar', + 'language_key' => 'api-multimedia-all_room_photos', + 'url' => Config::get('app.url') . '/multimedia/photo/room/all/' . $contentCodeConfirmToken, + 'photoUrl' => $firstPhoto['property_photo']['photoUrl'] + ]; + + + $propertyRoomPhotos = []; + foreach ($propertyRoomPhotoMapping as $propertyRoomPhoto) { + if ($propertyRoomPhoto['property_room']['status'] != 1) { + continue; + } + $propertyRoomPhotos[$propertyRoomPhoto['room_id']]['title'] = $propertyRoomPhoto['property_room']['name']; + $propertyRoomPhotos[$propertyRoomPhoto['room_id']]['photo'][] = $propertyRoomPhoto['property_room_photo']['photoUrl']; + } + + foreach ($propertyRoomPhotos as $propertyRoomId => $propertyRoomPhoto) { + $photoParam['room'][$propertyRoomId] = [ + 'id' => $propertyRoomId, + 'title' => $propertyRoomPhoto['title'], + 'language_key' => $propertyRoomPhoto['title'], + 'url' => Config::get('app.url') . '/multimedia/photo/room/' . $propertyRoomId . '/' . $contentCodeConfirmToken, + 'photoUrl' => reset($propertyRoomPhoto['photo']) + ]; + } + } + + //Place + $propertyPlacePhotoMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $responseData['data']['id']] + ], + 'with' => ['propertyPlacePhoto', 'propertyPlace'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $propertyPlacePhotoMapping = $this->propertyPlaceService->selectPhotoMapping($propertyPlacePhotoMappingCriteria); + + + if ($propertyPlacePhotoMapping['status'] == 'success' && !empty($propertyPlacePhotoMapping['data'])) { + + + $propertyPlacePhotoMapping = $propertyPlacePhotoMapping['data']; + $firstPhoto = reset($propertyPlacePhotoMapping); + + $photoParam['place']['all'] = [ + 'id' => 'all', + 'title' => 'Tüm Mekanlar', + 'language_key' => 'api-multimedia-all_place_photos', + 'url' => Config::get('app.url') . '/multimedia/photo/place/all/' . $contentCodeConfirmToken, + 'photoUrl' => $firstPhoto['property_place_photo']['photoUrl'] + ]; + + + $propertyPlacePhotos = []; + foreach ($propertyPlacePhotoMapping as $propertyPlacePhoto) { + $propertyPlacePhotos[$propertyPlacePhoto['place_id']]['title'] = $propertyPlacePhoto['property_place']['name']; + $propertyPlacePhotos[$propertyPlacePhoto['place_id']]['photo'][] = $propertyPlacePhoto['property_place_photo']['photoUrl']; + } + + foreach ($propertyPlacePhotos as $propertyPlaceId => $propertyPlacePhoto) { + $photoParam['place'][$propertyPlaceId] = [ + 'id' => $propertyRoomId, + 'title' => $propertyPlacePhoto['title'], + 'language_key' => $propertyPlacePhoto['title'], + 'url' => Config::get('app.url') . '/multimedia/photo/place/' . $propertyPlaceId . '/' . $contentCodeConfirmToken, + 'photoUrl' => reset($propertyPlacePhoto['photo']) + ]; + } + } + + + $multimedia = [ + "factSheet" => $factSheetParam, + "photo" => $photoParam + ]; + + } + + $responseData['data']['multimedia'] = $multimedia; + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 11); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function multimediaConfirm(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $contentCodeConfirmToken = null; + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->body['params']; + + $responseData = $this->myWebContentService->multimedia($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + if (empty($responseData['data']['content_code'])) { + throw new ApiErrorException('No security code has yet been created to download multimedia.'); + } + + if ($params['privateToken'] != md5($responseData['data']['content_code'])) { + throw new ApiErrorException('Security code could not be verified'); + } + + $contentCodeConfirmToken = md5($params['privateToken'] . '|' . $params['contentCodeToken']); + + $dataArray = [ + 'propertyId' => $responseData['data']['id'], + 'contentCodeConfirmToken' => $contentCodeConfirmToken + ]; + + Cache::put($contentCodeConfirmToken, $dataArray, 10 * 60); //10 Min, 600 TTL + + unset($dataArray['propertyId']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $dataArray]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function multimediaFactDownload(Request $request, $language = 'en', $contentCodeConfirmToken) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $contentCodeConfirmTokenCache = Cache::get($contentCodeConfirmToken); + + if (is_null($contentCodeConfirmTokenCache)) { + throw new ApiErrorException('Security code could not be verified'); + } + + $responseData = $this->myWebContentService->multimedia(['property_id' => $contentCodeConfirmTokenCache['propertyId']]); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $pdfDataRequest = [ + 'locale' => $language, + 'property_id' => $contentCodeConfirmTokenCache['propertyId'], + ]; + + $pdfDataResponse = $this->pdfContentService->pdfData($pdfDataRequest); + if ($pdfDataResponse['status'] != 'success') { + throw new Exception($pdfDataResponse['message']); + } + + $pdfData = $pdfDataResponse['data']; + + $logoBase64 = null; + if ($pdfData['property_brand']) { + if ($pdfData['property_brand']['logo_name']) { + $logoFile = Config::get('app.imageUrl') . '/property-photos/' . $pdfData['property_brand']['property_id'] . '/logo/' . $pdfData['property_brand']['logo_name'] . '_250x250.' . $pdfData['property_brand']['logo_file_ext']; + $logoBase64 = 'data:image/' . $pdfData['property_brand']['logo_file_ext'] . ';base64,' . base64_encode(file_get_contents($logoFile)); + } + } + + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $availableLanguages = $availableLanguages['status'] == 'success' ? $availableLanguages['data'] : []; + $availableLanguages = pickItemFromArray('code', $availableLanguages); + + if (!in_array($language, $availableLanguages)) { + $language = 'en'; + } + + + app('translator')->setLocale($language); + + $this->pdf->loadView('pdf.hotelContent', compact('pdfData', 'logoBase64'), [], 'UTF8'); + $this->pdf->setOptions(['dpi' => 100, 'isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]); + + return $this->pdf->stream()->header('Content-Type', 'application/pdf'); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function multimediaPhotoDownload(Request $request, $type, $id, $contentCodeConfirmToken) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $contentCodeConfirmTokenCache = Cache::get($contentCodeConfirmToken); + + if (is_null($contentCodeConfirmTokenCache)) { + throw new ApiErrorException('Security code could not be verified'); + } + + $downloadPhotoIds = []; + + switch ($type) { + case 'gallery': + + $photoMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $contentCodeConfirmTokenCache['propertyId']] + ], + 'with' => ['propertyPhoto'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + + $photoMapping = $this->propertyWebPhotoMappingService->select($photoMappingCriteria); + + if ($photoMapping['status'] == 'success' && !empty($photoMapping['data'])) { + $photoMapping = !empty($photoMapping['data']) ? $photoMapping['data'] : []; + $downloadPhotoIds = collect($photoMapping)->pluck('property_photo.photoUrl.fixed')->toArray(); + } + + + break; + case 'room': + + + $photoMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $contentCodeConfirmTokenCache['propertyId']] + ], + 'with' => ['propertyRoomPhoto', 'propertyRoom'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + if ($id != 'all' && is_numeric($id)) { + $photoMappingCriteria['criteria'][] = ['field' => 'room_id', 'condition' => '=', 'value' => $id]; + } + + $photoMapping = $this->propertyRoomPhotoMappingService->select($photoMappingCriteria); + + if ($photoMapping['status'] == 'success' && !empty($photoMapping['data'])) { + $photoMapping = !empty($photoMapping['data']) ? $photoMapping['data'] : []; + $downloadPhotoIds = collect($photoMapping)->pluck('property_room_photo.photoUrl.fixed')->toArray(); + } + + break; + case 'place': + + $photoMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $contentCodeConfirmTokenCache['propertyId']] + ], + 'with' => ['propertyPlacePhoto', 'propertyPlace'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + + ]; + + if ($id != 'all' && is_numeric($id)) { + $photoMappingCriteria['criteria'][] = ['field' => 'place_id', 'condition' => '=', 'value' => $id]; + } + + $photoMapping = $this->propertyPlaceService->selectPhotoMapping($photoMappingCriteria); + + if ($photoMapping['status'] == 'success' && !empty($photoMapping['data'])) { + $photoMapping = !empty($photoMapping['data']) ? $photoMapping['data'] : []; + $downloadPhotoIds = collect($photoMapping)->pluck('property_place_photo.photoUrl.fixed')->toArray(); + } + + break; + case 'default': + break; + + } + + if (empty($downloadPhotoIds)) { + throw new ApiErrorException('Photo list is empty'); + } + + + $publicDir = public_path(); + $zipFileStoragePath = $publicDir . '/property-zip-files'; + + if (!File::exists($zipFileStoragePath)) { + File::makeDirectory($zipFileStoragePath, 0777, true); + } + + $zipFileName = md5($contentCodeConfirmTokenCache['propertyId'] . '-' . $type . '-' . $id) . '.zip'; + + + $zipArchive = new ZipArchive; + if (file_exists($zipFileStoragePath . '/' . $zipFileName)) { + unlink($zipFileStoragePath . '/' . $zipFileName); + } + + if ($zipArchive->open($zipFileStoragePath . '/' . $zipFileName, ZipArchive::CREATE) === TRUE) { + foreach ($downloadPhotoIds as $downloadPhoto) { + + $downloadPhotoExplode = explode('/', $downloadPhoto); + $photoName = last($downloadPhotoExplode); + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $contentCodeConfirmTokenCache['propertyId'] . '/' . $photoName; + if (file_exists($photoUrlFilePath)) { + $zipArchive->addFile($photoUrlFilePath, $photoName); + } + } + $zipArchive->close(); + } + + $responseData = Config::get('app.zipFilesUrl') . $zipFileName; + + return redirect($responseData); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function content(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->content($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 6); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function contentDetail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->contentDetail($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + + $responseData['data']['metaTag'] = isset($responseData['data']['property_content']['id']) ? $this->webMetaTag($params['property_id'], 7, $responseData['data']['property_content']['id']) : null; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function policy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->policy($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 14); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function promotion(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + if ($request->headers->get('language')) { + $params['language'] = $request->headers->get('language'); + } + + $responseData = $this->myWebContentService->promotion($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 16); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function affiliateRequestMail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + + if ($request->headers->get('language')) { + $params['language'] = $request->headers->get('language'); + } + + + $responseData = $this->myWebContentService->affiliateRequestMail($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function booking(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData['data'] = null; + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 4); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function facts(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->aboutUs($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 8); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function privacyPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData = $this->myWebContentService->aboutUs($params); + if ($responseData['status'] != 'success') { + throw new ApiErrorException($responseData['message']); + } + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 15); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function announcement(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->body['params']; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $responseData['data'] = null; + + $responseData['data']['metaTag'] = $this->webMetaTag($params['property_id'], 3); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PaymentController.php b/app/Http/Controllers/V1/PaymentController.php new file mode 100644 index 0000000..dd09dca --- /dev/null +++ b/app/Http/Controllers/V1/PaymentController.php @@ -0,0 +1,368 @@ +propertyPaymentService = $propertyPaymentService ; + $this->request = $request ; + $this->currencyService = $currencyService ; + $this->bookingPaymentService = $bookingPaymentService ; + + } + + + public function getPaymentTypeList(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $paymentList = $this->propertyPaymentService->getPaymentTypeList($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $currencyList = $this->currencyService->getCurrencyList(); + + if($currencyList['status'] != 'success'){ + throw new Exception($currencyList['message']); + } + + $currencyList = collect($currencyList['data'])->map(function ($value){ + return [ + 'code' => $value['code'], + 'name' => $value['name'], + 'language_key' => $value['language_key'], + ]; + }) ; + $responseData['payment_types'] = $paymentList['data'] ; + $responseData['currencies'] = $currencyList ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPaymentType(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $paymentList = $this->propertyPaymentService->getPaymentType($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $paymentList['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPaymentMappingList(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $paymentList = $this->propertyPaymentService->getPaymentMappingList($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createPaymentMapping(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->createPaymentMapping($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePaymentMappingStatus(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->updatePaymentMappingStatus($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function setPaymentMappingDefault(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->setPaymentMappingDefault($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePaymentMapping(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->updatePaymentMapping($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePaymentInstallments(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->updateInstallments($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePaymentInstallmentStatus(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + $responseData = null ; + $paymentList = $this->propertyPaymentService->updatePaymentInstallmentStatus($params); + + if($paymentList['status'] != 'success'){ + throw new Exception($paymentList['message']); + } + + $responseData = $paymentList['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function paymentDashboard(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $paymentDashboard = $this->bookingPaymentService->getPaymentDashboard($params); + if($paymentDashboard['status'] != "success"){ + throw new ApiErrorException($paymentDashboard['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $paymentDashboard['data']]; + } catch (ApiErrorException $e) { + $responseData['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $responseData['message'] = $e->getMessage(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + + } +} diff --git a/app/Http/Controllers/V1/ProductController.php b/app/Http/Controllers/V1/ProductController.php new file mode 100644 index 0000000..a5a483d --- /dev/null +++ b/app/Http/Controllers/V1/ProductController.php @@ -0,0 +1,105 @@ +request = $request; + $this->productService = $productService; + } + + public function getPropertyProducts(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyProducts = $this->productService->getPropertyProducts($requestParams); + if($propertyProducts['status'] != 'success'){ + throw new ApiErrorException($propertyProducts['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyProducts['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyProductActivate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'product_id' => fillOnUndefined($params, 'product_id'), + ]; + + $propertyProducts = $this->productService->propertyProductActivate($requestParams); + if($propertyProducts['status'] != 'success'){ + throw new ApiErrorException($propertyProducts['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyProducts['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyAdditionalInfoController.php b/app/Http/Controllers/V1/PropertyAdditionalInfoController.php new file mode 100644 index 0000000..73c0ea6 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyAdditionalInfoController.php @@ -0,0 +1,131 @@ +request = $request; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + } + + public function getPropertyAdditionalInfo() + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + //TODO : Validataion eklenecek. Eklendikten sonra if kaldırılması gerekiyor + if (!isset($params['locale']) || empty($params['locale'])) { + throw new ApiErrorException(lang('Location is a required field')); + } + + $getPropertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo($params); + $getPropertyAdditionalInfo = $getPropertyAdditionalInfo ? $getPropertyAdditionalInfo : null; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyAdditionalInfo]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function insertPropertyAdditionalInfo() + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + + //TODO : Validataion eklenecek ( benzersiz alanları unutma!!!). Eklendikten sonra if'in kaldırılması gerekiyor. + if (!isset($params['data'][0]['additional_info_key_id']) || empty($params['data'][0]['additional_info_key_id'])) { + throw new ApiErrorException(lang('Location is a required field')); + } + + + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyAdditionalInfo() + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + + try { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + + //TODO : Validataion eklenecek ( benzersiz alanları unutma!!!). Eklendikten sonra if'in kaldırılması gerekiyor. + if (!isset(current($params['data'])['additional_info_key_id']) || empty(current($params['data'])['additional_info_key_id'])) { + throw new ApiErrorException(lang('Location is a required field')); + } + + $response = $this->propertyAdditionalInfoService->updatePropertyAdditionalInfo($params); + + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/PropertyAddonController.php b/app/Http/Controllers/V1/PropertyAddonController.php new file mode 100644 index 0000000..c41827b --- /dev/null +++ b/app/Http/Controllers/V1/PropertyAddonController.php @@ -0,0 +1,349 @@ +params = Input::all(); + $this->params = $this->params['params']; + $this->propertyAddonService = $propertyAddonService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyAddonValidator = $propertyAddonValidator; + $this->languageService = $languageService; + } + + protected function propertyChannelMappingCheck($propertyId, $channelId) + { + + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] == 'success') { + if (empty($propertyChannelMapping['data'])) { + return false; + } else { + return true; + } + } else { + return false; + } + + } + + public function getPropertyAddon(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + //TODO: Validator + + $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']); + if (!$propertyChannelMappingCheck) { + throw new ApiErrorException('Transactions cannot be made through a unconnected channel.'); + } + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']], + ['field' => 'status', 'condition' => '!=', 'value' => 3], + ], + //'with' => ['propertyAddon'] + ]; + $columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'title', 'description', 'amount', 'type', 'min_stay','status']; + $requestSelectResult = $this->propertyAddonService->selectPropertyChannelAddon($requestSelectCriteria, $columns); + + $propertyChannelAddon = []; + if ($requestSelectResult['status'] == 'success') { + $propertyChannelAddon = $requestSelectResult['data']; + } + + $propertyChannelAddonCollect = collect($propertyChannelAddon); + + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['fact'], + 'orderBy' => [ + ['field' => 'order_number', 'value' => 'ASC'] + ], + ]; + + $columns = ['id', 'fact_id', 'title', 'attribute', 'order_number']; + $propertyAddonResult = $this->propertyAddonService->selectPropertyAddon($requestSelectCriteria, $columns); + + $propertyAddon = []; + if ($requestSelectResult['status'] == 'success') { + $propertyAddon = $propertyAddonResult['data']; + } + + $getApplicationLanguages = $this->languageService->getApplicationLanguages(); + if ($getApplicationLanguages['status'] != 'success') { + throw new ApiErrorException($getApplicationLanguages['message']); + } + $applicationLanguages = $getApplicationLanguages['data']; + + $propertyAddonList = []; + foreach ($propertyAddon as $addon) { + + $channelAddon = []; + $channelAddons = $propertyChannelAddonCollect->where('property_addon_id', $addon['id'])->toArray(); + + $isSelected = false; + if ($channelAddons) { + $channelAddons = array_values($channelAddons); + + foreach ($channelAddons as $channelAddonItem) { + + $responseLangDescription = []; + $descriptionLangContents = json_decode($channelAddonItem['description'], 1); + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => isset($descriptionLangContents[$langKey]) ? $descriptionLangContents[$langKey] : null + ]; + } + + $channelAddonItem['description'] = $responseLangDescription; + $channelAddon[] = $channelAddonItem; + + } + + $isSelected = true; + + } else { + + $responseLangDescription = []; + foreach ($applicationLanguages as $applicationLanguage) { + $langKey = $applicationLanguage['code']; + $responseLangDescription[] = [ + 'language_code' => $langKey, + 'description' => null + ]; + } + + $channelAddon[] = [ + 'property_id' => $this->params['property_id'], + 'channel_id' => $this->params['channel_id'], + 'property_addon_id' => $addon['id'], + 'title' => '', + 'description' => $responseLangDescription, + 'amount' => '', + 'type' => '', + 'min_stay' => null, + 'status' => 1 + ]; + } + + $propertyAddonList[] = [ + 'id' => $addon['id'], + 'fact_id' => $addon['fact_id'], + 'name' => $addon['fact']['name'], + 'language_key' => $addon['fact']['language_key'], + 'icon' => $addon['fact']['icon'], + 'attributeArray' => $addon['attributeArray'], + 'is_selected' => $isSelected, + 'channelAddon' => $channelAddon + ]; + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyAddonList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncPropertyAddon(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + /*$validationResult = $this->propertyAddonValidator->validate($this->params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + }*/ + + $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']); + if (!$propertyChannelMappingCheck) { + throw new ApiErrorException('Transactions cannot be made through a unconnected channel.'); + } + + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']], + ['field' => 'property_addon_id', 'condition' => '=', 'value' => $this->params['property_addon_id']], + ] + ]; + $columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'amount', 'type']; + $requestSelectResult = $this->propertyAddonService->selectPropertyChannelAddon($requestSelectCriteria, $columns); + + $propertyChannelAddon = []; + if ($requestSelectResult['status'] == 'success') { + $propertyChannelAddon = $requestSelectResult['data']; + } + + $currentPropertyChannelAddon = $propertyChannelAddon; + $propertyChannelAddon = collect($propertyChannelAddon); + + DB::beginTransaction(); + + //Status Delete All ChannelAddon + foreach ($currentPropertyChannelAddon as $channelAddon) { + $updateParam = [ + 'property_id' => $channelAddon['property_id'], + 'channel_id' => $channelAddon['channel_id'], + 'property_addon_id' => $channelAddon['property_addon_id'], + 'status' => 3, + 'updated_by' => $request->auth->id, + ]; + $this->propertyAddonService->updatePropertyChannelAddon($channelAddon['id'], $updateParam); + } + //Status Delete All ChannelAddon + + + $channelAddonProcessed = []; + foreach ($this->params['channelAddon'] as $channelAddon) { + + + $description = []; + foreach (fillOnUndefined($channelAddon, "description", []) as $title) { + $description[$title['language_code']] = $title['description']; + } + + if (!isset($channelAddon['id'])) { + + $createParam = [ + 'property_id' => $this->params['property_id'], + 'channel_id' => $this->params['channel_id'], + 'property_addon_id' => $this->params['property_addon_id'], + 'title' => fillOnUndefined($channelAddon, 'title'), + 'description' => json_encode($description), + 'amount' => $channelAddon['amount'], + 'type' => $channelAddon['type'], + 'min_stay' => fillOnUndefined($channelAddon,'min_stay'), + 'status' => fillOnUndefined($channelAddon, 'status', 1) == 1 ? 1 : 0, + 'created_by' => $request->auth->id, + 'updated_by' => $request->auth->id, + ]; + + $syncPropertyAddon = $this->propertyAddonService->createPropertyChannelAddon($createParam); + + if ($syncPropertyAddon['status'] != 'success') { + throw new ApiErrorException($syncPropertyAddon['message']); + } + + $channelAddonProcessed[] = $syncPropertyAddon['data']; + + } elseif (isset($channelAddon['id']) && $propertyChannelAddon->where('id', $channelAddon['id'])->isNotEmpty()) { + + $updateParam = [ + 'property_id' => $this->params['property_id'], + 'channel_id' => $this->params['channel_id'], + 'property_addon_id' => $this->params['property_addon_id'], + 'title' => fillOnUndefined($channelAddon, 'title'), + 'description' => json_encode($description), + 'amount' => $channelAddon['amount'], + 'type' => $channelAddon['type'], + 'min_stay' => fillOnUndefined($channelAddon,'min_stay'), + 'status' => fillOnUndefined($channelAddon, 'status', 1) == 1 ? 1 : 0, + 'updated_by' => $request->auth->id, + ]; + + $syncPropertyAddon = $this->propertyAddonService->updatePropertyChannelAddon($channelAddon['id'], $updateParam); + + if ($syncPropertyAddon['status'] != 'success') { + throw new ApiErrorException($syncPropertyAddon['message']); + } + + $channelAddonProcessed[] = $syncPropertyAddon['data']; + } + + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelAddonProcessed]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/PropertyAwardCertificatesController.php b/app/Http/Controllers/V1/PropertyAwardCertificatesController.php new file mode 100644 index 0000000..5834011 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyAwardCertificatesController.php @@ -0,0 +1,256 @@ +request = $request ; + $this->propertyAwardsCertificateService = $propertyAwardsCertificateService ; + + } + + + public function getAwardCertificateCategories( ){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $getPropertyAwardsCertificateList = $this->propertyAwardsCertificateService->getCategoryList($params); + + if($getPropertyAwardsCertificateList['status'] != 'success'){ + throw new Exception($getPropertyAwardsCertificateList['message']); + } + + $responseData['award_certificate_categories'] = $getPropertyAwardsCertificateList['data'] ; + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createAwardsCertificates(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = + [ + "property_id" => $request->input('property_id'), + "category_id" => $request->input('category_id'), + "language_code" => $request->input('language_code'), + "name" => $request->input('name'), + "date" => $request->input('date'), + "url" => $request->input('url'), + "file" => $request->file('file'), + ]; + + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + + $storeAwardsCertificate = $this->propertyAwardsCertificateService->create($requestParams); + if ($storeAwardsCertificate['status'] != 'success') { + throw new ApiErrorException($storeAwardsCertificate['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeAwardsCertificate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function listAwardsCertificates(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + + $params['user_id'] = $this->request->auth->id; + + + $storeAwardsCertificate = $this->propertyAwardsCertificateService->listAwardsCertificates($params); + if ($storeAwardsCertificate['status'] != 'success') { + throw new ApiErrorException($storeAwardsCertificate['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeAwardsCertificate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function updateAwardsCertificates(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = + [ + "award_certificate_id" => $request->input('award_certificate_id'), + "property_id" => $request->input('property_id'), + "category_id" => $request->input('category_id'), + "language_code" => $request->input('language_code'), + "name" => $request->input('name'), + "date" => $request->input('date'), + "url" => $request->input('url'), + "file" => $request->file('file'), + ]; + + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + + $storeAwardsCertificate = $this->propertyAwardsCertificateService->update($requestParams); + if ($storeAwardsCertificate['status'] != 'success') { + throw new ApiErrorException($storeAwardsCertificate['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeAwardsCertificate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function deletePhotoAwardsCertificates(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + + $params['user_id'] = $this->request->auth->id; + + + $storeAwardsCertificate = $this->propertyAwardsCertificateService->deletePhotoAwardsCertificates($params); + if ($storeAwardsCertificate['status'] != 'success') { + throw new ApiErrorException($storeAwardsCertificate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeAwardsCertificate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function updateStatusAwardsCertificates(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + + $params['user_id'] = $this->request->auth->id; + + + $storeAwardsCertificate = $this->propertyAwardsCertificateService->updateStatus($params); + if ($storeAwardsCertificate['status'] != 'success') { + throw new ApiErrorException($storeAwardsCertificate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeAwardsCertificate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyBookingController.php b/app/Http/Controllers/V1/PropertyBookingController.php new file mode 100644 index 0000000..912ac1f --- /dev/null +++ b/app/Http/Controllers/V1/PropertyBookingController.php @@ -0,0 +1,888 @@ +request = $request; + $this->mailer = $mailer; + $this->bookingService = $bookingService; + $this->bookingRoomService = $bookingRoomService; + $this->propertyBookingEngineService = $propertyBookingEngineService; + $this->bookingTicketService = $bookingTicketService; + $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; + $this->channelManagerBookingService = $channelManagerBookingService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->bookingUpdateValidator = $bookingUpdateValidator; + $this->newBookingMailService = $newBookingMailService; + } + + public function getPropertyBookingList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyBooking = $this->bookingService->getBookingList($params); + if ($getPropertyBooking['status'] != "success") { + throw new ApiErrorException($getPropertyBooking['message']); + } + + if (isset($params['excelExport']) && $params['excelExport']) { + + + foreach ($getPropertyBooking['data'] as $bookingKey => $booking) { + + $dataTableData[$bookingKey]['booking_channel'] = $booking['booking_channel']['name']; + $dataTableData[$bookingKey]['booking_code'] = $booking['booking_code']; + $dataTableData[$bookingKey]['name_surname'] = $booking['booking_contact']['nameSurname']; + $dataTableData[$bookingKey]['checkin_date'] = $booking['checkin_date']; + $dataTableData[$bookingKey]['checkout_date'] = $booking['checkout_date']; + $dataTableData[$bookingKey]['payment_type'] = $booking['booking_payment_type']['name']; + $dataTableData[$bookingKey]['total'] = $booking['total']; + $dataTableData[$bookingKey]['currency_code'] = $booking['currency_code']; + $dataTableData[$bookingKey]['status'] = $booking['booking_status']['name']; + $dataTableData[$bookingKey]['reservation_time'] = Carbon::createFromTimestamp($booking['reservation_time'])->toDateTimeString(); + + } + + + $fileNameHash = [ + 'property_id' => $params['property_id'], + 'channel_id' => fillOnUndefined($params['filter'], 'channel_id'), + 'booking_code' => fillOnUndefined($params['filter'], 'booking_code'), + 'payment_type_code' => fillOnUndefined($params['filter'], 'payment_type_code'), + 'status' => fillOnUndefined($params['filter'], 'status'), + 'date_type' => fillOnUndefined($params['filter'], 'date_type'), + 'date_range' => fillOnUndefined($params['filter'], 'date_range'), + ]; + + $fileName = 'PropertyBookingList-' . md5(implode('-', $fileNameHash)) . '.xlsx'; + $fileNamePath = 'excel/' . $fileName; + $fileNamePublic = config('app.url') . '/' . $fileNamePath; + + $excelStore = Excel::store(new PropertyBookingListExport($dataTableData), $fileNamePath, 'public'); + + if (!$excelStore) { + throw new ApiErrorException(lang('Mapping data not found')); + } + + $data = [ + 'url' => $fileNamePublic + ]; + + //Delete files older than 1 hours + $excelFileDir = public_path('excel'); + foreach (glob($excelFileDir . '/' . "*") as $file) { + if (filemtime($file) < time() - 3600) { // 6 hours 21600 + unlink($file); + } + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $data]; + + } else { + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['booking' => $getPropertyBooking['data']]]; + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyBookingListFilter(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyBookingFilter = $this->bookingService->getPropertyBookingListFilter($params); + if ($getPropertyBookingFilter['status'] != "success") { + throw new ApiErrorException($getPropertyBookingFilter['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyBookingFilter['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyBookingDetail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $bookingDetail = $this->bookingService->getBookingDetail($params); + if ($bookingDetail['status'] != "success") { + throw new ApiErrorException($bookingDetail['message']); + } + + //BOOKING ADDON + $bookingAddons = $bookingDetail['data']['booking_addon']; + unset($bookingDetail['data']['booking_addon']); + + $bookingAddonList = []; + foreach ($bookingAddons as $bookingAddon) { + + $bookingAddonAttributeList = []; + $isHasAttribute = false; + $attributeArray = []; + if (!empty($bookingAddon['property_channel_addon']['property_addon']['attributeArray'])) { + $isHasAttribute = true; + $attributeArray = $bookingAddon['property_channel_addon']['property_addon']['attributeArray']; + $bookingAddonAttributes = json_decode($bookingAddon['attribute'], 1); + if (!is_null($bookingAddonAttributes)) { + foreach ($bookingAddonAttributes as $key => $bookingAddonAttribute) { + foreach ($bookingAddonAttribute as $bookingAddonAttributeKey => $bookingAddonAttributeValue) { + + if (isset($bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey])) { + $bookingAddonAttributeList[] = [ + 'key' => $bookingAddonAttributeKey, + 'name' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['name'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['language_key'], + 'value' => $bookingAddonAttributeValue, + ]; + } + + } + } + } + } + + $bookingAddonList[] = [ + 'id' => $bookingAddon['id'], + 'booking_id' => $bookingAddon['booking_id'], + 'property_channel_addon_id' => $bookingAddon['property_channel_addon_id'], + 'count' => $bookingAddon['count'], + 'amount' => $bookingAddon['amount'], + 'total' => $bookingAddon['total'], + 'min_stay' => $bookingAddon['property_channel_addon']['min_stay'], + 'currency_code' => $bookingAddon['currency_code'], + 'name' => $bookingAddon['property_channel_addon']['property_addon']['fact']['name'], + 'title' => $bookingAddon['property_channel_addon']['title'], + 'language_key' => $bookingAddon['property_channel_addon']['property_addon']['fact']['language_key'], + 'icon' => $bookingAddon['property_channel_addon']['property_addon']['fact']['icon'], + 'isHasAttribute' => $isHasAttribute, + 'attributeArray' => $attributeArray, + 'attribute' => $bookingAddonAttributeList + ]; + + } + + $bookingDetail['data']['booking_addon'] = $bookingAddonList; + //BOOKING ADDON + + //DAILY AMOUNT BY ROOM + foreach ($bookingDetail['data']['booking_room'] as $roomKey => $roomDetail) { + + if (!empty($roomDetail['room_rate_mapping']['property_room'])) { + $bookingDetail['data']['booking_room'][$roomKey]['room_name'] = $roomDetail['room_rate_mapping']['property_room']['name']; + } + + if (!empty($roomDetail['room_rate_mapping']['property_room_rate'])) { + $bookingDetail['data']['booking_room'][$roomKey]['room_rate_name'] = $roomDetail['room_rate_mapping']['property_room_rate']['name']; + } + + $diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date'])); + $baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays); + + $roomDailyAmount = []; + + + if (!empty($roomDetail['daily_amount'])) { + $roomDetailDailyAmount = json_decode($roomDetail['daily_amount'], 1); + if (!empty($roomDetailDailyAmount) && isset($roomDetailDailyAmount)) { + foreach ($roomDetailDailyAmount as $roomRateAmount) { + $roomDailyAmount[] = [ + 'date' => $roomRateAmount['date'], + 'amount' => $roomRateAmount['amount'], + 'currency_code' => $roomRateAmount['currency_code'], + ]; + } + } + } + + if (empty($roomDailyAmount)) { + $roomRateDetail = is_array($roomDetail['rate_detail']) ? $roomDetail['rate_detail'] : json_decode($roomDetail['rate_detail'], 1); + if (!empty($roomRateDetail) && isset($roomRateDetail['days'])) { + foreach ($roomRateDetail['days'] as $roomRateDay => $roomRateAmount) { + $roomDailyAmount[] = [ + 'date' => Carbon::parse($roomRateDay)->toDateString(), + 'amount' => $roomRateAmount, + 'currency_code' => $roomDetail['currency_code'], + ]; + } + } + } + + if (empty($roomDailyAmount)) { + $currentDate = $roomDetail['checkin_date']; + for ($i = 0; $i < $diffInDays; $i++) { + $roomDailyAmount[] = [ + 'date' => $currentDate, + 'amount' => $baseRateDaily, + 'currency_code' => $roomDetail['currency_code'], + ]; + $currentDate = Carbon::parse($currentDate)->addDay()->toDateString(); + } + } + + $bookingDetail['data']['booking_room'][$roomKey]['daily_amount'] = $roomDailyAmount; + + $extraParam = null; + if (!empty($roomDetail['extra_param'])) { + $extraParamDecode = json_decode($roomDetail['extra_param'], 1); + + foreach ($extraParamDecode as $extraParamKey => $extraParamValue) { + + $extraParamTitle = explode('_', $extraParamKey); + foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) { + $extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue); + } + $extraParamTitle = implode(' ', $extraParamTitle); + + $extraParam[$extraParamKey] = [ + 'title' => $extraParamTitle, + 'value' => $extraParamValue, + ]; + } + + } + + $bookingDetail['data']['booking_room'][$roomKey]['extra_param'] = $extraParam; + $bookingDetail['data']['booking_room'][$roomKey]['occupancyFormatted'] = occupancyCodeFormatted($roomDetail['occupancy_code']); + + } + //DAILY AMOUNT BY ROOM + + + if (empty($bookingDetail['data']['is_viewed'])) { + $this->bookingService->update($params['booking_id'], ['is_viewed' => 1]); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['booking_detail' => $bookingDetail['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function sendBookingEmail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $bookingDetail = $this->bookingService->getBookingDetail($params); + if ($bookingDetail['status'] != "success") { + throw new ApiErrorException($bookingDetail['message']); + } + + if (!in_array($bookingDetail['data']['status'], [0,1])) { + throw new ApiErrorException('Only active and canceled reservation emails can be sent'); + } + + if (in_array($bookingDetail['data']['status'], [0])) { + $mailParams = ['booking_id' => $params['booking_id']]; + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams)); + } + + if (in_array($bookingDetail['data']['status'], [1])) { + $mailParams = ['booking_id' => $params['booking_id']]; + $this->newBookingMailService->process($mailParams); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookEngineDashboard(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyBookingEngine = $this->propertyBookingEngineService->bookEngineDashboard($params); + if ($getPropertyBookingEngine['status'] != "success") { + throw new ApiErrorException($getPropertyBookingEngine['message']); + } + + $responseData['booking_engine'] = $getPropertyBookingEngine['data']; + + + //Cache + $getBookingDetailedListCacheKey = md5('getBookingDetailedList-' . $params['property_id']); + if (Cache::has($getBookingDetailedListCacheKey)) { + $responseDataCache = Cache::get($getBookingDetailedListCacheKey); + + $responseData['all_booking_count'] = $responseDataCache['all_booking_count']; + $responseData['success_booking_count'] = $responseDataCache['success_booking_count']; + $responseData['pre_booking_count'] = $responseDataCache['pre_booking_count']; + $responseData['conversion_rate'] = $responseDataCache['conversion_rate']; + $responseData['total_pax_count'] = $responseDataCache['total_pax_count']; + + } else { + + $getPropertyBooking = $this->bookingService->getBookingDetailedList($params); + if ($getPropertyBooking['status'] != "success") { + throw new ApiErrorException($getPropertyBooking['message']); + } + + $bookings = collect($getPropertyBooking['data']); + $channelBookings = $bookings->where('channel_id', '=', 1); + $getBookingEngineBookings = $channelBookings->all(); + $paxCountArray = $channelBookings->where('status', '=', 1)->map(function ($booking) { + $roomPaxCount = collect($booking['booking_room'])->map(function ($room) { + return collect($room['room_pax'])->count(); + })->values()->first(); + return [ + 'booking_id' => $booking['id'], + 'room_pax_count' => $roomPaxCount, + ]; + + })->values()->all(); + + $totalPaxCount = collect($paxCountArray)->sum('room_pax_count'); + + $allBookingCount = $channelBookings->count(); + $preBookingCount = $channelBookings->where('status', '=', 2)->count(); + $successBookingCount = $channelBookings->where('status', '=', 1)->count(); + + $conversionRate = $allBookingCount > 0 ? ($successBookingCount * 100) / $allBookingCount : 0; + + $responseData['all_booking_count'] = $allBookingCount; + $responseData['success_booking_count'] = $successBookingCount; + $responseData['pre_booking_count'] = $preBookingCount; + $responseData['conversion_rate'] = number_format($conversionRate, 2); + $responseData['total_pax_count'] = $totalPaxCount; + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function bookingEngineContractUpload(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = + [ + "property_id" => $request->input('property_id'), + "contract_file" => $request->file('contract_file'), + "user_id" => $this->request->auth->id + ]; + + $uploadResponse = $this->propertyBookingEngineService->contractFileUpload($params); + if ($uploadResponse['status'] != "success") { + throw new ApiErrorException($uploadResponse['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $uploadResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPropertyTransactionList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyTransaction = $this->bookingService->getTransactionList($params); + if ($getPropertyTransaction['status'] != "success") { + throw new ApiErrorException($getPropertyTransaction['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['transactions' => $getPropertyTransaction['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updateBooking(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + if (!isset($params['property_id'])) { + $params = $this->request->requestParams; + } + + $validationResult = $this->bookingUpdateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $bookingstatusList = $this->bookingService->getBookingstatusList(); + $bookingstatusListCollect = collect($bookingstatusList['data']); + if ($bookingstatusListCollect->where('id', $params['status'])->count() <= 0) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $bookingRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['booking_id']], + ], + 'with' => ['bookingRoom','propertyBookingEngineSearch'], + 'firstRow' => true + ]; + + $booking = $this->bookingService->select($bookingRequest); + + if ($booking['status'] != 'success') { + throw new ApiErrorException($booking['message']); + } + + if (empty($booking['data'])) { + throw new ApiErrorException('Booking not found.'); + } + + $booking = $booking['data']; + + $isNonRefundable = false; + if($params['status'] == 0) { + foreach ($booking['booking_room'] as $roomDetail) { + $cancellationPolicy = json_decode($roomDetail['cancellation_policy'],1); + if(!empty($cancellationPolicy) && is_array($cancellationPolicy)) { + if(isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) { + $isNonRefundable = true; + break; + } + } + } + } + + //Trivago Check + /*if(isset($booking['property_booking_engine_search']['referrer']) && $booking['property_booking_engine_search']['referrer'] == 'trivago:trivago') { + if($isNonRefundable) { + throw new ApiErrorException('Refunds are not permitted for non-refundable transactions received through Trivago.'); + } + }*/ + + + $bookingUpdateParam = []; + $bookingUpdateAvailableColumns = ['total', 'status', 'currency_code']; + foreach ($params as $param => $value) { + if (in_array($param, $bookingUpdateAvailableColumns)) { + $bookingUpdateParam[$param] = $value; + } + } + + $action = null; + $percentage = 1; + + if ($booking['status'] == 0) { + $percentage = 0; + } elseif ($bookingUpdateParam['total'] > $booking['total']) { + $action = 'INC'; + $percentage = ($bookingUpdateParam['total'] - $booking['total']) / $booking['total'] * 100; + } else { + $action = 'DEC'; + $percentage = ($booking['total'] - $bookingUpdateParam['total']) / $booking['total'] * 100; + } + + $bookingUpdate = $this->bookingService->update($booking['id'], $bookingUpdateParam); + + if ($bookingUpdate['status'] != 'success') { + throw new ApiErrorException($booking['message']); + } + + + foreach ($booking['booking_room'] as $room) { + + if (!is_null($action)) { + + $totalAmount = $room['total']; + $affectedAmount = ($room['total'] * $percentage) / 100; + + if ($action == 'INC') { + $totalAmount = $totalAmount + $affectedAmount; + } + if ($action == 'DEC') { + $totalAmount = $totalAmount - $affectedAmount; + } + + $bookingRoomUpdate = $this->bookingRoomService->update($room['id'], ['total' => $totalAmount]); + + if ($bookingUpdate['status'] != 'success') { + throw new ApiErrorException($bookingRoomUpdate['message']); + } + + } + + //Availability Decrease + if (in_array($params['status'], [0, 3]) && $booking['status'] == 1) { + + $dateByDay = []; + $diffInDays = Carbon::parse($room['checkin_date'])->floatDiffInDays(Carbon::parse($room['checkout_date'])); + for ($i = 0; $i < $diffInDays; $i++) { + $dateByDay[] = Carbon::parse($room['checkin_date'])->addDay($i)->format('Y-m-d'); + } + + foreach ($dateByDay as $day) { + + $requestParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $booking['property_id']], + ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1], + ['field' => 'date', 'condition' => '=', 'value' => $day] + ], + 'firstRow' => true, + ]; + + $dateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); + + if ($dateAvailability['status'] == 'success') { + $currentAvailability = $dateAvailability['data']['availability']; + $currentAvailability = $currentAvailability + 1; + $this->propertyRoomAvailabilityService->update($dateAvailability['data']['id'], ['availability' => $currentAvailability]); + } + + } + + + } + + } + + + //PUSH CHANNEL MANAGER QUEUE + //if ($booking['channel_id'] == 1) { + + $type = 'Modify'; + + if (in_array($params['status'], [1, 2, 3])) { + $type = 'Modify'; + } + + if (in_array($params['status'], [0])) { + $type = 'Cancel'; + } + + $channelManagerPropertyMappingCriteria = [ + 'criteria' => + [ + ['field' => 'property_id', 'condition' => '=', 'value' => $booking['property_id']], + ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); + + if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { + + foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) { + + $extraParamDecode = json_decode($booking['extra_param'], 1); + + if($channelPropertyData['channel_manager_id'] == 11 && !isset($extraParamDecode['trv_reference'])) { + continue; + } + + //Yandex + if(in_array($channelPropertyData['channel_manager_id'],[13])) { + continue; + } + + $channelManagerBookingCreateParam = [ + 'property_id' => $booking['property_id'], + 'booking_id' => $booking['id'], + 'channel_manager_id' => $channelPropertyData['channel_manager_id'], + 'type' => $type, + ]; + + $channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam); + + } + + } + + //} + //PUSH CHANNEL MANAGER QUEUE + + + //Booking Ticket Log + $bookingTicketRequest = [ + 'criteria' => [ + ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']], + ], + 'firstRow' => true + ]; + + $bookingTicket = $this->bookingTicketService->select($bookingTicketRequest, ['id']); + + $userId = isset($this->request->auth->id) ? $this->request->auth->id : 1; + + $createBookingTicketParams = []; + if (empty($bookingTicket['data'])) { + + $createBookingTicketParams = [ + 'booking_id' => $booking['id'], + 'code' => getTicketCodeGenerate('TCK'), + 'user_id' => $userId, + 'is_log' => true, + 'log' => json_encode($booking), + 'status' => 1 + ]; + + } else { + + $createBookingTicketParams = [ + 'parent_id' => $bookingTicket['data']['id'], + 'booking_id' => $booking['id'], + 'user_id' => $userId, + 'is_log' => true, + 'log' => json_encode($booking), + 'status' => 1 + ]; + + } + + $bookingTicketCreate = $this->bookingTicketService->create($createBookingTicketParams); + //Booking Ticket Log + + if ($type == 'Cancel') { + $notificationCancelToPropertyUser = [ + 'booking_id' => $booking['id'], + ]; + + $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser)); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['transactions' => $bookingUpdate['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getBookingPayment(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $getBookingPayment = $this->bookingService->getBookingPayment($params); + if ($getBookingPayment['status'] != "success") { + throw new ApiErrorException($getBookingPayment['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getBookingPayment['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyBookingTicketController.php b/app/Http/Controllers/V1/PropertyBookingTicketController.php new file mode 100644 index 0000000..8af8e17 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyBookingTicketController.php @@ -0,0 +1,293 @@ +bookingService = $bookingService; + $this->bookingTicketService = $bookingTicketService; + $this->propertyTicketGetValidator = $propertyTicketGetValidator; + $this->propertyTicketCreateValidator = $propertyTicketCreateValidator; + $this->mailer = $mailer; + $this->notificationService = $notificationService; + $this->params = json_decode($request->getContent(), 1); + $this->params = $this->params['params']; + } + + public function createTicket(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + + $params = $this->params; + if(is_null($params)) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params['ip_address'] = fillOnUndefined($params,'ip_address') ? $params['ip_address'] : $request->ip(); + + $validationResult = $this->propertyTicketCreateValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $bookingRequest = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['booking_code']], + ], + 'firstRow' => true + ]; + + $booking = $this->bookingService->select($bookingRequest); + + if ($booking['status'] != 'success') { + throw new ApiErrorException($booking['message']); + } + + if (empty($booking['data'])) { + throw new ApiErrorException('Booking not found.'); + } + + $booking = $booking['data']; + + $bookingTicketRequest = [ + 'criteria' => [ + ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']], + ], + 'firstRow' => true + ]; + + $bookingTicket = $this->bookingTicketService->select($bookingTicketRequest, ['id']); + if ($bookingTicket['status'] != 'success') { + throw new ApiErrorException($bookingTicket['message']); + } + + $createParams = []; + if (empty($bookingTicket['data'])) { + + $createParams = [ + 'booking_id' => $booking['id'], + 'code' => getTicketCodeGenerate('TCK'), + 'user_id' => $params['user_id'], + 'message' => $params['message'], + 'is_note' => fillOnUndefined($params, 'is_note') == false ? null : $params['is_note'], + 'is_log' => fillOnUndefined($params, 'is_log'), + 'ip_address' => fillOnUndefined($params,'ip_address'), + 'status' => 1 + ]; + + } else { + + $createParams = [ + 'parent_id' => $bookingTicket['data']['id'], + 'booking_id' => $booking['id'], + 'user_id' => $params['user_id'], + 'message' => $params['message'], + 'is_note' => fillOnUndefined($params, 'is_note') == false ? null : $params['is_note'], + 'is_log' => fillOnUndefined($params, 'is_log'), + 'ip_address' => fillOnUndefined($params,'ip_address'), + 'status' => 1 + ]; + + } + + $bookingTicketCreate = $this->bookingTicketService->create($createParams); + + if ($bookingTicketCreate['status'] != 'success') { + throw new ApiErrorException($bookingTicketCreate['message']); + } + + //BookingTicketMail + if(is_null($createParams['is_note'])) { + $mailParams = [ + 'user' => $params['user_id'], + 'booking_id' => $booking['id'], + //'locale' => 'en' + ]; + + $this->mailer->onQueue('bookingTicketMail', new BookingTicketMail($mailParams)); + } + //BookingTicketMail + + //PUSH NOTIFICATION + if(empty($params['user_id'])) { + $notificationParam = ['booking_id' => $booking['id']]; + $this->notificationService->sendTicketNotification($notificationParam); + } + //PUSH NOTIFICATION + + if(empty($params['user_id'])) { + $this->bookingService->update($booking['id'], ['is_viewed' => null]); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $bookingTicketCreate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if($response['status']) { + DB::commit(); + }else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getTicketList() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $this->params; + if(is_null($params)) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $validationResult = $this->propertyTicketGetValidator->validate($params); + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $bookingRequest = [ + 'criteria' => [ + ['field' => 'booking_code', 'condition' => '=', 'value' => $params['booking_code']], + ], + 'with' => ['bookingContact'], + 'firstRow' => true + ]; + + $booking = $this->bookingService->select($bookingRequest); + if ($booking['status'] != 'success') { + throw new ApiErrorException($booking['message']); + } + + $booking = $booking['data']; + + $bookingTicketRequest = [ + 'criteria' => [ + ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']], + ['field' => 'is_log', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + + ], + 'with' => ['user'], + 'orderBy' => [ + ['field' => 'created_at', 'value' => 'ASC'] + ] + ]; + + + if (!isset($params['user_id']) || is_null($params['user_id'])) { + $bookingTicketRequest['criteria'][] = ['field' => 'is_note', 'condition' => '=', 'value' => null]; + } + + $column = ['id', 'user_id', 'message', 'is_note', 'is_viewed', 'created_at']; + $bookingTicket = $this->bookingTicketService->select($bookingTicketRequest, $column); + if ($bookingTicket['status'] != 'success') { + throw new ApiErrorException($bookingTicket['message']); + } + + + foreach ($bookingTicket['data'] as $key => $row) { + + if(is_null($row['user_id'])) { + $bookingTicket['data'][$key]['nameSurname'] = $booking['booking_contact']['nameSurname']; + } else { + $bookingTicket['data'][$key]['nameSurname'] = $row['user']['nameSurname']; + } + + unset($bookingTicket['data'][$key]['user']); + } + + + $updateCriteria = [ + 'criteria' => [ + ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']], + ['field' => 'is_log', 'condition' => '=', 'value' => null], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + + if (!isset($params['user_id']) || is_null($params['user_id'])) { + $updateCriteria['criteria'][] = ['field' => 'user_id', 'condition' => '!=', 'value' => null]; + $updateCriteria['criteria'][] = ['field' => 'is_viewed', 'condition' => '=', 'value' => null]; + } else { + $updateCriteria['criteria'][] = ['field' => 'user_id', 'condition' => '=', 'value' => null]; + $updateCriteria['criteria'][] = ['field' => 'is_viewed', 'condition' => '=', 'value' => null]; + } + + + $updateParam = [ + 'is_viewed' => 1 + ]; + + $this->bookingTicketService->updateWhere($updateCriteria, $updateParam); + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $bookingTicket['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} + diff --git a/app/Http/Controllers/V1/PropertyBrandController.php b/app/Http/Controllers/V1/PropertyBrandController.php new file mode 100644 index 0000000..4e1bf3c --- /dev/null +++ b/app/Http/Controllers/V1/PropertyBrandController.php @@ -0,0 +1,158 @@ +request = $request; + $this->propertyBrandService = $propertyBrandService; + $this->propertyConfigService = $propertyConfigService ; + + } + + public function updatePropertyBrand(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + + + $params = + [ + "property_id" => $request->input('property_id'), + "title" => $request->input("title"), + "color_codes" => $request->input("colors"), + "logo_path" => $request->input( "logo_path"), + "logo_name" => $request->input( "logo_name"), + "photo" => $request->file('photo'), + "user_id" => $this->request->auth->id + ]; + + + $updateResponse = $this->propertyBrandService->updatePropertyBrand($params); + + if($updateResponse['status'] != 'success'){ + throw new ApiErrorException($updateResponse['message']); + } + + $rateParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => fillOnUndefined($params, 'user_id'), + 'property_rate_for' => 'Property.Brand.Update', + ]; + $this->propertyConfigService->rateProperty(array_merge($params, $rateParams)); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property_brand' => $updateResponse['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyBrand(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $getPropertyBrand = $this->propertyBrandService->getPropertyBrand($params); + if($getPropertyBrand['status'] != "success"){ + throw new ApiErrorException($getPropertyBrand['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property_brand' => $getPropertyBrand['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function clearBrandLogo(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->credentials->user_id; + + $getPropertyBrand = $this->propertyBrandService->clearBrandLogo($params); + + if($getPropertyBrand['status'] != "success"){ + throw new ApiErrorException($getPropertyBrand['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => '']; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/PropertyCancellationPolicyController.php b/app/Http/Controllers/V1/PropertyCancellationPolicyController.php new file mode 100644 index 0000000..6c3f638 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyCancellationPolicyController.php @@ -0,0 +1,207 @@ +request = $request; + $this->propertyCancellationPolicyService = $propertyCancellationPolicyService; + } + + public function getPropertyCancellationPolicyList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyCancellationList = $this->propertyCancellationPolicyService->getPropertyCancellationPolicyList($params); + + if ($getPropertyCancellationList['status'] != "success") { + throw new ApiErrorException($getPropertyCancellationList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['cancellation_policies' => $getPropertyCancellationList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyCancellationPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + if (!isset($params['is_date_range']) || (isset($params['is_date_range']) && $params['is_date_range'] == 0)) { + $params['is_date_range'] = 0; + unset($params['start_date']); + unset($params['finish_date']); + } + + $createResponse = $this->propertyCancellationPolicyService->createPropertyCancellationPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyCancellationPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + if (!isset($params['is_date_range']) || (isset($params['is_date_range']) && $params['is_date_range'] == 0)) { + $params['is_date_range'] = 0; + unset($params['start_date']); + unset($params['finish_date']); + } + + $updateResponse = $this->propertyCancellationPolicyService->updatePropertyCancellationPolicy($params); + + if ($updateResponse['status'] != 'success') { + throw new ApiErrorException($updateResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getRoomRateChannelCancellationPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyCancellationList = $this->propertyCancellationPolicyService->getRoomRateChannelCancellationPolicy($params); + + if ($getPropertyCancellationList['status'] != "success") { + throw new ApiErrorException($getPropertyCancellationList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['rooms' => $getPropertyCancellationList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updateRoomRateChannelCancellationPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + + $getPropertyCancellationList = $this->propertyCancellationPolicyService->updateRoomRateChannelCancellationPolicy($params); + + if ($getPropertyCancellationList['status'] != "success") { + throw new ApiErrorException($getPropertyCancellationList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyChainController.php b/app/Http/Controllers/V1/PropertyChainController.php new file mode 100644 index 0000000..2de0000 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChainController.php @@ -0,0 +1,72 @@ +request = $request; + $this->propertyChainService = $propertyChainService; + + } + + + + public function getPropertyChains(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + ]; + + $propertyChains = $this->propertyChainService->getPropertyChains($requestParams); + if($propertyChains['status'] != 'success'){ + throw new ApiErrorException($propertyChains['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChains['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyChannelBookingPaymentSetupController.php b/app/Http/Controllers/V1/PropertyChannelBookingPaymentSetupController.php new file mode 100644 index 0000000..ae66d7b --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelBookingPaymentSetupController.php @@ -0,0 +1,111 @@ +request = $request; + $this->propertyChannelBookingPaymentSetupService = $propertyChannelBookingPaymentSetupService; + + } + + + + public function getPropertyChannelBookingPaymentSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $propertyChannelBookingPaymentSetup = $this->propertyChannelBookingPaymentSetupService->getChannelBookingPaymentSetup($requestParams); + + if($propertyChannelBookingPaymentSetup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelBookingPaymentSetup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelBookingPaymentSetup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyChannelBookingPaymentSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $requestParams = $params ; + $requestParams['user_id'] = $this->request->auth->id; + + $propertyChannelBookingPaymentSetup = $this->propertyChannelBookingPaymentSetupService->addChannelBookingPaymentSetup($requestParams); + + if($propertyChannelBookingPaymentSetup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelBookingPaymentSetup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelBookingPaymentSetup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyChannelCategoryController.php b/app/Http/Controllers/V1/PropertyChannelCategoryController.php new file mode 100644 index 0000000..5e62a10 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelCategoryController.php @@ -0,0 +1,74 @@ +request = $request; + $this->propertyChannelCategoryService = $propertyChannelCategoryService; + + } + + + + public function getPropertyChannelCategories(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + ]; + + $propertyChannelCategory = $this->propertyChannelCategoryService->getPropertyChannelCategories($requestParams); + if($propertyChannelCategory['status'] != 'success'){ + throw new ApiErrorException($propertyChannelCategory['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelCategory['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyChannelContactController.php b/app/Http/Controllers/V1/PropertyChannelContactController.php new file mode 100644 index 0000000..d6216f5 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelContactController.php @@ -0,0 +1,262 @@ +request = $request; + $this->propertyChannelService = $propertyChannelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyChannelContactService = $propertyChannelContactService; + } + + + public function getPropertyChannelContact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $channelMappingRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $channelMapping = $this->propertyChannelMappingService->getOnlyPropertyChannelMapping($channelMappingRequest); + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']); + } + + if(!count($channelMapping['data'])){ + throw new ApiErrorException("This channel is not connected with this property"); + } + + $channelContactRequest = [ + 'property_channel_mapping_id' => $channelMapping["data"]["id"], + ]; + + if(isset($request->params['id'])){ + $channelContactRequest = [ + 'id' => fillOnUndefined($params, 'id'), + 'property_channel_mapping_id' => $channelMapping["data"]["id"], + ]; + } + + $channelContact = $this->propertyChannelContactService->getContact($channelContactRequest); + if($channelContact['status'] != 'success'){ + throw new ApiErrorException($channelContact['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelContact['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + public function addPropertyChannelContact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $channelMappingRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $channelMapping = $this->propertyChannelMappingService->getOnlyPropertyChannelMapping($channelMappingRequest); + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']); + } + + if(!count($channelMapping['data'])){ + throw new ApiErrorException("This channel is not connected with this property"); + } + + $requestParams = [ + 'property_channel_mapping_id' => $channelMapping["data"]["id"], + 'name' => fillOnUndefined($params, 'name', null), + 'email' => fillOnUndefined($params, 'email', null), + 'user_id' => $this->request->auth->id, + ]; + + $channelContact = $this->propertyChannelContactService->add($requestParams); + if($channelContact['status'] != 'success'){ + throw new ApiErrorException($channelContact['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelContact['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyChannelContact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $channelMappingRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $channelMapping = $this->propertyChannelMappingService->getOnlyPropertyChannelMapping($channelMappingRequest); + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']); + } + + if(!count($channelMapping['data']) || $channelMapping['data']['id'] != $params['property_channel_mapping_id']){ + throw new ApiErrorException("This channel is not connected with this property"); + } + + $requestParams = [ + 'name' => fillOnUndefined($params, 'name', null), + 'email' => fillOnUndefined($params, 'email', null), + 'updated_by' => $this->request->auth->id, + 'updated_at' => time() + ]; + + $channelContact = $this->propertyChannelContactService->update($params['id'],$requestParams); + if($channelContact['status'] != 'success'){ + throw new ApiErrorException($channelContact['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelContact['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function deletePropertyChannelContact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $channelMappingRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $channelMapping = $this->propertyChannelMappingService->getOnlyPropertyChannelMapping($channelMappingRequest); + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']); + } + + if(!count($channelMapping['data']) || $channelMapping['data']['id'] != $params['property_channel_mapping_id']){ + throw new ApiErrorException("This channel is not connected with this property"); + } + + $requestParams = [ + 'id' => $params["id"], + 'property_channel_mapping_id' => $params['property_channel_mapping_id'] + ]; + + $channelContact = $this->propertyChannelContactService->delete($requestParams); + if($channelContact['status'] != 'success'){ + throw new ApiErrorException($channelContact['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelContact['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyChannelController.php b/app/Http/Controllers/V1/PropertyChannelController.php new file mode 100644 index 0000000..41ce539 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelController.php @@ -0,0 +1,207 @@ +request = $request; + $this->propertyChannelService = $propertyChannelService; + + } + + + + public function getPropertyChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'type' => fillOnUndefined($params, 'type'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + ]; + + $propertyChannel = $this->propertyChannelService->getPropertyChannels($requestParams); + if($propertyChannel['status'] != 'success'){ + throw new ApiErrorException($propertyChannel['message']); + } + + //CHANNEL RESTRICTION PROPERTIES + foreach ($propertyChannel['data'] as $channelId => $channel) { + if(!empty($channel['restriction'])) { + $channelRestriction = json_decode($channel['restriction'],1); + if(!in_array($params['property_id'],$channelRestriction)) { + unset($propertyChannel['data'][$channelId]); + } + } + } + + + //dd($propertyChannel['data'], $params['property_id']); + + //TODO: Channell sıralaması için bir alan seçilip kurgulanacak + //$propertyChannelCollect = collect($propertyChannel['data']); + //$propertyChannel['data'] = $propertyChannelCollect->sortByDesc('fax', SORT_NUMERIC )->toArray(); + //$propertyChannel['data'] = array_values($propertyChannel['data']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannel['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'name' => fillOnUndefined($params, 'name'), + 'official_name' => fillOnUndefined($params, 'official_name'), + 'description' => fillOnUndefined($params, 'description'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'currency_code' => fillOnUndefined($params, 'currency_code', []), + 'logo' => fillOnUndefined($params, 'logo'), + 'address' => fillOnUndefined($params, 'address'), + 'zip_code' => fillOnUndefined($params, 'zip_code'), + 'email' => fillOnUndefined($params, 'email'), + 'phone' => fillOnUndefined($params, 'phone'), + 'phone2' => fillOnUndefined($params, 'phone2'), + 'fax' => fillOnUndefined($params, 'fax'), + 'score' => fillOnUndefined($params, 'score'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyChannel = $this->propertyChannelService->addPropertyChannel($requestParams); + if($propertyChannel['status'] != 'success'){ + throw new ApiErrorException($propertyChannel['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannel['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'parent_id' => fillOnUndefined($params, 'parent_id'), + 'name' => fillOnUndefined($params, 'name'), + 'official_name' => fillOnUndefined($params, 'official_name'), + 'description' => fillOnUndefined($params, 'description'), + 'channel_category_id' => fillOnUndefined($params, 'channel_category_id'), + 'country_code' => fillOnUndefined($params, 'country_code'), + 'currency_code' => fillOnUndefined($params, 'currency_code', []), + 'logo' => fillOnUndefined($params, 'logo'), + 'address' => fillOnUndefined($params, 'address'), + 'zip_code' => fillOnUndefined($params, 'zip_code'), + 'email' => fillOnUndefined($params, 'email'), + 'phone' => fillOnUndefined($params, 'phone'), + 'phone2' => fillOnUndefined($params, 'phone2'), + 'fax' => fillOnUndefined($params, 'fax'), + 'score' => fillOnUndefined($params, 'score'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyChannel = $this->propertyChannelService->updatePropertyChannel($requestParams); + if($propertyChannel['status'] != 'success'){ + throw new ApiErrorException($propertyChannel['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannel['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + + + +} diff --git a/app/Http/Controllers/V1/PropertyChannelGroupController.php b/app/Http/Controllers/V1/PropertyChannelGroupController.php new file mode 100644 index 0000000..e6e6663 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelGroupController.php @@ -0,0 +1,497 @@ +request = $request; + $this->propertyChannelGroupService = $propertyChannelGroupService; + $this->propertyChannelGroupChannelMappingRepository = $propertyChannelGroupChannelMappingRepository; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomService = $propertyRoomService; + } + + + public function getPropertyChannelGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + if(isset($request->params['group_id'])){ + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'id' => fillOnUndefined($params, 'group_id'), + ]; + } + + $propertyChannelGroup = $this->propertyChannelGroupService->getPropertyChannelGroup($requestParams); + if($propertyChannelGroup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelGroup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelGroup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyChannelGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id', null), + 'name' => fillOnUndefined($params, 'name', null), + 'created_by' => $this->request->auth->id, + 'updated_by' => $this->request->auth->id, + ]; + + + $propertyChannelGroup = $this->propertyChannelGroupService->create($requestParams); + if($propertyChannelGroup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelGroup['message']); + } + + $channels = fillOnUndefined($params, 'channels',[]); + + $insertData = []; + foreach ($channels as $channel){ + $insertData[] = [ + 'channel_group_id' => $propertyChannelGroup['data']['id'], + 'channel_id' => $channel, + 'status' => 1, + 'created_by' => $this->request->auth->id, + 'updated_by' => $this->request->auth->id, + 'created_at' => time(), + 'updated_at' => time() + ]; + } + + $propertyChannelGroupChannels = $this->propertyChannelGroupChannelMappingRepository->insert($insertData); + if($propertyChannelGroupChannels['status'] != 'success'){ + throw new ApiErrorException($propertyChannelGroupChannels['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelGroup['data']]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + DB::rollBack(); + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyChannelGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'name' => fillOnUndefined($params, 'name', null), + 'updated_by' => $this->request->auth->id, + 'updated_at' => time() + ]; + + + $propertyChannelGroup = $this->propertyChannelGroupService->update($params['group_id'], $requestParams); + if($propertyChannelGroup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelGroup['message']); + } + + $channels = fillOnUndefined($params, 'channels',[]); + + $channelRequest = [ + 'criteria' => [ + ['field' => 'channel_group_id', 'condition' => '=', 'value' => $params['group_id']], + ] + ]; + + $propertyChannelGroupChannelDelete = $this->propertyChannelGroupChannelMappingRepository->delete($channelRequest); + + $insertData = []; + foreach ($channels as $channel){ + $insertData[] = [ + 'channel_group_id' => $params['group_id'], + 'channel_id' => $channel, + 'status' => 1, + 'created_by' => $this->request->auth->id, + 'updated_by' => $this->request->auth->id, + 'created_at' => time(), + 'updated_at' => time() + ]; + } + + $propertyChannelGroupChannels = $this->propertyChannelGroupChannelMappingRepository->insert($insertData); + if($propertyChannelGroupChannels['status'] != 'success'){ + throw new ApiErrorException($propertyChannelGroupChannels['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelGroup['data']]; + DB::commit(); + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + DB::rollBack(); + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyGroupInventory(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $startDate = fillOnUndefinedAndEmpty($params, 'start_date', date('Y-m-d')) ; + $endDate = fillOnUndefinedAndEmpty($params, 'end_date', Carbon::parse($startDate)->addDay(15)->format('Y-m-d')) ; + + if($endDate < $startDate){ + throw new ApiErrorException('date error') ; + } + $diffInDays = Carbon::parse($startDate)->diffInDays($endDate); + if($diffInDays > 15){ + throw new ApiErrorException('date error') ; + } + + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_group_id' => fillOnUndefined($params, 'channel_group_id'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + + ]; + + $groupActiveChannels = $this->propertyChannelGroupService->getPropertyChannelGroupActiveChannels($requestParams); + if($groupActiveChannels['status'] != 'success'){ + throw new ApiErrorException($groupActiveChannels['message']); + } + + $inventoryData = $groupActiveChannels["data"]; + $inventoryData['channel_ids'] = []; + $inventoryData['currencies'] = []; + foreach ($groupActiveChannels['data']['channel_group_active_channels'] as $groupActiveChannel){ + + $channelId = $groupActiveChannel['channel_id']; + + $checkPropertyChannelMappingRequestParams = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ] + ]; + + $checkPropertyChannelMapping = $this->propertyChannelMappingService->select($checkPropertyChannelMappingRequestParams,['id', 'property_id', 'status']) ; + if($checkPropertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($checkPropertyChannelMapping['message']); + } + + if(!empty($checkPropertyChannelMapping['data'])){ + $inventoryData['channels'][$channelId] = $groupActiveChannel['channel']; + $inventoryData['channel_ids'][$channelId] = $channelId; + } + } + + if(!count($inventoryData['channel_ids'])){ + throw new ApiErrorException("There isn't any active channel in this channel group"); + } + + $channelMappingRequestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => $params['property_id'], + 'channel_ids' => $inventoryData['channel_ids'], + ]; + + $getChannelMappingResponse = $this->propertyChannelMappingService->getPropertyChannelMappingForChannelGroup($channelMappingRequestParams) ; + if($getChannelMappingResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponse['message']); + } + + foreach ($getChannelMappingResponse["data"] as $channelMapping){ + $channelId = $channelMapping['channel_id']; + + $inventoryData['channels'][$channelId]['currency_code'] = $channelMapping['currency_code']; + $inventoryData['channels'][$channelId]['property_availability_type_id'] = $channelMapping['property_availability_type_id']; + + $inventoryData['currencies'][$channelMapping['currency_code']] = $channelMapping['currency_code']; + } + + + foreach ($inventoryData['channel_ids'] as $channelId){ + + $getGroupInventoryRequestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => $params['property_id'], + 'channel_id' => $channelId, + ]; + + $inventoryData['channels'][$channelId]['rooms_temp'] = $this->propertyRoomService->inventoryRoomList($getGroupInventoryRequestParams); + + } + + + foreach ($inventoryData['channels'] as $channel){ + + $channelId = $channel['id']; + $currency = $channel['currency_code']; + + foreach ($channel['rooms_temp'] as $roomTemp){ + + $roomId = $roomTemp['id']; + + $dateKey = Carbon::parse($params['start_date']); + for ($i = 0; $i <= $diffInDays; $i++) { + + $responseAVAKey = 'AVA_1_'.$roomId.'_'. '0' .'_'.$dateKey->format('Ymd') ; + $responseSTSKey = 'STS_1_'.$roomId.'_'. '0' .'_'.$dateKey->format('Ymd') ; + + $roomAvailability[$dateKey->format('Y-m-d')] = [ + 'key' => $responseAVAKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $roomStopSell[$dateKey->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => 0, + ]; + + $dateKey = $dateKey->addDay(); + } + + foreach ($roomTemp['property_room_rate_mapping'] as $roomRateMapping ){ + + $roomRate = $roomRateMapping['property_room_rate']; + $roomRateId = $roomRate['id']; + $roomRateChannel = $roomRateMapping['property_room_rate_channel']; + + + foreach ($roomRateChannel as $roomRateChan){ + + if($roomRateChan['channel_id'] == $channelId && $roomRateChan['status'] == 1){ + + $inventoryData['rooms'][$roomId]['id'] = $roomTemp['id']; + $inventoryData['rooms'][$roomId]['name'] = $roomTemp['name']; + $inventoryData['rooms'][$roomId]['room_selected'] = false; + $inventoryData['rooms'][$roomId]['availability'] = $roomAvailability; + $inventoryData['rooms'][$roomId]['room_stop_sell'] = $roomStopSell; + + $rate['id'] = $roomRateId; + $rate['name'] = $roomRate['name']; + $rate['currency'] = $currency; + $rate['rate_selected'] = false; + $rate['room_rate_mapping_id'] = $roomRateChan['room_rate_mapping_id']; + + + $dateKey = Carbon::parse($params['start_date']); + for ($i = 0; $i <= $diffInDays; $i++) { + + $responsePRCKey = 'PRC_1'.'_'.$roomRateMapping['room_id'].'_'. $roomRateMapping['id'].'_'.$dateKey->format('Ymd').'_'.$currency ; + $responseSTSKey = 'STS_1'.'_'.$roomRateMapping['room_id'].'_'. $roomRateMapping['id'].'_'.$dateKey->format('Ymd'); + $responseMNSKey = 'MNS_1'.'_'.$roomRateMapping['room_id'].'_'. $roomRateMapping['id'].'_'.$dateKey->format('Ymd'); + + $price[$dateKey->format('Y-m-d')] = [ + 'key' => $responsePRCKey, + 'value' => null, + 'stop_sell' => 0 + ]; + + $stopSell[$dateKey->format('Y-m-d')] = [ + 'key' => $responseSTSKey, + 'value' => 0, + ]; + + $minStay[$dateKey->format('Y-m-d')] = [ + 'key' => $responseMNSKey, + 'value' => 1, + ]; + + $dateKey = $dateKey->addDay(); + } + + $rate['price'] = $price; + $rate['stop_sell'] = $stopSell; + $rate['min_stay'] = $minStay; + + + $inventoryData['rooms'][$roomId]['rates'][$roomRateId][$currency] = $rate; + + } + } + } + } + + } + + if(isset($inventoryData['channel_group_active_channels'])){ + unset($inventoryData['channel_group_active_channels']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $inventoryData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyChannelGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $mappedChannelCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'], + ]; + + $propertyChannelsForGroup = $this->propertyChannelMappingService->select($mappedChannelCriteria); + if($propertyChannelsForGroup['status'] != 'success'){ + throw new ApiErrorException($propertyChannelsForGroup['message']); + } + + $channels = []; + + foreach ($propertyChannelsForGroup['data'] as $data){ + if($data['property_availability_type_id'] == 1 && $data['channel']['parent_id'] == null){ + $channels[$data['id']] = $data['channel']; + } + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channels]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyChannelMappingController.php b/app/Http/Controllers/V1/PropertyChannelMappingController.php new file mode 100644 index 0000000..6b522cb --- /dev/null +++ b/app/Http/Controllers/V1/PropertyChannelMappingController.php @@ -0,0 +1,447 @@ +request = $request; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyChannelService = $propertyChannelService ; + $this->propertyBookingEngineService = $propertyBookingEngineService; + + } + + + + public function getPropertyChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->getPropertyChannelMapping($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channels' => fillOnUndefined($params, 'channels', []), + 'user_id' => $this->request->auth->id, + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->addPropertyChannelMapping($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function removePropertyChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channels' => fillOnUndefined($params, 'channels', []), + 'user_id' => $this->request->auth->id, + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->removePropertyChannelMapping($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $propertyChannelMapping = $this->propertyChannelMappingService->updatePropertyChannelMapping($params); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyChannelSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = + [ + "property_id" => $request->input('property_id'), + "channel_id" => $request->input('channel_id'), + "booking_type_id" => $request->input('booking_type_id') != 'null' ? $request->input('booking_type_id') : null, + "availability_type_id" => $request->input('availability_type_id') != 'null' ? $request->input('availability_type_id') : null, + "room_pricing_type_id" => $request->input('room_pricing_type_id') != 'null' ? $request->input('room_pricing_type_id') : null, + "currency_code" => $request->input('currency_code') != 'null' ? $request->input('currency_code') : null, + "connected_channel_id" => $request->input('connected_channel_id') != 'null' ? $request->input('connected_channel_id') : null, + "connected_channel_action" => $request->input('connected_channel_action') != 'null' ? $request->input('connected_channel_action') : null, + "contract_file" => $request->file('contract_file') + ]; + + $requestParams = $params ; + $requestParams['user_id'] = $this->request->auth->id; + + $getChannelRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'channel_category_id']) ; + if($getChannelResponse['status'] != 'success' && !empty($getChannelResponse['data'])){ + throw new ApiErrorException($getChannelResponse['message']); + } + + + if($getChannelResponse['data']['channel_category_id'] === self::CHANNEL_MANAGER && $getChannelResponse['data']['parent_id'] === self::PARENT_ID + && !$requestParams['booking_type_id'] && !$requestParams['availability_type_id'] && !$requestParams['room_pricing_type_id'] ){ + + $propertyChannelMapping = $this->propertyChannelMappingService->addPropertyChannelSetupWithMissingParameters($requestParams); + + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['data']]; + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + $propertyChannelMapping = $this->propertyChannelMappingService->addPropertyChannelSetup($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $getChannelRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel', 'propertyChannelCategory'], + 'firstRow' => 1 + ]; + $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'default_currency', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']) ; + if($getChannelResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelResponse['message']); + } + $channelData['channel'] = $getChannelResponse['data'] ; + + + $getChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest) ; + + if($getChannelMappingResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponse['message']); + } + $channelData['channel']['currency_list'] = json_decode($channelData['channel']['currency_code'] , 1); + $channelData['channel']['currency'] = isset($getChannelMappingResponse['data']['currency_code']) ? $getChannelMappingResponse['data']['currency_code'] : $channelData['channel']['default_currency'] ; + $channelData['channel']['is_connected'] = $getChannelMappingResponse['data'] ? true : false ; + + + $propertyChannelMapping = $this->propertyChannelMappingService->getPropertyChannelSetup($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $channelData = array_merge($channelData, $propertyChannelMapping['data']) ; + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyChannelSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $requestParams = $params ; + $requestParams['user_id'] = $this->request->auth->id; + + $getChannelRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['parentChannel', 'propertyChannelCategory'], + 'firstRow' => 1 + ]; + $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'name', 'official_name', 'default_currency', 'description', 'channel_category_id', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']) ; + if($getChannelResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelResponse['message']); + } + $channelData['channel'] = $getChannelResponse['data'] ; + + $childChannels = []; + if(!empty($channelData['channel']) && $channelData['channel']['parent_id'] === NULL + && $channelData['channel']['property_channel_category']['id'] == 4 ){ + + $childChannels = $this->propertyChannelMappingService->getPropertyChildChannel(['property_id' => $params['property_id']]); + + $childChannels = $childChannels['data']; + + } + + + $getChannelMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'with' => ['channelBookingType', 'channelAvailabilityType', 'channelRoomPricingType'] , + 'firstRow' => 1 + ]; + $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest); + + if($getChannelMappingResponse['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponse['message']); + } + + $getChannelMappingRequestData = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ], + 'firstRow' => 1 + ]; + $getChannelMappingResponseData = $this->propertyChannelMappingService->select($getChannelMappingRequestData) ; + + if($getChannelMappingResponseData['status'] != 'success'){ + throw new ApiErrorException($getChannelMappingResponseData['message']); + } + + $isPending = false; + if(isset($getChannelMappingResponse['data']['status'])){ + $isPending = $getChannelMappingResponse['data']['status'] === 2 ? true : false ; + } + + + $isConnected = false ; + if(isset($getChannelMappingResponse['data']['status'])){ + $isConnected = $getChannelMappingResponse['data']['status'] ? true : false ; + } + + $channelData['channel']['is_connected'] = $isConnected ; + $channelData['channel']['is_pending'] = $isPending ; + $channelData['channel']['currency_list'] = json_decode($channelData['channel']['currency_code'] , 1); + $channelData['channel']['currency'] = isset($getChannelMappingResponse['data']['currency_code']) ? $getChannelMappingResponse['data']['currency_code'] : $channelData['channel']['default_currency'] ; + $channelData['channel']['channel_booking_type'] = isset($getChannelMappingResponse['data']['channel_booking_type']) ? $getChannelMappingResponse['data']['channel_booking_type'] : null; + $channelData['channel']['channel_availability_type'] = isset($getChannelMappingResponse['data']['channel_availability_type']) ? $getChannelMappingResponse['data']['channel_availability_type'] : null ; + $channelData['channel']['channel_room_pricing_type'] = isset($getChannelMappingResponse['data']['channel_room_pricing_type'] ) ? $getChannelMappingResponse['data']['channel_room_pricing_type'] : null; + $channelData['channel']['connected_channel_id'] = isset($getChannelMappingResponse['data']['connected_channel_id'] ) ? $getChannelMappingResponse['data']['connected_channel_id'] : null; + $channelData['channel']['connected_channel_action'] = isset($getChannelMappingResponse['data']['connected_channel_action'] ) ? $getChannelMappingResponse['data']['connected_channel_action'] : null; + + $propertyChannelMapping = $this->propertyChannelMappingService->getPropertyChannelSetup($requestParams); + if($propertyChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $channelData = array_merge($channelData, $propertyChannelMapping['data']) ; + $channelData['mapping_child_channels'] = $childChannels; + + + $channelData['channel']['bookingEngineUrl'] = null; + $channelData['channel']['bookingEngineToken'] = null; + $propertyBookingEngineRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + $propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineRequest); + + $bookingEngineUrl = null; + $bookingEngineToken = null; + if($propertyBookingEngine['status'] == 'success' && !empty($propertyBookingEngine['data'])) { + $bookingEngineToken = $propertyBookingEngine['data']['token']; + $bookingEngineUrl = Config::get('app.bookingEngineUrl').'/'.$propertyBookingEngine['data']['token']; + } + + $channelData['channel']['bookingEngineUrl'] = $bookingEngineUrl; + $channelData['channel']['bookingEngineToken'] = $bookingEngineToken; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + +} diff --git a/app/Http/Controllers/V1/PropertyCompetitorGroupController.php b/app/Http/Controllers/V1/PropertyCompetitorGroupController.php new file mode 100644 index 0000000..fbba37d --- /dev/null +++ b/app/Http/Controllers/V1/PropertyCompetitorGroupController.php @@ -0,0 +1,184 @@ +propertyCompetitorGroupService = $propertyCompetitorGroupService; + $this->request = $request; + $this->params = $request->all(); + } + + public function getPropertyCompetitorGroup(Request $request) + { + + $params = $this->params; + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['params']['property_id']], + ] + ]; + + // created_by, updated_by, created_at, updated_at alanları get cevaplarında gizlenir + $columns = ['id', 'property_id', 'name', 'status']; + $requestSelectResult = $this->propertyCompetitorGroupService->selectPropertyCompetitorGroup($requestSelectCriteria, $columns); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestSelectResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncPropertyCompetitorGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + DB::beginTransaction(); + + try { + + $requestParams = [ + 'id' => $this->params['params']['id'] ?? null, + 'property_id' => $this->params['params']['property_id'] ?? null, + 'name' => $this->params['params']['name'] ?? null, + 'status' => $this->params['params']['status'] ?? 1, + // Öncelik: auth üzerinden gelen kullanıcı + 'user_id' => ($this->request->auth->id ?? null) ?: ($this->params['params']['user_id'] ?? null), + ]; + + $requestResult = $this->propertyCompetitorGroupService->syncPropertyCompetitorGroup($requestParams); + + if ($requestResult['status'] != 'success') { + throw new ApiErrorException($requestResult['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestResult['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPropertyCompetitorGroupMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + $requestParams = [ + 'property_id' => $this->params['params']['property_id'] ?? null, + 'competitor_group_id' => $this->params['params']['competitor_group_id'] ?? null, + ]; + + $result = $this->propertyCompetitorGroupService->getPropertyCompetitorGroupMapping($requestParams); + + if (($result['status'] ?? false) !== true && ($result['status'] ?? '') !== 'success') { + throw new ApiErrorException($result['message'] ?? 'unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $result['data'] ?? null]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function syncPropertyCompetitorGroupMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + DB::beginTransaction(); + try { + $requestParams = [ + 'property_id' => $this->params['params']['property_id'] ?? null, + 'competitor_group_id' => $this->params['params']['competitor_group_id'] ?? null, + 'competitor' => $this->params['params']['competitor'] ?? [], + // Öncelik: auth üzerinden gelen kullanıcı + 'user_id' => ($this->request->auth->id ?? null) ?: ($this->params['params']['user_id'] ?? null), + ]; + + $result = $this->propertyCompetitorGroupService->syncPropertyCompetitorGroupMapping($requestParams); + + if (($result['status'] ?? false) !== true && ($result['status'] ?? '') !== 'success') { + throw new ApiErrorException($result['message'] ?? 'unknown_error'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $result['data'] ?? null]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyConfigController.php b/app/Http/Controllers/V1/PropertyConfigController.php new file mode 100644 index 0000000..536e4dc --- /dev/null +++ b/app/Http/Controllers/V1/PropertyConfigController.php @@ -0,0 +1,165 @@ +request = $request; + $this->propertyConfigService = $propertyConfigService; + + } + + public function getPropertyConfig() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'config_keys' => fillOnUndefined($params, 'config_keys'), + + + ]; + $propertyConfig = $this->propertyConfigService->getPropertyConfig($requestParams); + + if($propertyConfig['status'] != 'success'){ + throw new ApiErrorException($propertyConfig['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyConfig['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyConfig(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'config_keys' => fillOnUndefined($params, 'config_keys'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + + + $propertyConfig = $this->propertyConfigService->propertyConfigUpdate($requestParams); + + if($propertyConfig['status'] != 'success'){ + + throw new ApiErrorException($propertyConfig['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyConfig['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyConfig(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'executive_type' => fillOnUndefined($params, 'executive_type'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + + + $propertyConfig = $this->propertyConfigService->propertyConfigDelete($requestParams); + + if($propertyConfig['status'] != 'success'){ + + throw new ApiErrorException($propertyConfig['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyConfig['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyContactController.php b/app/Http/Controllers/V1/PropertyContactController.php new file mode 100644 index 0000000..20a6bc5 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyContactController.php @@ -0,0 +1,175 @@ +request = $request; + $this->propertyService = $propertyService ; + $this->propertyContactService = $propertyContactService; + + } + + /** + * @return \Illuminate\Http\JsonResponse + */ + public function getPropertyContact() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + $propertyContact = $this->propertyContactService->propertyContact($requestParams); + + if ($propertyContact['status'] != 'success'){ + throw new Exception($propertyContact['message']); + } + $requestParams = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'firstRow' => 1 + ]; + $property = $this->propertyService->select($requestParams, ['country']); + if($property['status'] != 'success'){ + throw new Exception($property['message']); + } + $propertyContact['data']['country_code'] = strtolower($property['data']['country']) ; + + + $responseData = $propertyContact['data']; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'official_name','tax_office', 'tax_number']; + $property = $this->propertyService->select($propertyRequest, $getPropertyFields); + + if($property['status'] != 'success'){ + throw new Exception($property['message']); + } + $responseData['get_property'] = $property['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + /** + * @param Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function updateOrCreatePropertyContact(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'contact' => fillOnUndefined($params, 'contact'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + $propertyContact = $this->propertyContactService->propertyContactUpdateOrCreate($requestParams); + + + if($propertyContact['status'] != 'success'){ + + throw new ApiErrorException($propertyContact['message']); + } + + + $propertyData = fillOnUndefined($params, 'property_info'); + + if($propertyData){ + $updateData = []; + $validateKeys = ['official_name', 'tax_office', 'tax_number']; + foreach ($propertyData as $key => $value) { + + if (!in_array($key, $validateKeys)) { + throw new ApiErrorException(lang('Error Columns')); + } + $updateData[$key] = $value; + } + + if ($updateData) { + $updateData['updated_by'] = $requestParams['user_id']; + $updateData['updated_at'] = time(); + } + $propertyUpdateResult = $this->propertyService->update($params['property_id'], $updateData); + + if ($propertyUpdateResult['status'] != 'success') { + throw new ApiErrorException($propertyUpdateResult['message']); + } + + } + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContact['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyContentController.php b/app/Http/Controllers/V1/PropertyContentController.php new file mode 100644 index 0000000..748625f --- /dev/null +++ b/app/Http/Controllers/V1/PropertyContentController.php @@ -0,0 +1,122 @@ +request = $request; + $this->propertyContentService = $propertyContentService; + + } + + public function getPropertyContent() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + + 'language_code' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'category_id' => fillOnUndefined($params, 'category_id'), + + ]; + $propertyContent = $this->propertyContentService->propertyContent($requestParams); + + if($propertyContent['status'] != 'success'){ + throw new Exception($propertyContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyContent(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'active_user' => $this->request->credentials->user_id, + 'locale' => fillOnUndefined($params, 'locale'), + 'contents' => fillOnUndefined($params, 'contents'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + + + $propertyContent = $this->propertyContentService->propertyContentUpdate($requestParams); + + if($propertyContent['status'] != 'success'){ + + throw new ApiErrorException($propertyContent['message']); + } + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyController.php b/app/Http/Controllers/V1/PropertyController.php new file mode 100644 index 0000000..e73f14d --- /dev/null +++ b/app/Http/Controllers/V1/PropertyController.php @@ -0,0 +1,1220 @@ +request = $request; + $this->propertyService = $propertyService; + $this->propertyTypeService = $propertyTypeService; + $this->propertyChainService = $propertyChainService; + $this->userPropertyMappingService = $userPropertyMappingService; + $this->permissionService = $permissionService; + $this->propertyConfigService = $propertyConfigService; + $this->siteConfigService = $siteConfigService; + $this->countryService = $countryService; + $this->generalTimezoneService = $generalTimezoneService; + $this->propertyNetworkService = $propertyNetworkService; + $this->productService = $productService; + $this->dashboardPlusService = $dashboardPlusService; + } + + public function listProperty(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'user_id' => $request->credentials->user_id, + + ]; + + $property = $this->propertyService->getPropertyList($requestParams); + + if ($property['status'] != 'success') { + throw new Exception($property['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $property['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getProperty(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $return = []; + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + + $property = $this->propertyService->getProperty($requestParams); + + if ($property['status'] != 'success') { + throw new Exception($property['message']); + } + $return['get_property'] = $property['data']['get_property']; + $return['minimum_age_policies'] = $property['data']['minimum_age_policies']; + + + $propertyType = $this->propertyTypeService->getPropertyTypes($requestParams); + if ($propertyType['status'] != 'success') { + throw new ApiErrorException($propertyType['message']); + } + $return['property_type'] = $propertyType['data']['property_type']; + + + $propertyChains = $this->propertyChainService->getPropertyChains($requestParams); + if ($propertyChains['status'] != 'success') { + throw new ApiErrorException($propertyChains['message']); + } + $return['property_chains'] = $propertyChains['data']['property_chains']; + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + $countries = $this->countryService->getCountryList($criteria); + if ($countries['status'] != 'success') { + throw new ApiErrorException($countries['message']); + } + $return['countries'] = $countries['data']; + + $generalTimeZones = $this->generalTimezoneService->getAllaGeneralTimezone($params); + if ($generalTimeZones['status'] != 'success') { + throw new ApiErrorException($generalTimeZones['message']); + } + $return['general_timezone'] = $generalTimeZones['data']; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updateProperty(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_info' => fillOnUndefined($params, 'property_info'), + 'additional_info' => fillOnUndefined($params, 'additional_info'), + 'property_language_spoken' => fillOnUndefined($params, 'property_language_spoken'), + 'has_locale_name' => fillOnUndefined($params, 'has_locale_name', false), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + + $property = $this->propertyService->propertyUpdate($requestParams); + + if ($property['status'] != 'success') { + + throw new ApiErrorException($property['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $property['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyContentCode(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'content_code' => fillOnUndefined($params, 'content_code') + ]; + + $validator = Validator::make($requestParams, ['content_code' => 'nullable|min:5|max:10']); + if (!empty($validator->errors()->messages())) { + throw new ApiErrorException('The verification code must be a minimum of 5 and a maximum of 10 digits.'); + } + + $property = $this->propertyService->update($params['property_id'], $requestParams); + + if ($property['status'] != 'success') { + throw new ApiErrorException($property['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function userPropertyMenu(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + $userId = $request->credentials->user_id; + $params = $request->params; + + $mappingPropertiesCriteria = [ + 'criteria' => [ + ['field' => 'user_id', 'condition' => '=', 'value' => $userId], + ], + 'with' => ['property'], + ]; + if (isset($params['property_id'])) { + $mappingPropertiesCriteria['criteria'][] = ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']]; + } + + $mappingProperties = $this->userPropertyMappingService->select($mappingPropertiesCriteria); + if (!$mappingProperties['data']) { + throw new ApiErrorException(lang('User Property mapping not found')); + } + + $propertyList = collect($mappingProperties['data'])->map(function ($value) use ($userId, $params) { + + $menuParams = [ + 'user_id' => $userId, + 'property_id' => $value['property']['id'], + 'locale' => fillOnUndefined($params, 'locale') + ]; + if (is_array($value['property'])) { + return $value['property'] = [ + 'id' => $value['property']['id'], + 'name' => $value['property']['name'], + 'property_menu' => $this->permissionService->getMenuTreeForUser($menuParams) + ]; + } + })->toArray(); + $return['property_list'] = $propertyList; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function propertyDashBoard(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $propertyDashBoardparams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + 'locale' => array_shift($request->header()['language']) + ]; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + $property = $this->propertyService->select($propertyRequest); + if ($property['status'] != 'success' || !isset($property['data'])) { + throw new ApiErrorException($property['message']); + } + $property = isset($property['data']) ? $property['data'] : []; + + $siteConfig = $this->propertyConfigService->propertyDashBoard($propertyDashBoardparams); + if ($siteConfig['status'] != 'success') { + throw new ApiErrorException($siteConfig['message']); + } + $return = $siteConfig['data']; + $return['hotel_name'] = $property['name']; + + $siteHints = $this->siteConfigService->siteHints($propertyDashBoardparams); + if ($siteHints['status'] != 'success') { + throw new ApiErrorException($siteConfig['message']); + } + $return['site_hints'] = $siteHints['data']; + + $return['content_code'] = $property['content_code']; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyPabDashBoard(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestData = [ + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + + $property = $this->propertyNetworkService->getAllDashboardData($requestData); + + if ($property['status'] != 'success' || !isset($property['data'])) { + throw new ApiErrorException($property['message']); + } + + $property = isset($property['data']) ? $property['data'] : []; + + + /*$return = [ + 'hotel_name' => $property['name'], + + 'room_and_rate' => [ + 'room_count' => 16, + 'rate_count' => 8 + + ], + 'channels' => [ + 'channel_percent' => 25, + 'avail_channels' => 48, + 'saved_channel' => 12 + ], + 'reservation' => [ + [ + 'day' => 'Mon', + 'reservation_count' => 16, + 'reservation_percent' => 50 + ], + [ + 'day' => 'Tue', + 'reservation_count' => 5, + 'reservation_percent' => 15 + ], + [ + 'day' => 'Wed', + 'reservation_count' => 12, + 'reservation_percent' => 30 + ], + [ + 'day' => 'Thu', + 'reservation_count' => 15, + 'reservation_percent' => 50 + ], + [ + 'day' => 'Fri', + 'reservation_count' => 45, + 'reservation_percent' => 95 + ], + [ + 'day' => 'Sat', + 'reservation_count' => 47, + 'reservation_percent' => 97 + ], + [ + 'day' => 'Mon', + 'reservation_count' => 49, + 'reservation_percent' => 100 + ], + + ], + 'for_cast' => [ + 'total' => 40, + 'popular_channels' => [ + + [ + 'name' => 'Booking.Com', + 'cast' => 12, + ], + [ + 'name' => 'Agoda', + 'cast' => 13, + ], [ + 'name' => 'Trivago', + 'cast' => 15, + ], + ] + + ] + + + ];*/ + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $property]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createProperty(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + DB::beginTransaction(); + + $return = []; + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $userId = $request->credentials->user_id; + $propertyInsertData = [ + 'name' => __('enw-your_property_name'), + 'property_chain' => 1, + 'status' => 2, + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => time(), + 'updated_at' => time(), + ]; + $propertyCreate = $this->propertyService->create($propertyInsertData); + if ($propertyCreate['status'] != 'success') { + throw new ApiErrorException($propertyCreate['message']); + } + + $return = $propertyCreate['data']; + $userPropertyMappingData = [ + 'user_id' => $userId, + 'status' => 1, + 'property_id' => $propertyCreate['data']['id'], + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => time(), + 'updated_at' => time(), + ]; + $userPropertyMappingCreate = $this->userPropertyMappingService->create($userPropertyMappingData); + if ($userPropertyMappingCreate['status'] != 'success') { + throw new ApiErrorException($userPropertyMappingCreate['message']); + } + + $propertyProducts = $this->productService->setDefaultPropertyProducts($userPropertyMappingData); + if ($propertyProducts['status'] != 'success') { + throw new ApiErrorException($propertyProducts['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return]; + DB::commit(); + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + DB::rollBack(); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + DB::rollBack(); + + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + /* + * Dashboard Plus + */ + + public function propertyDashBoardPlus(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + + $propertyCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + $property = $this->propertyService->select($propertyCriteria); + + if ($property['status'] != 'success' || !isset($property['data'])) { + throw new ApiErrorException($property['message']); + } + + $property = isset($property['data']) ? $property['data'] : []; + + + $dashBoardParam = [ + 'property_id' => $params['property_id'], + 'start_date' => fillOnUndefined($params, 'start_date', Carbon::now()->subYear()->toDateString()), + 'finish_date' => fillOnUndefined($params, 'finish_date', Carbon::now()->subDay()->toDateString()), + ]; + + + $todayCheckin = $this->dashboardPlusService->todayCheckin($dashBoardParam); + $todayCheckin = $todayCheckin['status'] ? $todayCheckin['data'] : 0; + + $todayCheckout = $this->dashboardPlusService->todayCheckout($dashBoardParam); + $todayCheckout = $todayCheckout['status'] ? $todayCheckout['data'] : 0; + + $lengthOfStay = $this->dashboardPlusService->lengthOfStay($dashBoardParam); + $lengthOfStay = $lengthOfStay['status'] ? $lengthOfStay['data'] : 0; + + $lengthOfBooking = $this->dashboardPlusService->lengthOfBooking($dashBoardParam); + $lengthOfBooking = $lengthOfBooking['status'] ? $lengthOfBooking['data'] : 0; + + $totalBooking = $this->dashboardPlusService->totalBooking($dashBoardParam); + $totalBooking = $totalBooking['status'] ? $totalBooking['data'] : []; + + $averageDailyRate = $this->dashboardPlusService->averageDailyRate($dashBoardParam); + $averageDailyRate = $averageDailyRate['status'] ? $averageDailyRate['data'] : []; + + $totalPax = $this->dashboardPlusService->totalPax($dashBoardParam); + $totalPax = $totalPax['status'] ? $totalPax['data'] : []; + + $responseData = [ + 'propertyId' => $property['id'], + 'propertyName' => $property['name'], + 'todayCheckin' => $todayCheckin, + 'todayCheckout' => $todayCheckout, + 'lengthOfStay' => $lengthOfStay, + 'lengthOfBooking' => $lengthOfBooking, + 'totalBooking' => $totalBooking, + 'totalPax' => $totalPax, + 'averageDailyRate' => $averageDailyRate, + ]; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyDashBoardPlusWebVisitor(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + $webVisitorParam = [ + 'property_id' => $params['property_id'], + 'start_date' => fillOnUndefined($params, 'start_date', Carbon::now()->subYear()->toDateString()), + 'finish_date' => fillOnUndefined($params, 'finish_date', Carbon::now()->subDay()->toDateString()), + ]; + + $webVisitor = $this->dashboardPlusService->webVisitor($webVisitorParam); + if (!$webVisitor['status']) { + throw new ApiErrorException($webVisitor['message']); + } + + $responseData = $webVisitor['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyDashBoardPlusGuestDemographic(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + $webVisitorParam = [ + 'property_id' => $params['property_id'], + 'start_date' => fillOnUndefined($params, 'start_date', Carbon::now()->subYear()->toDateString()), + 'finish_date' => fillOnUndefined($params, 'finish_date', Carbon::now()->subDay()->toDateString()), + ]; + + $webVisitor = $this->dashboardPlusService->guestDemographic($webVisitorParam); + if (!$webVisitor['status']) { + throw new ApiErrorException($webVisitor['message']); + } + + $responseData = $webVisitor['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyDashBoardPlusTopChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + $topChannelParam = [ + 'property_id' => $params['property_id'], + 'start_date' => fillOnUndefined($params, 'start_date', Carbon::now()->subYear()->toDateString()), + 'finish_date' => fillOnUndefined($params, 'finish_date', Carbon::now()->subDay()->toDateString()), + ]; + + $webVisitor = $this->dashboardPlusService->topChannel($topChannelParam); + if (!$webVisitor['status']) { + throw new ApiErrorException($webVisitor['message']); + } + + $responseData = $webVisitor['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function propertyDashBoardPlusChannelForecast(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + $topChannelParam = [ + 'property_id' => $params['property_id'], + 'start_date' => fillOnUndefined($params, 'start_date', Carbon::now()->subYear()->toDateString()), + 'finish_date' => fillOnUndefined($params, 'finish_date', Carbon::now()->subDay()->toDateString()), + ]; + + $webVisitor = $this->dashboardPlusService->channelForecast($topChannelParam); + if (!$webVisitor['status']) { + throw new ApiErrorException($webVisitor['message']); + } + + $responseData = $webVisitor['data']; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function bookingEngineReport(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + $reportTypes = [ + 'TRS' => 'Transaction Report', + 'GTR' => 'Guest Transaction Report', + 'DSR' => 'Date Search Report', + 'DSS' => 'Date Search Stay Report', + 'UCR' => 'User Country Report', + 'ULR' => 'User Language Report', + ]; + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + if (!in_array(fillOnUndefined($params, 'type'), array_keys($reportTypes))) { + throw new ApiErrorException('Undefined report type.'); + + } + + $propertyCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + $property = $this->propertyService->select($propertyCriteria); + + if ($property['status'] != 'success' || !isset($property['data'])) { + throw new ApiErrorException($property['message']); + } + + $property = isset($property['data']) ? $property['data'] : []; + + $reportType = $params['type']; + + if($reportType != 'DSS') { + $searchData = vwBookingEngineSearch::where('property_id', $property['id']) + ->whereBetween('date', [$params['start_date'], $params['finish_date']]) + ->get()->toArray(); + } + + $responseData = []; + + switch ($reportType) { + case 'TRS': + + $responseData['search'] = collect($searchData)->count(); + $responseData['roomFound'] = collect($searchData)->where('status', 1)->count(); + $responseData['roomNotFound'] = collect($searchData)->where('status', 0)->count(); + $responseData['preBooking'] = collect($searchData)->where('status', 2)->count(); + $responseData['booking'] = collect($searchData)->where('status', 3)->count(); + + break; + case 'GTR': + + $occupancyCodes = collect($searchData)->groupBy('pax')->keys()->toArray(); + foreach ($occupancyCodes as $occupancyCode) { + $responseData[$occupancyCode]['text'] = occupancyCodeFormatted($occupancyCode); + $responseData[$occupancyCode]['count'] = collect($searchData)->where('pax', $occupancyCode)->count(); + } + + $responseData = collect($responseData)->sortByDesc('count')->toArray(); + + break; + case 'DSR': + + //Daily Intensity + $dailyIntensity = []; + foreach ($searchData as $data) { + $checkInDate = $data['checkin_date']; + $checkOutDate = $data['checkout_date']; + $dateDiff = Carbon::parse($data['checkout_date'])->diffInDays(Carbon::parse($data['checkin_date'])); + + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($checkInDate)->addDays($i)->toDateString(); + + if (!isset($dailyIntensity[$date])) { + $dailyIntensity[$date]['text'] = Carbon::parse($date)->format('d.m.Y'); + $dailyIntensity[$date]['search'] = 0; + $dailyIntensity[$date]['roomFound'] = 0; + $dailyIntensity[$date]['roomNotFound'] = 0; + $dailyIntensity[$date]['preBooking'] = 0; + $dailyIntensity[$date]['booking'] = 0; + } + + $dailyIntensity[$date]['search']++; + $dailyIntensity[$date]['roomFound'] += $data['status'] == 1 ? 1 : 0; + $dailyIntensity[$date]['roomNotFound'] += $data['status'] == 0 ? 1 : 0; + $dailyIntensity[$date]['preBooking'] += $data['status'] == 2 ? 1 : 0; + $dailyIntensity[$date]['booking'] += $data['status'] == 3 ? 1 : 0; + + } + } + ksort($dailyIntensity); + $responseData = $dailyIntensity; + //Daily Intensity + break; + case 'DSS': + + //Daily Intensity + + + $searchData = vwBookingEngineSearch::where('property_id', $property['id']) + ->where('channel_id', $params['channel_id']) + ->whereBetween('checkin_date', [$params['start_date'], $params['finish_date']]) + ->orderByDesc('id') + ->get()->toArray(); + + + $dailyIntensity = []; + foreach ($searchData as $data) { + + $checkInDate = $data['checkin_date']; + $checkOutDate = $data['checkout_date']; + $dateDiff = Carbon::parse($data['checkout_date'])->diffInDays(Carbon::parse($data['checkin_date'])); + + for ($i = 0; $i < $dateDiff; $i++) { + $date = Carbon::parse($checkInDate)->addDays($i)->toDateString(); + + if(!Carbon::parse($date)->betweenIncluded($params['start_date'], $params['finish_date'])) { + continue; + } + + if (!isset($dailyIntensity[$date])) { + $dailyIntensity[$date]['text'] = Carbon::parse($date)->format('d.m.Y'); + $dailyIntensity[$date]['search'] = 0; + $dailyIntensity[$date]['roomFound'] = 0; + $dailyIntensity[$date]['roomNotFound'] = 0; + $dailyIntensity[$date]['preBooking'] = 0; + $dailyIntensity[$date]['booking'] = 0; + $dailyIntensity[$date]['bookingCode'] = []; + } + + $dailyIntensity[$date]['search']++; + $dailyIntensity[$date]['roomFound'] += $data['status'] == 1 ? 1 : 0; + $dailyIntensity[$date]['roomNotFound'] += $data['status'] == 0 ? 1 : 0; + $dailyIntensity[$date]['preBooking'] += $data['status'] == 2 ? 1 : 0; + $dailyIntensity[$date]['booking'] += $data['status'] == 3 ? 1 : 0; + + if(!empty($data['booking_code'])) { + $dailyIntensity[$date]['bookingCode'][] = $data['booking_code']; + } + + } + } + ksort($dailyIntensity); + $responseData = $dailyIntensity; + //Daily Intensity + break; + case 'UCR': + + $countryList = Country::all()->toArray(); + $countryCodes = collect($searchData)->where('country_code', '!=', null)->groupBy('country_code')->keys()->toArray(); + + foreach ($countryCodes as $countryCode) { + $countryText = $countryCode; + $countryTextCheck = collect($countryList)->where('country_code', mb_strtoupper($countryCode))->first(); + if (!empty($countryTextCheck)) { + $countryText = $countryTextCheck['name']; + } + $responseData[$countryCode]['text'] = $countryText; + $responseData[$countryCode]['search'] = collect($searchData)->where('country_code', $countryCode)->count(); + $responseData[$countryCode]['roomFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 1)->count(); + $responseData[$countryCode]['roomNotFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 0)->count(); + $responseData[$countryCode]['preBooking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 2)->count(); + $responseData[$countryCode]['booking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 3)->count(); + } + + break; + case 'ULR': + + $languageList = Language::all()->toArray(); + $languageCodes = collect($searchData)->groupBy('language_code')->keys()->toArray(); + foreach ($languageCodes as $languageCode) { + $languageText = $languageCode; + $languageTextCheck = collect($languageList)->where('code', $languageCode)->first(); + if (!empty($languageTextCheck)) { + $languageText = $languageTextCheck['name']; + } + $responseData[$languageCode]['text'] = $languageText; + $responseData[$languageCode]['search'] = collect($searchData)->where('language_code', $languageCode)->count(); + $responseData[$languageCode]['roomFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 1)->count(); + $responseData[$languageCode]['roomNotFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 0)->count(); + $responseData[$languageCode]['preBooking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 2)->count(); + $responseData[$languageCode]['booking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 3)->count(); + } + + $responseData = collect($responseData)->sortByDesc('search')->toArray(); + + break; + case 'default': + break; + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function couponCodeReport(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400]; + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + //Date Check + $diffInDays = Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['finish_date'])); + if ($diffInDays > 180) { + throw new ApiErrorException('A maximum of 180 days of data can be retrieved.'); + } + if (Carbon::parse($params['finish_date'])->isBefore(Carbon::parse($params['start_date']))) { + throw new ApiErrorException('The finish date cannot be earlier than the start date.'); + } + + $propertyCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => true + ]; + $property = $this->propertyService->select($propertyCriteria); + + if ($property['status'] != 'success' || !isset($property['data'])) { + throw new ApiErrorException($property['message']); + } + + $property = isset($property['data']) ? $property['data'] : []; + + + $startDate = Carbon::parse($params['start_date'])->startOfDay()->toDateTimeString(); + $finishDate = Carbon::parse($params['finish_date'])->endOfDay()->toDateTimeString(); + + $status = fillOnUndefined($params,'status', 1); + + if (empty(fillOnUndefined($params, 'code'))) { + $searchData = vwBookingSummaryAll::where('property_id', $property['id']) + ->where('coupon_code', '!=', null) + ->where('status', '=', $status) + ->whereBetween('time', [$startDate, $finishDate]) + ->with('bookingStatus') + ->get()->toArray(); + } else { + $searchData = vwBookingSummaryAll::where('property_id', $property['id']) + ->where('coupon_code', $params['code']) + ->where('status', '=', $status) + ->whereBetween('time', [$startDate, $finishDate]) + ->with('bookingStatus') + ->get()->toArray(); + } + + $responseData = []; + + foreach ($searchData as $data) { + + $responseData[] = [ + 'id' => $data['id'], + 'transaction_period' => $data['transaction_period'], + 'checkout_period' => $data['checkout_period'], + 'code' => $data['coupon_code'], + 'booking_code' => $data['booking_code'], + 'name_surname' => $data['name_surname'], + 'checkin_date' => $data['checkin_date'], + 'checkout_date' => $data['checkout_date'], + 'length_of_stay' => $data['length_of_stay'], + 'length_of_booking' => $data['length_of_booking'], + 'total' => $data['total'], + 'total_formatted' => $data['total_formatted'], + 'currency_code' => $data['currency_code'], + 'status' => $data['status'], + 'status_name' => $data['booking_status']['name'], + 'status_language_key' => $data['booking_status']['language_key'], + 'time' => $data['time'], + 'time_formatted' => Carbon::parse($data['time'])->format('d.m.Y H:i:s') + ]; + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 400; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/PropertyCouponController.php b/app/Http/Controllers/V1/PropertyCouponController.php new file mode 100644 index 0000000..8c21cd4 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyCouponController.php @@ -0,0 +1,204 @@ +params = Input::all(); + $this->params = $this->params['params']; + $this->propertyChannelCouponService = $propertyChannelCouponService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyChannelCouponValidator = $propertyChannelCouponValidator; + } + + protected function propertyChannelMappingCheck($propertyId, $channelId) + { + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] == 'success') { + if (empty($propertyChannelMapping['data'])) { + return false; + } else { + return true; + } + } else { + return false; + } + + } + + public function getPropertyChannelCoupon(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']); + if (!$propertyChannelMappingCheck) { + throw new ApiErrorException('Transactions cannot be made through a unconnected channel.'); + } + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']], + ], + ]; + $columns = ['id', 'title', 'property_id', 'channel_id', 'code', 'start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', 'type', 'value', 'is_notify', 'email', 'status']; + $requestSelectResult = $this->propertyChannelCouponService->select($requestSelectCriteria, $columns); + + $propertyChannelCoupon = []; + if ($requestSelectResult['status'] == 'success') { + $propertyChannelCoupon = $requestSelectResult['data']; + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelCoupon]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncPropertyChannelCoupon(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $validationResult = $this->propertyChannelCouponValidator->validate($this->params); + + if ($validationResult->errors()->first()) { + $errors = $validationResult->errors()->all(); + throw new ApiErrorException($errors); + } + + $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']); + if (!$propertyChannelMappingCheck) { + throw new ApiErrorException('Transactions cannot be made through a unconnected channel.'); + } + + $propertyChannelCoupon = []; + if (isset($this->params['id'])) { + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $this->params['id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']], + ], + 'firstRow' => true + ]; + $columns = ['id', 'property_id', 'channel_id', 'code', 'start_date', 'end_date', 'type', 'value', 'status']; + $requestSelectResult = $this->propertyChannelCouponService->select($requestSelectCriteria, $columns); + + + if ($requestSelectResult['status'] == 'success') { + $propertyChannelCoupon = $requestSelectResult['data']; + } + } + + DB::beginTransaction(); + + if (empty($propertyChannelCoupon)) { + + $createParam = [ + 'title' => fillOnUndefined($this->params, 'title'), + 'property_id' => $this->params['property_id'], + 'channel_id' => $this->params['channel_id'], + 'code' => $this->params['code'], + 'start_date' => $this->params['start_date'], + 'end_date' => $this->params['end_date'], + 'reservation_start_date' => fillOnUndefined($this->params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($this->params, 'reservation_end_date'), + 'type' => $this->params['type'], + 'value' => $this->params['value'], + 'is_notify' => fillOnUndefined($this->params, 'is_notify'), + 'email' => fillOnUndefined($this->params, 'email'), + 'status' => fillOnUndefined($this->params, 'status', 1), + 'created_by' => $request->auth->id, + 'updated_by' => $request->auth->id, + ]; + + $syncPropertyChannelCoupon = $this->propertyChannelCouponService->create($createParam); + } else { + $this->params['updated_by'] = $request->auth->id; + $syncPropertyChannelCoupon = $this->propertyChannelCouponService->update($propertyChannelCoupon['id'], $this->params); + + } + + if ($syncPropertyChannelCoupon['status'] != 'success') { + throw new ApiErrorException($syncPropertyChannelCoupon['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $syncPropertyChannelCoupon['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/PropertyExecutiveController.php b/app/Http/Controllers/V1/PropertyExecutiveController.php new file mode 100644 index 0000000..b495b18 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyExecutiveController.php @@ -0,0 +1,271 @@ +request = $request; + $this->propertyExecutiveService = $propertyExecutiveService; + $this->propertyService = $propertyService; + + } + + public function getPropertyExecutive() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + $propertyExecutive = $this->propertyExecutiveService->getPropertyExecutive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new Exception($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + public function listPropertyExecutive() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + $propertyExecutive = $this->propertyExecutiveService->listPropertyExecutive($requestParams); + if($propertyExecutive['status'] != 'success'){ + throw new Exception($propertyExecutive['message']); + } + + $requestParams = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'firstRow' => 1 + ]; + $property = $this->propertyService->select($requestParams, ['country']); + if($property['status'] != 'success'){ + throw new Exception($property['message']); + } + $propertyExecutive['data']['country_code'] = strtolower($property['data']['country']) ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyExecutive(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'executive_type' => fillOnUndefined($params, 'executive_type'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + $propertyExecutive = $this->propertyExecutiveService->propertyExecutiveAdd($requestParams); + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyExecutive(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + $params = $this->request->params; + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'executive_type' => fillOnUndefined($params, 'executive_type'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + $oldPropertyExecutive = $this->propertyExecutiveService->listPropertyExecutive($requestParams); + + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'executive_type' => fillOnUndefined($params, 'executive_type'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + $propertyExecutive = $this->propertyExecutiveService->propertyExecutiveUpdate($requestParams); + + if($propertyExecutive['status'] != 'success'){ + throw new ApiErrorException($propertyExecutive['message']); + } + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch (ApiErrorException $e) { + $response['data'] = $oldPropertyExecutive['data'] ; + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['data'] = $oldPropertyExecutive['data'] ; + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyExecutive(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_executive_id' => fillOnUndefined($params, 'property_executive_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + + + $propertyExecutive = $this->propertyExecutiveService->propertyExecutivePassive($requestParams); + + if($propertyExecutive['status'] != 'success'){ + + throw new ApiErrorException($propertyExecutive['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyExecutive['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyFactController.php b/app/Http/Controllers/V1/PropertyFactController.php new file mode 100644 index 0000000..883c64d --- /dev/null +++ b/app/Http/Controllers/V1/PropertyFactController.php @@ -0,0 +1,183 @@ +request = $request; + $this->propertyFactService = $propertyFactService; + + } + + public function getPropertyFact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $getPropertyFact = $this->propertyFactService->getPropertyFact($requestFact); + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_facts' => $getPropertyFact['data']] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function searchPropertyFact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'search_term' => fillOnUndefined($params, 'search_term'), + ]; + + $getPropertyFact = $this->propertyFactService->searchPropertyFact($requestFact); + + if($getPropertyFact['status'] != 'success'){ + + throw new ApiErrorException($getPropertyFact['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_facts' => $getPropertyFact['data']] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getSubCategoryFacts(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'sub_category_id' => fillOnUndefined($params, 'sub_category_id'), + ]; + + $factRequestData = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['sub_category_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'type', 'condition' => '=', 'value' => 0], + ], + 'with' => ['propertyFactParent'], + 'firstRow' => 1 + ]; + $thisFact = $this->propertyFactService->select($factRequestData, ['id', 'parent_id', 'name', 'language_key', 'title_language_key']); + if($thisFact['status'] != 'success' || !$thisFact['data']){ + throw new ApiErrorException('Fact data not found') ; + } + + + $subCategoryFacts = $this->propertyFactService->getSubCategoryFacts($requestFact); + if($subCategoryFacts['status'] != 'success'){ + throw new ApiErrorException($subCategoryFacts['message']) ; + } + + $requestFact['parent_id'] = $thisFact['data']['parent_id'] ; + + $thisMenus = $this->propertyFactService->getSubCategoryMenus($requestFact); + if($thisMenus['status'] != 'success'){ + throw new ApiErrorException($thisMenus['message']) ; + } + $thisSubCategory = $thisFact['data'] ; + $thisMainCategory = $thisSubCategory['property_fact_parent'] ; + unset($thisSubCategory['property_fact_parent']) ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => + [ + 'get_facts' => $subCategoryFacts['data'], + 'get_menus' => $thisMenus['data'], + 'this_sub_category' => $thisSubCategory, + 'this_main_category' => $thisMainCategory, + ] + + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyFactMappingController.php b/app/Http/Controllers/V1/PropertyFactMappingController.php new file mode 100644 index 0000000..9019f37 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyFactMappingController.php @@ -0,0 +1,165 @@ +request = $request; + $this->propertyFactMappingService = $propertyFactMappingService; + + } + + public function getPropertyFactMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($request->getContent(),1); + + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $params]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function removePropertyFactMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + + $params = $params['property_fact_mapping_remove'] ; + + $requestParams = [ + 'active_user' => $this->request->credentials->user_id, + 'facts' => fillOnUndefined($params, 'facts'), + ]; + + $removeResponse = $this->propertyFactMappingService->removePropertyFactMapping($requestParams); + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $removeResponse]; + //$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function addPropertyFactMapping() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyFactMappingService->addPropertyFactMapping($params); + + + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyFactMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyFactMappingService->updatePropertyFactMapping($params); + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + + +} diff --git a/app/Http/Controllers/V1/PropertyNonrefundableController.php b/app/Http/Controllers/V1/PropertyNonrefundableController.php new file mode 100644 index 0000000..b64fc45 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyNonrefundableController.php @@ -0,0 +1,130 @@ +request = $request; + $this->propertyNonrefundableService = $propertyNonrefundableService; + } + + public function createPropertyChannelNonrefundable(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $getPropertyNonrefundable = $this->propertyNonrefundableService->createForm($params); + if($getPropertyNonrefundable['status'] != "success"){ + throw new ApiErrorException($getPropertyNonrefundable['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyNonrefundable['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function storePropertyChannelNonrefundable(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + $updateResponse = $this->propertyNonrefundableService->storePropertyNonrefundable($params); + + if($updateResponse['status'] != 'success'){ + throw new ApiErrorException($updateResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyChannelNonrefundable(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $getPropertyNonrefundable = $this->propertyNonrefundableService->getNonrefundableData($params); + if($getPropertyNonrefundable['status'] != "success"){ + throw new ApiErrorException($getPropertyNonrefundable['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['channel_list' => $getPropertyNonrefundable['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyOfferController.php b/app/Http/Controllers/V1/PropertyOfferController.php new file mode 100644 index 0000000..2f13313 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyOfferController.php @@ -0,0 +1,1073 @@ +request = $request; + $this->mailer = $mailer; + $this->offerService = $offerService; + $this->propertyFactService = $propertyFactService; + $this->propertyExecutiveService = $propertyExecutiveService; + $this->propertyRoomService = $propertyRoomService; + $this->propertyPhotoService = $propertyPhotoService; + $this->languageService = $languageService; + $this->currencyService = $currencyService; + $this->propertyBrandService = $propertyBrandService; + $this->propertyService = $propertyService; + $this->propertyContactService = $propertyContactService; + $this->propertyPaymentService = $propertyPaymentService; + // $this->qrCode = $qrCode; + + } + + + public function listPropertyOffer(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + 'with' => ['offerAcceptStatus','paymentTransaction'], + "orderBy" => [ + ["field" => "id", "value" => "DESC"] + ] + ]; + $ticketCode = fillOnUndefinedAndEmpty($params, 'ticket_code'); + if ($ticketCode) { + $propertyRequest['criteria'][] = ['field' => 'ticket_code', 'condition' => 'like', 'value' => '%' . $ticketCode . '%']; + } + + $propertyOffers = $this->offerService->select($propertyRequest); + + if ($propertyOffers['status'] != 'success') { + throw new Exception($propertyOffers['message']); + } + + $offerList = []; + foreach ($propertyOffers['data'] as $offerKey => $value) { + $offerList[$offerKey] = $value; + $offerList[$offerKey]['total'] = moneyDoubleFormat($value['total']); + if(!empty($value['payment_type_mapping_id'])) { + $offerList[$offerKey]['is_payment_received'] = false; + $paymentTransactionList = collect($value['payment_transaction']); + if($paymentTransactionList->where('status',1)->count() > 0) { + $offerList[$offerKey]['is_payment_received'] = true; + } + } + + unset($offerList[$offerKey]['payment_transaction']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $offerList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createPropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + $getPropertyFact = $this->propertyFactService->getPropertyFact($requestParams); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $getPropertyFact = $this->propertyFactService->getPropertyOfferFilter($getPropertyFact['data'], []); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $accommodationTypes = $getPropertyFact['data']['accommodation_types']; + $propertyFacts = $getPropertyFact['data']['get_facts']; + + $propertyExecutive = $this->propertyExecutiveService->listPropertyExecutive($requestParams); + if ($propertyExecutive['status'] != 'success') { + throw new Exception($propertyExecutive['message']); + } + + + $propertyRooms = $this->propertyRoomService->getPropertyRooms($requestParams); + if ($propertyRooms['status'] != 'success') { + throw new ApiErrorException($propertyRooms['message']); + } + + $propertyPhotos = $this->propertyPhotoService->getPropertyPhotos($params); + if ($propertyPhotos['status'] != 'success') { + throw new ApiErrorException($propertyPhotos['message']); + } + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $languages = $this->languageService->getAllLanguages($languageCriteria, ['id', 'code', 'name', 'status', 'language_key']); + if ($languages['status'] != 'success') { + throw new ApiErrorException($languages['message']); + } + + + $currencies = $this->currencyService->getCurrencyList(['justBasicCurrencies' => true]); + if ($currencies['status'] != 'success') { + throw new ApiErrorException($currencies['message']); + } + + $offerConfirmType = $this->offerService->selectOfferConfirmType([], ['code', 'name', 'language_key']); + if ($offerConfirmType['status'] != 'success') { + throw new ApiErrorException($offerConfirmType['message']); + } + + $offerConfirmType = $offerConfirmType['data']; + + $paymentList = $this->propertyPaymentService->getPaymentMappingList($params); + if ($paymentList['status'] != 'success') { + throw new ApiErrorException($paymentList['message']); + } + + $paymentListType = collect($paymentList['data'])->map(function ($payment) { + return [ + 'id' => $payment['id'], + 'name' => $payment['name'], + 'currency_code' => $payment['currency_code'], + 'title' => $payment['name'] . ' - ' . $payment['currency_code'], + 'status' => $payment['status'] + ]; + })->sortBy('title')->toArray(); + $paymentListType = array_values($paymentListType); + + $responseData = [ + 'get_facts' => $propertyFacts, + 'accommodation_types' => $accommodationTypes, + 'executives' => $propertyExecutive['data']['executives'], + 'property_rooms' => $propertyRooms['data'], + 'photos' => $propertyPhotos['data'], + 'languages' => $languages['data'], + 'currencies' => $currencies['data'], + 'offer_confirm_type' => $offerConfirmType, + 'payment_list_type' => $paymentListType, + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function storePropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + $storeOffer = $this->offerService->addNewOffer($requestParams); + if ($storeOffer['status'] != 'success') { + throw new ApiErrorException($storeOffer['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeOffer['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPricePropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $storeOffer = $this->offerService->getPriceList($requestParams); + if ($storeOffer['status'] != 'success') { + throw new ApiErrorException($storeOffer['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeOffer['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function storePricePropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $storeOffer = $this->offerService->storePriceList($requestParams); + if ($storeOffer['status'] != 'success') { + throw new ApiErrorException($storeOffer['message']); + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeOffer['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function editPropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'offer_id' => fillOnUndefined($params, 'offer_id'), + ]; + + $getOffer = $this->offerService->findOffer($requestParams); + if ($getOffer['status'] != 'success') { + throw new ApiErrorException($getOffer['message']); + } + + $offerPrice = $getOffer['data']['offer_price']; + $startDate = collect($offerPrice)->keyBy('date')->keys()->min(); + $endDate = collect($offerPrice)->keyBy('date')->keys()->max(); + + $getPropertyFact = $this->propertyFactService->getPropertyFact($requestParams); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + + $offerAccommodationMapping = collect($getOffer['data']['offer_accommodation_mapping'])->keyBy('id')->keys()->all(); + $offerFactMapping = collect($getOffer['data']['offer_fact_mapping'])->keyBy('id')->keys()->all(); + $offerAllFactIds = array_merge($offerAccommodationMapping, $offerFactMapping); + + $getPropertyFact = $this->propertyFactService->getPropertyOfferFilter($getPropertyFact['data'], $offerAllFactIds); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $accommodationTypes = $getPropertyFact['data']['accommodation_types']; + $propertyFacts = $getPropertyFact['data']['get_facts']; + + + $propertyExecutive = $this->propertyExecutiveService->listPropertyExecutive($requestParams); + if ($propertyExecutive['status'] != 'success') { + throw new Exception($propertyExecutive['message']); + } + + $propertyRooms = $this->propertyRoomService->getPropertyRooms($requestParams); + if ($propertyRooms['status'] != 'success') { + throw new ApiErrorException($propertyRooms['message']); + } + + $propertyPhotos = $this->propertyPhotoService->getPropertyPhotos($params); + if ($propertyPhotos['status'] != 'success') { + throw new ApiErrorException($propertyPhotos['message']); + } + + $languageCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $languages = $this->languageService->getAllLanguages($languageCriteria, ['id', 'code', 'name', 'status', 'language_key']); + if ($languages['status'] != 'success') { + throw new ApiErrorException($languages['message']); + } + + + $currencies = $this->currencyService->getCurrencyList(); + if ($currencies['status'] != 'success') { + throw new ApiErrorException($currencies['message']); + } + + $offerConfirmTypes = $this->offerService->selectOfferConfirmType([], ['code', 'name', 'language_key']); + if ($offerConfirmTypes['status'] != 'success') { + throw new ApiErrorException($offerConfirmTypes['message']); + } + + $offerConfirmType = []; + foreach ($offerConfirmTypes['data'] as $offerConfirmTypeData) { + + $isSelectedOfferConfirmType = false; + if ($offerConfirmTypeData['code'] == $getOffer['data']['confirm_type']) { + $isSelectedOfferConfirmType = true; + } + + $offerConfirmType[] = [ + 'code' => $offerConfirmTypeData['code'], + 'name' => $offerConfirmTypeData['name'], + 'language_key' => $offerConfirmTypeData['language_key'], + 'is_selected' => $isSelectedOfferConfirmType + ]; + } + + $paymentList = $this->propertyPaymentService->getPaymentMappingList($params); + if ($paymentList['status'] != 'success') { + throw new ApiErrorException($paymentList['message']); + } + + $paymentListType = collect($paymentList['data'])->map(function ($payment) use ($getOffer) { + + + $isSelectedPaymentType = false; + if ($payment['id'] == $getOffer['data']['payment_type_mapping_id']) { + $isSelectedPaymentType = true; + } + + return [ + 'id' => $payment['id'], + 'name' => $payment['name'], + 'currency_code' => $payment['currency_code'], + 'title' => $payment['name'] . ' - ' . $payment['currency_code'], + 'status' => $payment['status'], + 'is_selected' => $isSelectedPaymentType + ]; + })->sortBy('title')->toArray(); + + $paymentListType = array_values($paymentListType); + + $responseData = [ + 'get_offer' => $getOffer['data'], + 'get_facts' => $propertyFacts, + 'accommodation_types' => $accommodationTypes, + 'executives' => $propertyExecutive['data']['executives'], + 'property_rooms' => $propertyRooms['data'], + 'photos' => $propertyPhotos['data'], + 'languages' => $languages['data'], + 'currencies' => $currencies['data'], + 'start_date' => fillOnUndefined($getOffer['data'], "check_in"), + 'end_date' => fillOnUndefined($getOffer['data'], "check_out"), + 'offer_confirm_type' => $offerConfirmType, + 'payment_list_type' => $paymentListType, + ]; + + $responseData = $this->offerService->editFormCheckValues($responseData); + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyOffer(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $storeOffer = $this->offerService->updateOffer($requestParams); + if ($storeOffer['status'] != 'success') { + throw new ApiErrorException($storeOffer['message']); + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $storeOffer['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function listPropertyOfferPublish(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $checkOffer = [ + 'criteria' => [ + ['field' => 'offer_code', 'condition' => '=', 'value' => fillOnUndefined($params, 'offer_code')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['paymentTransaction'], + 'whereIn' => [ + ['field' => 'accept_status', 'value' => [1, 2, 3]], + ], + 'firstRow' => 1 + ]; + $checkOfferData = $this->offerService->select($checkOffer); + if ($checkOfferData['status'] != "success" || !$checkOfferData['data']) { + throw new ApiErrorException('offer not found'); + } + $params['offer_id'] = $checkOfferData['data']['id']; + $params['property_id'] = $checkOfferData['data']['property_id']; + $params['offer_code'] = $checkOfferData['data']['offer_code']; + + /* $offerUrl = config('app.client_server')."/offer/".$params['offer_code']; + $generatedQRCode = $this->qrCode->generate($offerUrl, 250); + + if($generatedQRCode['status'] === false){ + throw new ApiErrorException($generatedQRCode['message']); + } + + $qrCode = (string) Image::make($generatedQRCode['data'])->encode('data-url');*/ + + $requestParams = $params; + + $getOffer = $this->offerService->findOffer($requestParams); + + if ($getOffer['status'] != 'success') { + throw new ApiErrorException($getOffer['message']); + } + + $offerLanguage = $getOffer['data']['language']; + $requestParams['locale'] = $offerLanguage; + + $requestBrand = [ + + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + + ], + 'firstRow' => 1 + ]; + $getPropertyBrand = $this->propertyBrandService->select($requestBrand); + $getPropertyBrand['data']['color_codes'] = json_decode($getPropertyBrand['data']['color_codes'], true); + if ($getPropertyBrand['status'] != "success") { + throw new ApiErrorException($getPropertyBrand['message']); + } + + $defaultLogo = "/assets/img/logo/logo.png"; + $getPropertyBrand['data']['logo_url'] = isset($getPropertyBrand['data']['logo_name']) ? Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/logo/' . $getPropertyBrand['data']['logo_name'] . '_250x250.' . $getPropertyBrand['data']['logo_file_ext'] : $defaultLogo; + + $getOffer['data']['expire_date'] = humanReadableDate($getOffer['data']['expire_date']); + $getPropertyFact = $this->propertyFactService->getPropertyFact($requestParams); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + $offerAccommodationMapping = collect($getOffer['data']['offer_accommodation_mapping'])->keyBy('id')->keys()->all(); + $offerFactMapping = collect($getOffer['data']['offer_fact_mapping'])->keyBy('id')->keys()->all(); + $offerAllFactIds = array_merge($offerAccommodationMapping, $offerFactMapping); + $getPropertyFact = $this->propertyFactService->getPropertyOfferFilterForHtml($getPropertyFact['data'], $offerAllFactIds); + if ($getPropertyFact['status'] != 'success') { + throw new ApiErrorException($getPropertyFact['message']); + } + + + $getProperty = $this->propertyService->getPropertyDetail($requestParams); + + if ($getProperty['status'] != 'success') { + throw new ApiErrorException($getProperty['message']); + } + + $propertyContact = $this->propertyContactService->propertyContact($requestParams); + + if ($propertyContact['status'] != 'success') { + throw new Exception($propertyContact['message']); + } + + $getProperty['data']['contact'] = $propertyContact['data']['property_contact']; + $getRoomPriceParams = [ + + 'offer_id' => $getOffer['data']['id'], + 'property_id' => fillOnUndefined($params, 'property_id'), + 'locale' => $offerLanguage, + + ]; + + $getRoomPrice = $this->offerService->getPrice($getRoomPriceParams); + + if ($getRoomPrice['status'] != 'success') { + throw new ApiErrorException($getRoomPrice['message']); + } + + + $offerPayment = []; + if(!empty($checkOfferData['data']['payment_type_mapping_id'])) { + $paymentTransaction = collect($checkOfferData['data']['payment_transaction']); + + $paymentLink = $paymentTransaction->where('code',null)->first(); + + if(isset($paymentLink['manuelPaymentLink'])) { + $offerPayment['payment_link'] = $paymentLink['manuelPaymentLink']; + $offerPayment['is_payment_received'] = false; + } + + if($paymentTransaction->where('status',1)->count() > 0) { + $offerPayment['is_payment_received'] = true; + } + + } + + unset($getOffer['data']['offer_accommodation_mapping']); + unset($getOffer['data']['offer_fact_mapping']); + unset($getOffer['data']['offer_price']); + unset($getOffer['data']['offer_room_mapping']); + + $offerPublishData = [ + 'property_brand' => fillOnUndefined($getPropertyBrand, "data", []), + 'offer' => fillOnUndefined($getOffer, 'data', []), + 'property' => fillOnUndefined($getProperty, 'data', []), + 'property_fact' => fillOnUndefined($getPropertyFact, 'data', []), + 'room_price' => fillOnUndefined($getRoomPrice, 'data', []), + 'offer_payment' => $offerPayment + // "qr_code" => $qrCode + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $offerPublishData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 404; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyOfferStatus(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + + $requestParams['user_id'] = $this->request->auth->id; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $statusOffer = $this->offerService->updateStatus($requestParams); + if ($statusOffer['status'] != 'success') { + throw new ApiErrorException($statusOffer['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $statusOffer['data']]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function updatePropertyOfferAceptStatus(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams['user_id'] = $this->request->auth->id; + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + $requestParams['offer_id'] = $checkPropertyOfferPermissionAccess['data']['id']; + $requestParams['offer_code'] = $checkPropertyOfferPermissionAccess['data']['offer_code']; + + if ($checkPropertyOfferPermissionAccess['data']['confirm_type'] == 'HTL' && $checkPropertyOfferPermissionAccess['data']['accept_status'] == 2) { + $requestParams['accept_status'] = 1; + + $statusOffer = $this->offerService->updateAcceptStatus($requestParams); + if ($statusOffer['status'] != 'success') { + throw new ApiErrorException($statusOffer['message']); + } + + $offerAcceptMailParam = [ + 'offer_id' => $checkPropertyOfferPermissionAccess['data']['id'], + 'property_id' => $checkPropertyOfferPermissionAccess['data']['property_id'], + 'paymentUrl' => null + ]; + + //Integrated Payment Link + if (!is_null($checkPropertyOfferPermissionAccess['data']['payment_type_mapping_id'])) { + + $paymentLinkParam = [ + 'property_id' => $checkPropertyOfferPermissionAccess['data']['property_id'], + 'title' => $checkPropertyOfferPermissionAccess['data']['title'], + 'description' => $checkPropertyOfferPermissionAccess['data']['ticket_code'] . '-' . $checkPropertyOfferPermissionAccess['data']['offer_code'], + 'email' => $checkPropertyOfferPermissionAccess['data']['email'], + 'currency' => $checkPropertyOfferPermissionAccess['data']['currency'], + 'base_amount' => $checkPropertyOfferPermissionAccess['data']['total'], + 'commission' => '0', + 'payment_method' => 'online', + 'payment_type_mapping_id' => $checkPropertyOfferPermissionAccess['data']['payment_type_mapping_id'], + 'locale' => $checkPropertyOfferPermissionAccess['data']['language'], + 'user_id' => $checkPropertyOfferPermissionAccess['data']['created_by'], + ]; + + $createPaymentLink = $this->propertyPaymentService->createManualPayment($paymentLinkParam); + + if ($createPaymentLink['status'] == "success") { + $offerAcceptMailParam['paymentUrl'] = $createPaymentLink['data']['payment_link']; + $this->offerService->update($checkPropertyOfferPermissionAccess['data']['id'], ['payment_transaction_order_id' => $createPaymentLink['data']['order_id']]); + } + + } + + $this->mailer->onQueue('offerAcceptMail', new OfferAcceptMail($offerAcceptMailParam)); + + } else { + throw new ApiErrorException('Offer status not available'); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function dashboardPropertyOffer(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + ]; + $propertyOffers = $this->offerService->select($propertyRequest); + $propertyOffers = collect($propertyOffers['data'])->groupBy('accept_status')->map->count()->toArray(); + + $propertyPassiveRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 0], + ], + ]; + $propertyPassiveOffers = $this->offerService->select($propertyPassiveRequest); + $passiveCounts = collect($propertyPassiveOffers['data'])->count(); + $acceptAndPendingCount = collect($propertyOffers)->sum(); + $offerDashboardData = + [ + "passive" => $passiveCounts, + "canceled" => fillOnUndefined($propertyOffers, 0, 0), + "accepted" => fillOnUndefined($propertyOffers, 1, 0), + "pending" => fillOnUndefined($propertyOffers, 2, 0), + "total" => $passiveCounts + $acceptAndPendingCount, + + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $offerDashboardData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyOfferAcceptStatus(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $requestParams = $this->request->params; + + $checkOfferApprovedParam = [ + 'offer_id' => $requestParams['offer_id'] + ]; + $checkOfferApprovedStatus = $this->offerService->checkOfferApprovedStatus($checkOfferApprovedParam); + + if ($checkOfferApprovedStatus['status'] != 'success') { + throw new ApiErrorException($checkOfferApprovedStatus['message']); + } + + $requestParams['accept_status'] = 1; + if ($checkOfferApprovedStatus['data']['confirm_type'] == 'HTL') { + $requestParams['accept_status'] = 2; + } + + + $acceptStatusOffer = $this->offerService->updateAcceptStatus($requestParams); + if ($acceptStatusOffer['status'] != 'success') { + throw new ApiErrorException($acceptStatusOffer['message']); + } + + if ($checkOfferApprovedStatus['data']['confirm_type'] == 'INS') { + + $offerAcceptMailParam = [ + 'offer_id' => $checkOfferApprovedStatus['data']['id'], + 'property_id' => $checkOfferApprovedStatus['data']['property_id'], + 'paymentUrl' => null + ]; + + + //Integrated Payment Link + if (!is_null($checkOfferApprovedStatus['data']['payment_type_mapping_id'])) { + + + $paymentLinkParam = [ + 'property_id' => $checkOfferApprovedStatus['data']['property_id'], + 'title' => $checkOfferApprovedStatus['data']['title'], + 'description' => $checkOfferApprovedStatus['data']['ticket_code'] . '-' . $checkOfferApprovedStatus['data']['offer_code'], + 'email' => $checkOfferApprovedStatus['data']['email'], + 'currency' => $checkOfferApprovedStatus['data']['currency'], + 'base_amount' => $checkOfferApprovedStatus['data']['total'], + 'commission' => '0', + 'payment_method' => 'online', + 'payment_type_mapping_id' => $checkOfferApprovedStatus['data']['payment_type_mapping_id'], + 'locale' => $checkOfferApprovedStatus['data']['language'], + 'user_id' => $checkOfferApprovedStatus['data']['created_by'], + ]; + + $createPaymentLink = $this->propertyPaymentService->createManualPayment($paymentLinkParam); + + if ($createPaymentLink['status'] == "success") { + $offerAcceptMailParam['paymentUrl'] = $createPaymentLink['data']['payment_link']; + $this->offerService->update($checkOfferApprovedStatus['data']['id'], ['payment_transaction_order_id' => $createPaymentLink['data']['order_id']]); + } + + } + + $this->mailer->onQueue('offerAcceptMail', new OfferAcceptMail($offerAcceptMailParam)); + + } elseif ($checkOfferApprovedStatus['data']['confirm_type'] == 'HTL') { + + $offerAcceptMailParam = [ + 'offer_id' => $checkOfferApprovedStatus['data']['id'], + 'property_id' => $checkOfferApprovedStatus['data']['property_id'], + ]; + + $this->mailer->onQueue('offerPreConfirmCustomerMail', new OfferPreConfirmCustomerMail($offerAcceptMailParam)); + + $this->mailer->onQueue('offerPreConfirmPropertyMail', new OfferPreConfirmPropertyMail($offerAcceptMailParam)); + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function sendOfferEmail(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $checkPropertyOfferPermissionAccess = $this->offerService->checkPropertyOfferPermissionAccess(['property_id' => $params['property_id'], 'offer_id' => $params['offer_id']]); + if ($checkPropertyOfferPermissionAccess['status'] != 'success') { + throw new ApiErrorException($checkPropertyOfferPermissionAccess['message']); + } + + + $offerSendMailParam = [ + 'offer_id' => $params['offer_id'], + 'property_id' => $params['property_id'] + ]; + + $this->mailer->onQueue('offerSendMail', new OfferSendMail($offerSendMailParam)); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + + +} diff --git a/app/Http/Controllers/V1/PropertyPersonPricingPolicyController.php b/app/Http/Controllers/V1/PropertyPersonPricingPolicyController.php new file mode 100644 index 0000000..51bc52b --- /dev/null +++ b/app/Http/Controllers/V1/PropertyPersonPricingPolicyController.php @@ -0,0 +1,431 @@ +request = $request; + $this->propertyPersonPricingPolicyService = $propertyPersonPricingPolicyService; + } + + public function getPropertyPersonPricingPolicyList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + + $getPropertyPersonPricingList = $this->propertyPersonPricingPolicyService->getPropertyPersonPricingPolicyList($params); + + if ($getPropertyPersonPricingList['status'] != "success") { + throw new ApiErrorException($getPropertyPersonPricingList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['pricing_policies' => $getPropertyPersonPricingList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyPersonPricingAdultPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult_action_type' => fillOnUndefined($params, 'adult_action_type'), + 'adult' => fillOnUndefined($params, 'adult'), + 'action_type' => fillOnUndefined($params, 'action_type'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->createPropertyPersonPricingAdultPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createPropertyPersonPricingChildPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult' => fillOnUndefined($params, 'adult'), + 'child_order' => fillOnUndefined($params, 'child_order'), + 'child_age_start' => fillOnUndefined($params, 'child_age_start'), + 'child_age_end' => fillOnUndefined($params, 'child_age_end'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->createPropertyPersonPricingChildPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyPersonPricingAdultPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'pricing_policy_id' => fillOnUndefined($params, 'pricing_policy_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult_action_type' => fillOnUndefined($params, 'adult_action_type'), + 'adult' => fillOnUndefined($params, 'adult'), + 'action_type' => fillOnUndefined($params, 'action_type'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->updatePropertyPersonPricingAdultPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyPersonPricingChildPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = + [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'pricing_policy_id' => fillOnUndefined($params, 'pricing_policy_id'), + 'name' => fillOnUndefined($params, 'name'), + 'adult' => fillOnUndefined($params, 'adult'), + 'child_order' => fillOnUndefined($params, 'child_order'), + 'child_age_start' => fillOnUndefined($params, 'child_age_start'), + 'child_age_end' => fillOnUndefined($params, 'child_age_end'), + 'type' => fillOnUndefined($params, 'type'), + 'value' => fillOnUndefined($params, 'value'), + 'reservation_start_date' => fillOnUndefined($params, 'reservation_start_date'), + 'reservation_end_date' => fillOnUndefined($params, 'reservation_end_date'), + 'room_rate_channel_mapping_id' => fillOnUndefined($params, 'room_rate_channel_mapping_id'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->updatePropertyPersonPricingChildPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function deletePropertyPersonPricingAdultPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'pricing_policy_id' => fillOnUndefined($params, 'pricing_policy_id'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->deletePropertyPersonPricingAdultPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function deletePropertyPersonPricingChildPolicy(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $userId = $request->credentials->user_id; + $params = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'pricing_policy_id' => fillOnUndefined($params, 'pricing_policy_id'), + 'user_id' => $userId, + ]; + + $createResponse = $this->propertyPersonPricingPolicyService->deletePropertyPersonPricingChildPolicy($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updateRoomRatePricingAdultPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $checkChannelRoomPricingType = $this->propertyPersonPricingPolicyService->checkChannelRoomPricingType($params); + if ($checkChannelRoomPricingType['status'] != 'success') { + throw new ApiErrorException($checkChannelRoomPricingType['message']); + } + + $getPropertyPersonPricingList = $this->propertyPersonPricingPolicyService->updateRoomRatePricingAdultPolicy($params); + + if ($getPropertyPersonPricingList['status'] != "success") { + throw new ApiErrorException($getPropertyPersonPricingList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updateRoomRatePricingChildPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $checkChannelRoomPricingType = $this->propertyPersonPricingPolicyService->checkChannelRoomPricingType($params); + if ($checkChannelRoomPricingType['status'] != 'success') { + throw new ApiErrorException($checkChannelRoomPricingType['message']); + } + + $getPropertyPersonPricingList = $this->propertyPersonPricingPolicyService->updateRoomRatePricingChildPolicy($params); + + if ($getPropertyPersonPricingList['status'] != "success") { + throw new ApiErrorException($getPropertyPersonPricingList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getRoomRateChannelPersonPricingPolicy(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $checkChannelRoomPricingType = $this->propertyPersonPricingPolicyService->checkChannelRoomPricingType($params); + if ($checkChannelRoomPricingType['status'] != 'success') { + throw new ApiErrorException($checkChannelRoomPricingType['message']); + } + + $getPropertyPersonPricingList = $this->propertyPersonPricingPolicyService->getRoomRateChannelPersonPricingPolicy($params); + + if ($getPropertyPersonPricingList['status'] != "success") { + throw new ApiErrorException($getPropertyPersonPricingList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['rooms' => $getPropertyPersonPricingList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyPhotoCategoryController.php b/app/Http/Controllers/V1/PropertyPhotoCategoryController.php new file mode 100644 index 0000000..02fc3be --- /dev/null +++ b/app/Http/Controllers/V1/PropertyPhotoCategoryController.php @@ -0,0 +1,76 @@ +request = $request; + $this->propertyPhotoCategoryService = $propertyPhotoCategoryService; + + } + + public function propertyPhotoCategoryList() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + + ]; + $propertyPhotoCategory = $this->propertyPhotoCategoryService->getPropertyPhotoCategoryList($requestParams); + + if($propertyPhotoCategory['status'] != 'success'){ + throw new Exception($propertyPhotoCategory['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyPhotoCategory['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyPhotoController.php b/app/Http/Controllers/V1/PropertyPhotoController.php new file mode 100644 index 0000000..f0ebe3c --- /dev/null +++ b/app/Http/Controllers/V1/PropertyPhotoController.php @@ -0,0 +1,381 @@ +propertyPhotoService = $propertyPhotoService; + $this->googleVisionLabelService = $googleVisionLabelService; + $this->propertyConfigService = $propertyConfigService; + $this->propertyService = $propertyService ; + } + + public function getPropertyPhotos(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + + //TODO : Validation Yapılması gerekiyor. + $response = $this->propertyPhotoService->getPropertyPhotos($params); + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function uploadPropertyPhoto(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + try + { + if(!$request->hasFile('image')) + { + throw new ApiErrorException(lang('Photos not found')); + } + + $propertyId = $request->input('property_id'); + $photo = $request->file('image'); + + $param = + [ + "property_id" => $propertyId, + "photo" => $photo, + ]; + + $response = $this->propertyPhotoService->propertyPhotoUploadFilter($param); + + $rateParams = [ + 'property_id' => $propertyId, + 'user_id' => 1, + 'property_rate_for' => 'Property.Photo.Upload', + ]; + $this->propertyConfigService->rateProperty($rateParams); + + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function setDefaultPhoto(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + //TODO : Validation Yapılması gerekiyor. + $response = $this->propertyPhotoService->setDefaultPhoto($params); + + + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + $response['message'] = $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function setPropertyPhotoOrder(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'set_photo_order' => fillOnUndefined($params, 'set_photo_order'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + //TODO : Validation Yapılması gerekiyor. + $response = $this->propertyPhotoService->setPhotoOrder($requestParams); + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function publishPhotos(Request $request) + { + + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + + //TODO : Validation Yapılması gerekiyor. + $response = $this->propertyPhotoService->publishPhotos($params); + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function deletePropertyPhotos(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + + //TODO : Validation Yapılması gerekiyor. + $deletePhoto = $this->propertyPhotoService->deletePhotos($params); + if ($deletePhoto['status'] == false) { + throw new ApiErrorException($deletePhoto['message']); + } + + $defaultPhotoCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_default', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $propertyPhotoData = $this->propertyPhotoService->select($defaultPhotoCriteria, ['id']); + if ($propertyPhotoData['status'] == false) { + throw new ApiErrorException($propertyPhotoData['message']); + } + + $defaultPhoto = isset($propertyPhotoData['data']['id']) ? $propertyPhotoData['data']['id'] : null ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['default_photo' => $defaultPhoto] ]; + + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function setPropertyPhotoCategory(Request $request) + { + $response = ['status' => false, 'statusCode' => 500 ,'message' => '', 'data' => null]; + + try + { + if ( is_null( $request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = json_decode($request->getContent(),1); + $params = current($params); + + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + 'set_photo_category' => fillOnUndefined($params, 'set_photo_category'), + ]; + + //TODO : Validation Yapılması gerekiyor. + $response = $this->propertyPhotoService->setPhotoCategory($requestParams); + + + + }catch (ApiErrorException $e) + { + $response['message'] = $e->getMessage(); + + }catch (Exception $e) + { + $message = $e->getFile().' '.$e->getLine().' '.$e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function downloadPropertyPhotos(Request $request) + { + + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + if (is_null($request->getContent())) { + throw new Exception('api-unknown_error'); + } + $params = json_decode($request->getContent(), 1); + $params = current($params); + $responseData = null ; + $propertyId = $params['property_id']; + $getPhotosRequest = [ + 'property_id' => $propertyId + ]; + + if(isset($params['custom']) && !empty($params['custom'])) { + $getPhotosRequest['custom'] = $params['custom']; + } + + $response = $this->propertyPhotoService->getPropertyPhotos($getPhotosRequest); + + if ($response['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + if (!$response['data']) { + throw new Exception('api-unknown_error'); + } + $photos = $response['data']; + + if ($photos) { + $public_dir = public_path(); + $zipFileStoragePath = $public_dir . '/property-zip-files'; + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyId], + ], + 'firstRow' => true + ]; + $thisProperty = $this->propertyService->select($propertyRequest); + if ($thisProperty['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + $hotelName = Str::slug($thisProperty['data']['name'], '_', 'en'); + if (!File::exists($zipFileStoragePath)) { + File::makeDirectory($zipFileStoragePath, 0777, true); + } + $zipFileName = $hotelName . '_photos.zip'; + $zip = new ZipArchive; + if(file_exists($zipFileStoragePath . '/' . $zipFileName)) { + unlink($zipFileStoragePath . '/' . $zipFileName); + } + + if ($zip->open($zipFileStoragePath . '/' . $zipFileName, ZipArchive::CREATE) === TRUE) { + foreach ($photos as $photo) { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$photo['property_id']}" . "/{$photo['photo_name']}_medium.{$photo['file_ext']}"; + $fileName = "{$photo['photo_name']}_medium.{$photo['file_ext']}"; + if (file_exists($photoUrlFilePath)) { + $zip->addFile($photoUrlFilePath, $fileName); + } + } + $zip->close(); + } + $responseData = Config::get('app.zipFilesUrl').$zipFileName; + } + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['zipFile' => $responseData]]; + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyPlaceController.php b/app/Http/Controllers/V1/PropertyPlaceController.php new file mode 100644 index 0000000..64d06b7 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyPlaceController.php @@ -0,0 +1,520 @@ +request = $request ; + $this->propertyPlaceService = $propertyPlaceService ; + $this->propertyPhotoService = $propertyPhotoService ; + + + } + + + public function getPlaceCategories(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $placeCategories = $this->propertyPlaceService->getPropertyPlaceCategories($params); + + if($placeCategories['status'] != 'success'){ + throw new Exception($placeCategories['message']); + } + + $responseData['place_categories'] = $placeCategories['data'] ; + + $placeWorkingHours = $this->propertyPlaceService->getPropertyWorkingHours($params); + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + $responseData['place_working_hours'] = $placeWorkingHours['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPlaceCategoriesSingle(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $placeCategories = $this->propertyPlaceService->getPropertyPlaceCategoriesSingle($params); + + if($placeCategories['status'] != 'success'){ + throw new Exception($placeCategories['message']); + } + + $responseData['place_categories'] = $placeCategories['data'] ; + + $placeWorkingHours = $this->propertyPlaceService->getPropertyWorkingHours($params); + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + $responseData['place_working_hours'] = $placeWorkingHours['data'] ; + + + $placeIncludes = $this->propertyPlaceService->getPlaceIncludes($params); + if($placeIncludes['status'] != 'success'){ + throw new Exception($placeIncludes['message']); + } + $responseData['place_includes'] = $placeIncludes['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPlacePlaceWorkingHours(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->getPropertyWorkingHours($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $responseData['place_working_hours'] = $placeWorkingHours['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createPlace(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->create($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $responseData['property_place'] = $placeWorkingHours['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function listPlace(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $listPlaces = $this->propertyPlaceService->listPlaces($params); + + if($listPlaces['status'] != 'success'){ + throw new Exception($listPlaces['message']); + } + + $responseData['places'] = $listPlaces['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyPlacePhoto(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'place_id' => fillOnUndefined($params, 'place_id'), + ]; + + $getPropertyPhoto = $this->propertyPhotoService->getPropertyPlacePhoto($requestFact); + if ($getPropertyPhoto['status'] != 'success') { + throw new ApiErrorException($getPropertyPhoto['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyPhoto['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyPlacePhotoMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyPlaceService->updatePropertyPlacePhotoMapping($params); + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePlace(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->update($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $placeWorkingHours['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePlaceStatus(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->updateStatus($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $placeWorkingHours['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function deletePlace(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->deletePlace($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $placeWorkingHours['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function editPlace(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $listPlaces = $this->propertyPlaceService->editPlaces($params); + + if($listPlaces['status'] != 'success'){ + throw new Exception($listPlaces['message']); + } + + $responseData = $listPlaces['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function listPlaceFacilities(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $listPlaces = $this->propertyPlaceService->listPlaceFacilities($params); + + if($listPlaces['status'] != 'success'){ + throw new Exception($listPlaces['message']); + } + + $responseData['place_facilities'] = $listPlaces['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePlaceFacilities(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeWorkingHours = $this->propertyPlaceService->updatePlaceFacilities($params); + + if($placeWorkingHours['status'] != 'success'){ + throw new Exception($placeWorkingHours['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $placeWorkingHours['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPlaceCategoryFields(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $responseData = null ; + $placeCategoryFields = $this->propertyPlaceService->getPlaceCategoryFields($params); + if($placeCategoryFields['status'] != 'success'){ + throw new Exception($placeCategoryFields['message']); + } + $responseData['place_category_fields'] = $placeCategoryFields['data'] ; + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function insertNewFieldMapping(){ + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + $responseData = null ; + $placeCategoryFields = $this->propertyPlaceService->insertNewFieldMapping($params); + if($placeCategoryFields['status'] != 'success'){ + throw new Exception($placeCategoryFields['message']); + } + $responseData['place_category_fields'] = $placeCategoryFields['data'] ; + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyPromotionController.php b/app/Http/Controllers/V1/PropertyPromotionController.php new file mode 100644 index 0000000..ce72974 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyPromotionController.php @@ -0,0 +1,264 @@ +request = $request; + $this->propertyPromotionService = $propertyPromotionService; + } + + + public function getPromotionTypeList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPromotionTypeList = $this->propertyPromotionService->getPromotionTypeList($params); + + if ($getPromotionTypeList['status'] != "success") { + throw new ApiErrorException($getPromotionTypeList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['promotion_type' => $getPromotionTypeList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyPromotionList(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyPromotionList = $this->propertyPromotionService->getPropertyPromotionList($params); + + if ($getPropertyPromotionList['status'] != "success") { + throw new ApiErrorException($getPropertyPromotionList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_promotions' => $getPropertyPromotionList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyPromotion(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + $createResponse = $this->propertyPromotionService->createPropertyPromotion($params); + + if ($createResponse['status'] != 'success') { + throw new ApiErrorException($createResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $createResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getRoomRateChannelPromotion(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $getPropertyPromotionList = $this->propertyPromotionService->getRoomRateChannelPromotion($params); + + if ($getPropertyPromotionList['status'] != "success") { + throw new ApiErrorException($getPropertyPromotionList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['rooms' => $getPropertyPromotionList['data']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyPromotion(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + $updateResponse = $this->propertyPromotionService->updatePropertyPromotion($params); + + if ($updateResponse['status'] != 'success') { + throw new ApiErrorException($updateResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updateRoomRateChannelPromotion(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + + $getPropertyPromotionList = $this->propertyPromotionService->updateRoomRateChannelPromotion($params); + + if ($getPropertyPromotionList['status'] != "success") { + throw new ApiErrorException($getPropertyPromotionList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyPromotion(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $params = $this->request->params; + $params['user_id'] = $request->credentials->user_id; + + $updateResponse = $this->propertyPromotionService->deletePropertyPromotion($params); + + if ($updateResponse['status'] != 'success') { + throw new ApiErrorException($updateResponse['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateResponse['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + + +} diff --git a/app/Http/Controllers/V1/PropertyQuickPricingController.php b/app/Http/Controllers/V1/PropertyQuickPricingController.php new file mode 100644 index 0000000..2772630 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyQuickPricingController.php @@ -0,0 +1,490 @@ +params = Input::all(); + $this->propertyQuickPricingService = $propertyQuickPricingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + } + + public function syncPropertyQuickPricing(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + //TODO Param validator + + $propertyRoomRateChannelIds = []; + + $channelRoomRateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + + $propertyRoomRateChannels = $this->propertyRoomRateChannelMappingService->select($channelRoomRateCriteria); + + if ($propertyRoomRateChannels['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateChannels['message']); + } + + $propertyRoomRateChannelIds = pickItemFromArray('id', $propertyRoomRateChannels['data']); + + if (empty($propertyRoomRateChannelIds)) { + throw new ApiErrorException('Not mapping room rate this channel.'); + } + + + DB::beginTransaction(); + + $quickPricingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ] + ]; + + $quickPricingResult = $this->propertyQuickPricingService->selectPropertyQuickPricingMapping($quickPricingCriteria); + + if ($quickPricingResult['status'] != 'success') { + throw new ApiErrorException($quickPricingResult['message']); + } + + if (!empty($quickPricingResult['data'])) { + $deleteIds = pickItemFromArray('id', $quickPricingResult['data']); + $deletePropertyQuickPricingMapping = $this->propertyQuickPricingService->deletePropertyQuickPricingMapping($deleteIds); + if ($deletePropertyQuickPricingMapping['status'] != 'success') { + throw new ApiErrorException($deletePropertyQuickPricingMapping['message']); + } + } + + $roomRateChannelMappingIdCollect = collect($this->params['params']['room_rates'])->groupBy('room_rate_channel_mapping_id')->toArray(); + foreach ($roomRateChannelMappingIdCollect as $roomRateChannelMapping) { + if (count($roomRateChannelMapping) > 1) { + throw new ApiErrorException('The same room rate channel id can not be processed.'); + } + } + + + $requestResultData = []; + foreach ($this->params['params']['room_rates'] as $roomRate) { + + if (!in_array($roomRate['room_rate_channel_mapping_id'], $propertyRoomRateChannelIds)) { + continue; + } + + $requestParam = [ + 'property_id' => $this->params['params']['property_id'], + 'channel_id' => $this->params['params']['channel_id'], + 'room_rate_channel_mapping_id' => $roomRate['room_rate_channel_mapping_id'], + 'action_type' => fillOnUndefined($roomRate, 'action_type'), + 'price_type' => fillOnUndefined($roomRate, 'price_type'), + 'price_value' => fillOnUndefined($roomRate, 'price_value'), + 'created_by' => $request->auth->id, + 'updated_by' => $request->auth->id, + ]; + + + $requestResult = $this->propertyQuickPricingService->createPropertyQuickPricingMapping($requestParam); + + if ($requestResult['status'] != 'success') { + throw new ApiErrorException($requestResult['message']); + } + + $requestResultData[] = $requestResult['data']; + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $requestResultData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getPropertyQuickPricing(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ], + 'with' => ['propertyRoomRateChannelMapping.propertyRoomRateMapping'] + ]; + + $columns = ['id', 'property_id', 'channel_id', 'room_rate_channel_mapping_id', 'action_type', 'price_type', 'price_value']; + $requestSelectResult = $this->propertyQuickPricingService->selectPropertyQuickPricingMapping($requestSelectCriteria, $columns); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + $requestSelectResultData = []; + foreach ($requestSelectResult['data'] as $key => $value) { + $requestSelectResultData[$value['room_rate_channel_mapping_id']] = [ + 'property_id' => $value['property_id'], + 'channel_id' => $value['channel_id'], + 'room_id' => $value['property_room_rate_channel_mapping']['property_room_rate_mapping']['room_id'], + 'room_rate_id' => $value['property_room_rate_channel_mapping']['property_room_rate_mapping']['room_rate_id'], + 'room_rate_mapping_id' => $value['property_room_rate_channel_mapping']['room_rate_mapping_id'], + 'room_rate_channel_mapping_id' => $value['room_rate_channel_mapping_id'], + 'action_type' => $value['action_type'], + 'price_type' => $value['price_type'], + 'price_value' => $value['price_value'], + ]; + + } + + $channelRoomRateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['propertyRoomRateMapping.propertyRoom', 'propertyRoomRateMapping.propertyRoomRate'] + ]; + + + $propertyRoomRateChannels = $this->propertyRoomRateChannelMappingService->select($channelRoomRateCriteria); + + if ($propertyRoomRateChannels['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateChannels['message']); + } + + $propertyRoomRateChannelQp = []; + foreach ($propertyRoomRateChannels['data'] as $propertyRoomRateChannel) { + + //Best Available Rate Manipulate + if($propertyRoomRateChannel['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') { + continue; + } + + $roomId = $propertyRoomRateChannel['property_room_rate_mapping']['room_id']; + + //dd($propertyRoomRateChannel['property_room_rate_mapping']['property_room']['name']); + + $propertyRoomRateChannelQp['rooms'][$roomId]['name'] = $propertyRoomRateChannel['property_room_rate_mapping']['property_room']['name']; + + $propertyRoomRateChannelQp['rooms'][$roomId]['property_room_rate_mapping'][$propertyRoomRateChannel['room_rate_mapping_id']] = [ + 'name' => $propertyRoomRateChannel['property_room_rate_mapping']['property_room_rate']['name'], + 'room_rate_channel_mapping_id' => $propertyRoomRateChannel['id'], + 'action_type' => null, + 'price_type' => null, + 'price_value' => null + ]; + + if (isset($requestSelectResultData[$propertyRoomRateChannel['id']])) { + $propertyRoomRateChannelQp['rooms'][$roomId]['property_room_rate_mapping'][$propertyRoomRateChannel['room_rate_mapping_id']] = [ + 'name' => $propertyRoomRateChannel['property_room_rate_mapping']['property_room_rate']['name'], + 'room_rate_channel_mapping_id' => $propertyRoomRateChannel['id'], + 'action_type' => $requestSelectResultData[$propertyRoomRateChannel['id']]['action_type'], + 'price_type' => $requestSelectResultData[$propertyRoomRateChannel['id']]['price_type'], + 'price_value' => $requestSelectResultData[$propertyRoomRateChannel['id']]['price_value'], + ]; + } + + } + + + //array_values + foreach ($propertyRoomRateChannelQp['rooms'] as $roomId => $rooms) { + $propertyRoomRateChannelQp['rooms'][$roomId]['property_room_rate_mapping'] = array_values($rooms['property_room_rate_mapping']); + } + + $propertyRoomRateChannelQp['rooms'] = array_values($propertyRoomRateChannelQp['rooms']); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateChannelQp]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function propertyQuickPricingRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + //Burada kanal ve proeprty ile kanal maping detaylatı çekilmeli property_channel_mapping tablosundan + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + $propertyChannelMapping = $propertyChannelMapping['data']; + + + //CONNECTED CHANNEL RATE CHECK + $propertyChannelConnectedList = []; + $propertyChannelConnectedCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyChannelConnected = $this->propertyChannelMappingService->select($propertyChannelConnectedCriteria); + if ($propertyChannelConnected['status'] == 'success') { + $propertyChannelConnectedList = $propertyChannelConnected['data']; + + } + //CONNECTED CHANNEL RATE CHECK + + /* + + "property_id" => 1 + "channel_id" => 1 + "currency_code" => "EUR" + "property_booking_type_id" => 1 + "property_availability_type_id" => 1 + + * */ + + //Property ve Kanala ait mapping yapılan room rate ler + $propertyRoomRateChannelIds = []; + $channelRoomRateCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + + $propertyRoomRateChannels = $this->propertyRoomRateChannelMappingService->select($channelRoomRateCriteria); + + if ($propertyRoomRateChannels['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateChannels['message']); + } + + $propertyRoomRateChannelIds = pickItemFromArray('id', $propertyRoomRateChannels['data']); + + if (empty($propertyRoomRateChannelIds)) { + throw new ApiErrorException('Not mapping room rate this channel.'); + } + + $propertyQuickPricingMapping = []; + $requestSelectCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['params']['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['params']['channel_id']], + ], + 'with' => ['propertyRoomRateChannelMapping.propertyRoomRateMapping', 'propertyRoomRateChannelMapping.propertyRoomRateMapping'] + ]; + + $columns = ['id', 'property_id', 'channel_id', 'room_rate_channel_mapping_id', 'action_type', 'price_type', 'price_value']; + $requestSelectResult = $this->propertyQuickPricingService->selectPropertyQuickPricingMapping($requestSelectCriteria, $columns); + + if ($requestSelectResult['status'] != 'success') { + throw new ApiErrorException($requestSelectResult['message']); + } + + $propertyQuickPricingMapping = $requestSelectResult['data']; + + DB::beginTransaction(); + + foreach ($propertyQuickPricingMapping as $quickPricing) { + + //Eğer kanalda kapalı bir room rate var ise onun fiyatı güncellenmez + if (!in_array($quickPricing['room_rate_channel_mapping_id'], $propertyRoomRateChannelIds)) { + continue; + } + + //dd($quickPricing,$propertyChannelMapping,$this->params); + + + $requestParams = [ + 'property_id' => $quickPricing['property_id'], + 'channel_id' => $quickPricing['channel_id'], + 'user_id' => $request->auth->id, + 'availability' => [] + ]; + + $requestParams['rates'] = []; + + foreach ($this->params['params']['data'] as $date => $amount) { + + + $dateForSql = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2); + + if (!Carbon::parse($dateForSql)) { + throw new ApiErrorException('Invalid date format.'); + } + + if (Carbon::parse($dateForSql)->isBefore(Carbon::now()->toDateString())) { + throw new ApiErrorException('Date to be updated cannot be earlier than today'); + } + + $dateKeyParam = []; + $dateKeyParam[] = $propertyChannelMapping['property_availability_type_id']; + $dateKeyParam[] = $quickPricing['property_room_rate_channel_mapping']['property_room_rate_mapping']['room_id']; + $dateKeyParam[] = $quickPricing['property_room_rate_channel_mapping']['room_rate_mapping_id']; + $dateKeyParam[] = $dateForSql; + $dateKey = implode('|', $dateKeyParam); + + + $amountCalculated = $amount; + + $amountAffected = 0; + if ($quickPricing['price_type'] == 'PER') { + $amountAffected = ($amount * $quickPricing['price_value']) / 100; + } elseif ($quickPricing['price_type'] == 'FIX') { + $amountAffected = $quickPricing['price_value']; + } + + if ($quickPricing['action_type'] == 'INC') { + $amountCalculated = $amountCalculated + $amountAffected; + } + + if ($quickPricing['action_type'] == 'DEC') { + $amountCalculated = $amountCalculated - $amountAffected; + } + + if ($amountCalculated <= 0) { + throw new ApiErrorException('Calculated amount cannot be 0 or less.'); + } + + + $requestParams['rates'][$dateKey] = [ + "setup_type_id" => $propertyChannelMapping['property_availability_type_id'], + "room_id" => $quickPricing['property_room_rate_channel_mapping']['property_room_rate_mapping']['room_id'], + "room_rate_mapping_id" => $quickPricing['property_room_rate_channel_mapping']['room_rate_mapping_id'], + "date" => $dateForSql, + "amount" => $amountCalculated + ]; + + } + + $requestParams['quickPricing'] = true; + + $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams); + + if ($roomRateUpdate['status'] != 'success') { + throw new ApiErrorException($roomRateUpdate['message']); + } + + + //CONNECTED CHANNEL RATE UPDATE + foreach ($propertyChannelConnectedList as $propertyChannelConnected) { + $requestParams['channel_id'] = $propertyChannelConnected['channel_id']; + $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams); + if ($roomRateUpdate['status'] != 'success') { + throw new ApiErrorException($roomRateUpdate['message']); + } + } + //CONNECTED CHANNEL RATE UPDATE + + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/PropertyRoomBedController.php b/app/Http/Controllers/V1/PropertyRoomBedController.php new file mode 100644 index 0000000..7207de2 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomBedController.php @@ -0,0 +1,119 @@ +request = $request; + $this->propertyRoomBedService = $propertyRoomBedService; + + } + + + + public function getPropertyRoomBed(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + ]; + + $propertyRoomBedType = $this->propertyRoomBedService->getPropertyRoomBeds($requestParams); + if($propertyRoomBedType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomBedType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomBedType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomBed(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id', null), + 'room_id' => fillOnUndefined($params, 'room_id', null), + 'room_bed_group' => fillOnUndefined($params, 'room_bed_group', []), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomBedType = $this->propertyRoomBedService->addPropertyRoomBed($requestParams); + if($propertyRoomBedType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomBedType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomBedType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyRoomBedTypeController.php b/app/Http/Controllers/V1/PropertyRoomBedTypeController.php new file mode 100644 index 0000000..11e48c7 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomBedTypeController.php @@ -0,0 +1,74 @@ +request = $request; + $this->propertyRoomBedTypeService = $propertyRoomBedTypeService; + + } + + + + public function getPropertyRoomBedTypes(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + ]; + + $propertyRoomBedType = $this->propertyRoomBedTypeService->getPropertyRoomBedTypes($requestParams); + if($propertyRoomBedType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomBedType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomBedType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyRoomController.php b/app/Http/Controllers/V1/PropertyRoomController.php new file mode 100644 index 0000000..100375b --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomController.php @@ -0,0 +1,665 @@ +request = $request; + $this->propertyRoomService = $propertyRoomService; + $this->propertyRoomTypeService = $propertyRoomTypeService; + $this->propertyRoomBedTypeService = $propertyRoomBedTypeService; + $this->propertyRoomViewTypeService = $propertyRoomViewTypeService; + $this->propertyChannelMappingService = $propertyChannelMappingService ; + + } + + + + public function getPropertyRoom(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRooms($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoom(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'room_size' => fillOnUndefined($params, 'room_size'), + 'room_size_type' => fillOnUndefined($params, 'room_size_type'), + 'room_type_count' => fillOnUndefined($params, 'room_type_count',1), + 'room_count' => fillOnUndefined($params, 'room_count'), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count'), + 'toilet_count' => fillOnUndefined($params, 'toilet_count'), + 'lounge_count' => fillOnUndefined($params, 'lounge_count'), + 'max_child_number' => fillOnUndefined($params, 'max_child_number'), + 'description' => fillOnUndefined($params, 'description'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomType = $this->propertyRoomService->addPropertyRoom($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomAndBed(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => trim(fillOnUndefined($params, 'name')), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => fillOnUndefined($params, 'exclude_occupancy'), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'description' => fillOnUndefined($params, 'description', []), + 'room_bed_group' => fillOnUndefined($params, 'room_bed_group'), + 'room_view_type' => fillOnUndefined($params, 'room_view_type'), + 'is_connected_room' => fillOnUndefined($params, 'is_connected_room', null), + 'is_connected_room_price' => fillOnUndefined($params, 'is_connected_room_price', null), + 'is_connected_room_availability' => fillOnUndefined($params, 'is_connected_room_availability', null), + 'connected_rooms' => fillOnUndefined($params, 'connected_rooms', []), + 'user_id' => $this->request->auth->id, + ]; + + + + $propertyRoomType = $this->propertyRoomService->addPropertyRoomAndBed($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomAndBed(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'name' => trim(fillOnUndefined($params, 'name')), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => fillOnUndefined($params, 'exclude_occupancy'), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'description' => fillOnUndefined($params, 'description', []), + 'room_bed_group' => fillOnUndefined($params, 'room_bed_group'), + 'room_view_type' => fillOnUndefined($params, 'room_view_type'), + 'is_connected_room' => fillOnUndefined($params, 'is_connected_room', null), + 'is_connected_room_price' => fillOnUndefined($params, 'is_connected_room_price', null), + 'is_connected_room_availability' => fillOnUndefined($params, 'is_connected_room_availability', null), + 'connected_rooms' => fillOnUndefined($params, 'connected_rooms', []), + "status" => fillOnUndefined($params, "status", 1), + 'user_id' => $this->request->auth->id, + ]; + + + + $propertyRoomType = $this->propertyRoomService->updatePropertyRoomAndBed($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoom(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => trim(fillOnUndefined($params, 'name')), + 'room_type_id' => fillOnUndefined($params, 'room_type_id'), + 'max_occupancy' => fillOnUndefined($params, 'max_occupancy'), + 'max_adult' => fillOnUndefined($params, 'max_adult'), + 'max_child' => fillOnUndefined($params, 'max_child'), + 'occupancy_lock' => fillOnUndefined($params, 'occupancy_lock'), + 'exclude_occupancy' => fillOnUndefined($params, 'exclude_occupancy'), + 'room_size' => fillOnUndefined($params, 'room_size', null), + 'room_size_type' => fillOnUndefined($params, 'room_size_type', null), + 'room_type_count' => fillOnUndefined($params, 'room_type_count', 1), + 'room_count' => fillOnUndefined($params, 'room_count', null), + 'bathroom_count' => fillOnUndefined($params, 'bathroom_count', null), + 'toilet_count' => fillOnUndefined($params, 'toilet_count', null), + 'lounge_count' => fillOnUndefined($params, 'lounge_count', null), + 'max_child_number' => fillOnUndefined($params, 'max_child_number', null), + 'description' => fillOnUndefined($params, 'description', []), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomType = $this->propertyRoomService->updatePropertyRoom($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + $propertyRoomType['data']['exclude_occupancy'] = json_decode($propertyRoomType['data']['exclude_occupancy'], true); + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyRoomAndBed(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'room_id' => fillOnUndefined($params, 'room_id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoom = $this->propertyRoomService->getPropertyRoomAndBed($requestParams); + if($propertyRoom['status'] != 'success'){ + throw new ApiErrorException($propertyRoom['message']); + } + + $responseData['property_room'] = $propertyRoom['data'] ; + + + $propertyRoomType = $this->propertyRoomTypeService->getPropertyRoomTypes($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $responseData['property_room_types'] = $propertyRoomType['data'] ; + + $propertyRoomBedType = $this->propertyRoomBedTypeService->getPropertyRoomBedTypes($requestParams); + if($propertyRoomBedType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomBedType['message']); + } + + $responseData['property_room_bed_types'] = $propertyRoomBedType['data'] ; + + + $propertyRoomViewTypeCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $propertyRoomViewTypeList = $this->propertyRoomViewTypeService->getPropertyRoomViewTypes($propertyRoomViewTypeCriteria); + + if($propertyRoomViewTypeList['status'] != 'success'){ + throw new ApiErrorException($propertyRoomViewTypeList['message']); + } + + $responseData['property_room_view_types'] = $propertyRoomViewTypeList['data'] ; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyRoom(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'user_id' => $this->request->auth->id, + + ]; + + $propertyRoomType = $this->propertyRoomService->deletePropertyRoom($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyRoomRateChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRoomRateChannel($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyRoomInventory(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + + ]; + + $propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + //Best Available Rate Manipulate + foreach ($propertyRoomType['data'] as $roomKey => $room) { + foreach ($room['property_room_rate_mapping'] as $roomRateMappingKey => $roomRateMapping) { + if($roomRateMapping['name'] == 'Best Available Rate') { + unset($room['property_room_rate_mapping'][$roomRateMappingKey]); + } + } + + $propertyRoomType['data'][$roomKey]['property_room_rate_mapping'] = array_values($room['property_room_rate_mapping']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getChannelRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $propertyRoomType = $this->propertyRoomService->getChannelRoomRateMapping($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getChannelBulkUpdateParams(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $propertyRooms = $this->propertyRoomService->getChannelRoomRateMapping($requestParams); + if($propertyRooms['status'] != 'success'){ + throw new ApiErrorException($propertyRooms['message']); + } + $propertyRooms = $propertyRooms['data'] ; + + $rooms = [] ; + foreach ($propertyRooms as $propertyRoom) { + $room = [ + 'id' => $propertyRoom['id'], + 'name' => $propertyRoom['name'], + 'room_selected' => false, + ] ; + $rates = [] ; + foreach ($propertyRoom['property_room_rate_mapping'] as $roomRate) { + + //Best Available Rate Manipulate + if($roomRate['name'] == 'Best Available Rate') { + continue; + } + + if($roomRate['is_selected'] === true){ + + $rate = [ + 'id' => $roomRate['room_rate_id'], + 'room_rate_mapping_id' => $roomRate['id'], + 'name' => $roomRate['name'], + 'rate_selected' => false, + ] ; + $rates[] = $rate ; + } + + } + if($rates){ + $room['room_rate_mapping'] = $rates; + $rooms[] = $room; + } + } + + $bulkUpdateOptionParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'user_id' => $this->request->auth->id, + ]; + + + $channelMapping = $this->propertyChannelMappingService->getPropertyChannelSetup($bulkUpdateOptionParams); + if($channelMapping['status'] != 'success'){ + throw new ApiErrorException($channelMapping['message']); + } + + $channelMapping = $channelMapping['data'] ; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['room_rates' => $rooms, 'bulk_update_options' => $channelMapping['bulk_update_options']]]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomFactMappingController.php b/app/Http/Controllers/V1/PropertyRoomFactMappingController.php new file mode 100644 index 0000000..61137ba --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomFactMappingController.php @@ -0,0 +1,135 @@ +request = $request; + $this->propertyRoomFactMappingService = $propertyRoomFactMappingService; + $this->propertyFactService = $propertyFactService; + + } + + public function updatePropertyRoomFactMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyRoomFactMappingService->updatePropertyRoomFactMapping($params); + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyRoomFact(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + ]; + + $getPropertyFact = $this->propertyFactService->getPropertyRoomFact($requestFact); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyFact['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomFactIsFeature(){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyRoomFactMappingService->updatePropertyRoomFactIsFeature($params); + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomPhotoMappingController.php b/app/Http/Controllers/V1/PropertyRoomPhotoMappingController.php new file mode 100644 index 0000000..f0d967e --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomPhotoMappingController.php @@ -0,0 +1,109 @@ +request = $request; + $this->propertyRoomPhotoMappingService = $propertyRoomPhotoMappingService; + $this->propertyPhotoService = $propertyPhotoService; + + } + + public function updatePropertyRoomPhotoMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try + { + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + $params = json_decode($this->request->getContent(),1); + $params = current($params); + $params['user_id'] = $this->request->auth->id; + + $response = $this->propertyRoomPhotoMappingService->updatePropertyRoomPhotoMapping($params); + + }catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyRoomPhoto(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestFact = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + ]; + + $getPropertyPhoto = $this->propertyPhotoService->getPropertyRoomPhoto($requestFact); + if ($getPropertyPhoto['status'] != 'success') { + throw new ApiErrorException($getPropertyPhoto['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $getPropertyPhoto['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomRateChannelMappingController.php b/app/Http/Controllers/V1/PropertyRoomRateChannelMappingController.php new file mode 100644 index 0000000..4236d58 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRateChannelMappingController.php @@ -0,0 +1,177 @@ +request = $request; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyChannelService = $propertyChannelService ; + + } + + + + public function getPropertyRoomRateChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + ]; + + $propertyChannel = $this->propertyChannelService->getPropertyChannels($requestParams); + if($propertyChannel['status'] != 'success'){ + throw new ApiErrorException($propertyChannel['message']); + } + $propertyChannels = collect($propertyChannel['data'])->where('is_selected', '=', true); + if($requestParams['channel_id']){ + $propertyChannels = $propertyChannels->whereIn('id', $requestParams['channel_id']) ; + } + $propertyChannels = $propertyChannels->values()->toArray() ; + $requestParams['channels'] = $propertyChannels ; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->getPropertyRoomRateChannelMapping($requestParams); + if($propertyRoomRateChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'channels' => fillOnUndefined($params, 'channels'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->addPropertyRoomRateChannelMapping($requestParams); + if($propertyRoomRateChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomRateChannelMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_channel_mapping' => fillOnUndefined($params, 'room_rate_channel_mapping'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->updatePropertyRoomRateChannelMapping($requestParams); + if($propertyRoomRateChannelMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateChannelMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateChannelMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomRateController.php b/app/Http/Controllers/V1/PropertyRoomRateController.php new file mode 100644 index 0000000..58189ca --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRateController.php @@ -0,0 +1,527 @@ +request = $request; + $this->propertyRoomRateService = $propertyRoomRateService; + $this->propertyRoomRateMappingService = $propertyRoomRateMappingService; + $this->propertyRoomService = $propertyRoomService; + } + + + + public function getPropertyRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyRoomRate = $this->propertyRoomRateService->getPropertyRoomRates($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyRoomRateConnected(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + ]; + + $propertyRoomRateConnected = $this->propertyRoomRateMappingService->getPropertyRoomRateMappingConnected($requestParams); + if($propertyRoomRateConnected['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateConnected['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateConnected['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function syncPropertyRoomRateConnected(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'connected_room_rate' => fillOnUndefined($params, 'connected_room_rate'), + ]; + + $propertyRoomRateConnected = $this->propertyRoomRateMappingService->syncPropertyRoomRateMappingConnected($requestParams); + if($propertyRoomRateConnected['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateConnected['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateConnected['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'description' => fillOnUndefined($params, 'description'), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRate = $this->propertyRoomRateService->addPropertyRoomRate($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateWithInclusion(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'description' => fillOnUndefined($params, 'description'), + /* 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'),*/ + 'facts' => fillOnUndefined($params, 'facts'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomRate = $this->propertyRoomRateService->addPropertyRoomRateWithInclusion($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + foreach ($params['rooms'] as $room){ + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => [$room['room_id']], + 'room_rate_id' => $propertyRoomRate['data']['id'], + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => $room['value'], + 'room_rate_mapping_setup' => [ + [ + 'setup_type' => 'EXT_ADULT', + 'value_type' => fillOnUndefined($params, 'ext_adult_type'), + 'value' => fillOnUndefined($params, 'ext_adult_rate'), + ], + + [ + 'setup_type' => 'EXT_CHILD', + 'value_type' => fillOnUndefined($params, 'ext_child_type'), + 'value' => fillOnUndefined($params, 'ext_child_rate'), + ], + + [ + 'setup_type' => 'DIS_GUEST', + 'value_type' => fillOnUndefined($params, 'dis_guest_type'), + 'value' => fillOnUndefined($params, 'dis_guest_rate'), + ], + + + ], + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->addPropertyRoomRateMappingWithSetup($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => trim(fillOnUndefined($params, 'name')), + 'accommodation_type' => fillOnUndefined($params, 'accommodation_type'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'facts' => fillOnUndefined($params, 'facts', []), + 'description' => fillOnUndefined($params, 'description'), + 'user_id' => $this->request->auth->id, + ]; + + + if(isset($params['status'])){ + $requestParams['status'] = fillOnUndefined($params, "status", 0); + } + $propertyRoomRate = $this->propertyRoomRateService->updatePropertyRoomRate($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + if(isset($params['rooms'])){ + foreach ($params['rooms'] as $room){ + + $criteria = [ + + ['field' => 'room_id', 'condition' => '=', 'value' => $room['room_id']], + ['field' => 'room_rate_id', 'condition' => '=', 'value' => $params['id']] + + ]; + + $data = [ + 'room_id' => fillOnUndefined($room, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'id'), + 'included_occupancy' => fillOnUndefined($room, 'value'), + 'status' => 1, + 'created_by' => $this->request->auth->id, + 'updated_by' => $this->request->auth->id, + 'created_at' => time(), + 'updated_at' => time(), + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->updateOrCreate($criteria,$data); + if($propertyRoomRateMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + } + } + + DB::commit(); + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + DB::rollBack(); + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + DB::rollBack(); + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'user_id' => $this->request->auth->id, + + ]; + + $propertyRoomRate = $this->propertyRoomRateService->deletePropertyRoomRate($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyAccommodationTypes(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $this->request->auth->id, + + ]; + $propertyRoomRate = $this->propertyRoomRateService->getPropertyAccommodationTypes($requestParams); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function editPropertyRoomRate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + $criteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $params['room_rate_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'firstRow' => 1 + ]; + + $propertyRoomRate = $this->propertyRoomRateService->select($criteria); + if($propertyRoomRate['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRate['message']); + } + + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'with' => ['propertyRoomRateMapping'] + ]; + + $propertyRoom = $this->propertyRoomService->select($criteria); + if($propertyRoom['status'] != 'success'){ + throw new ApiErrorException($propertyRoom['message']); + } + + $propertyRoomRate['data']['rooms'] = $propertyRoom['data']; + + foreach ($propertyRoomRate['data']['rooms'] as $roomKey => $roomVal){ + + $propertyRoomRate['data']['rooms'][$roomKey]['is_selected'] = false; + $propertyRoomRate['data']['rooms'][$roomKey]['is_selected_lock'] = false; + $propertyRoomRate['data']['rooms'][$roomKey]['included_occupancy'] = null; + + foreach ($roomVal['property_room_rate_mapping'] as $rate){ + if($rate['room_rate_id'] == $params['room_rate_id']){ + $propertyRoomRate['data']['rooms'][$roomKey]['is_selected'] = true; + $propertyRoomRate['data']['rooms'][$roomKey]['is_selected_lock'] = true; + $propertyRoomRate['data']['rooms'][$roomKey]['included_occupancy'] = $rate['included_occupancy']; + break; + } + } + + unset($propertyRoomRate['data']['rooms'][$roomKey]['property_room_rate_mapping']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRate['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomRateInclusionMappingController.php b/app/Http/Controllers/V1/PropertyRoomRateInclusionMappingController.php new file mode 100644 index 0000000..c4ae946 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRateInclusionMappingController.php @@ -0,0 +1,124 @@ +request = $request; + $this->propertyRoomRateInclusionMappingService = $propertyRoomRateInclusionMappingService; + + } + + + + public function getPropertyRoomRateInclusionMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomRateInclusionMapping = $this->propertyRoomRateInclusionMappingService->getPropertyRoomRateInclusionMapping($requestParams); + if($propertyRoomRateInclusionMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateInclusionMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateInclusionMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateInclusionMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'facts' => fillOnUndefined($params, 'facts'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateInclusionMapping = $this->propertyRoomRateInclusionMappingService->addPropertyRoomRateInclusionMapping($requestParams); + if($propertyRoomRateInclusionMapping['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateInclusionMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateInclusionMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyRoomRateMappingController.php b/app/Http/Controllers/V1/PropertyRoomRateMappingController.php new file mode 100644 index 0000000..de10747 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRateMappingController.php @@ -0,0 +1,1630 @@ +request = $request; + $this->propertyRoomRateMappingService = $propertyRoomRateMappingService; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; + $this->propertyChannelGroupService = $propertyChannelGroupService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; + $this->propertyRoomService = $propertyRoomService; + $this->mailer = $mailer; + $this->languageService = $languageService; + + $this->actionTitleByKey = [ + 'PRC' => [ + 'title' => 'Price', + 'language_key' => 'enw-action-title-price', + ], + 'AVA' => [ + 'title' => 'Availability', + 'language_key' => 'enw-action-title-availability', + ], + 'STS' => [ + 'title' => 'Stop Sell', + 'language_key' => 'enw-action-title-stop_sell', + ], + 'MNS' => [ + 'title' => 'Min Stay', + 'language_key' => 'enw-action-title-min_stay', + ] + ]; + + } + + + public function getPropertyRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->getPropertyRoomRateMapping($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'description' => fillOnUndefined($params, 'description'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->addPropertyRoomRateMapping($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateMappingWithSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + 'room_rate_mapping_setup' => [ + [ + 'setup_type' => 'EXT_ADULT', + 'value_type' => fillOnUndefined($params, 'ext_adult_type'), + 'value' => fillOnUndefined($params, 'ext_adult_rate'), + ], + + [ + 'setup_type' => 'EXT_CHILD', + 'value_type' => fillOnUndefined($params, 'ext_child_type'), + 'value' => fillOnUndefined($params, 'ext_child_rate'), + ], + + [ + 'setup_type' => 'DIS_GUEST', + 'value_type' => fillOnUndefined($params, 'dis_guest_type'), + 'value' => fillOnUndefined($params, 'dis_guest_rate'), + ], + + + ], + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->addPropertyRoomRateMappingWithSetup($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'locale' => fillOnUndefined($params, 'locale'), + 'id' => fillOnUndefined($params, 'id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_id' => fillOnUndefined($params, 'room_rate_id'), + 'description' => fillOnUndefined($params, 'description'), + 'rack_rate' => fillOnUndefined($params, 'rack_rate'), + 'included_occupancy' => fillOnUndefined($params, 'included_occupancy'), + + 'user_id' => $this->request->auth->id, + ]; + + + if (isset($params['status'])) { + $requestParams['status'] = fillOnUndefined($params, "status", 0); + } + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->updatePropertyRoomRateMapping($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'user_id' => $this->request->auth->id, + + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->deletePropertyRoomRateMapping($requestParams); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function channelGroupRoomRateAvailabilityMappingBulkUpdate($requestParams = []) + { + + $channelGroupChannels = []; + $channelGroupCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $requestParams['channel_group_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + 'with' => ['channelGroupActiveChannels'] + ]; + + $channelGroup = $this->propertyChannelGroupService->select($channelGroupCriteria); + + if ($channelGroup['status'] == 'success') { + $channelGroupChannels = $channelGroup['data']['channel_group_active_channels']; + } + + $paramsListChannel = []; + foreach ($channelGroupChannels as $channel) { + + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + continue; + } + + + $propertyRoomRateChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + continue; + } + + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']); + + if ($requestParams['update_type'] == 'rate') { + + + foreach ($requestParams['room_rates'] as $roomRate) { + + $value = null; + $roomRates = []; + + //currency_code check + if ($roomRate['currency'] == $propertyChannelMapping['data']['currency_code']) { + + //room_rate_mapping_id check + if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRate['room_rate_mapping_id'])->isNotEmpty()) { + + $value = $roomRate['value']; + $roomRates[] = [ + 'room_id' => $roomRate['room_id'], + 'room_rate_mapping_id' => [ + $roomRate['room_rate_mapping_id'] + ], + ]; + + } + + } + + if (is_null($value) || empty($roomRate)) { + continue; + } + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($requestParams, 'locale'), + 'property_id' => fillOnUndefined($requestParams, 'property_id'), + 'update_type' => fillOnUndefined($requestParams, 'update_type'), + 'value' => $value, + 'channel_id' => fillOnUndefined($channel, 'channel_id'), + 'availability_type_id' => fillOnUndefined($requestParams, 'availability_type_id', 1), + 'room_rates' => $roomRates, + 'start_date' => fillOnUndefined($requestParams, 'start_date'), + 'end_date' => fillOnUndefined($requestParams, 'end_date'), + 'include_days' => fillOnUndefined($requestParams, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + + + } + + } elseif (in_array($requestParams['update_type'], ['min_stay', 'rate_stop_sell'])) { + + foreach ($requestParams['room_rates'] as $roomRate) { + + $value = null; + $roomRates = []; + + //room_rate_mapping_id check + if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRate['room_rate_mapping_id'])->isNotEmpty()) { + + $value = $roomRate['value']; + $roomRates[] = [ + 'room_id' => $roomRate['room_id'], + 'room_rate_mapping_id' => [ + $roomRate['room_rate_mapping_id'] + ], + ]; + + } + + + if (is_null($value) || empty($roomRate)) { + continue; + } + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($requestParams, 'locale'), + 'property_id' => fillOnUndefined($requestParams, 'property_id'), + 'update_type' => fillOnUndefined($requestParams, 'update_type'), + 'value' => $value, + 'channel_id' => fillOnUndefined($channel, 'channel_id'), + 'availability_type_id' => fillOnUndefined($requestParams, 'availability_type_id', 1), + 'room_rates' => $roomRates, + 'start_date' => fillOnUndefined($requestParams, 'start_date'), + 'end_date' => fillOnUndefined($requestParams, 'end_date'), + 'include_days' => fillOnUndefined($requestParams, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + + } + + + } + + + } + + //dd($paramsListChannel, $requestParams); + + return $paramsListChannel; + } + + public function bulkUpdate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + DB::beginTransaction(); + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + + if (!Carbon::parse($params['start_date'])->lessThanOrEqualTo(Carbon::parse($params['end_date']))) { + throw new ApiErrorException(lang('api-error-update-start_end_date_diff')); + } + + $paramsListChannel = []; + if (isset($params['channel_group_id'])) { + + if (Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['end_date'])) > 365) { + throw new ApiErrorException(lang('api-error-update-date_month')); + } + + $paramsListChannel = $this->channelGroupRoomRateAvailabilityMappingBulkUpdate($params); + + } elseif (isset($params['channel_id'])) { + + //CONNECTED CHANNEL RATE CHECK + $currentChannelCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + 'with' => ['channel'] + ]; + + $currentChannel = $this->propertyChannelMappingService->select($currentChannelCriteria); + if ($currentChannel['status'] != 'success') { + throw new ApiErrorException($currentChannel['message']); + } + + $currentChannel = $currentChannel['data']; + + if (!is_null($currentChannel['connected_channel_id'])) { + throw new ApiErrorException('Channel prices linked to a channel cannot be updated.'); + } + //CONNECTED CHANNEL RATE CHECK + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'update_type' => fillOnUndefined($params, 'update_type'), + 'value' => fillOnUndefined($params, 'value'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1), + 'room_rates' => fillOnUndefined($params, 'room_rates'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'include_days' => fillOnUndefined($params, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + + + //CONNECTED CHANNEL RATE UPDATE + if (in_array($params['update_type'], ['rate', 'rate_by_rate', 'rate_stop_sell', 'min_stay', 'quick_pricing'])) { + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] == 'success') { + + foreach ($propertyChannelMapping['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'update_type' => fillOnUndefined($params, 'update_type'), + 'value' => fillOnUndefined($params, 'value'), + 'channel_id' => $channel['channel_id'], + 'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1), + 'room_rates' => fillOnUndefined($params, 'room_rates'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'include_days' => fillOnUndefined($params, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + + } + + } + } + //CONNECTED CHANNEL RATE UPDATE + + } + + + if (in_array($params['update_type'], ['rate'])) { + + + //CONNECTED RATE + $roomRates = collect($params['room_rates']); + $propertyRoomIds = $roomRates->pluck('room_id')->toArray(); + $propertyRoomIds = array_unique($propertyRoomIds); + + $propertyRoomRateMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'room_id', 'value' => $propertyRoomIds] + ] + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->select($propertyRoomRateMappingCriteria); + $propertyRoomRateMapping = $propertyRoomRateMapping['status'] == 'success' ? $propertyRoomRateMapping['data'] : []; + $propertyRoomRateMapping = collect($propertyRoomRateMapping); + + $connectedRoomRateBulk = []; + foreach ($params['room_rates'] as $roomRateKey => $roomRate) { + + $currentRoomRateIds = $propertyRoomRateMapping->whereIn('id', $roomRate['room_rate_mapping_id'])->pluck('room_rate_id')->toArray(); + + $propertyRoomRateConnectedList = $propertyRoomRateMapping->where('room_id', $roomRate['room_id'])->whereIn('connected_rate_id', $currentRoomRateIds)->toArray(); + + if (empty($propertyRoomRateConnectedList)) { + continue; + } + + foreach ($propertyRoomRateConnectedList as $propertyRoomRateConnected) { + + $roomRateConnectedRoomRates = []; + $roomRateConnectedAmount = $params['value']; + + $amountAffected = 0; + if ($propertyRoomRateConnected['is_affected_price']) { + if ($propertyRoomRateConnected['affect_price_type'] == 'PER') { + $amountAffected = ($roomRateConnectedAmount * $propertyRoomRateConnected['affect_price_value']) / 100; + } elseif ($propertyRoomRateConnected['affect_price_type'] == 'FIX') { + $amountAffected = $propertyRoomRateConnected['affect_price_value']; + } + + if ($propertyRoomRateConnected['affect_price_action_type'] == 'INC') { + $roomRateConnectedAmount = $roomRateConnectedAmount + $amountAffected; + } + + if ($propertyRoomRateConnected['affect_price_action_type'] == 'DEC') { + $roomRateConnectedAmount = $roomRateConnectedAmount - $amountAffected; + } + } + + $roomRateConnectedAmount = $roomRateConnectedAmount == 0 ? "0" : $roomRateConnectedAmount; + + $roomRateConnectedRoomRates[] = [ + 'room_id' => $propertyRoomRateConnected['room_id'], + 'room_rate_mapping_id' => [$propertyRoomRateConnected['id']], + ]; + + foreach ($paramsListChannel as $channelParam) { + $connectedRoomRateBulk[] = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'update_type' => fillOnUndefined($params, 'update_type'), + 'value' => $roomRateConnectedAmount, + 'channel_id' => $channelParam['channel_id'], + 'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1), + 'room_rates' => $roomRateConnectedRoomRates, + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'include_days' => fillOnUndefined($params, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + } + + } + + } + + if (!empty($connectedRoomRateBulk)) { + $paramsListChannel = array_merge($paramsListChannel, $connectedRoomRateBulk); + } + + } + + //CONNECTED RATE + + foreach ($paramsListChannel as $channelParam) { + + + $requestParams = [ + 'locale' => fillOnUndefined($channelParam, 'locale'), + 'property_id' => fillOnUndefined($channelParam, 'property_id'), + 'update_type' => fillOnUndefined($channelParam, 'update_type'), + 'value' => fillOnUndefined($channelParam, 'value'), + 'channel_id' => fillOnUndefined($channelParam, 'channel_id'), + 'availability_type_id' => fillOnUndefined($channelParam, 'availability_type_id', 1), + 'room_rates' => fillOnUndefined($channelParam, 'room_rates'), + 'start_date' => fillOnUndefined($channelParam, 'start_date'), + 'end_date' => fillOnUndefined($channelParam, 'end_date'), + 'include_days' => fillOnUndefined($channelParam, 'include_days'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomRateMapping = []; + if ($requestParams['update_type'] == 'availability' || $requestParams['update_type'] == 'room_stop_sell') { + $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams); + } elseif ($requestParams['update_type'] == 'rate_by_rate') { + + $roomRatesPriceGroup = []; + foreach ($requestParams['room_rates'] as $roomRateMapping) { + foreach ($roomRateMapping['room_rate_mapping_id'] as $roomRates) { + foreach ($roomRates as $roomRateMappingId => $roomRatePrice) { + $roomRatePriceHashed = md5($roomRatePrice); + $roomRatesPriceGroup[$roomRatePriceHashed]['amount'] = $roomRatePrice; + $roomRatesPriceGroup[$roomRatePriceHashed]['roomRates'][$roomRateMapping['room_id']][$roomRateMappingId] = [ + 'roomId' => $roomRateMapping['room_id'], + 'roomRateMappingId' => $roomRateMappingId + ]; + } + } + } + + foreach ($roomRatesPriceGroup as $roomRatesPrice) { + + $requestParams['room_rates'] = []; + $requestParams['value'] = $roomRatesPrice['amount']; + $requestParams['update_type'] = 'rate'; + + $roomRateKey = 0; + foreach ($roomRatesPrice['roomRates'] as $roomId => $roomRates) { + foreach ($roomRates as $roomRateMappingId => $roomRate) { + $requestParams['room_rates'][$roomRateKey]['room_id'] = $roomId; + $requestParams['room_rates'][$roomRateKey]['room_rate_mapping_id'][] = $roomRateMappingId; + } + $roomRateKey++; + } + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + + } + + } else { + + $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams); + } + + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + DB::commit(); + + //$roomRateAvailabilityUpdateNotification + foreach ($paramsListChannel as $channelParam) { + $roomRateAvailabilityUpdateNotification = $this->roomRateAvailabilityBulkUpdateNotification($channelParam); + } + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + DB::rollBack(); + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + public function channelGroupRoomRateAvailabilityMapping($requestParams = []) + { + + //PRC_1_1_1_20210424 + //availability_type_id, room_id, room_rate_mapping_id, date + + $channelGroupChannels = []; + $channelGroupCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $requestParams['channel_group_id']], + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + 'with' => ['channelGroupActiveChannels'] + ]; + + $channelGroup = $this->propertyChannelGroupService->select($channelGroupCriteria); + + if ($channelGroup['status'] == 'success') { + $channelGroupChannels = $channelGroup['data']['channel_group_active_channels']; + } + + $paramsListChannel = []; + foreach ($channelGroupChannels as $channel) { + + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + continue; + } + + + $propertyRoomRateChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + continue; + } + + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']); + + + $roomRateAvailabilityMapping = []; + foreach ($requestParams['data'] as $roomRateKey => $roomRateValue) { + + $roomRateKeyParsed = explode('_', $roomRateKey); + + $roomRateKeyArray['type'] = $roomRateKeyParsed[0]; + $roomRateKeyArray['availabilityId'] = $roomRateKeyParsed[1]; + $roomRateKeyArray['roomId'] = $roomRateKeyParsed[2]; + $roomRateKeyArray['roomRateMappingId'] = $roomRateKeyParsed[3]; + $roomRateKeyArray['date'] = $roomRateKeyParsed[4]; + $roomRateKeyArray['currencyCode'] = $roomRateKeyParsed[0] == 'PRC' && isset($roomRateKeyParsed[5]) ? $roomRateKeyParsed[5] : null; + + if ($roomRateKeyArray['type'] == 'PRC') { + + //currency_code check + if (!is_null($roomRateKeyArray['currencyCode']) && $roomRateKeyArray['currencyCode'] == $propertyChannelMapping['data']['currency_code']) { + + //room_rate_mapping_id check + if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKeyArray['roomRateMappingId'])->isNotEmpty()) { + unset($roomRateKeyArray['currencyCode']); + $roomRateKey = implode('_', $roomRateKeyArray); + $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue; + } + + } + + } elseif (in_array($roomRateKeyArray['type'], ['STS', 'MNS'])) { + + if ($roomRateKeyArray['roomRateMappingId'] != 0) { + + //room_rate_mapping_id check + if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKeyArray['roomRateMappingId'])->isNotEmpty()) { + $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue; + } + + } else { + $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue; + } + + } else { + $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue; + } + + } + + if (!empty($roomRateAvailabilityMapping)) { + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($requestParams, 'locale'), + 'property_id' => fillOnUndefined($requestParams, 'property_id'), + 'channel_id' => fillOnUndefined($channel, 'channel_id'), + 'rates' => $roomRateAvailabilityMapping, + 'user_id' => $this->request->auth->id, + ]; + } + + } + + //dd($paramsListChannel, $requestParams); + + return $paramsListChannel; + } + + public function roomRateAvailabilityUpdate(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + DB::beginTransaction(); + + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $paramsListChannel = []; + if (isset($params['channel_group_id'])) { + + $paramsListChannel = $this->channelGroupRoomRateAvailabilityMapping($params); + + } elseif (isset($params['channel_id'])) { + + + //CONNECTED CHANNEL RATE CHECK + $currentChannelCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + 'with' => ['channel'] + ]; + + $currentChannel = $this->propertyChannelMappingService->select($currentChannelCriteria); + if ($currentChannel['status'] != 'success') { + throw new ApiErrorException($currentChannel['message']); + } + + $currentChannel = $currentChannel['data']; + + if (!is_null($currentChannel['connected_channel_id'])) { + throw new ApiErrorException('Channel prices linked to a channel cannot be updated.'); + } + //CONNECTED CHANNEL RATE CHECK + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'rates' => fillOnUndefined($params, 'data'), + 'user_id' => $this->request->auth->id, + ]; + + //CONNECTED CHANNEL RATE UPDATE + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'] + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] == 'success') { + + foreach ($propertyChannelMapping['data'] as $channel) { + + if (!is_null($channel['channel']['parent_id'])) { + continue; + } + + $paramsListChannel[] = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'channel_id' => $channel['channel_id'], + 'rates' => fillOnUndefined($params, 'data'), + 'user_id' => $this->request->auth->id, + ]; + + } + + } + //CONNECTED CHANNEL RATE UPDATE + + } + + foreach ($paramsListChannel as $channelParam) { + + $requestParams = [ + 'locale' => fillOnUndefined($channelParam, 'locale'), + 'property_id' => fillOnUndefined($channelParam, 'property_id'), + 'channel_id' => fillOnUndefined($channelParam, 'channel_id'), + 'rates' => fillOnUndefined($channelParam, 'rates'), + 'user_id' => $this->request->auth->id, + ]; + + $formMapping = $this->propertyRoomRatePriceService->formElementsToArray($requestParams); + + if (!$formMapping) { + throw new ApiErrorException('Form Error.'); + } + + $requestParams['rates'] = $formMapping['rates']; + $requestParams['availability'] = $formMapping['availability']; + + //Amount Empty to Zero Value !important + foreach ($requestParams['rates'] as $roomRateKey => $roomRate) { + if (isset($roomRate['amount']) && empty($roomRate['amount'])) { + $requestParams['rates'][$roomRateKey]['amount'] = "0"; + } + } + + //CONNECTED RATE + $roomRates = collect($requestParams['rates']); + $propertyRoomIds = $roomRates->pluck('room_id')->toArray(); + $propertyRoomIds = array_unique($propertyRoomIds); + + + $propertyRoomRateMappingCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'whereIn' => [ + ['field' => 'room_id', 'value' => $propertyRoomIds] + ] + ]; + + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->select($propertyRoomRateMappingCriteria); + $propertyRoomRateMapping = $propertyRoomRateMapping['status'] == 'success' ? $propertyRoomRateMapping['data'] : []; + $propertyRoomRateMapping = collect($propertyRoomRateMapping); + + //dd($propertyRoomRateMapping, $propertyRoomRateMappingCriteria); + + foreach ($requestParams['rates'] as $roomRateKey => $roomRate) { + + if (!isset($roomRate['amount'])) { + continue; + } + + $currentRoomRateIds = $propertyRoomRateMapping->whereIn('id', $roomRate['room_rate_mapping_id'])->pluck('room_rate_id')->toArray(); + $propertyRoomRateConnectedList = $propertyRoomRateMapping->where('room_id', $roomRate['room_id'])->whereIn('connected_rate_id', $currentRoomRateIds)->toArray(); + + + if (empty($propertyRoomRateConnectedList)) { + continue; + } + + foreach ($propertyRoomRateConnectedList as $propertyRoomRateConnected) { + + $roomRateConnected = $roomRate; + $roomRateConnectedAmount = $roomRate['amount']; + + $amountAffected = 0; + if ($propertyRoomRateConnected['is_affected_price']) { + if ($propertyRoomRateConnected['affect_price_type'] == 'PER') { + $amountAffected = ($roomRateConnectedAmount * $propertyRoomRateConnected['affect_price_value']) / 100; + } elseif ($propertyRoomRateConnected['affect_price_type'] == 'FIX') { + $amountAffected = $propertyRoomRateConnected['affect_price_value']; + } + + if ($propertyRoomRateConnected['affect_price_action_type'] == 'INC') { + $roomRateConnectedAmount = $roomRateConnectedAmount + $amountAffected; + } + + if ($propertyRoomRateConnected['affect_price_action_type'] == 'DEC') { + $roomRateConnectedAmount = $roomRateConnectedAmount - $amountAffected; + } + } + + $roomRateConnected['amount'] = $roomRateConnectedAmount == 0 ? "0" : $roomRateConnectedAmount; + $roomRateConnected['room_rate_mapping_id'] = $propertyRoomRateConnected['id']; + + + $roomRateConnectedKeyParam = []; + $roomRateConnectedKeyParam[] = $roomRateConnected['setup_type_id']; + $roomRateConnectedKeyParam[] = $roomRateConnected['room_id']; + $roomRateConnectedKeyParam[] = $roomRateConnected['room_rate_mapping_id']; + $roomRateConnectedKeyParam[] = $roomRateConnected['date']; + $roomRateConnectedKey = implode('|', $roomRateConnectedKeyParam); + + if (array_key_exists($roomRateConnectedKey, $requestParams['rates'])) { + continue; + } + + $requestParams['rates'][$roomRateConnectedKey] = $roomRateConnected; + + } + + } + //CONNECTED RATE + + + $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams); + if ($roomRateUpdate['status'] != 'success') { + throw new ApiErrorException($roomRateUpdate['message']); + } + + $availabilityUpdate = $this->propertyRoomAvailabilityService->roomAvailabilityUpdate($requestParams); + + if ($availabilityUpdate['status'] != 'success') { + throw new ApiErrorException($availabilityUpdate['message']); + } + + + } + + DB::commit(); + + //$roomRateAvailabilityUpdateNotification + foreach ($paramsListChannel as $channelParam) { + $roomRateAvailabilityUpdateNotification = $this->roomRateAvailabilityUpdateNotification($channelParam); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + DB::rollBack(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function roomRateAvailabilityUpdateNotification($requestParams = []) + { + + //dd($requestParams['locale'], $requestParams['property_id'], $requestParams['channel_id']); + + //PRC_1_1_1_20210424 - Price Room Rate + //availability_type_id, room_id, room_rate_mapping_id, date + //AVA_1_2_0_20210424 - Availability Room + //STS_1_1_0_20210426 - Stop Sell Room + //STS_1_1_1_20210425 - Stop Sell Room Rate + //MNS_1_1_1_20210421 - Min Stay Room Rate + + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property', 'channelContact'], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + return false; + } + + if (empty($propertyChannelMapping['data']['channel_contact'])) { + return false; + } + + $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray(); + + if (empty($channelContact)) { + return true; + } + + + //LANGUAGE + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all(); + + $mailLanguage = 'en'; + if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) { + $mailLanguage = $propertyChannelMapping['data']['channel']['country_code']; + } + + + $propertyRoomRateChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType' + ] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria); + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']); + + $propertyRoomsParams = [ + 'property_id' => $requestParams['property_id'], + ]; + + $getPropertyRooms = $this->propertyRoomService->getPropertyRooms($propertyRoomsParams); + $propertyRoomsCollect = collect($getPropertyRooms['data']); + + + $roomRateGrouped = []; + foreach ($requestParams['rates'] as $roomRateKey => $roomRateValue) { + + $roomRateKeyParsed = explode('_', $roomRateKey); + + $roomRateKeyArray['type'] = $roomRateKeyParsed[0]; + $roomRateKeyArray['availabilityId'] = $roomRateKeyParsed[1]; + $roomRateKeyArray['roomId'] = $roomRateKeyParsed[2]; + $roomRateKeyArray['roomRateMappingId'] = $roomRateKeyParsed[3]; + $roomRateKeyArray['date'] = $roomRateKeyParsed[4]; + + $roomRateGrouped[$roomRateKeyArray['type']] + [$roomRateKeyArray['roomId']][$roomRateKeyArray['roomRateMappingId']][$roomRateKeyArray['date']] = [ + 'value' => $roomRateValue, + 'currency' => $propertyChannelMapping['data']['currency_code'], + ]; + + ksort($roomRateGrouped[$roomRateKeyArray['type']][$roomRateKeyArray['roomId']][$roomRateKeyArray['roomRateMappingId']]); + + } + + $roomRateNotificationGroup = []; + foreach ($roomRateGrouped as $typeKey => $room) { + + foreach ($room as $roomKey => $roomRate) { + + //roomDetail + $roomDetail = $propertyRoomsCollect->where('id', $roomKey)->first(); + if (empty($roomDetail)) { + continue; + } + + foreach ($roomRate as $roomRateKey => $roomRateDate) { + + + //roomRateChannelMappingDetail + $roomRateDetail = []; + $roomRateChannelMappingDetail = $propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKey)->first(); + if (empty($roomRateChannelMappingDetail) && $roomRateKey != 0) { + continue; + } + + if ($roomRateKey != 0) { + $roomRateDetail = $roomRateChannelMappingDetail['property_room_rate_mapping']['property_room_rate']; + } + + + $actionByDate = []; + foreach ($roomRateDate as $dateKey => $dateValue) { + + $dateKey = substr($dateKey, 0, 4) . '-' . substr($dateKey, 4, 2) . '-' . substr($dateKey, 6, 2); + + + $lastAction = last($actionByDate); + $lastActionKey = array_key_last($actionByDate); + + + //if ($dateKey == '2021-04-27') { + // dd($actionByDate, $lastAction, $lastActionKey); + + //} + + if ($lastAction['value'] == $dateValue['value'] && Carbon::parse($lastAction['endDate'])->addDay()->toDateString() == $dateKey) { + $actionByDate[$lastActionKey]['endDate'] = $dateKey; + } else { + if ($typeKey == 'PRC') { + $actionByDate[] = [ + 'startDate' => $dateKey, + 'endDate' => $dateKey, + 'value' => $dateValue['value'], + 'currency' => $dateValue['currency'] + ]; + } else { + $actionByDate[] = [ + 'startDate' => $dateKey, + 'endDate' => $dateKey, + 'value' => $dateValue['value'] + ]; + } + + } + + } + + $roomRateNotificationGroup[$typeKey]['title'] = isset($this->actionTitleByKey[$typeKey]) ? $this->actionTitleByKey[$typeKey]['language_key'] : $typeKey; + + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['title'] = $roomDetail['name']; + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['titleRoomType'] = $roomDetail['property_room_type']['language_key']; + + if (empty($roomRateDetail)) { + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['title'] = null; + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['titleAccommodation'] = null; + } else { + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['title'] = $roomRateDetail['name']; + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['titleAccommodation'] = $roomRateDetail['property_room_rate_accommodation']['language_key']; + } + + $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['actionByDate'] = $actionByDate; + + //$roomRateNotificationGroup[$typeKey][$roomKey][$roomRateKey] = $actionByDate; + + } + + } + + } + + + //inventoryActionMail + $mailParams = [ + 'locale' => $mailLanguage, + 'propertyName' => $propertyChannelMapping['data']['property']['name'], + 'channelContact' => $channelContact, + 'roomRateNotificationData' => $roomRateNotificationGroup, + ]; + + $this->mailer->onQueue('inventoryActionMail', new InventoryActionMail($mailParams)); + //inventoryActionMail + + + return true; + } + + public function roomRateAvailabilityBulkUpdateNotification($requestParams = []) + { + + //update_type, rate, min_stay, rate_stop_sell + + $typeKeyMapping = [ + 'rate' => 'PRC', + 'min_stay' => 'MNS', + 'rate_stop_sell' => 'STS', + ]; + + $typeKey = null; + if (isset($typeKeyMapping[$requestParams['update_type']])) { + $typeKey = $typeKeyMapping[$requestParams['update_type']]; + } + + if (is_null($typeKey)) { + return false; + } + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property', 'channelContact'], + 'firstRow' => true + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + return false; + } + + if (empty($propertyChannelMapping['data']['channel_contact'])) { + return false; + } + + $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray(); + + if (empty($channelContact)) { + return true; + } + + //LANGUAGE + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all(); + + $mailLanguage = 'en'; + if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) { + $mailLanguage = $propertyChannelMapping['data']['channel']['country_code']; + } + + + $propertyRoomRateChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', + 'propertyRoomRateMapping.propertyRoom.propertyRoomType' + ] + ]; + + $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria); + $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']); + + $propertyRoomsParams = [ + 'property_id' => $requestParams['property_id'], + ]; + + $getPropertyRooms = $this->propertyRoomService->getPropertyRooms($propertyRoomsParams); + $propertyRoomsCollect = collect($getPropertyRooms['data']); + + + //Burada time lar hesaplancak, hepsinde aynı zaten mantığı + + $actionByDate = []; + + + $diffInDays = Carbon::parse($requestParams['start_date'])->diffInDays($requestParams['end_date']); + + $startDate = $requestParams['start_date']; + for ($i = 0; $i <= $diffInDays; $i++) { + + $dateKey = Carbon::parse($startDate)->addDays($i)->toDateString(); + + if (!in_array(Carbon::parse($dateKey)->shortDayName, $requestParams['include_days'])) { + continue; + } + + $lastAction = last($actionByDate); + $lastActionKey = array_key_last($actionByDate); + + if (Carbon::parse($lastAction['endDate'])->addDay()->toDateString() == $dateKey) { + $actionByDate[$lastActionKey]['endDate'] = $dateKey; + } else { + if ($typeKey == 'PRC') { + $actionByDate[] = [ + 'startDate' => $dateKey, + 'endDate' => $dateKey, + 'value' => $requestParams['value'], + 'currency' => $propertyChannelMapping['data']['currency_code'] + ]; + } else { + $actionByDate[] = [ + 'startDate' => $dateKey, + 'endDate' => $dateKey, + 'value' => $requestParams['value'] + ]; + } + + } + + } + + $roomRateNotificationGroup = []; + foreach ($requestParams['room_rates'] as $room) { + + foreach ($room['room_rate_mapping_id'] as $roomRateId) { + + //roomDetail + $roomDetail = $propertyRoomsCollect->where('id', $room['room_id'])->first(); + if (empty($roomDetail)) { + continue; + } + + //roomRateChannelMappingDetail + $roomRateDetail = []; + $roomRateChannelMappingDetail = $propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateId)->first(); + if (empty($roomRateChannelMappingDetail) && $roomRateId != 0) { + continue; + } + + if ($roomRateId != 0) { + $roomRateDetail = $roomRateChannelMappingDetail['property_room_rate_mapping']['property_room_rate']; + } + + + $roomRateNotificationGroup[$typeKey]['title'] = isset($this->actionTitleByKey[$typeKey]) ? $this->actionTitleByKey[$typeKey]['language_key'] : $typeKey; + + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['title'] = $roomDetail['name']; + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['titleRoomType'] = $roomDetail['property_room_type']['language_key']; + + if (empty($roomRateDetail)) { + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['title'] = null; + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['titleAccommodation'] = null; + } else { + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['title'] = $roomRateDetail['name']; + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['titleAccommodation'] = $roomRateDetail['property_room_rate_accommodation']['language_key']; + } + + $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['actionByDate'] = $actionByDate; + + } + + } + + //inventoryActionMail + $mailParams = [ + 'locale' => $mailLanguage, + 'propertyName' => $propertyChannelMapping['data']['property']['name'], + 'channelContact' => $channelContact, + 'roomRateNotificationData' => $roomRateNotificationGroup, + ]; + + $this->mailer->onQueue('inventoryActionMail', new InventoryActionMail($mailParams)); + //inventoryActionMail + + + return true; + } + + public function setStatusPropertyRoomRateMapping(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $params['user_id'] = $this->request->auth->id; + + + if (isset($params['status'])) { + $requestParams['status'] = fillOnUndefined($params, "status", 0); + } + $propertyRoomRateMapping = $this->propertyRoomRateMappingService->setStatusPropertyRoomRateMapping($params); + if ($propertyRoomRateMapping['status'] != 'success') { + throw new ApiErrorException($propertyRoomRateMapping['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function postInventoryLink(Request $request) + { + + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $this->request->params; + + $propertyChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'property', 'channelContact'], + 'firstRow' => true + ]; + + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria); + if ($propertyChannelMapping['status'] != 'success') { + throw new ApiErrorException($propertyChannelMapping['message']); + } + + if (empty($propertyChannelMapping['data']['channel_contact'])) { + throw new ApiErrorException("There is not any email address founded for this channel"); + } + + $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray(); + + if (empty($channelContact)) { + return true; + } + + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all(); + + $mailLanguage = 'en'; + if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) { + $mailLanguage = $propertyChannelMapping['data']['channel']['country_code']; + } + + + $mailParams = [ + 'locale' => $mailLanguage, + 'propertyName' => $propertyChannelMapping['data']['property']['name'], + 'channelContact' => $channelContact, + 'link' => Config::get('app.url') . '/app/v1/channel-pdf-inventory/' . $propertyChannelMapping['data']['token'] + + ]; + + $this->mailer->onQueue('inventoryPdfLinkMail', new InventoryPdfLinkMail($mailParams)); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $mailParams]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } +} + + diff --git a/app/Http/Controllers/V1/PropertyRoomRateMappingSetupController.php b/app/Http/Controllers/V1/PropertyRoomRateMappingSetupController.php new file mode 100644 index 0000000..d1cc953 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRateMappingSetupController.php @@ -0,0 +1,124 @@ +request = $request; + $this->propertyRoomRateMappingSetupService = $propertyRoomRateMappingSetupService; + + } + + + + public function getPropertyRoomRateMappingSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'user_id' => $this->request->auth->id, + ]; + + $propertyRoomRateMappingSetup = $this->propertyRoomRateMappingSetupService->getPropertyRoomRateMappingSetup($requestParams); + if($propertyRoomRateMappingSetup['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateMappingSetup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMappingSetup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRateMappingSetup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'room_id' => fillOnUndefined($params, 'room_id'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'setup' => fillOnUndefined($params, 'setup'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRateMappingSetup = $this->propertyRoomRateMappingSetupService->addPropertyRoomRateMappingSetup($requestParams); + if($propertyRoomRateMappingSetup['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRateMappingSetup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMappingSetup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyRoomRatePriceController.php b/app/Http/Controllers/V1/PropertyRoomRatePriceController.php new file mode 100644 index 0000000..e7a249e --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomRatePriceController.php @@ -0,0 +1,217 @@ +request = $request; + $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; + + } + + + + public function getPropertyRoomRatePrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyRoomRatePrice = $this->propertyRoomRatePriceService->getPropertyRoomRatePrices($requestParams); + if($propertyRoomRatePrice['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRatePrice['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRatePrice['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function addPropertyRoomRatePrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_room_id' => fillOnUndefined($params, 'property_room_id'), + 'room_rate_mapping_id' => fillOnUndefined($params, 'room_rate_mapping_id'), + 'offer_id' => fillOnUndefined($params, 'offer_id'), + 'channel_id' => fillOnUndefined($params, 'channel_id'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + 'max_stay' => fillOnUndefined($params, 'max_stay'), + 'stop_sell' => fillOnUndefined($params, 'stop_sell'), + 'booking_on_request' => fillOnUndefined($params, 'booking_on_request'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'amount' => fillOnUndefined($params, 'amount'), + 'currency' => fillOnUndefined($params, 'currency'), + 'user_id' => $this->request->auth->id, + ]; + + + $propertyRoomRatePrice = $this->propertyRoomRatePriceService->addPropertyRoomRatePrice($requestParams); + if($propertyRoomRatePrice['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRatePrice['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRatePrice['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyRoomRatePrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'property_id' => fillOnUndefined($params, 'property_id'), + 'name' => fillOnUndefined($params, 'name'), + 'description' => fillOnUndefined($params, 'description'), + 'min_stay' => fillOnUndefined($params, 'min_stay'), + + 'user_id' => $this->request->auth->id, + ]; + + + if(isset($params['status'])){ + $requestParams['status'] = fillOnUndefined($params, "status", 0); + } + $propertyRoomRatePrice = $this->propertyRoomRatePriceService->updatePropertyRoomRatePrice($requestParams); + if($propertyRoomRatePrice['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRatePrice['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRatePrice['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyRoomRatePrice(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + + 'id' => fillOnUndefined($params, 'id'), + 'user_id' => $this->request->auth->id, + + ]; + + $propertyRoomRatePrice = $this->propertyRoomRatePriceService->deletePropertyRoomRatePrice($requestParams); + if($propertyRoomRatePrice['status'] != 'success'){ + throw new ApiErrorException($propertyRoomRatePrice['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRatePrice['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + + + +} diff --git a/app/Http/Controllers/V1/PropertyRoomSizeTypeController.php b/app/Http/Controllers/V1/PropertyRoomSizeTypeController.php new file mode 100644 index 0000000..61a7f0a --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomSizeTypeController.php @@ -0,0 +1,60 @@ +propertyRoomSizeTypeService = $propertyRoomSizeTypeService; + + } + + public function getPropertyRoomSizeTypes(){ + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyRoomSizeTypeCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $propertyRoomSizeTypes = $this->propertyRoomSizeTypeService->select($propertyRoomSizeTypeCriteria, ['id', 'name', 'code', 'language_key']); + + + if($propertyRoomSizeTypes['status'] != 'success'){ + throw new Exception($propertyRoomSizeTypes['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomSizeTypes['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + +} diff --git a/app/Http/Controllers/V1/PropertyRoomTypeController.php b/app/Http/Controllers/V1/PropertyRoomTypeController.php new file mode 100644 index 0000000..bdd1669 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomTypeController.php @@ -0,0 +1,112 @@ +request = $request; + $this->propertyRoomTypeService = $propertyRoomTypeService; + + } + + + + public function getPropertyRoomTypes(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + ]; + + $propertyRoomType = $this->propertyRoomTypeService->getPropertyRoomTypes($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyMappedRoomTypes(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + 'property_id' => fillOnUndefined($params, 'property_id'), + ]; + + $propertyRoomType = $this->propertyRoomTypeService->getPropertyMappedRoomTypes($requestParams); + if($propertyRoomType['status'] != 'success'){ + throw new ApiErrorException($propertyRoomType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyRoomViewTypeController.php b/app/Http/Controllers/V1/PropertyRoomViewTypeController.php new file mode 100644 index 0000000..e8950cb --- /dev/null +++ b/app/Http/Controllers/V1/PropertyRoomViewTypeController.php @@ -0,0 +1,66 @@ +propertyRoomViewTypeService = $propertyRoomViewTypeService; + } + + + + public function getPropertyRoomViewTypeList() + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $propertyRoomViewTypeCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + "orderBy" => [ + ["field" => "name", "value" => "ASC"] + ] + ]; + + $propertyRoomViewTypeList = $this->propertyRoomViewTypeService->getPropertyRoomViewTypes($propertyRoomViewTypeCriteria); + + if($propertyRoomViewTypeList['status'] != 'success'){ + throw new ApiErrorException($propertyRoomViewTypeList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomViewTypeList['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} diff --git a/app/Http/Controllers/V1/PropertyTypeController.php b/app/Http/Controllers/V1/PropertyTypeController.php new file mode 100644 index 0000000..43635fe --- /dev/null +++ b/app/Http/Controllers/V1/PropertyTypeController.php @@ -0,0 +1,72 @@ +request = $request; + $this->propertyTypeService = $propertyTypeService; + + } + + + + public function getPropertyTypes(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'locale' => fillOnUndefined($params, 'locale'), + ]; + + $propertyType = $this->propertyTypeService->getPropertyTypes($requestParams); + if($propertyType['status'] != 'success'){ + throw new ApiErrorException($propertyType['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyType['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/V1/PropertyWebComponentController.php b/app/Http/Controllers/V1/PropertyWebComponentController.php new file mode 100644 index 0000000..aad4167 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyWebComponentController.php @@ -0,0 +1,250 @@ +params = Input::all(); + $this->params = $this->params['params']; + $this->propertyWebService = $propertyWebService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->languageService = $languageService; + } + + + public function getPropertyWebComponent(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + //TODO: Validator + + $propertyWebComponentCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyWebComponent = $this->propertyWebService->selectPropertyWebComponent($propertyWebComponentCriteria); + $propertyWebComponent = $propertyWebComponent['status'] == 'success' && !empty($propertyWebComponent['data']) ? $propertyWebComponent['data'] : []; + + + $propertyWebComponentMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyWebComponentMapping = $this->propertyWebService->selectPropertyWebComponentMapping($propertyWebComponentMappingCriteria); + $propertyWebComponentMapping = $propertyWebComponentMapping['status'] == 'success' && !empty($propertyWebComponentMapping['data']) ? $propertyWebComponentMapping['data'] : []; + $propertyChannelAddonCollect = collect($propertyWebComponentMapping); + + $propertyWebComponentList = []; + foreach ($propertyWebComponent as $webComponentKey => $webComponent) { + + $webComponentMapping = $propertyChannelAddonCollect->where('component_id', $webComponent['id'])->first(); + + $webComponentDetail = null; + $isSelected = $webComponentMapping ? true : false; + + if ($webComponentMapping) { + $webComponentDetail = [ + 'component_id' => $webComponentMapping['component_id'], + 'parameterArray' => $webComponentMapping['parameterArray'], + 'language' => $webComponentMapping['language'], + 'languageArray' => $webComponentMapping['languageArray'], + ]; + } + + + $propertyWebComponentList[] = [ + //'code' => $webComponent['code'], + 'id' => $webComponent['id'], + 'name' => $webComponent['name'], + 'component' => $webComponent['component'], + 'icon' => $webComponent['icon'], + 'iconUrl' => $webComponent['iconUrl'], + 'parameterArray' => $webComponent['parameterArray'], + 'is_selected' => $isSelected, + 'componentDetail' => $webComponentDetail + ]; + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebComponentList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncPropertyWebComponent(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + + $propertyWebComponentCriteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'component_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyWebComponent = $this->propertyWebService->selectPropertyWebComponent($propertyWebComponentCriteria); + $propertyWebComponent = $propertyWebComponent['status'] == 'success' && !empty($propertyWebComponent['data']) ? $propertyWebComponent['data'] : []; + + if(empty($propertyWebComponent)){ + throw new ApiErrorException(lang('Component data not found')); + } + + + //Parameter Check + if (!empty($this->params['componentDetail'])) { + + $parameterCheck = array_diff(array_keys($propertyWebComponent['parameterArray']),array_keys($this->params['componentDetail']['parameter'])); + if(!empty($parameterCheck)) { + throw new ApiErrorException(lang('Missing or incorrect parameter')); + } + } + + + $propertyWebComponentMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'channel_id')], + ['field' => 'component_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'component_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $propertyWebComponentMapping = $this->propertyWebService->selectPropertyWebComponentMapping($propertyWebComponentMappingCriteria); + $propertyWebComponentMapping = $propertyWebComponentMapping['status'] == 'success' && !empty($propertyWebComponentMapping['data']) ? $propertyWebComponentMapping['data'] : []; + + + //Parameter Check + + + DB::beginTransaction(); + + if ($propertyWebComponentMapping) { + + + //Remove + if (empty($this->params['componentDetail'])) { + + $syncPropertyWebComponent = $this->propertyWebService->deletePropertyWebComponentMapping($propertyWebComponentMapping['id']) ; + if($syncPropertyWebComponent['status'] != 'success'){ + throw new Exception('api-unknown_error'); + } + + } else { + + //Update + $updateParam = [ + 'property_id' => fillOnUndefined($this->params, 'property_id'), + 'channel_id' => fillOnUndefined($this->params, 'channel_id'), + 'component_id' => fillOnUndefined($this->params, 'component_id'), + 'parameter' => fillOnUndefined($this->params['componentDetail'], 'parameter') ? json_encode($this->params['componentDetail']['parameter']) : null, + 'language' => fillOnUndefined($this->params['componentDetail'], 'language') ? json_encode($this->params['componentDetail']['language']) : null, + 'updated_by' => $request->auth->id, + ]; + + $syncPropertyWebComponent = $this->propertyWebService->updatePropertyWebComponentMapping($propertyWebComponentMapping['id'], $updateParam); + + if ($syncPropertyWebComponent['status'] != 'success') { + throw new ApiErrorException($syncPropertyWebComponent['message']); + } + + } + + } else { + + $createParam = [ + 'property_id' => fillOnUndefined($this->params, 'property_id'), + 'channel_id' => fillOnUndefined($this->params, 'channel_id'), + 'component_id' => fillOnUndefined($this->params, 'component_id'), + 'parameter' => fillOnUndefined($this->params['componentDetail'], 'parameter') ? json_encode($this->params['componentDetail']['parameter']) : null, + 'language' => fillOnUndefined($this->params['componentDetail'], 'language') ? json_encode($this->params['componentDetail']['language']) : null, + 'status' => 1, + 'created_by' => $request->auth->id, + ]; + + $syncPropertyWebComponent = $this->propertyWebService->createPropertyWebComponentMapping($createParam); + + if ($syncPropertyWebComponent['status'] != 'success') { + throw new ApiErrorException($syncPropertyWebComponent['message']); + } + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/PropertyWebContentController.php b/app/Http/Controllers/V1/PropertyWebContentController.php new file mode 100644 index 0000000..1df4a1b --- /dev/null +++ b/app/Http/Controllers/V1/PropertyWebContentController.php @@ -0,0 +1,296 @@ +request = $request; + $this->propertyWebContentService = $propertyWebContentService; + } + + public function getPropertyWebContent(Request $request, $id = null) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $columns = ['id', 'property_id', 'content_category_id', 'title', 'slug', 'image', 'language_code', 'status', 'created_at']; + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']] + ], + 'with' => ['ContentCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + + $availableFilterArray = ['title', 'content_category_id', 'language_code']; + if (!empty($params['filter'])) { + foreach ($params['filter'] as $filterKey => $filterValue) { + if (in_array($filterKey, $availableFilterArray)) { + if (in_array($filterKey, ['content_category_id', 'language_code', 'status'])) { + $propertyWebContentCriteria['criteria'][] = ['field' => $filterKey, 'condition' => '=', 'value' => $filterValue]; + } + + if (in_array($filterKey, ['title'])) { + $propertyWebContentCriteria['criteria'][] = ['field' => $filterKey, 'condition' => 'LIKE', 'value' => '%' . $filterValue . '%']; + } + + } + } + } + + if (!empty($id)) { + $propertyWebContentCriteria['criteria'][] = ['field' => 'id', 'condition' => '=', 'value' => $id]; + $propertyWebContentCriteria['firstRow'] = true; + $columns[] = 'content'; + } + + + $propertyWebContent = $this->propertyWebContentService->select($propertyWebContentCriteria, $columns); + + if ($propertyWebContent['status'] != 'success') { + throw new Exception($propertyWebContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function getPropertyWebContentCategory(Request $request, $id = null) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $columns = ['id', 'name', 'language_key']; + $propertyWebContentCategoryCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ] + ]; + + $propertyWebContentCategory = $this->propertyWebContentService->selectWebContentCategory($propertyWebContentCategoryCriteria, $columns); + if ($propertyWebContentCategory['status'] != 'success') { + throw new Exception($propertyWebContentCategory['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebContentCategory['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyWebContent(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'content_category_id' => fillOnUndefined($params, 'content_category_id'), + 'title' => fillOnUndefined($params, 'title'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'image' => fillOnUndefined($params, 'image'), + 'content' => fillOnUndefined($params, 'content'), + 'user_id' => $this->request->credentials->user_id + ]; + + $propertyContent = $this->propertyWebContentService->create($requestParams); + + if ($propertyContent['status'] != 'success') { + throw new ApiErrorException($propertyContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyWebContent(Request $request, $id) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'content_category_id' => fillOnUndefined($params, 'content_category_id'), + 'title' => fillOnUndefined($params, 'title'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'image' => fillOnUndefined($params, 'image'), + 'content' => fillOnUndefined($params, 'content'), + 'updated_by' => $this->request->credentials->user_id + ]; + + $propertyContent = $this->propertyWebContentService->update($id, $requestParams); + + if ($propertyContent['status'] != 'success') { + throw new ApiErrorException($propertyContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyWebContent(Request $request, $id) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'id' => $id, + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + + $propertyContent = $this->propertyWebContentService->delete($id, $requestParams); + + if ($propertyContent['status'] != 'success') { + throw new ApiErrorException($propertyContent['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyContent['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function uploadPropertyWebContentImage(Request $request) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + if (!$request->hasFile('image')) { + throw new ApiErrorException(lang('Photos not found')); + } + + $param = [ + "property_id" => $request->input('property_id'), + "photo" => $request->file('image'), + ]; + + $response = $this->propertyWebContentService->uploadPhoto($param); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/PropertyWebController.php b/app/Http/Controllers/V1/PropertyWebController.php new file mode 100644 index 0000000..d679070 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyWebController.php @@ -0,0 +1,2418 @@ +request = $request; + $this->propertyWebService = $propertyWebService; + $this->languageService = $languageService; + $this->languageBaseService = $languageBaseService; + $this->propertyWebMenuService = $propertyWebMenuService; + $this->propertyWebMenuMappingService = $propertyWebMenuMappingService; + $this->propertyWebSetupService = $propertyWebSetupService; + $this->propertyWebLanguageMappingService = $propertyWebLanguageMappingService; + $this->propertyWebColorMappingService = $propertyWebColorMappingService; + $this->propertyBrandService = $propertyBrandService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyGroupMappingService = $propertyGroupMappingService; + $this->findCountryCodeService = $findCountryCodeService; + $this->propertyWebLogService = $propertyWebLogService; + $this->propertyWebMetaService = $propertyWebMetaService; + $this->bookingService = $bookingService; + $this->propertyWebAboutUsService = $propertyWebAboutUsService; + $this->propertyPlaceService = $propertyPlaceService; + $this->propertyAdditionalInfoService = $propertyAdditionalInfoService; + $this->propertyService = $propertyService; + $this->propertyRoomService = $propertyRoomService; + $this->propertyWebContentService = $propertyWebContentService; + $this->pdf = $pdf; + } + + + public function listPropertyWeb(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $propertyRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ], + "orderBy" => [ + ["field" => "id", "value" => "DESC"] + ], + "with" => ['propertyWebTemplate', 'propertyWebLanguage'], + ]; + $propertyWebs = $this->propertyWebService->select($propertyRequest, ['id', 'domain', 'default_language', 'template_id', 'token', 'status', 'is_published', 'is_dns_checked']); + + if ($propertyWebs['status'] != 'success') { + throw new ApiErrorException($propertyWebs['message']); + } + + $web = []; + foreach ($propertyWebs['data'] as $key => $propertyWeb) { + + //Cache + $dashboardCountablePlaceCacheKey = md5('dashboardCountablePlace-' . $params['property_id']); + if (Cache::has($dashboardCountablePlaceCacheKey)) { + $counts = Cache::get($dashboardCountablePlaceCacheKey); + } else { + $counts = $this->dashboardCountablePlace($params, $propertyWeb['id']); + } + + + if ($counts['status'] === false) { + throw new ApiErrorException($counts['message']); + } + + $webData = [ + 'live_url' => Config::get('app.mainHostAddress') . '/live/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + 'preview_url' => Config::get('app.mainHostAddress') . '/preview/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + 'log' => $counts['data'] + ]; + $web[$key] = array_merge($propertyWeb, $webData); + } + + $web = reset($web); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $web]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyWeb(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyWebRequest = [ + 'id' => fillOnUndefined($params, 'property_web_id'), + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $propertyWeb = $this->propertyWebService->getPropertyWeb($propertyWebRequest); + if ($propertyWeb['status'] != 'success') { + throw new ApiErrorException($propertyWeb['message']); + } + + $propertyWeb = $propertyWeb['data']; + $webData = [ + 'live_url' => Config::get('app.mainHostAddress') . '/live/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + 'preview_url' => Config::get('app.mainHostAddress') . '/preview/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + ]; + $propertyWeb = array_merge($propertyWeb, $webData); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function createPropertyWeb(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + + $storePropertyWeb = $this->propertyWebService->create($requestParams); + if ($storePropertyWeb['status'] != 'success') { + throw new ApiErrorException($storePropertyWeb['message']); + } + + $propertyWebRequest = [ + 'id' => $storePropertyWeb['data']['id'], + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $this->request->auth->id + ]; + + + $storePropertyWebPhotos = $this->propertyWebService->insertAllPropertyWebPhotosToMapping($propertyWebRequest); + if ($storePropertyWebPhotos['status'] != 'success') { + throw new ApiErrorException($storePropertyWebPhotos['message']); + } + + + $propertyWeb = $this->propertyWebService->getPropertyWeb($propertyWebRequest); + if ($propertyWeb['status'] != 'success') { + throw new ApiErrorException($propertyWeb['message']); + } + + $propertyWeb['data']['log'] = [ + 'active_user_count' => 0, + 'booking_count' => 0, + 'country_count' => [], + 'mobile_count' => 0, + 'web_count' => 0 + + ]; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function updatePropertyWeb(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + $requestParams = $params; + $requestParams['user_id'] = $this->request->auth->id; + $propertyWebId = $params['property_web_id']; + + $storePropertyWeb = $this->propertyWebService->update($propertyWebId, $requestParams); + if ($storePropertyWeb['status'] != 'success') { + throw new ApiErrorException($storePropertyWeb['message']); + } + + $propertyWebRequest = [ + 'id' => $propertyWebId, + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $propertyWeb = $this->propertyWebService->getPropertyWeb($propertyWebRequest); + if ($propertyWeb['status'] != 'success') { + throw new ApiErrorException($propertyWeb['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function checkDomain(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $params['mode'] = fillOnUndefined($params, 'mode', null); + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'domain', 'condition' => '=', 'value' => fillOnUndefined($params, 'domain')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + "with" => [ + 'property', 'property.propertyAwardsCertificates.awardsCertificateCategory', 'propertyWebTemplate', 'propertyBookingEngine', + 'propertyWebMenuMenuMapping', 'propertyWebLanguageMapping', + 'propertyGroupMapping.propertyGroup', 'propertyWebAbout', 'propertyWebPopup', 'propertyWebWeather', + 'propertyWebComponent', 'propertyWebRoomMapping.roomDetail', 'propertyWebColorMapping' + ] + ]; + $propertyWeb = $this->propertyWebService->select($propertyRequest, ['id', 'property_id', 'domain', 'default_language', 'template_id', 'token', 'is_ssl_active', 'weather_active', 'cover_video_id']); + $propertyGroupId = NULL; + $propertyBookingEngineGroupId = NULL; + if (isset($propertyWeb['data']['property_group_mapping'])) { + foreach ($propertyWeb['data']['property_group_mapping'] as $propertyGroupMapping) { + if (!empty($propertyGroupMapping['property_group'] && $propertyGroupMapping['property_group']['type'] === "MYW")) { + $propertyGroupId = $propertyGroupMapping['property_group']['id']; + } + if (!empty($propertyGroupMapping['property_group'] && $propertyGroupMapping['property_group']['type'] === "MYW")) { + $propertyBookingEngineGroupId = $propertyGroupMapping['property_group']['id']; + } + } + } + + if (!isset($propertyWeb['data']['property'])) { + throw new ApiErrorException('Property is not active!', 101); + //101: Passive Property + } + + if ($propertyWeb['data']['property']['status'] != 1) { + throw new ApiErrorException('Property is not active!', 101); + //101: Passive Property + } + + + $propertyGroupMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_group_id', 'condition' => '=', 'value' => $propertyGroupId], + ['field' => 'property_id', 'condition' => '!=', 'value' => fillOnUndefined($propertyWeb['data'], 'property_id')] + ], + 'orderBy' => [ + ["field" => "order_number", "value" => "ASC"] + ], + "with" => ['property.propertyWeb'] + ]; + + $propertyGroupWebSiteResult = $this->propertyGroupMappingService->getPropertyGroupMapping($propertyGroupMappingRequest); + if ($propertyGroupWebSiteResult['status'] != 'success') { + throw new ApiErrorException($propertyGroupWebSiteResult['message']); + } + + $propertyGroupWebSites = $propertyGroupWebSiteResult['data']; + + $groupWebSites = []; + foreach ($propertyGroupWebSites as $propertyGroupWebSite) { + if ($propertyGroupWebSite['property'] && $propertyGroupWebSite['property']['property_web']) { + $propertyGroupWebSite['property']['property_web']['name'] = $propertyGroupWebSite['property']['name']; + $groupWebSites[] = $propertyGroupWebSite['property']['property_web']; + } + } + + $groupWebSites = collect($groupWebSites)/*->where('is_published', 1)*/ ->values()->toArray(); + + + if (!empty($propertyWeb['data'])) { + $propertyWeb['data']['property_group_web_sites'] = $groupWebSites; + unset($propertyWeb['data']['property_group_mapping']); + } + + $propertyBookingGroupMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_group_id', 'condition' => '=', 'value' => $propertyBookingEngineGroupId], + ], + 'orderBy' => [ + ["field" => "order_number", "value" => "ASC"] + ], + "with" => [ + 'property.propertyBookingEngineToken', + 'property.propertyWeb.propertyWebPhotoMapping.propertyPhoto' + ] + ]; + + $propertyGroupBookingResult = $this->propertyGroupMappingService->getPropertyGroupMapping($propertyBookingGroupMappingRequest); + if ($propertyGroupBookingResult['status'] != 'success') { + throw new ApiErrorException($propertyGroupBookingResult['message']); + } + + $propertyGroupBookings = $propertyGroupBookingResult['data']; + + + $bookingGroupProperties = []; + foreach ($propertyGroupBookings as $key => $propertyGroupBooking) { + if ($propertyGroupBooking['property']) { + $bookingGroupProperties[$key]['property_id'] = $propertyGroupBooking['property']['id']; + $bookingGroupProperties[$key]['name'] = $propertyGroupBooking['property']['name']; + $bookingGroupProperties[$key]['name'] = $propertyGroupBooking['property']['name']; + if ($propertyGroupBooking['property']['property_booking_engine_token']) { + $bookingGroupProperties[$key]['token'] = $propertyGroupBooking['property']['property_booking_engine_token']['token']; + } else { + $bookingGroupProperties[$key]['token'] = null; + } + + $bookingGroupProperties[$key]['web'] = null; + if (!empty($propertyGroupBooking['property']['property_web'])) { + if ($propertyGroupBooking['property']['property_web']['status'] && $propertyGroupBooking['property']['property_web']['is_published']) { + $bookingGroupProperties[$key]['web'] = $propertyGroupBooking['property']['property_web']['webProtocolUrl']; + } + } + + $propertyWebPhotoMapping = collect($propertyGroupBooking['property']['property_web']['property_web_photo_mapping']) + ->where('status', 1) + ->where('is_cover', 1) + ->toArray(); + + $bookingGroupProperties[$key]['coverPhoto'] = []; + foreach ($propertyWebPhotoMapping as $propertyWebPhoto) { + $bookingGroupProperties[$key]['coverPhoto'][] = $propertyWebPhoto['property_photo']['photoUrl']; + } + } + } + + if (!empty($bookingGroupProperties)) { + $propertyWeb['data']['property_booking_group'] = collect($bookingGroupProperties)->where('token', '!=', NULL)->toArray(); + } + + if (!empty($propertyWeb['data']['property_booking_engine'])) { + $propertyChannelMappingRequestData = [ + 'property_id' => $propertyWeb['data']['property_booking_engine']['property_id'], + 'channel_id' => $propertyWeb['data']['property_booking_engine']['channel_id'] + ]; + $propertyChannelMappingData = $this->propertyChannelMappingService->checkPropertyChannelMapping($propertyChannelMappingRequestData); + if ($propertyChannelMappingData['data'] === "") { + $propertyWeb['data']['property_booking_engine']['token'] = NULL; + } + } + + $propertyWebPreviewOrLiveMenus = []; + if (isset($propertyWeb['data']['property_web_menu_menu_mapping'])) { + $propertyWebPreviewOrLiveMenus = collect($propertyWeb['data']['property_web_menu_menu_mapping']) + ->where('status', 1)->toArray(); // live + } + + if ($propertyWeb['status'] != 'success' || !$propertyWeb['data']) { + throw new ApiErrorException('Domain not found'); + } + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + + $propertyWebLanguageMappings = $propertyWeb['data']['property_web_language_mapping'] ? $propertyWeb['data']['property_web_language_mapping'] : []; + $propertyWebLanguageMappings = collect($propertyWebLanguageMappings)->keyBy('language_code')->toArray(); + + if ($propertyWebLanguageMappings) { + foreach ($availableLanguages['data'] as $language) { + if (array_key_exists($language['code'], $propertyWebLanguageMappings)) { + $propertyWeb['data']['available_language_codes'][$language['code']] = $language; + } + } + } else { + foreach ($availableLanguages['data'] as $language) { + $propertyWeb['data']['available_language_codes'][$language['code']] = $language; + } + } + + $webMenu = []; + if (empty($propertyWebPreviewOrLiveMenus)) { + $myWebMenus = $this->propertyWebMenuService->getPropertyWebMenu(); + if ($myWebMenus['status'] != 'success') { + throw new ApiErrorException($myWebMenus['message']); + } + $propertyWeb['data']['web_menu']['LVL1'] = collect($myWebMenus['data']['property_web_menus'])->where('type', '=', '1')->keyBy('alias')->toArray(); + $propertyWeb['data']['web_menu']['LEGAL'] = collect($myWebMenus['data']['property_web_menus'])->where('type', '=', '3')->keyBy('alias')->toArray(); + unset($propertyWeb['data']['property_web_menu_menu_mapping']); + } else { + + $webMenuTypes = collect($propertyWeb['data']['property_web_menu_menu_mapping']) + ->where('status', 1) + ->groupBy('menu_code')->toArray(); + + $allLevelData = []; + $allTopData = []; + foreach ($webMenuTypes as $menuTypeKey => $webMenuType) { + if ($menuTypeKey === self::MENU_CODE_LVL1) { + $allLevelData = $this->getTypeMenus($webMenuType, $menuTypeKey); + + } elseif ($menuTypeKey === self::MENU_CODE_TOP) { + $allTopData = $this->getTypeMenus($webMenuType, $menuTypeKey); + + } + } + + $staticMenu = $this->propertyWebMenuService->getPropertyWebMenu(); + if ($staticMenu['status'] != 'success') { + throw new ApiErrorException($staticMenu['message']); + } + + unset($propertyWeb['data']['property_web_menu_menu_mapping']); + $propertyWeb['data']['web_menu'] = array_merge($allTopData, $allLevelData); + $propertyWeb['data']['web_menu']['LEGAL'] = collect($staticMenu['data']['property_web_menus'])->where('type', '=', '3')->keyBy('alias')->toArray(); + + } + + if ($propertyWeb['data']['property']['country'] == 'TR') { + unset($propertyWeb['data']['web_menu']['LEGAL']['Protection']); + } else { + unset($propertyWeb['data']['web_menu']['LEGAL']['Kvkk']); + } + + + //property_web_room_mapping + $propertyWebRoomMapping = []; + $propertyWebRoomMappingTemp = $propertyWeb['data']['property_web_room_mapping']; + unset($propertyWeb['data']['property_web_room_mapping']); + foreach ($propertyWebRoomMappingTemp as $propertyWebRoom) { + $propertyWebRoomMapping[] = [ + 'id' => $propertyWebRoom['room_detail']['id'], + 'name' => $propertyWebRoom['room_detail']['name'], + 'slug' => Str::slug($propertyWebRoom['room_detail']['name'], $separator = '-', $language = 'en') . '-' . $propertyWebRoom['room_detail']['id'] + ]; + } + $propertyWeb['data']['property_web_room_mapping'] = $propertyWebRoomMapping; + //property_web_room_mapping + + + $agentIp = !empty($params['agentInfo']) && $params['agentInfo']['ip'] ? $params['agentInfo']['ip'] : NULL; + + if ($agentIp !== NULL) { + // Find Country Code with IP + $ipResponse = $this->findCountryCodeService->findCountryWithIpAddress($agentIp); + if ($ipResponse['status'] !== 'success') { + //throw new ApiErrorException('IP Not Found'); + } + + // Create or Update Web Log + if (!empty($params['agentInfo']) && !empty($ipResponse['data']) && !empty($ipResponse['data']['code']) && $ipResponse['status']) { + + $agentParams = [ + 'web_id' => fillOnUndefined($propertyWeb['data'], 'id'), + 'ip' => $agentIp, + 'country_code' => $ipResponse['data'] ? $ipResponse['data']['code'] : null, + 'isRobot' => $params['agentInfo']['isRobot'] === true ? $params['agentInfo']['isRobot'] : false, + 'isDesktop' => $params['agentInfo']['isDesktop'] === true ? $params['agentInfo']['isDesktop'] : false, + 'isPhone' => $params['agentInfo']['isPhone'] === true ? $params['agentInfo']['isPhone'] : false + ]; + + + if ($agentParams['isRobot'] === false) { + $webLogResponse = $this->propertyWebLogService->createPropertyWebLog($agentParams); + if ($webLogResponse['status'] != 'success') { + throw new ApiErrorException('Property Web Log Not Created'); + } + } + + } + } + + //PropertyWebPopUp + $propertyWebPopUp = null; + if ($propertyWeb['data']['property_web_popup']) { + $propertyWebPopUp = collect($propertyWeb['data']['property_web_popup']) + ->where('start_date', '<=', Carbon::now()->toDateString()) + ->where('end_date', '>=', Carbon::now()->toDateString()) + ->toArray(); + + $propertyWebPopUp = array_values($propertyWebPopUp); + + } + + $propertyWeb['data']['property_web_popup'] = $propertyWebPopUp; + //PropertyWebPopUp + + + //PropertyWebContent + $propertyWebContent = null; + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyWeb['data']['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + //'with' => ['ContentCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + $propertyWebContentCriteria['skip'] = 0; + $propertyWebContentCriteria['take'] = 100; + $propertyWebContent = $this->propertyWebContentService->select($propertyWebContentCriteria, ['id', 'title', 'property_id', 'content_category_id', 'slug', 'language_code', 'image']); + $propertyWebContent = ($propertyWebContent['status'] == 'success' && !empty($propertyWebContent['data'])) ? array_values($propertyWebContent['data']) : []; + + $propertyWebContentGrouped = null; + foreach ($propertyWebContent as $content) { + if (isset($propertyWebContentGrouped[$content['language_code']]) && count($propertyWebContentGrouped[$content['language_code']]) > 2) { + continue; + } + $propertyWebContentGrouped[$content['language_code']][] = $content; + } + + $propertyWeb['data']['property_web_content'] = $propertyWebContentGrouped; + //PropertyWebContent + + + //property_web_weather + $propertyWeb['data']['property_web_weather'] = $propertyWeb['data']['weather_active'] == 1 ? $propertyWeb['data']['property_web_weather'] : null; + + //PropertyWebComponent + if ($propertyWeb['data']['property_web_component']) { + + $propertyWebComponent = $propertyWeb['data']['property_web_component']; + unset($propertyWeb['data']['property_web_component']); + + $propertyWebComponentGoogleTagManager = collect($propertyWebComponent) + ->where('component_id', 1) + ->first(); + + if ($propertyWebComponentGoogleTagManager) { + $propertyWeb['data']['property_web_component']['google_tag_manager'] = $propertyWebComponentGoogleTagManager['parameterArray']; + } + + $propertyWebComponentGoogleAnalytics = collect($propertyWebComponent) + ->where('component_id', 4) + ->first(); + + if ($propertyWebComponentGoogleAnalytics) { + $propertyWeb['data']['property_web_component']['google_analytics'] = $propertyWebComponentGoogleAnalytics['parameterArray']; + } + + $propertyWebComponentJotform = collect($propertyWebComponent) + ->where('component_id', 5) + ->first(); + + if ($propertyWebComponentJotform) { + $propertyWeb['data']['property_web_component']['jotform'] = $propertyWebComponentJotform['parameterArray']; + } + + + $propertyWebComponentMetaPixel = collect($propertyWebComponent) + ->where('component_id', 6) + ->first(); + + if ($propertyWebComponentMetaPixel) { + $propertyWeb['data']['property_web_component']['metapixel'] = $propertyWebComponentMetaPixel['parameterArray']; + } + + + $propertyWebComponentTawkTo = collect($propertyWebComponent) + ->where('component_id', 7) + ->first(); + + if ($propertyWebComponentTawkTo) { + $propertyWeb['data']['property_web_component']['tawkto'] = $propertyWebComponentTawkTo['parameterArray']; + } + + $propertyWebComponentGoogleSiteVerification = collect($propertyWebComponent) + ->where('component_id', 8) + ->first(); + + if ($propertyWebComponentGoogleSiteVerification) { + $propertyWeb['data']['property_web_component']['googlesiteverification'] = $propertyWebComponentGoogleSiteVerification['parameterArray']; + } + + $propertyWebComponentSojernWeb = collect($propertyWebComponent) + ->where('component_id', 9) + ->first(); + + if ($propertyWebComponentSojernWeb) { + $propertyWeb['data']['property_web_component']['sojernweb'] = $propertyWebComponentSojernWeb['parameterArray']; + } + + $propertyWebComponentSojernBookingEngine = collect($propertyWebComponent) + ->where('component_id', 10) + ->first(); + + if ($propertyWebComponentSojernBookingEngine) { + $propertyWeb['data']['property_web_component']['sojernbookingengine'] = $propertyWebComponentSojernBookingEngine['parameterArray']; + } + + + $propertyWebComponentGoogleAds = collect($propertyWebComponent) + ->where('component_id', 11) + ->first(); + + if ($propertyWebComponentGoogleAds) { + $propertyWeb['data']['property_web_component']['googleads'] = $propertyWebComponentGoogleAds['parameterArray']; + } + + $propertyWebComponentMetaVerification = collect($propertyWebComponent) + ->where('component_id', 12) + ->first(); + + if ($propertyWebComponentMetaVerification) { + $propertyWeb['data']['property_web_component']['metaverification'] = $propertyWebComponentMetaVerification['parameterArray']; + } + + + $propertyWebComponentClarityweb = collect($propertyWebComponent) + ->where('component_id', 13) + ->first(); + + if ($propertyWebComponentClarityweb) { + $propertyWeb['data']['property_web_component']['clarityweb'] = $propertyWebComponentClarityweb['parameterArray']; + } + + $propertyWebComponentClarityBookingEngine = collect($propertyWebComponent) + ->where('component_id', 14) + ->first(); + + if ($propertyWebComponentClarityBookingEngine) { + $propertyWeb['data']['property_web_component']['claritybookingengine'] = $propertyWebComponentClarityBookingEngine['parameterArray']; + } + + } + //PropertyWebComponent + + //PropertyAwardsCertificates + if (!empty($propertyWeb['data']['property']['property_awards_certificates'])) { + + $staticPolicyIds = [134, 177, 211, 232]; + $staticPolicyGroup = []; + + $propertyAwardsCertificates = collect($propertyWeb['data']['property']['property_awards_certificates'])->where('status', 1)->whereIn('category_id', $staticPolicyIds)->sortByDesc('id')->toArray(); + + if ($propertyAwardsCertificates) { + + foreach ($propertyAwardsCertificates as $propertyAwardsCertificate) { + + if (isset($staticPolicyGroup[$propertyAwardsCertificate['category_id']]['language'][$propertyAwardsCertificate['language_code']])) { + continue; + } + + + $staticPolicyGroup[$propertyAwardsCertificate['category_id']]['name'] = $propertyAwardsCertificate['awards_certificate_category']['name']; + $staticPolicyGroup[$propertyAwardsCertificate['category_id']]['language_key'] = $propertyAwardsCertificate['awards_certificate_category']['language_key']; + + if (empty($propertyAwardsCertificate['language_code'])) { + $propertyAwardsCertificate['language_code'] = 'default'; + } + + $staticPolicyGroup[$propertyAwardsCertificate['category_id']]['language'][$propertyAwardsCertificate['language_code']] = [ + 'file' => $propertyAwardsCertificate['file_path'], + 'url' => Config::get('app.imageUrl') . '/property-photos/' . $propertyWeb['data']['property']['id'] . '/awards-certificates/' . $propertyAwardsCertificate['file_path'] + ]; + + } + + } + + $propertyWeb['data']['static_policy'] = !empty($staticPolicyGroup) ? $staticPolicyGroup : null; + + unset($propertyWeb['data']['property']['property_awards_certificates']); + + } + //PropertyAwardsCertificates + + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyWeb['data']['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates.awardsCertificateCategory', + 'propertyPaymentMapping' + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $propertyDetail = $this->propertyService->select($propertyRequest, $getPropertyFields); + $propertyDetail = $propertyDetail['data']; + + + $propertyDetail['property_brand']['logo_url'] = isset($propertyDetail['property_brand']) ? Config::get('app.imageUrl') . '/property-photos/' . $propertyDetail['id'] . "/logo/" . $propertyDetail['property_brand']['logo_name'] . '_250x250.' . $propertyDetail['property_brand']['logo_file_ext'] : null; + $propertyDetail['property_contact']['social_media_addresses'] = json_decode($propertyDetail['property_contact']['social_media_addresses'], 1); + + + $colorCodes = []; + foreach ($propertyWeb['data']['property_web_color_mapping'] as $color) { + $colorCodes[] = [ + 'color_number' => $color['order_number'], + 'color_code' => $color['color_code'], + ]; + } + $colorCodes = $colorCodes ? $colorCodes : json_decode($propertyDetail['property_brand']['color_codes'], 1); + $propertyDetail['property_brand']['color_codes'] = $colorCodes; + + $propertyAdditionalInfo = null; + $propertyAdditionalInfoRequest = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy(['property_id' => $propertyDetail['id']]); + if (isset($propertyAdditionalInfoRequest['data'])) { + $propertyAdditionalInfo = $propertyAdditionalInfoRequest['data']; + } + + + //coverPhotos + $coverPhotosParam = [ + 'property_id' => $propertyWeb['data']['property']['id'], + 'property_web_id' => $propertyWeb['data']['id'], + 'mode' => $params['mode'], + ]; + $landingPhoto = $this->coverPhotos($coverPhotosParam); + //coverPhotos + + + $propertyWeb['data']['property']['name'] = $propertyDetail['name']; + $propertyWeb['data']['property']['property_type'] = $propertyDetail['property_type']['name']; + $propertyWeb['data']['property']['property_type_key'] = $propertyDetail['property_type']['language_key']; + $propertyWeb['data']['property']['property_chain'] = $propertyDetail['property_chain']['name']; + $propertyWeb['data']['property']['official_name'] = $propertyDetail['official_name']; + $propertyWeb['data']['property']['tax_office'] = $propertyDetail['tax_office']; + $propertyWeb['data']['property']['tax_number'] = $propertyDetail['tax_number']; + $propertyWeb['data']['property']['currency_type'] = $propertyDetail['currency_type']; + $propertyWeb['data']['property']['property_brand'] = $propertyDetail['property_brand']; + $propertyWeb['data']['property']['property_contact'] = $propertyDetail['property_contact']; + $propertyWeb['data']['property']['description'] = $propertyDetail['name']; + $propertyWeb['data']['property']['additional_info'] = $propertyAdditionalInfo; + $propertyWeb['data']['property']['landing_photo'] = $landingPhoto; + + $propertyWeb['data']['is_virtual_payment_active'] = collect($propertyDetail['property_payment_mapping'])->where('status', 1)->count() > 0 ? true : false; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + $response['errorCode'] = $e->getCode(); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode'], fillOnUndefined($response, 'errorCode', null)); + } + + public function checkDomainToken(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => fillOnUndefined($params, 'token')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true, + "with" => [ + 'property', 'propertyWebTemplate', 'propertyBookingEngine', + 'propertyWebMenuMenuMapping', 'propertyWebLanguageMapping', + 'propertyGroupMapping.propertyGroup', 'propertyWebAbout', 'propertyWebPopup', 'propertyWebWeather', + 'propertyWebComponent', 'propertyWebRoomMapping.roomDetail' + ] + ]; + $propertyWeb = $this->propertyWebService->select($propertyRequest, ['id', 'property_id', 'domain', 'default_language', 'template_id', 'token', 'is_ssl_active', 'weather_active', 'cover_video_id']); + $propertyGroupId = NULL; + $propertyBookingEngineGroupId = NULL; + if (isset($propertyWeb['data']['property_group_mapping'])) { + foreach ($propertyWeb['data']['property_group_mapping'] as $propertyGroupMapping) { + if (!empty($propertyGroupMapping['property_group'] && $propertyGroupMapping['property_group']['type'] === "MYW")) { + $propertyGroupId = $propertyGroupMapping['property_group']['id']; + } + if (!empty($propertyGroupMapping['property_group'] && $propertyGroupMapping['property_group']['type'] === "BEN")) { + $propertyBookingEngineGroupId = $propertyGroupMapping['property_group']['id']; + } + } + } + + $propertyGroupMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_group_id', 'condition' => '=', 'value' => $propertyGroupId], + ['field' => 'property_id', 'condition' => '!=', 'value' => fillOnUndefined($propertyWeb['data'], 'property_id')] + ], + 'orderBy' => [ + ["field" => "order_number", "value" => "ASC"] + ], + "with" => ['property.propertyWeb'] + ]; + + $propertyGroupWebSiteResult = $this->propertyGroupMappingService->getPropertyGroupMapping($propertyGroupMappingRequest); + + if ($propertyGroupWebSiteResult['status'] != 'success') { + throw new ApiErrorException($propertyGroupWebSiteResult['message']); + } + + $propertyGroupWebSites = $propertyGroupWebSiteResult['data']; + + $groupWebSites = []; + foreach ($propertyGroupWebSites as $propertyGroupWebSite) { + if ($propertyGroupWebSite['property'] && $propertyGroupWebSite['property']['property_web']) { + $propertyGroupWebSite['property']['property_web']['name'] = $propertyGroupWebSite['property']['name']; + $groupWebSites[] = $propertyGroupWebSite['property']['property_web']; + } + } + + $groupWebSites = collect($groupWebSites)/*->where('is_published', 1)*/ ->values()->toArray(); + + if (!empty($propertyWeb['data'])) { + $propertyWeb['data']['property_group_web_sites'] = $groupWebSites; + unset($propertyWeb['data']['property_group_mapping']); + } + + $propertyBookingGroupMappingRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_group_id', 'condition' => '=', 'value' => $propertyBookingEngineGroupId], + ], + 'orderBy' => [ + ["field" => "order_number", "value" => "ASC"] + ], + "with" => ['property.propertyBookingEngineToken', 'property.propertyWeb'] + ]; + + $propertyGroupBookingResult = $this->propertyGroupMappingService->getPropertyGroupMapping($propertyBookingGroupMappingRequest); + if ($propertyGroupBookingResult['status'] != 'success') { + throw new ApiErrorException($propertyGroupBookingResult['message']); + } + + $propertyGroupBookings = $propertyGroupBookingResult['data']; + + $bookingGroupProperties = []; + foreach ($propertyGroupBookings as $key => $propertyGroupBooking) { + if ($propertyGroupBooking['property']) { + $bookingGroupProperties[$key]['property_id'] = $propertyGroupBooking['property']['id']; + $bookingGroupProperties[$key]['name'] = $propertyGroupBooking['property']['name']; + if ($propertyGroupBooking['property']['property_booking_engine_token']) { + $bookingGroupProperties[$key]['token'] = $propertyGroupBooking['property']['property_booking_engine_token']['token']; + } else { + $bookingGroupProperties[$key]['token'] = NULL; + } + + $bookingGroupProperties[$key]['web'] = null; + if (!empty($propertyGroupBooking['property']['property_web'])) { + if ($propertyGroupBooking['property']['property_web']['status'] && $propertyGroupBooking['property']['property_web']['is_published']) { + $bookingGroupProperties[$key]['web'] = $propertyGroupBooking['property']['property_web']['webProtocolUrl']; + } + } + } + } + + if (!empty($bookingGroupProperties)) { + $propertyWeb['data']['property_booking_group'] = collect($bookingGroupProperties)->where('token', '!=', NULL)->toArray(); + } + + $mywebServiceMode = fillOnUndefined($params, 'serviceMode', 'live'); // preview or live + $mywebServiceModeStatus = $mywebServiceMode === "live" ? 1 : 2; + + if (!empty($propertyWeb['data']['property_booking_engine'])) { + $propertyChannelMappingRequestData = [ + 'property_id' => $propertyWeb['data']['property_booking_engine']['property_id'], + 'channel_id' => $propertyWeb['data']['property_booking_engine']['channel_id'] + ]; + $propertyChannelMappingData = $this->propertyChannelMappingService->checkPropertyChannelMapping($propertyChannelMappingRequestData); + if ($propertyChannelMappingData['data'] === "") { + $propertyWeb['data']['property_booking_engine']['token'] = NULL; + } + } + + $propertyWebPreviewOrLiveMenus = []; + if (isset($propertyWeb['data']['property_web_menu_menu_mapping'])) { + $propertyWebPreviewOrLiveMenus = collect($propertyWeb['data']['property_web_menu_menu_mapping']) + ->where('status', $mywebServiceModeStatus)->toArray(); + } + + if ($propertyWeb['status'] != 'success' || !$propertyWeb['data']) { + throw new ApiErrorException('Domain not found'); + } + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + + $propertyWebLanguageMappings = $propertyWeb['data']['property_web_language_mapping'] ? $propertyWeb['data']['property_web_language_mapping'] : []; + $propertyWebLanguageMappings = collect($propertyWebLanguageMappings) + ->keyBy('language_code') + ->where('status', $mywebServiceModeStatus) + ->toArray(); + + if ($propertyWebLanguageMappings) { + foreach ($availableLanguages['data'] as $language) { + if (array_key_exists($language['code'], $propertyWebLanguageMappings)) { + $propertyWeb['data']['available_language_codes'][$language['code']] = $language; + } + } + } else { + foreach ($availableLanguages['data'] as $language) { + $propertyWeb['data']['available_language_codes'][$language['code']] = $language; + } + } + $webMenu = []; + if (empty($propertyWebPreviewOrLiveMenus)) { + $myWebMenus = $this->propertyWebMenuService->getPropertyWebMenu(); + if ($myWebMenus['status'] != 'success') { + throw new ApiErrorException($myWebMenus['message']); + } + $propertyWeb['data']['web_menu']['LVL1'] = collect($myWebMenus['data']['property_web_menus'])->where('type', '=', '1')->keyBy('alias')->toArray(); + $propertyWeb['data']['web_menu']['LEGAL'] = collect($myWebMenus['data']['property_web_menus'])->where('type', '=', '3')->keyBy('alias')->toArray(); + unset($propertyWeb['data']['property_web_menu_menu_mapping']); + } else { + + $webMenuTypes = collect($propertyWeb['data']['property_web_menu_menu_mapping']) + ->where('status', $mywebServiceModeStatus) + ->groupBy('menu_code')->toArray(); + + $allLevelData = []; + $allTopData = []; + foreach ($webMenuTypes as $menuTypeKey => $webMenuType) { + if ($menuTypeKey === self::MENU_CODE_LVL1) { + $allLevelData = $this->getTypeMenus($webMenuType, $menuTypeKey); + } elseif ($menuTypeKey === self::MENU_CODE_TOP) { + $allTopData = $this->getTypeMenus($webMenuType, $menuTypeKey); + } + } + + + unset($propertyWeb['data']['property_web_menu_menu_mapping']); + $propertyWeb['data']['web_menu'] = array_merge($allTopData, $allLevelData); + } + + //property_web_room_mapping + $propertyWebRoomMapping = []; + $propertyWebRoomMappingTemp = $propertyWeb['data']['property_web_room_mapping']; + unset($propertyWeb['data']['property_web_room_mapping']); + foreach ($propertyWebRoomMappingTemp as $propertyWebRoom) { + $propertyWebRoomMapping[] = [ + 'id' => $propertyWebRoom['room_detail']['id'], + 'name' => $propertyWebRoom['room_detail']['name'], + 'slug' => Str::slug($propertyWebRoom['room_detail']['name'], $separator = '-', $language = 'en') . '-' . $propertyWebRoom['room_detail']['id'] + ]; + } + $propertyWeb['data']['property_web_room_mapping'] = $propertyWebRoomMapping; + //property_web_room_mapping + + //PropertyWebPopUp + $propertyWebPopUp = null; + if ($propertyWeb['data']['property_web_popup']) { + $propertyWebPopUp = collect($propertyWeb['data']['property_web_popup']) + ->where('start_date', '<=', Carbon::now()->toDateString()) + ->where('end_date', '>=', Carbon::now()->toDateString()) + ->toArray(); + + $propertyWebPopUp = array_values($propertyWebPopUp); + + } + + $propertyWeb['data']['property_web_popup'] = $propertyWebPopUp; + //PropertyWebPopUp + + //PropertyWebContent + $propertyWebContent = null; + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyWeb['data']['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + //'with' => ['ContentCategory'], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + $propertyWebContentCriteria['skip'] = 0; + $propertyWebContentCriteria['take'] = 100; + $propertyWebContent = $this->propertyWebContentService->select($propertyWebContentCriteria, ['id', 'title', 'property_id', 'slug', 'content_category_id', 'language_code', 'image']); + $propertyWebContent = ($propertyWebContent['status'] == 'success' && !empty($propertyWebContent['data'])) ? array_values($propertyWebContent['data']) : []; + + $propertyWebContentGrouped = null; + foreach ($propertyWebContent as $content) { + if (isset($propertyWebContentGrouped[$content['language_code']]) && count($propertyWebContentGrouped[$content['language_code']]) > 2) { + continue; + } + $propertyWebContentGrouped[$content['language_code']][] = $content; + } + + $propertyWeb['data']['property_web_content'] = $propertyWebContentGrouped; + //PropertyWebContent + + + //property_web_weather + $propertyWeb['data']['property_web_weather'] = $propertyWeb['data']['weather_active'] == 1 ? $propertyWeb['data']['property_web_weather'] : null; + + + //PropertyWebComponent + if ($propertyWeb['data']['property_web_component']) { + + $propertyWebComponent = $propertyWeb['data']['property_web_component']; + unset($propertyWeb['data']['property_web_component']); + + $propertyWebComponentGoogleTagManager = collect($propertyWebComponent) + ->where('component_id', 1) + ->first(); + + if ($propertyWebComponentGoogleTagManager) { + $propertyWeb['data']['property_web_component']['google_tag_manager'] = $propertyWebComponentGoogleTagManager['parameterArray']; + } + + $propertyWebComponentGoogleAnalytics = collect($propertyWebComponent) + ->where('component_id', 4) + ->first(); + + if ($propertyWebComponentGoogleAnalytics) { + $propertyWeb['data']['property_web_component']['google_analytics'] = $propertyWebComponentGoogleAnalytics['parameterArray']; + } + + $propertyWebComponentJotform = collect($propertyWebComponent) + ->where('component_id', 5) + ->first(); + + if ($propertyWebComponentJotform) { + $propertyWeb['data']['property_web_component']['jotform'] = $propertyWebComponentJotform['parameterArray']; + } + + + $propertyWebComponentMetaPixel = collect($propertyWebComponent) + ->where('component_id', 6) + ->first(); + + if ($propertyWebComponentMetaPixel) { + $propertyWeb['data']['property_web_component']['metapixel'] = $propertyWebComponentMetaPixel['parameterArray']; + } + + + $propertyWebComponentTawkTo = collect($propertyWebComponent) + ->where('component_id', 7) + ->first(); + + if ($propertyWebComponentTawkTo) { + $propertyWeb['data']['property_web_component']['tawkto'] = $propertyWebComponentTawkTo['parameterArray']; + } + + $propertyWebComponentGoogleSiteVerification = collect($propertyWebComponent) + ->where('component_id', 8) + ->first(); + + if ($propertyWebComponentGoogleSiteVerification) { + $propertyWeb['data']['property_web_component']['googlesiteverification'] = $propertyWebComponentGoogleSiteVerification['parameterArray']; + } + + $propertyWebComponentMetaVerification = collect($propertyWebComponent) + ->where('component_id', 12) + ->first(); + + if ($propertyWebComponentMetaVerification) { + $propertyWeb['data']['property_web_component']['metaverification'] = $propertyWebComponentMetaVerification['parameterArray']; + } + + } + //PropertyWebComponent + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $propertyWeb['data']['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyBrand', 'propertyContact', 'propertyPhotos', 'propertyType', 'propertyChain', + 'propertyRooms', 'propertyWeb', 'propertyAwardsCertificates.awardsCertificateCategory', + 'propertyPaymentMapping' + ], + 'firstRow' => true + ]; + + $getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country']; + $propertyDetail = $this->propertyService->select($propertyRequest, $getPropertyFields); + $propertyDetail = $propertyDetail['data']; + + + $propertyDetail['property_brand']['logo_url'] = $propertyDetail['property_brand'] ? Config::get('app.imageUrl') . '/property-photos/' . $propertyDetail['id'] . "/logo/" . $propertyDetail['property_brand']['logo_name'] . '_250x250.' . $propertyDetail['property_brand']['logo_file_ext'] : null; + $propertyDetail['property_contact']['social_media_addresses'] = json_decode($propertyDetail['property_contact']['social_media_addresses'], 1); + + $colorCodes = json_decode($propertyDetail['property_brand']['color_codes'], 1); + $propertyDetail['property_brand']['color_codes'] = $colorCodes; + + $propertyAdditionalInfo = null; + $propertyAdditionalInfoRequest = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy(['property_id' => $propertyDetail['id']]); + if (isset($propertyAdditionalInfoRequest['data'])) { + $propertyAdditionalInfo = $propertyAdditionalInfoRequest['data']; + } + + + //coverPhotos + $coverPhotosParam = [ + 'property_id' => $propertyWeb['data']['property']['id'], + 'property_web_id' => $propertyWeb['data']['id'], + 'mode' => $mywebServiceModeStatus, + ]; + $landingPhoto = $this->coverPhotos($coverPhotosParam); + //coverPhotos + + + $propertyWeb['data']['property']['name'] = $propertyDetail['name']; + $propertyWeb['data']['property']['property_type'] = $propertyDetail['property_type']['name']; + $propertyWeb['data']['property']['property_type_key'] = $propertyDetail['property_type']['language_key']; + $propertyWeb['data']['property']['property_chain'] = $propertyDetail['property_chain']['name']; + $propertyWeb['data']['property']['official_name'] = $propertyDetail['official_name']; + $propertyWeb['data']['property']['tax_office'] = $propertyDetail['tax_office']; + $propertyWeb['data']['property']['tax_number'] = $propertyDetail['tax_number']; + $propertyWeb['data']['property']['currency_type'] = $propertyDetail['currency_type']; + $propertyWeb['data']['property']['property_brand'] = $propertyDetail['property_brand']; + $propertyWeb['data']['property']['property_contact'] = $propertyDetail['property_contact']; + $propertyWeb['data']['property']['description'] = $propertyDetail['name']; + $propertyWeb['data']['property']['additional_info'] = $propertyAdditionalInfo; + $propertyWeb['data']['property']['landing_photo'] = $landingPhoto; + + $propertyWeb['data']['is_virtual_payment_active'] = collect($propertyDetail['property_payment_mapping'])->where('status', 1)->count() > 0 ? true : false; + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function checkDomainWebGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'domain', 'condition' => '=', 'value' => fillOnUndefined($params, 'domain')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyGroupMapping.property.propertyWeb.propertyWebPhotoMapping.propertyPhoto', + 'propertyGroupMapping.property.propertyBrand', 'propertyGroupMapping.property.propertyContact', + 'propertyGroupMapping.property.propertyBookingEngineToken' + ], + 'firstRow' => true, + ]; + + $propertyWebGroup = $this->propertyWebService->selectWebGroup($propertyRequest, + [ + 'id', 'title', 'property_group_id', 'domain', 'default_language', + 'logo', 'is_ssl_active', 'address', 'email', 'phone', 'template', 'slogan' + ]); + + if ($propertyWebGroup['status'] != 'success') { + throw new ApiErrorException(lang('Domain not found.')); + } + + $propertyWebGroup = !empty($propertyWebGroup['data']) ? $propertyWebGroup['data'] : null; + + if (empty($propertyWebGroup)) { + throw new ApiErrorException(lang('Domain not found.')); + } + + + $propertyWebGroupData = []; + $propertyWebGroupData['title'] = $propertyWebGroup['title']; + $propertyWebGroupData['domain'] = $propertyWebGroup['domain']; + $propertyWebGroupData['template'] = $propertyWebGroup['template']; + $propertyWebGroupData['default_language'] = $propertyWebGroup['default_language']; + $propertyWebGroupData['logo'] = $propertyWebGroup['logo']; + $propertyWebGroupData['logoUrl'] = $propertyWebGroup['logoUrl']; + $propertyWebGroupData['address'] = $propertyWebGroup['address']; + $propertyWebGroupData['email'] = $propertyWebGroup['email']; + $propertyWebGroupData['phone'] = $propertyWebGroup['phone']; + $propertyWebGroupData['is_ssl_active'] = $propertyWebGroup['is_ssl_active']; + $propertyWebGroupData['slogan'] = $propertyWebGroup['slogan']; + + if (!empty($propertyWebGroup['property_group_mapping'])) { + $propertyWebGroup['property_group_mapping'] = collect($propertyWebGroup['property_group_mapping'])->sortBy('order_number')->toArray(); + } + + $propertyGroupMapping = []; + foreach ($propertyWebGroup['property_group_mapping'] as $property) { + + if (empty($property['property']['property_web'])) { + continue; + } + + if ($property['property']['property_web']['status'] != 1 || $property['property']['property_web']['is_published'] != 1) { + continue; + } + + $propertyGroupMapping[$property['property_id']]['id'] = $property['property']['id']; + $propertyGroupMapping[$property['property_id']]['title'] = $property['property']['name']; + $propertyGroupMapping[$property['property_id']]['domain'] = $property['property']['property_web']['domain']; + $propertyGroupMapping[$property['property_id']]['webProtocolUrl'] = $property['property']['property_web']['webProtocolUrl']; + $propertyGroupMapping[$property['property_id']]['logoUrl'] = $property['property']['property_brand']['logoUrl']; + $propertyGroupMapping[$property['property_id']]['address'] = $property['property']['property_contact']['address']; + $propertyGroupMapping[$property['property_id']]['email'] = $property['property']['property_contact']['email']; + $propertyGroupMapping[$property['property_id']]['phone'] = $property['property']['property_contact']['view_full_phone']; + $propertyGroupMapping[$property['property_id']]['content_code'] = $property['property']['content_code']; + $propertyGroupMapping[$property['property_id']]['token'] = $property['property']['property_booking_engine_token']['token']; + + + $colorCodes = json_decode($property['property']['property_brand']['color_codes'], 1); + $propertyGroupMapping[$property['property_id']]['colorCodes'] = $colorCodes; + + + $propertyWebPhotoMapping = collect($property['property']['property_web']['property_web_photo_mapping']) + ->where('status', 1) + ->where('is_cover', 1) + ->toArray(); + + $propertyGroupMapping[$property['property_id']]['coverPhoto'] = []; + foreach ($propertyWebPhotoMapping as $propertyWebPhoto) { + $propertyGroupMapping[$property['property_id']]['coverPhoto'][] = $propertyWebPhoto['property_photo']['photoUrl']; + } + + + } + + $propertyWebGroupData['propertyGroupMapping'] = array_values($propertyGroupMapping); + + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + + foreach ($availableLanguages['data'] as $language) { + $propertyWebGroupData['available_language_codes'][$language['code']] = $language; + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebGroupData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function contentDomainWebGroup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyRequest = [ + 'criteria' => [ + ['field' => 'domain', 'condition' => '=', 'value' => fillOnUndefined($params, 'domain')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1], + ], + 'with' => [ + 'propertyGroupMapping.property.propertyWeb.propertyWebPhotoMapping.propertyPhoto', + 'propertyGroupMapping.property.propertyWeb.propertyWebContentSummary.ContentCategory', + 'propertyGroupMapping.property.propertyBrand', 'propertyGroupMapping.property.propertyContact', + 'propertyGroupMapping.property.propertyBookingEngineToken', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceCategory', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceWorkingHour', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlacePhotoMapping.propertyPlacePhoto', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFact', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlaceFactMapping.propertyPlaceFactTitleFactMapping.placeFactTitle', + 'propertyGroupMapping.property.propertyWeb.propertyWebPlaceMapping.placeDetail.propertyPlacePhotoMapping', + ], + 'firstRow' => true, + ]; + + $propertyWebGroup = $this->propertyWebService->selectWebGroup($propertyRequest, + [ + 'id', 'title', 'property_group_id', 'domain', 'default_language', + 'logo', 'is_ssl_active', 'address', 'email', 'phone', 'template', 'slogan' + ]); + + if ($propertyWebGroup['status'] != 'success') { + throw new ApiErrorException(lang('Domain not found.')); + } + + $propertyWebGroup = !empty($propertyWebGroup['data']) ? $propertyWebGroup['data'] : null; + + if (empty($propertyWebGroup)) { + throw new ApiErrorException(lang('Domain not found.')); + } + + + $propertyWebGroupData = []; + $propertyWebGroupData['title'] = $propertyWebGroup['title']; + $propertyWebGroupData['domain'] = $propertyWebGroup['domain']; + $propertyWebGroupData['template'] = $propertyWebGroup['template']; + $propertyWebGroupData['default_language'] = $propertyWebGroup['default_language']; + $propertyWebGroupData['logo'] = $propertyWebGroup['logo']; + $propertyWebGroupData['logoUrl'] = $propertyWebGroup['logoUrl']; + $propertyWebGroupData['address'] = $propertyWebGroup['address']; + $propertyWebGroupData['email'] = $propertyWebGroup['email']; + $propertyWebGroupData['phone'] = $propertyWebGroup['phone']; + $propertyWebGroupData['is_ssl_active'] = $propertyWebGroup['is_ssl_active']; + $propertyWebGroupData['slogan'] = $propertyWebGroup['slogan']; + + if (!empty($propertyWebGroup['property_group_mapping'])) { + $propertyWebGroup['property_group_mapping'] = collect($propertyWebGroup['property_group_mapping'])->sortBy('order_number')->toArray(); + } + + $propertyGroupMapping = []; + foreach ($propertyWebGroup['property_group_mapping'] as $property) { + + //dd($property); + + if (empty($property['property']['property_web'])) { + continue; + } + + if ($property['property']['property_web']['status'] != 1 || $property['property']['property_web']['is_published'] != 1) { + continue; + } + + $propertyGroupMapping[$property['property_id']]['id'] = $property['property']['id']; + $propertyGroupMapping[$property['property_id']]['title'] = $property['property']['name']; + $propertyGroupMapping[$property['property_id']]['domain'] = $property['property']['property_web']['domain']; + $propertyGroupMapping[$property['property_id']]['webProtocolUrl'] = $property['property']['property_web']['webProtocolUrl']; + $propertyGroupMapping[$property['property_id']]['logoUrl'] = $property['property']['property_brand']['logoUrl']; + $propertyGroupMapping[$property['property_id']]['address'] = $property['property']['property_contact']['address']; + $propertyGroupMapping[$property['property_id']]['email'] = $property['property']['property_contact']['email']; + $propertyGroupMapping[$property['property_id']]['phone'] = $property['property']['property_contact']['view_full_phone']; + $propertyGroupMapping[$property['property_id']]['content_code'] = $property['property']['content_code']; + $propertyGroupMapping[$property['property_id']]['token'] = $property['property']['property_booking_engine_token']['token']; + + + $propertyGroupMapping[$property['property_id']]['property_place'] = $property['property']['property_web']['property_web_place_mapping']; + $propertyGroupMapping[$property['property_id']]['property_web_content'] = $property['property']['property_web']['property_web_content_summary']; + + + $colorCodes = json_decode($property['property']['property_brand']['color_codes'], 1); + $propertyGroupMapping[$property['property_id']]['colorCodes'] = $colorCodes; + + $propertyWebPhotoMapping = collect($property['property']['property_web']['property_web_photo_mapping']) + ->where('status', 1) + ->toArray(); + + $propertyGroupMapping[$property['property_id']]['propertyWebPhoto'] = []; + foreach ($propertyWebPhotoMapping as $propertyWebPhoto) { + $propertyGroupMapping[$property['property_id']]['propertyWebPhoto'][] = $propertyWebPhoto['property_photo']['photoUrl']; + } + + + $propertyWebPhotoMapping = collect($property['property']['property_web']['property_web_photo_mapping']) + ->where('status', 1) + ->where('is_cover', 1) + ->toArray(); + + $propertyGroupMapping[$property['property_id']]['coverPhoto'] = []; + foreach ($propertyWebPhotoMapping as $propertyWebPhoto) { + $propertyGroupMapping[$property['property_id']]['coverPhoto'][] = $propertyWebPhoto['property_photo']['photoUrl']; + } + + + } + + $propertyWebGroupData['propertyGroupMapping'] = array_values($propertyGroupMapping); + + + $availableLanguageRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'is_application', 'condition' => '=', 'value' => 1], + ['field' => 'is_published', 'condition' => '=', 'value' => 1] + ], + ]; + + $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']); + + foreach ($availableLanguages['data'] as $language) { + $propertyWebGroupData['available_language_codes'][$language['code']] = $language; + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebGroupData]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function test(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $params]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getLanguages(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + + $languageData = $this->languageBaseService->createApplicationLanguageData(); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $languageData['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyWebEditContent(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + + $propertyWebRequest = [ + 'id' => fillOnUndefined($params, 'property_web_id'), + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $propertyWeb = $this->propertyWebService->getPropertyWeb($propertyWebRequest); + if ($propertyWeb['status'] != 'success') { + throw new ApiErrorException($propertyWeb['message']); + } + + $propertyWebPhotos = $this->propertyWebService->getPropertyWebPhotos($propertyWebRequest); + if ($propertyWeb['status'] != 'success') { + throw new ApiErrorException($propertyWeb['message']); + } + $languages = $this->languageService->getApplicationLanguages(); + if ($languages['status'] != 'success') { + throw new ApiErrorException($languages['message']); + } + + $myWebMenus = $this->propertyWebMenuService->getPropertyWebMenu(); + if ($myWebMenus['status'] != 'success') { + throw new ApiErrorException($myWebMenus['message']); + } + + $myWebMenus = collect($myWebMenus['data']['property_web_menus'])->where('type', '!=', '3')->toArray(); + $placeRequest = [ + 'property_id' => $params['property_id'] + ]; + $myPlaces = $this->propertyPlaceService->webMenuPlaceCategoriesAndPlaces($placeRequest); + if ($myPlaces['status'] != 'success') { + throw new ApiErrorException($myPlaces['message']); + } + + $myPlaces = $myPlaces['data']; + $myWebMenus = array_merge($myWebMenus, $myPlaces); + + $myWebMenuMappingRequest = [ + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $myWebMenuMapping = $this->propertyWebMenuMappingService->getPropertyWebMenuMapping($myWebMenuMappingRequest); + + if ($myWebMenuMapping['status'] != 'success') { + throw new ApiErrorException($myWebMenuMapping['message']); + } + + $menuIndex = 1; + $responseMenus = []; + + + $myWebMenuMappingCollection = collect($myWebMenuMapping['data']['property_web_menu_mapping']); + foreach ($myWebMenus as $myWebMenu) { + $checkMenuMapping = $myWebMenuMappingCollection->where('type', '=', $myWebMenu['menu_type']) + ->where('property_web_menu_id', '=', $myWebMenu['id'])->first(); + + if ($checkMenuMapping) { + $myWebMenu['is_selected'] = true; + $myWebMenu['order_number_mapping'] = $checkMenuMapping['order_number']; + $myWebMenu['order_number'] = $menuIndex; + $myWebMenu['menu_code'] = $checkMenuMapping['menu_code']; + } else { + $myWebMenu['is_selected'] = false; + $myWebMenu['order_number_mapping'] = null; + $myWebMenu['order_number'] = $menuIndex; + + } + $menuIndex++; + $responseMenus[] = $myWebMenu; + } + $myWebMenus = $responseMenus; + + $myWebLanguageMapping = $this->propertyWebLanguageMappingService->getPropertyWebLanguageMapping($myWebMenuMappingRequest); + + if ($myWebLanguageMapping['status'] != 'success') { + throw new ApiErrorException($myWebLanguageMapping['message']); + } + + $myWebLanguageMapping = collect($myWebLanguageMapping['data']['property_web_language_mapping'])->keyBy('language_code')->toArray(); + + $myWebColorMapping = $this->propertyWebColorMappingService->getPropertyWebColorMapping($myWebMenuMappingRequest); + + if ($myWebColorMapping['status'] != 'success') { + throw new ApiErrorException($myWebColorMapping['message']); + } + + $myWebColors = []; + if ($myWebColorMapping['data']['property_web_color_mapping']) { + $myWebColorMapping = $myWebColorMapping['data']['property_web_color_mapping']; + + foreach ($myWebColorMapping as $key => $myWebColorMappingData) { + $myWebColors[$key]['color_number'] = $myWebColorMappingData['order_number']; + $myWebColors[$key]['color_code'] = $myWebColorMappingData['color_code']; + } + } else { + + $brandParam = [ + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $propertyBrand = $this->propertyBrandService->getPropertyBrand($brandParam); + if ($propertyBrand['status'] != 'success') { + throw new ApiErrorException($propertyBrand['message']); + } + $myWebColors = collect($propertyBrand['data']['color_codes'])->take(3)->toArray(); + } + + $propertyWebAboutUsParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'property_web_id' => fillOnUndefined($params, 'property_web_id'), + 'mode' => 1, // live + ]; + $propertyWebAboutUs = $this->propertyWebAboutUsService->getPropertyWebAboutUs($propertyWebAboutUsParams); + + if ($propertyWebAboutUs['status'] != 'success') { + throw new ApiErrorException($propertyWebAboutUs['message']); + } + + $languages = $languages['data']; + + $propertyWebColors = $myWebColors ? $myWebColors : []; + + + foreach ($languages as &$language) { + if (array_key_exists($language['code'], $myWebLanguageMapping)) { + $language['is_selected'] = true; + } else { + $language['is_selected'] = false; + } + } + + $propertyWeb = $propertyWeb['data']; + $webData = [ + 'live_url' => Config::get('app.mainHostAddress') . '/live/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + 'preview_url' => Config::get('app.mainHostAddress') . '/preview/' . $propertyWeb['token'] . '/' . $propertyWeb['default_language'], + ]; + $propertyWeb = array_merge($propertyWeb, $webData); + + $propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params); + if ($propertyAdditionalInfo['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + + $propertyRequest = [ + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + $property = $this->propertyService->getProperty($propertyRequest); + + if ($property['status'] != 'success') { + throw new ApiErrorException('api-unknown-error'); + } + + $propertyData = $property['data'] ? $property['data'] : []; + + $propertyCountryCode = $propertyData['get_property']['property_info']['country']; + + + $myWebContactEmail = isset($propertyAdditionalInfo['data']['myweb_contact_email']) ? $propertyAdditionalInfo['data']['myweb_contact_email'] : null; + $kvkkMersisNo = isset($propertyAdditionalInfo['data']['kvkk_mersis_no']) ? $propertyAdditionalInfo['data']['kvkk_mersis_no'] : null; + $kvkkDataController = isset($propertyAdditionalInfo['data']['kvkk_data_controller']) ? $propertyAdditionalInfo['data']['kvkk_data_controller'] : null; + $kvkkContactPerson = isset($propertyAdditionalInfo['data']['kvkk_contact_person']) ? $propertyAdditionalInfo['data']['kvkk_contact_person'] : null; + $kvkkAddress = isset($propertyAdditionalInfo['data']['kvkk_address']) ? $propertyAdditionalInfo['data']['kvkk_address'] : null; + $kvkkPhone = isset($propertyAdditionalInfo['data']['kvkk_phone']) ? $propertyAdditionalInfo['data']['kvkk_phone'] : null; + $kvkkTaxOffice = isset($propertyAdditionalInfo['data']['kvkk_tax_office']) ? $propertyAdditionalInfo['data']['kvkk_tax_office'] : null; + $kvkkTaxNumber = isset($propertyAdditionalInfo['data']['kvkk_tax_number']) ? $propertyAdditionalInfo['data']['kvkk_tax_number'] : null; + $kvkkEmail = isset($propertyAdditionalInfo['data']['kvkk_email']) ? $propertyAdditionalInfo['data']['kvkk_email'] : null; + $kvkkWebSite = isset($propertyAdditionalInfo['data']['kvkk_web_site']) ? $propertyAdditionalInfo['data']['kvkk_web_site'] : null; + $kvkkContactEmail = isset($propertyAdditionalInfo['data']['kvkk_contact_email']) ? $propertyAdditionalInfo['data']['kvkk_contact_email'] : null; + $kvkkContactAddress = isset($propertyAdditionalInfo['data']['kvkk_contact_address']) ? $propertyAdditionalInfo['data']['kvkk_contact_address'] : null; + + $propertyWeb['languages'] = $languages; + + $propertyWeb['colors'] = $propertyWebColors; + + $propertyWeb['property_country_code'] = $propertyCountryCode; + + $propertyWeb['menus'] = $myWebMenus; + + $propertyWeb['property_web_photos'] = $propertyWebPhotos['data']; + + $propertyWeb['property_web_about_us'] = $propertyWebAboutUs['data']; + $propertyWeb['additional_info']['myweb_contact_email'] = $myWebContactEmail; + $propertyWeb['additional_info']['kvkk_mersis_no'] = $kvkkMersisNo; + $propertyWeb['additional_info']['kvkk_data_controller'] = $kvkkDataController; + $propertyWeb['additional_info']['kvkk_contact_person'] = $kvkkContactPerson; + $propertyWeb['additional_info']['kvkk_address'] = $kvkkAddress; + $propertyWeb['additional_info']['kvkk_phone'] = $kvkkPhone; + $propertyWeb['additional_info']['kvkk_tax_office'] = $kvkkTaxOffice; + $propertyWeb['additional_info']['kvkk_tax_number'] = $kvkkTaxNumber; + $propertyWeb['additional_info']['kvkk_email'] = $kvkkEmail; + $propertyWeb['additional_info']['kvkk_web_site'] = $kvkkWebSite; + $propertyWeb['additional_info']['kvkk_contact_email'] = $kvkkContactEmail; + $propertyWeb['additional_info']['kvkk_contact_address'] = $kvkkContactAddress; + + + $propertyRooms = []; + $getPropertyRoomCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'with' => ['propertyRoomType', 'propertyWebRoomMapping'], + ]; + + $getPropertyRoom = $this->propertyRoomService->select($getPropertyRoomCriteria); + + if ($getPropertyRoom['status'] == 'success') { + $getPropertyRoom = $getPropertyRoom['data']; + foreach ($getPropertyRoom as $propertyRoom) { + $propertyRooms[] = [ + 'id' => $propertyRoom['id'], + 'name' => $propertyRoom['name'], + 'type' => $propertyRoom['property_room_type']['language_key'], + 'is_selected' => !empty($propertyRoom['property_web_room_mapping']) ? true : false + + ]; + } + } + + $propertyWeb['rooms'] = $propertyRooms; + + + $propertyPlaces = []; + $getPropertyPlaceCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'ASC'] + ], + 'with' => ['propertyPlaceCategory', 'propertyWebPlaceMapping'], + ]; + + $getPropertyPlace = $this->propertyPlaceService->select($getPropertyPlaceCriteria); + + if ($getPropertyPlace['status'] == 'success') { + $getPropertyPlace = $getPropertyPlace['data']; + foreach ($getPropertyPlace as $propertyPlace) { + $propertyPlaces[] = [ + 'id' => $propertyPlace['id'], + 'name' => $propertyPlace['name'], + 'type' => $propertyPlace['property_place_category']['language_key'], + 'is_selected' => !empty($propertyPlace['property_web_place_mapping']) ? true : false + + ]; + } + } + + $propertyWeb['places'] = $propertyPlaces; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWeb]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function updatePropertyWebContent(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $params['user_id'] = $this->request->auth->id; + $updateWeb = $this->propertyWebService->updatePropertyWebContent($params); + if ($updateWeb['status'] != 'success') { + throw new ApiErrorException($updateWeb['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function setPublishWeb(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $request->params; + $params['user_id'] = $this->request->auth->id; + $updateWeb = $this->propertyWebService->setPublishWeb($params); + if ($updateWeb['status'] != 'success') { + throw new ApiErrorException($updateWeb['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $updateWeb['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyWebMeta(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $request->params ?? []; + $result = $this->propertyWebMetaService->select($params, ['id', 'name', 'status']); + + if ($result['status'] != 'success') { + throw new ApiErrorException($result['message']); + } + + foreach ($result['data'] as $key => $datum) { + + $dataArray = null; + + if ($datum['name'] == 'ContentDetail') { + + $propertyWebContentCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + $propertyWebContent = $this->propertyWebContentService->select($propertyWebContentCriteria, ['id', 'title']); + $propertyWebContent = ($propertyWebContent['status'] == 'success' && !empty($propertyWebContent['data'])) ? array_values($propertyWebContent['data']) : []; + foreach ($propertyWebContent as $propertyWebContentData) { + $dataArray[] = [ + 'code' => $propertyWebContentData['id'], + 'name' => $propertyWebContentData['title'], + ]; + } + + } + + if ($datum['name'] == 'PlaceDetail') { + + $propertyPlacetCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + $propertyPlaces = $this->propertyPlaceService->select($propertyPlacetCriteria, ['id', 'name', 'language_name']); + $propertyPlaces = ($propertyPlaces['status'] == 'success' && !empty($propertyPlaces['data'])) ? array_values($propertyPlaces['data']) : []; + + foreach ($propertyPlaces as $propertyPlacesData) { + $dataArray[] = [ + 'code' => $propertyPlacesData['id'], + 'name' => $propertyPlacesData['name'], + ]; + } + + } + + if ($datum['name'] == 'RoomDetail') { + + $propertyRoomtCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1] + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + $propertyRooms = $this->propertyRoomService->select($propertyRoomtCriteria, ['id', 'name']); + $propertyRooms = ($propertyRooms['status'] == 'success' && !empty($propertyRooms['data'])) ? array_values($propertyRooms['data']) : []; + + foreach ($propertyRooms as $propertyRoomsData) { + $dataArray[] = [ + 'code' => $propertyRoomsData['id'], + 'name' => $propertyRoomsData['name'], + ]; + } + + } + + $result['data'][$key]['detail'] = $dataArray; + + } + + + //dd($result); + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $result['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function getPropertyWebMetaTag(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $request->params ?? []; + $result = $this->propertyWebMetaService->selectTag($params, ['id', 'name', 'status']); + + if ($result['status'] != 'success') { + throw new ApiErrorException($result['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $result['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function syncPropertyWebMetaTag(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $request->params ?? []; + $params['user_id'] = $this->request->auth->id; + $result = $this->propertyWebMetaService->syncTag($params); + + if ($result['status'] != 'success') { + throw new ApiErrorException($result['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => $result['message'], 'data' => $result['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + public function listPropertyWebMetaTagMapping(Request $request) + { + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + $params = $request->params ?? []; + $result = $this->propertyWebMetaService->selectMapping($params); + + if ($result['status'] != 'success') { + throw new ApiErrorException($result['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $result['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + + public function dashboardCountablePlace($params, $propertyWebId) + { + + $response = ["status" => false, "data" => null, "message" => ""]; + + try { + + $propertyWebLog = DB::select(" + SELECT property_web_log.country_code 'country_code', ip_nation_countries.country 'country', property_web_log.device_type 'device_type', count(property_web_log.id) 'count' + FROM property_web_log + INNER JOIN ip_nation_countries ON ip_nation_countries.code = property_web_log.country_code + WHERE property_web_log.web_id = $propertyWebId AND property_web_log.status = 1 GROUP BY property_web_log.country_code,ip_nation_countries.country, property_web_log.device_type; + "); + + $propertyWebLog = json_decode(json_encode($propertyWebLog), true); + + + $bookingCount = $this->bookingService->getBookingListCount(['property_id' => fillOnUndefined($params, 'property_id'), 'channel_id' => 1]); + + if ($bookingCount['status'] != 'success') { + throw new ApiErrorException($bookingCount['message']); + } + + $countryGroups = collect($propertyWebLog)->groupBy('country_code')->toArray(); + + $countyGroupCount = []; + foreach ($countryGroups as $countryGroupKey => $countryGroup) { + foreach ($countryGroup as $key => $groupData) { + + if (!isset($countyGroupCount[$countryGroupKey]['value'])) { + $countyGroupCount[$countryGroupKey]['value'] = 0; + } + + $countyGroupCount[$countryGroupKey]['value'] += $groupData['count']; + $countyGroupCount[$countryGroupKey]['country'] = $groupData['country_code']; + $countyGroupCount[$countryGroupKey]['country_name'] = $groupData['country']; + } + } + + array_multisort(array_column($countyGroupCount, 'value'), SORT_DESC, + $countyGroupCount + ); + + $activeUser = DB::select("SELECT count(id) 'count' FROM property_web_log + WHERE web_id = $propertyWebId AND created_at > " . Carbon::now()->subMinutes(self::WEB_ACTIVE_USER_MINUTE)->timestamp); + + $activeUser = json_decode(json_encode($activeUser), true); + $activeUser = reset($activeUser); + + + $response['data'] = [ + 'web_count' => collect($propertyWebLog)->where('device_type', 'web')->sum('count'), + 'mobile_count' => collect($propertyWebLog)->where('device_type', 'mobile')->sum('count'), + 'active_user_count' => $activeUser['count'], + 'booking_count' => $bookingCount['data'], + 'country_count' => collect($countyGroupCount)->values()->toArray(), + ]; + + $response['status'] = true; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['status'] = false; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = "Raw Query Error"; + $response['status'] = false; + } + + return $response; + } + + private function getTypeMenus($menuType, $menuTypeKey) + { + + $webMenuTypes = collect($menuType)->groupBy('type')->toArray(); + + $allData = []; + $allData[$menuTypeKey] = []; + foreach ($webMenuTypes as $webMenuTypeKey => $webMenuType) { + + if ($webMenuTypeKey === self::PLACE) { + + $placesIds = collect($webMenuTypes[$webMenuTypeKey])->pluck('property_web_menu_id')->toArray(); + + $checkPropertyMappingRequest = [ + 'criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]], + "whereIn" => [["field" => "id", "value" => $placesIds]] + ]; + $propertyPlaces = $this->propertyPlaceService->select($checkPropertyMappingRequest, ['id', 'name', 'order_number', 'language_name']); + + if ($propertyPlaces['status'] != 'success') { + throw new ApiErrorException('Have a problem in Get Property Place '); + } + + $myWebMenuMapping = collect($webMenuTypes[$webMenuTypeKey])->keyBy('property_web_menu_id')->toArray(); + + foreach ($propertyPlaces['data'] as $propertyPlace) { + + $propertyPlace['order_number'] = $myWebMenuMapping[$propertyPlace['id']]['order_number']; + $propertyPlace['type'] = $myWebMenuMapping[$propertyPlace['id']]['type']; + $propertyPlace['menu_code'] = $myWebMenuMapping[$propertyPlace['id']]['menu_code']; + $propertyPlace['route'] = '/place/' . Str::slug($propertyPlace['name'], $separator = '-', $language = 'en') . '-' . $propertyPlace['id']; + $alias = $myWebMenuMapping[$propertyPlace['id']]['type'] . '-' . $propertyPlace['id']; + $propertyPlace['alias'] = $alias; + $propertyPlace['name'] = $this->appearanceTitle($menuTypeKey, $propertyPlace['name']); + $allData[$menuTypeKey][] = $propertyPlace; + } + + } elseif ($webMenuTypeKey === self::MAIN) { + + $myWebMenus = $this->propertyWebMenuService->getPropertyWebMenu(); + $webMenus = $myWebMenus['data']['property_web_menus']; + $webMenuLevelIds = collect($webMenuTypes[$webMenuTypeKey])->keyBy('property_web_menu_id')->toArray(); + foreach ($webMenus as $webMenu) { + if (isset($webMenuLevelIds[$webMenu['id']])) { + $webMenu['order_number'] = $webMenuLevelIds[$webMenu['id']]['order_number']; + $webMenu['name'] = $this->appearanceTitle($menuTypeKey, $webMenu['name']); + $allData[$menuTypeKey][] = $webMenu; + } + } + + } elseif ($webMenuTypeKey === self::PLACE_CATEGORY) { + + $placesIds = collect($webMenuTypes[$webMenuTypeKey])->pluck('property_web_menu_id')->toArray(); + $checkPropertyMappingRequest = [ + 'criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]], + "whereIn" => [["field" => "id", "value" => $placesIds]] + ]; + $propertyPlaceCategories = $this->propertyPlaceService->propertyPlaceCategories($checkPropertyMappingRequest, ['id', 'name', 'language_key', 'order_number']); + + if ($propertyPlaceCategories['status'] != 'success') { + throw new ApiErrorException('Have a problem in Get Property Place Category '); + } + + $myWebMenuMapping = collect($webMenuTypes[$webMenuTypeKey])->keyBy('property_web_menu_id')->toArray(); + + foreach ($propertyPlaceCategories['data'] as $propertyPlaceCategory) { + + $propertyPlaceCategory['order_number'] = $myWebMenuMapping[$propertyPlaceCategory['id']]['order_number']; + $propertyPlaceCategory['type'] = $myWebMenuMapping[$propertyPlaceCategory['id']]['type']; + $propertyPlaceCategory['menu_code'] = $myWebMenuMapping[$propertyPlaceCategory['id']]['menu_code']; + $propertyPlaceCategory['route'] = '/place-category/' . Str::slug($propertyPlaceCategory['name'], $separator = '-', $language = 'en') . '-' . $propertyPlaceCategory['id']; + $alias = $myWebMenuMapping[$propertyPlaceCategory['id']]['type'] . '-' . $propertyPlaceCategory['id']; + $propertyPlaceCategory['alias'] = $alias; + $propertyPlaceCategory['name'] = $this->appearanceTitle($menuTypeKey, $propertyPlaceCategory['name']); + $allData[$menuTypeKey][] = $propertyPlaceCategory; + } + } + + $allData[$menuTypeKey] = collect($allData[$menuTypeKey])->sortBy('order_number')->keyBy('alias')->toArray(); + } + + return $allData; + } + + private function appearanceTitle($type, $title) + { + if ($type === self::MENU_CODE_LVL1) { + $title = Str::upper($title); + } elseif ($type === self::MENU_CODE_TOP) { + $title = Str::title($title); + } + return $title; + } + + public function coverPhotos($params = []) + { + + $propertyWebPhotoMappingRequest = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')], + ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')], + ['field' => 'is_cover', 'condition' => '=', 'value' => 1], + ['field' => 'status', 'condition' => '=', 'value' => $params['mode'] == 'preview' ? 2 : 1], + ], + 'with' => ['propertyPhoto'] + ]; + $propertyWebMappingPhotos = $this->propertyWebService->selectPropertyWebPhotos($propertyWebPhotoMappingRequest); + $propertyWebMappingPhotos = $propertyWebMappingPhotos['status'] == 'success' && !empty($propertyWebMappingPhotos['status']) ? $propertyWebMappingPhotos['data'] : []; + + $coverPhotos = []; + + foreach ($propertyWebMappingPhotos as $key => $photo) { + $photoUrlFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_1024x768.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_medium.' . $photo['property_photo']['file_ext']; + } + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_200x200.' . $photo['property_photo']['file_ext']; + } else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '_thumbnail.' . $photo['property_photo']['file_ext']; + } + $coverPhotos[$key]['default'] = Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' . $photo['property_photo']['photo_name'] . '.' . $photo['property_photo']['file_ext']; + $coverPhotos[$key]['fixed'] = $photoUrlFilePath; + $coverPhotos[$key]['thumb'] = $photoUrlThumbFilePath; + } + + return $coverPhotos; + + } + + public function propertyComparison(Request $request, $weekKey, $userId = null) + { + + $daysCount = [1, 15, 45, 90]; + $comparisonChannels = ['BookingEngine', 'Agoda.com', 'etstur.com', 'Booking.com']; + + $response = ['status' => false, 'message' => '', 'data' => null]; + + try { + + $userDetail = null; + $propertyPriceComparison = PropertyPriceComparison::where('week_key', $weekKey)->with('propertyDetail.propertyContractUser')->orderBy('property_id')->get(); + $propertyPriceComparison = $propertyPriceComparison ? $propertyPriceComparison->toArray() : []; + + + if (!empty($userId)) { + $propertyPriceComparison = collect($propertyPriceComparison)->where('property_detail.property_contract_user.id', $userId)->toArray(); + $userDetail = isset(reset($propertyPriceComparison)['property_detail']['property_contract_user']) ? reset($propertyPriceComparison)['property_detail']['property_contract_user'] : null; + } + + $response = [ + 'status' => true + ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + } + + if (!is_null($userId)) { + $pdf = $this->pdf + ->setOptions(['isRemoteEnabled' => false, 'isHtml5ParserEnabled' => true, 'isFontSubsettingEnabled' => true]) + //->setPaper('A4', 'landscape') + ->loadView('pdf.priceComparison', + compact('response', 'daysCount', 'comparisonChannels', 'propertyPriceComparison', 'userDetail'), + [], 'UTF8'); + + return $pdf->stream(); + + } + + + return view('pdf.priceComparison', compact('response', 'daysCount', 'comparisonChannels', 'propertyPriceComparison', 'userDetail')); + + } + +} diff --git a/app/Http/Controllers/V1/PropertyWebPopupController.php b/app/Http/Controllers/V1/PropertyWebPopupController.php new file mode 100644 index 0000000..f3ec515 --- /dev/null +++ b/app/Http/Controllers/V1/PropertyWebPopupController.php @@ -0,0 +1,255 @@ +request = $request; + $this->propertyWebPopupService = $propertyWebPopupService; + } + + public function getPropertyWebPopup(Request $request, $id = null) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $columns = ['id', 'property_id', 'title', 'language_code', 'start_date', 'end_date', 'url', 'image', 'status', 'created_at']; + $criteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']], + ], + 'orderBy' => [ + ['field' => 'id', 'value' => 'DESC'] + ] + ]; + + $availableFilterArray = ['title', 'language_code']; + if (!empty($params['filter'])) { + foreach ($params['filter'] as $filterKey => $filterValue) { + if (in_array($filterKey, $availableFilterArray)) { + if (in_array($filterKey, ['language_code', 'status'])) { + $criteria['criteria'][] = ['field' => $filterKey, 'condition' => '=', 'value' => $filterValue]; + } + + if (in_array($filterKey, ['title'])) { + $criteria['criteria'][] = ['field' => $filterKey, 'condition' => 'LIKE', 'value' => '%' . $filterValue . '%']; + } + + } + } + } + + if (!empty($id)) { + $criteria['criteria'][] = ['field' => 'id', 'condition' => '=', 'value' => $id]; + $criteria['firstRow'] = true; + } + + + $propertyWebPopup = $this->propertyWebPopupService->select($criteria, $columns); + + if ($propertyWebPopup['status'] != 'success') { + throw new Exception($propertyWebPopup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebPopup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function createPropertyWebPopup(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'title' => fillOnUndefined($params, 'title'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'image' => fillOnUndefined($params, 'image'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'url' => fillOnUndefined($params, 'url'), + 'user_id' => $this->request->credentials->user_id + ]; + + + $propertyWebPopup = $this->propertyWebPopupService->create($requestParams); + + if ($propertyWebPopup['status'] != 'success') { + throw new ApiErrorException($propertyWebPopup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebPopup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function updatePropertyWebPopup(Request $request, $id) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'title' => fillOnUndefined($params, 'title'), + 'language_code' => fillOnUndefined($params, 'language_code'), + 'image' => fillOnUndefined($params, 'image'), + 'start_date' => fillOnUndefined($params, 'start_date'), + 'end_date' => fillOnUndefined($params, 'end_date'), + 'url' => fillOnUndefined($params, 'url'), + 'updated_by' => $this->request->credentials->user_id + ]; + + $propertyWebPopup = $this->propertyWebPopupService->update($id, $requestParams); + + if ($propertyWebPopup['status'] != 'success') { + throw new ApiErrorException($propertyWebPopup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebPopup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function deletePropertyWebPopup(Request $request, $id) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + try { + + if (is_null($this->request->getContent())) { + throw new ApiErrorException(lang('Parameter Error.')); + } + + $params = $this->request->params; + + $requestParams = [ + 'id' => $id, + 'property_id' => fillOnUndefined($params, 'property_id') + ]; + + $propertyWebPopup = $this->propertyWebPopupService->delete($id, $requestParams); + + if ($propertyWebPopup['status'] != 'success') { + throw new ApiErrorException($propertyWebPopup['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyWebPopup['data']]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + + } + + public function uploadPropertyWebPopupImage(Request $request) + { + $response = ['status' => false, 'statusCode' => 500, 'message' => '', 'data' => null]; + try { + if (!$request->hasFile('image')) { + throw new ApiErrorException(lang('Photos not found')); + } + + $param = [ + "property_id" => $request->input('property_id'), + "photo" => $request->file('image'), + ]; + + $response = $this->propertyWebPopupService->uploadPhoto($param); + + } catch (ApiErrorException $e) { + $response['message'] = $e->getMessage(); + + } catch (Exception $e) { + $message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage(); + Log::error($message); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + } + + +} diff --git a/app/Http/Controllers/V1/ReputationManagementController.php b/app/Http/Controllers/V1/ReputationManagementController.php new file mode 100644 index 0000000..723015f --- /dev/null +++ b/app/Http/Controllers/V1/ReputationManagementController.php @@ -0,0 +1,570 @@ +params = Input::all(); + $this->params = $this->params['params']; + + $this->reputationManagementService = $reputationManagementService; + } + + + public function getChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + $criteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $reputationManagementChannel = $this->reputationManagementService->selectChannel($criteria, ['id', 'name', 'logo', 'parameter', 'logo']); + $reputationManagementChannel = $reputationManagementChannel['status'] == 'success' && !empty($reputationManagementChannel['data']) ? $reputationManagementChannel['data'] : []; + + + $reputationManagementMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['fetchStatus'], + ]; + + $reputationManagementMapping = $this->reputationManagementService->selectChannelMapping($reputationManagementMappingCriteria); + $reputationManagementMapping = $reputationManagementMapping['status'] == 'success' && !empty($reputationManagementMapping['data']) ? $reputationManagementMapping['data'] : []; + $reputationManagementMappingCollect = collect($reputationManagementMapping); + + + $reputationManagementList = []; + foreach ($reputationManagementChannel as $reputationManagementChannelKey => $reputationManagementChannel) { + + $reputationManagementMapping = $reputationManagementMappingCollect->where('channel_id', $reputationManagementChannel['id'])->first(); + + + $reputationManagementDetail = null; + $isSelected = $reputationManagementMapping ? true : false; + + if ($reputationManagementMapping) { + $reputationManagementDetail = [ + 'fetchStatus' => $reputationManagementMapping['fetch_status'], + 'parameterArray' => $reputationManagementMapping['parameterArray'] + ]; + } + + $reputationManagementList[] = [ + //'code' => $webComponent['code'], + 'id' => $reputationManagementChannel['id'], + 'name' => $reputationManagementChannel['name'], + 'logo' => $reputationManagementChannel['logo'], + 'logoUrl' => $reputationManagementChannel['logoUrl'], + 'parameterArray' => $reputationManagementChannel['parameterArray'], + 'is_selected' => $isSelected, + 'channelDetail' => $reputationManagementDetail + ]; + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $reputationManagementList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function syncChannel(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + + $criteria = [ + 'criteria' => [ + ['field' => 'id', 'condition' => '=', 'value' => $this->params['channel_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $reputationManagementChannel = $this->reputationManagementService->selectChannel($criteria, ['id', 'name', 'logo', 'parameter', 'logo']); + $reputationManagementChannel = $reputationManagementChannel['status'] == 'success' && !empty($reputationManagementChannel['data']) ? $reputationManagementChannel['data'] : []; + + if (empty($reputationManagementChannel)) { + throw new ApiErrorException(lang('Channel data not found')); + } + + //Parameter Check + if (!empty($this->params['channelDetail'])) { + $parameterCheck = array_diff(array_keys($reputationManagementChannel['parameterArray']), array_keys($this->params['channelDetail']['parameter'])); + if (!empty($parameterCheck)) { + throw new ApiErrorException(lang('Missing or incorrect parameter')); + } + } + + + $reputationManagementChannelMappingCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'property_id')], + ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'channel_id')], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => true + ]; + + $reputationManagementChannelMapping = $this->reputationManagementService->selectChannelMapping($reputationManagementChannelMappingCriteria); + $reputationManagementChannelMapping = $reputationManagementChannelMapping['status'] == 'success' && !empty($reputationManagementChannelMapping['data']) ? $reputationManagementChannelMapping['data'] : []; + + //Parameter Check + + + DB::beginTransaction(); + + if ($reputationManagementChannelMapping) { + + + //Remove + if (empty($this->params['channelDetail'])) { + + $syncReputationManagementChannelMapping = $this->reputationManagementService->deleteChannelMapping($reputationManagementChannelMapping['id']); + if ($syncReputationManagementChannelMapping['status'] != 'success') { + throw new Exception('api-unknown_error'); + } + + } else { + + //Update + $updateParam = [ + 'property_id' => fillOnUndefined($this->params, 'property_id'), + 'channel_id' => fillOnUndefined($this->params, 'channel_id'), + 'parameter' => fillOnUndefined($this->params['channelDetail'], 'parameter') ? json_encode($this->params['channelDetail']['parameter']) : null, + 'fetch_status' => fillOnUndefined($reputationManagementChannelMapping, 'fetch_status'), + 'updated_by' => $request->auth->id, + ]; + + $syncReputationManagementChannelMapping = $this->reputationManagementService->updateChannelMapping($reputationManagementChannelMapping['id'], $updateParam); + + if ($syncReputationManagementChannelMapping['status'] != 'success') { + throw new ApiErrorException($syncReputationManagementChannelMapping['message']); + } + + } + + } else { + + $createParam = [ + 'property_id' => fillOnUndefined($this->params, 'property_id'), + 'channel_id' => fillOnUndefined($this->params, 'channel_id'), + 'parameter' => fillOnUndefined($this->params['channelDetail'], 'parameter') ? json_encode($this->params['channelDetail']['parameter']) : null, + 'fetch_status' => 3, + 'status' => 1, + 'created_by' => $request->auth->id, + ]; + + $syncReputationManagementChannelMapping = $this->reputationManagementService->createChannelMapping($createParam); + + if ($syncReputationManagementChannelMapping['status'] != 'success') { + throw new ApiErrorException($syncReputationManagementChannelMapping['message']); + } + + //First Fetch Review + dispatch(new PropertyReviewServiceJob($createParam['property_id'], $createParam['channel_id'])); + + } + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + if ($response['status']) { + DB::commit(); + } else { + DB::rollBack(); + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getReview(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + + $propertyReviewCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'channel', 'categoryMapping.category'], + 'orderBy' => [ + ['field' => 'review_date', 'value' => 'DESC'] + ], + ]; + + + if (isset($this->params['filter']) && !empty(isset($this->params['filter']))) { + + if (isset($this->params['filter']['channel_id'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['filter']['channel_id']]; + } + + if (isset($this->params['filter']['start_date'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => $this->params['filter']['start_date']]; + } + + if (isset($this->params['filter']['end_date'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '<=', 'value' => $this->params['filter']['end_date']]; + } + + if (isset($this->params['filter']['sentiment'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'sentiment', 'condition' => '=', 'value' => $this->params['filter']['sentiment']]; + } + + + if (isset($this->params['filter']['keyword'])) { + $propertyReviewCriteria['whereOr'][] = ['field' => 'author', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; + $propertyReviewCriteria['whereOr'][] = ['field' => 'title', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; + $propertyReviewCriteria['whereOr'][] = ['field' => 'review', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; + } + + + } + + //Just Last 1 Year + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => Carbon::now()->subYear()->toDateString()]; + + + $propertyReviewCriteriaCount = $propertyReviewCriteria; + $propertyReviewCriteriaCount['count'] = true; + $propertyReviewCount = $this->reputationManagementService->select($propertyReviewCriteriaCount, ['id']); + + + $propertyReviewCriteria['skip'] = fillOnUndefined($this->params, 'page', 0) ? ($this->params['page'] - 1) : 0; + $propertyReviewCriteria['take'] = fillOnUndefined($this->params, 'per_page', 20); + $propertyReviewCriteria['skip'] = $propertyReviewCriteria['skip'] * $propertyReviewCriteria['take']; + + $column = ['id', 'property_id', 'channel_id', 'author', 'title', 'review', 'review_date', 'rating', 'top_rating', 'score', 'sentiment', 'language']; + $propertyReview = $this->reputationManagementService->select($propertyReviewCriteria, $column); + $propertyReview = $propertyReview['status'] == 'success' && !empty($propertyReview['data']) ? $propertyReview['data'] : []; + + + $propertyReviewList = [ + 'total' => $propertyReviewCount['data'], + 'page' => $this->params['page'], + 'count' => count($propertyReview), + 'review' => $propertyReview + ]; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyReviewList]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + public function getReviewStatistics(Request $request) + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; + + try { + + + $propertyReviewCriteria = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel', 'channel', 'categoryMapping.category', 'keywordMapping'], + 'orderBy' => [ + ['field' => 'review_date', 'value' => 'DESC'] + ], + ]; + + if (isset($this->params['filter']) && !empty(isset($this->params['filter']))) { + + if (isset($this->params['filter']['channel_id'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['filter']['channel_id']]; + } + + if (isset($this->params['filter']['start_date'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => $this->params['filter']['start_date']]; + } + + if (isset($this->params['filter']['end_date'])) { + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '<=', 'value' => $this->params['filter']['end_date']]; + } + + } + + //Just Last 1 Year + $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => Carbon::now()->subYear()->toDateString()]; + + + $column = ['id', 'property_id', 'channel_id', 'review_date', 'rating', 'top_rating', 'score', 'sentiment', 'language']; + $propertyReview = $this->reputationManagementService->select($propertyReviewCriteria, $column); + $propertyReview = $propertyReview['status'] == 'success' && !empty($propertyReview['data']) ? $propertyReview['data'] : []; + + + $propertyReviewStatistics['reviewScore'] = collect($propertyReview)->average('score'); + $propertyReviewStatistics['reviewScore'] = (float)number_format($propertyReviewStatistics['reviewScore'], 2, '.', ''); + + + $reviewSentimentGroup = collect($propertyReview)->groupBy('sentiment')->map->count(); + $reviewSentimentGroup = $reviewSentimentGroup ? $reviewSentimentGroup->toArray() : null; + + $reviewSentiment['positive'] = isset($reviewSentimentGroup[1]) ? $reviewSentimentGroup[1] : 0; + $reviewSentiment['negative'] = isset($reviewSentimentGroup[0]) ? $reviewSentimentGroup[0] : 0; + + $propertyReviewStatistics['reviewScoreBySystem'] = null; + if (($reviewSentiment['positive'] + $reviewSentiment['negative']) > 0) { + $propertyReviewStatistics['reviewScoreBySystem'] = $reviewSentiment['positive'] / ($reviewSentiment['positive'] + $reviewSentiment['negative']) * 100; + $propertyReviewStatistics['reviewScoreBySystem'] = (float)number_format($propertyReviewStatistics['reviewScoreBySystem'], 2, '.', ''); + } + + + //$reviewCategoryScoreBySystem + $reviewCategoryMapping = []; + $reviewCategoryScoreBySystem = []; + $reviewKeywordScoreBySystem = []; + foreach ($propertyReview as $review) { + + foreach ($review['category_mapping'] as $reviewCategory) { + if (!isset($reviewCategoryScoreBySystem[$reviewCategory['category_id']])) { + $reviewCategoryScoreBySystem[$reviewCategory['category_id']][0] = 0; + $reviewCategoryScoreBySystem[$reviewCategory['category_id']][1] = 0; + } + $reviewCategoryScoreBySystem[$reviewCategory['category_id']][$reviewCategory['sentiment']]++; + + $reviewCategoryMapping[$reviewCategory['category_id']]['name'] = $reviewCategory['category']['name']; + $reviewCategoryMapping[$reviewCategory['category_id']]['score'][$review['review_date']] = $review['score']; + + if (!isset($reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')])) { + $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][0] = 0; + $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][1] = 0; + } + + $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][$reviewCategory['sentiment']]++; + + } + + foreach ($review['keyword_mapping'] as $reviewKeyword) { + if (!isset($reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])])) { + $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['positive'] = 0; + $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['negative'] = 0; + $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['keyword'] = $reviewKeyword['keyword']; + } + + if ($reviewKeyword['sentiment'] == 1) { + $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['positive']++; + } elseif ($reviewKeyword['sentiment'] == 0) { + $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['negative']++; + } + + } + } + + + $propertyReviewCategoryCriteria = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ] + ]; + + $propertyReviewCategory = $this->reputationManagementService->selectCategory($propertyReviewCategoryCriteria); + $propertyReviewCategory = $propertyReviewCategory['status'] == 'success' ? $propertyReviewCategory['data'] : []; + + $propertyReviewCategoryScore = []; + foreach ($propertyReviewCategory as $reviewCategory) { + if (empty($reviewCategoryScoreBySystem)) { + continue; + } + if (isset($reviewCategoryScoreBySystem[$reviewCategory['id']]) && array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]) < 5) { + continue; + } + $propertyReviewCategoryScore[$reviewCategory['id']] = [ + 'name' => $reviewCategory['name'], + 'language_key' => $reviewCategory['language_key'], + ]; + + $propertyReviewCategoryScore[$reviewCategory['id']]['score'] = null; + if (isset($reviewCategoryScoreBySystem[$reviewCategory['id']])) { + + $propertyReviewCategoryScore[$reviewCategory['id']]['score'] = (float)number_format($reviewCategoryScoreBySystem[$reviewCategory['id']][1] / array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]) * 100, 2, '.', ''); + $propertyReviewCategoryScore[$reviewCategory['id']]['positive'] = $reviewCategoryScoreBySystem[$reviewCategory['id']][1]; + $propertyReviewCategoryScore[$reviewCategory['id']]['negative'] = $reviewCategoryScoreBySystem[$reviewCategory['id']][0]; + $propertyReviewCategoryScore[$reviewCategory['id']]['total'] = array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]); + + + krsort($reviewCategoryMapping[$reviewCategory['id']]['score']); + $propertyReviewCategoryScore[$reviewCategory['id']]['scoreLastNumber'] = array_slice($reviewCategoryMapping[$reviewCategory['id']]['score'], 0, 10); + + //Group By Month + /*$propertyReviewCategoryGroupScore = []; + foreach ($reviewCategoryMapping[$reviewCategory['id']]['score'] as $reviewDateTime => $reviewScore) { + $propertyReviewCategoryGroupScore[Carbon::parse($reviewDateTime)->format('m-Y')][] = $reviewScore; + } + $propertyReviewCategoryGroupScoreAverage = []; + foreach ($propertyReviewCategoryGroupScore as $reviewPeriod => $reviewPeriodScore) { + $propertyReviewCategoryGroupScoreAverage[$reviewPeriod] = round(collect($reviewPeriodScore)->avg()); + }*/ + //Group By Month + + + //Group By Month + ksort($reviewCategoryMapping[$reviewCategory['id']]['sentimentScore']); + $propertyReviewCategoryGroupScoreAverage = []; + foreach ($reviewCategoryMapping[$reviewCategory['id']]['sentimentScore'] as $reviewPeriod => $reviewPeriodScore) { + $categorySentimentScore = (float)number_format($reviewPeriodScore[1] / array_sum($reviewPeriodScore) * 100, 2, '.', ''); + if ($categorySentimentScore <= 0) { + continue; + } + $propertyReviewCategoryGroupScoreAverage[$reviewPeriod] = round($categorySentimentScore); + } + //Group By Month + + $propertyReviewCategoryScore[$reviewCategory['id']]['scoreMonthlyGroup'] = $propertyReviewCategoryGroupScoreAverage; + $propertyReviewCategoryScore[$reviewCategory['id']]['scoreMonthlyGroupAverage'] = (float)number_format(collect($propertyReviewCategoryGroupScoreAverage)->average(), 2, '.', ''); + + } + + } + $propertyReviewStatistics['reviewCategoryScoreBySystem'] = array_values($propertyReviewCategoryScore); + //$reviewCategoryScoreBySystem + + + foreach ($reviewKeywordScoreBySystem as $reviewKeywordKey => $reviewKeyword) { + if (($reviewKeyword['positive'] + $reviewKeyword['negative']) < 3) { + unset($reviewKeywordScoreBySystem[$reviewKeywordKey]); + continue; + } + if (isset($reviewKeywordScoreBySystem[$reviewKeywordKey])) { + $reviewKeywordScoreBySystem[$reviewKeywordKey]['score'] = (float)number_format($reviewKeywordScoreBySystem[$reviewKeywordKey]['positive'] / array_sum($reviewKeywordScoreBySystem[$reviewKeywordKey]) * 100, 2, '.', ''); + } + } + + $propertyReviewStatistics['reviewKeywordScoreBySystem'] = array_values($reviewKeywordScoreBySystem); + + + //Dashboard Summary + $propertyReviewStatistics['dashboard'] = []; + $currentWeekStart = Carbon::now()->startOfWeek(Carbon::MONDAY)->toDateString(); + $currentWeekFinish = Carbon::now()->addWeek()->startOfWeek(Carbon::MONDAY)->toDateString(); + + //TOTAL + $totalReview = count($propertyReview); + $extraReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->count(); + $propertyReviewStatistics['dashboard'] ['total'] = [ + 'count' => $totalReview, + 'extraReviewCount' => $extraReviewCount + ]; + + //POSITIVE + $totalReviewPositive = collect($propertyReview)->where('sentiment', 1)->count(); + $extraPositiveReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->where('sentiment', 1)->count(); + $propertyReviewStatistics['dashboard'] ['positive'] = [ + 'count' => $totalReviewPositive, + 'extraReviewCount' => $extraPositiveReviewCount + ]; + + //NEGATIVE + $totalReviewNegative = collect($propertyReview)->where('sentiment', '!=', 1)->count(); + $extraNegativeReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->where('sentiment', '!=', 1)->count(); + $propertyReviewStatistics['dashboard'] ['negative'] = [ + 'count' => $totalReviewNegative, + 'extraReviewCount' => $extraNegativeReviewCount + ]; + + //BEST + $bestReview = collect($propertyReviewCategoryScore)->sortByDesc('positive')->first(); + $propertyReviewStatistics['dashboard'] ['best'] = [ + 'name' => $bestReview['name'], + 'language_key' => $bestReview['language_key'], + 'score' => $bestReview['score'], + 'positive' => $bestReview['positive'], + 'negative' => $bestReview['negative'], + 'total' => $bestReview['total'], + ]; + + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyReviewStatistics]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); + + } + + +} + diff --git a/app/Http/Controllers/V1/TempPropertyController.php b/app/Http/Controllers/V1/TempPropertyController.php new file mode 100644 index 0000000..2230efa --- /dev/null +++ b/app/Http/Controllers/V1/TempPropertyController.php @@ -0,0 +1,67 @@ +request = $request; + $this->tempPropertyService = $tempPropertyService ; + + } + + + public function getTempPropertyList() + { + + $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 400 ]; + try { + + if (is_null($this->request->getContent())) { + throw new Exception(lang('Parameter Error.')) ; + } + $tempPropertyListCriteria = $this->request->getContent(); + $tempPropertyListCriteria = json_decode($tempPropertyListCriteria,1); + $tempPropertyListCriteria = $tempPropertyListCriteria['params']; + + $temPropertyList = $this->tempPropertyService->search($tempPropertyListCriteria, fillOnUndefined($tempPropertyListCriteria, 'select', ['*'])); + if ($temPropertyList['status'] != 'success') { + throw new Exception($temPropertyList['message']); + } + + $response = ['status' => 1, 'statusCode' => 200, 'message' => null,'data' => $temPropertyList['data'] ]; + + } catch (ApiErrorException $e) { + $response['message'] = implode(', ', $e->getMessageArr()); + $response['statusCode'] = 400; + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error($message); + $response['message'] = $e->getMessage(); + $response['statusCode'] = 500; + } + return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);; + + } +} diff --git a/app/Http/Controllers/bulutController.backup.php b/app/Http/Controllers/bulutController.backup.php new file mode 100644 index 0000000..93e5c0f --- /dev/null +++ b/app/Http/Controllers/bulutController.backup.php @@ -0,0 +1,364 @@ + 15, + 'headers' => array( + 'x-rapidapi-host' => env('BULUT_RAPIDAPI_HOST'), + 'x-rapidapi-key' => env('BULUT_RAPIDAPI_KEY'), + ), + )); + } + + /** + * ADIM 1: Otel adına göre ara → hotel_id al + * GET /bulut/search?name=Grand Yavuz Hotel Istanbul + */ + public function search(Request $request) + { + $name = $request->query('name', ''); + + if (!$name) { + return response()->json(array('status' => false, 'message' => 'name parametresi gerekli'), 422); + } + + try { + $response = $this->client()->get( + 'https://' . env('BULUT_RAPIDAPI_HOST') . '/locations/auto-complete', + array('query' => array('text' => $name, 'languagecode' => 'en-us')) + ); + + $data = json_decode($response->getBody()->getContents(), true); + + return response()->json(array('status' => true, 'raw' => $data)); + } catch (Exception $e) { + Log::error('search error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + /** + * ADIM 2: Otel detayları + * GET /bulut/hotel-data?hotel_id=1234567&checkin=2026-06-01&checkout=2026-06-02 + */ + public function hotelData(Request $request) + { + $hotelId = $request->query('hotel_id'); + $checkin = $request->query('checkin'); + $checkout = $request->query('checkout'); + + if (!$hotelId) { + return response()->json(array('status' => false, 'message' => 'hotel_id gerekli'), 422); + } + + try { + $response = $this->client()->get( + 'https://' . env('BULUT_RAPIDAPI_HOST') . '/properties/detail', + array('query' => array( + 'hotel_id' => $hotelId, + 'arrival_date' => $checkin, + 'departure_date' => $checkout, + 'languagecode' => 'en-us', + 'currency_code' => 'USD', + )) + ); + + $data = json_decode($response->getBody()->getContents(), true); + return response()->json(array('status' => true, 'data' => $data)); + } catch (Exception $e) { + Log::error('hotelData error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + public function hotelPhotos(Request $request) + { + $hotelIds = $request->query('hotel_ids'); + $hotelName = $request->query('hotel_name', 'hotel'); + $propertyId = $request->query('property_id', $hotelIds); + + if (!$hotelIds) { + return response()->json(array( + 'status' => false, + 'message' => 'hotel_ids gerekli' + ), 422); + } + + try { + $response = $this->client()->get( + 'https://' . env('BULUT_RAPIDAPI_HOST') . '/properties/get-hotel-photos', + array( + 'query' => array( + 'hotel_ids' => $hotelIds, + 'languagecode' => 'en-us', + ) + ) + ); + + $data = json_decode($response->getBody()->getContents(), true); + + $savedImages = $this->saveHotelPhotosFromResponse($data, $hotelName, $propertyId); + Log::info('BULUT RAW RESPONSE KEYS', array( + 'main_keys' => array_keys($data), + 'data_keys' => isset($data['data']) && is_array($data['data']) ? array_keys($data['data']) : array(), + + )); + + return response()->json(array( + 'status' => true, + 'message' => 'Otel görselleri başarıyla indirildi ve gruplandı.', + 'debug' => array( + 'main_keys' => array_keys($data), + 'data_keys' => isset($data['data']) && is_array($data['data']) ? array_keys($data['data']) : array(), + 'data_data_keys' => isset($data['data']['data']) && is_array($data['data']['data']) ? array_keys($data['data']['data']) : array(), + ), + 'saved_images' => $savedImages + )); + } catch (Exception $e) { + Log::error('hotelPhotos error: ' . $e->getMessage()); + + return response()->json(array( + 'status' => false, + 'message' => $e->getMessage() + ), 500); + } + } + + private function saveHotelPhotosFromResponse(array $responseData, string $hotelName, $propertyId) + { + $result = array(); + + $urlPrefix = 'https://cf.bstatic.com'; + + if (isset($responseData['url_prefix'])) { + $urlPrefix = $responseData['url_prefix']; + } + + if (isset($responseData['data']['url_prefix'])) { + $urlPrefix = $responseData['data']['url_prefix']; + } + + $hotels = $this->extractHotelsFromPhotoResponse($responseData); + + Log::info('BULUT PHOTO HOTELS EXTRACTED', array( + 'hotel_count' => count($hotels), + 'hotel_keys' => array_keys($hotels), + 'url_prefix' => $urlPrefix + )); + + $uploadRootPath = rtrim(Config::get('app.fileSystemDriver'), '/'); + + $propertyBasePath = $uploadRootPath . '/property-photos/' . $propertyId; + + if (!File::exists($propertyBasePath)) { + File::makeDirectory($propertyBasePath, 0777, true); + } + + foreach ($hotels as $hotelId => $photos) { + $hotelFolderName = Str::slug($hotelName) . '-' . $hotelId; + + $basePath = $propertyBasePath . '/bulut/' . $hotelFolderName; + + if (!File::exists($basePath)) { + File::makeDirectory($basePath, 0777, true); + } + + $result[$hotelId] = array( + 'hotel_name' => $hotelName, + 'property_id' => $propertyId, + 'folder' => '/property-photos/' . $propertyId . '/bulut/' . $hotelFolderName, + 'physical_path' => $basePath, + 'groups' => array() + ); + + foreach ($photos as $photo) { + $photoId = isset($photo[2]) ? $photo[2] : uniqid(); + $tags = isset($photo[3]) ? $photo[3] : array(); + $imagePath = isset($photo[4]) ? $photo[4] : null; + + if (!$imagePath) { + continue; + } + + $groupName = $this->detectPhotoGroup($tags); + + $groupPath = $basePath . '/' . $groupName; + + if (!File::exists($groupPath)) { + File::makeDirectory($groupPath, 0777, true); + } + + $imageUrl = $urlPrefix . $imagePath; + + $fileName = $photoId . '.jpg'; + $savePath = $groupPath . '/' . $fileName; + + try { + $this->downloadImage($imageUrl, $savePath); + + $relativePath = '/property-photos/' . $propertyId . '/bulut/' . $hotelFolderName . '/' . $groupName . '/' . $fileName; + + if (!isset($result[$hotelId]['groups'][$groupName])) { + $result[$hotelId]['groups'][$groupName] = array(); + } + + $result[$hotelId]['groups'][$groupName][] = array( + 'photo_id' => $photoId, + 'file_name' => $fileName, + 'photo_path' => '/property-photos/' . $propertyId . '/bulut/' . $hotelFolderName . '/' . $groupName . '/', + 'relative_path' => $relativePath, + 'physical_path' => $savePath, + 'source_url' => $imageUrl, + 'tags' => $tags + ); + } catch (Exception $e) { + Log::error('BULUT IMAGE DOWNLOAD ERROR: ' . $e->getMessage(), array( + 'image_url' => $imageUrl, + 'save_path' => $savePath + )); + } + } + } + + return $result; + } + + private function detectPhotoGroup(array $tags) + { + $tagNames = array(); + + foreach ($tags as $tag) { + if (isset($tag['tag'])) { + $tagNames[] = strtolower($tag['tag']); + } + } + + $tagText = implode(' ', $tagNames); + + if ( + strpos($tagText, 'room') !== false || + strpos($tagText, 'bedroom') !== false || + strpos($tagText, 'bed') !== false || + strpos($tagText, 'living room') !== false + ) { + return 'rooms'; + } + + if ( + strpos($tagText, 'bathroom') !== false || + strpos($tagText, 'shower') !== false || + strpos($tagText, 'toilet') !== false + ) { + return 'bathroom'; + } + + if ( + strpos($tagText, 'breakfast') !== false || + strpos($tagText, 'buffet') !== false + ) { + return 'breakfast'; + } + + if ( + strpos($tagText, 'restaurant') !== false || + strpos($tagText, 'food') !== false || + strpos($tagText, 'drinks') !== false || + strpos($tagText, 'lunch') !== false || + strpos($tagText, 'dinner') !== false + ) { + return 'restaurant'; + } + + if ( + strpos($tagText, 'lobby') !== false || + strpos($tagText, 'reception') !== false || + strpos($tagText, 'lounge') !== false || + strpos($tagText, 'seating area') !== false + ) { + return 'lobby'; + } + + if ( + strpos($tagText, 'spa') !== false || + strpos($tagText, 'wellness') !== false || + strpos($tagText, 'public bath') !== false + ) { + return 'spa'; + } + + if ( + strpos($tagText, 'balcony') !== false || + strpos($tagText, 'terrace') !== false || + strpos($tagText, 'garden') !== false || + strpos($tagText, 'sea view') !== false || + strpos($tagText, 'city view') !== false + ) { + return 'view-and-outdoor'; + } + + if ( + strpos($tagText, 'property building') !== false || + strpos($tagText, 'property') !== false + ) { + return 'property'; + } + + return 'other'; + } + + private function downloadImage(string $imageUrl, string $savePath) + { + $client = new Client(array( + 'timeout' => 30, + 'verify' => false, + 'headers' => array( + 'User-Agent' => 'Mozilla/5.0' + ) + )); + + $response = $client->get($imageUrl); + + if ($response->getStatusCode() !== 200) { + throw new Exception('Image download failed: ' . $imageUrl); + } + + File::put($savePath, $response->getBody()->getContents()); + + return true; + } + + private function extractHotelsFromPhotoResponse(array $responseData) + { + if (isset($responseData['data']) && is_array($responseData['data'])) { + foreach ($responseData['data'] as $key => $value) { + if (is_numeric($key) && is_array($value)) { + return $responseData['data']; + } + } + } + + if (isset($responseData['data']['data']) && is_array($responseData['data']['data'])) { + return $responseData['data']['data']; + } + + if (isset($responseData['data']['data']['data']) && is_array($responseData['data']['data']['data'])) { + return $responseData['data']['data']['data']; + } + + return array(); + } +} diff --git a/app/Http/Controllers/bulutController.php b/app/Http/Controllers/bulutController.php new file mode 100644 index 0000000..71d4b5b --- /dev/null +++ b/app/Http/Controllers/bulutController.php @@ -0,0 +1,1079 @@ + 30, + 'headers' => array( + 'x-rapidapi-host' => env('BULUT_RAPIDAPI_HOST', self::API_HOST), + 'x-rapidapi-key' => env('BULUT_RAPIDAPI_KEY'), + 'Content-Type' => 'application/json', + ), + )); + } + + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 1: Otel adına göre ara → hotel_id bul + // GET /bulut/search?name=Grand+Yavuz+Hotel + // ───────────────────────────────────────────────────────────────────────────── + public function search(Request $request) + { + $name = $request->query('name', ''); + + if (!$name) { + return response()->json(array('status' => false, 'message' => 'name parametresi gerekli'), 422); + } + + try { + $response = $this->client()->get( + self::API_BASE . '/api/v1/hotels/searchDestination', + array('query' => array('query' => $name)) + ); + + $data = json_decode($response->getBody()->getContents(), true); + + return response()->json(array('status' => true, 'data' => $data)); + } catch (Exception $e) { + Log::error('Bulut.search error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 2: Otel detayları + // GET /bulut/hotel-data?hotel_id=89675&checkin=2026-06-01&checkout=2026-06-02 + // ───────────────────────────────────────────────────────────────────────────── + public function hotelData(Request $request) + { + $hotelId = $request->query('hotel_id'); + $checkin = $request->query('checkin', date('Y-m-d', strtotime('+30 days'))); + $checkout = $request->query('checkout', date('Y-m-d', strtotime('+31 days'))); + + if (!$hotelId) { + return response()->json(array('status' => false, 'message' => 'hotel_id gerekli'), 422); + } + + try { + $response = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelDetails', + array('query' => array( + 'hotel_id' => $hotelId, + 'arrival_date' => $checkin, + 'departure_date' => $checkout, + 'adults' => 1, + 'room_qty' => 1, + 'languagecode' => 'en-us', + 'currency_code' => 'USD', + 'units' => 'metric', + 'temperature_unit' => 'c', + )) + ); + + $data = json_decode($response->getBody()->getContents(), true); + return response()->json(array('status' => true, 'data' => $data)); + } catch (Exception $e) { + Log::error('Bulut.hotelData error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 3: Otel fotoğraflarını indir → property_photo tablosuna kaydet + // GET /bulut/hotel-photos?hotel_id=89675&property_id=1 + // ───────────────────────────────────────────────────────────────────────────── + public function hotelPhotos(Request $request) + { + $hotelId = $request->query('hotel_id'); + $propertyId = $request->query('property_id', 1); + $limit = (int) $request->query('limit', 20); + + if (!$hotelId) { + return response()->json(array('status' => false, 'message' => 'hotel_id gerekli'), 422); + } + + try { + $response = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelPhotos', + array('query' => array( + 'hotel_id' => $hotelId, + 'page_number' => 1, + )) + ); + + $data = json_decode($response->getBody()->getContents(), true); + + $savedPhotos = $this->processAndSavePhotos($data, $hotelId, $propertyId, $limit); + + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'property_id' => $propertyId, + 'photos_saved' => $savedPhotos, + )); + } catch (Exception $e) { + Log::error('Bulut.hotelPhotos error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // TAM PIPELINE: otel adı gönder → ara → detay + fotoğrafları kaydet + // GET /bulut/test-api?name=Grand+Yavuz+Hotel&property_id=1&limit=5 + // ───────────────────────────────────────────────────────────────────────────── + public function testApi(Request $request) + { + $name = $request->query('name', ''); + $propertyId = $request->query('property_id', 1); + $checkin = $request->query('checkin', date('Y-m-d', strtotime('+30 days'))); + $checkout = $request->query('checkout', date('Y-m-d', strtotime('+31 days'))); + $limit = (int) $request->query('limit', 5); + + if (!$name) { + return response()->json(array('status' => false, 'message' => 'name parametresi gerekli'), 422); + } + + try { + // ── 1. Ara ─────────────────────────────────────────────────────────── + $searchResponse = $this->client()->get( + self::API_BASE . '/api/v1/hotels/searchDestination', + array('query' => array('query' => $name)) + ); + $searchData = json_decode($searchResponse->getBody()->getContents(), true); + + if (empty($searchData['data'])) { + return response()->json(array( + 'status' => false, + 'message' => 'Otel bulunamadı', + 'raw' => $searchData + ), 404); + } + + // Önce dest_type=hotel olanı bul, yoksa ilk sonucu al + $hotelResult = null; + foreach ($searchData['data'] as $item) { + if (isset($item['dest_type']) && $item['dest_type'] === 'hotel') { + $hotelResult = $item; + break; + } + } + if (!$hotelResult) { + $hotelResult = $searchData['data'][0]; + } + + $hotelId = isset($hotelResult['dest_id']) ? $hotelResult['dest_id'] : null; + $hotelName = isset($hotelResult['label']) ? $hotelResult['label'] : $name; + + if (!$hotelId) { + return response()->json(array( + 'status' => false, + 'message' => 'hotel_id bulunamadı', + 'search_result' => $hotelResult, + ), 404); + } + + // ── 2. Otel detayı ─────────────────────────────────────────────────── + $detailResponse = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelDetails', + array('query' => array( + 'hotel_id' => $hotelId, + 'arrival_date' => $checkin, + 'departure_date' => $checkout, + 'adults' => 1, + 'room_qty' => 1, + 'languagecode' => 'en-us', + 'currency_code' => 'USD', + 'units' => 'metric', + 'temperature_unit' => 'c', + )) + ); + $detailData = json_decode($detailResponse->getBody()->getContents(), true); + + // ── 3. Fotoğrafları çek ve kaydet ──────────────────────────────────── + $photoResponse = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelPhotos', + array('query' => array( + 'hotel_id' => $hotelId, + 'page_number' => 1, + )) + ); + $photoData = json_decode($photoResponse->getBody()->getContents(), true); + $savedPhotos = $this->processAndSavePhotos($photoData, $hotelId, $propertyId, $limit); + + // ── 4. Facility matching ────────────────────────────────────────────── + $detail = isset($detailData['data']) ? $detailData['data'] : $detailData; + $facilityResult = $this->matchAndLogFacilities($detail, $hotelId, $propertyId); + + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'hotel_name' => $hotelName, + 'hotel_details' => $detail, + 'photos_saved' => $savedPhotos, + 'facility_matching' => $facilityResult, + )); + } catch (Exception $e) { + Log::error('Bulut.testApi error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // Private: API'den gelen foto listesinden URL çıkar, indir, boyutlandır, DB'ye kaydet + // ───────────────────────────────────────────────────────────────────────────── + private function processAndSavePhotos(array $responseData, $hotelId, $propertyId, $limit = 20) + { + $photoUrls = $this->extractPhotoUrls($responseData); + + if (empty($photoUrls)) { + return array( + 'count' => 0, + 'message' => 'API yanıtında fotoğraf URL bulunamadı', + 'raw_keys' => array_keys($responseData), + ); + } + + $uploadRoot = rtrim(Config::get('app.fileSystemDriver'), '/'); + $urlPath = '/property-photos/' . $propertyId . '/'; + $filePath = $uploadRoot . $urlPath; + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + // Bu property için zaten default foto var mı? + $hasDefault = PropertyPhoto::where('property_id', $propertyId) + ->where('status', 1) + ->where('is_default', 1) + ->exists(); + + $saved = array(); + $isFirstPhoto = true; + $total = min(count($photoUrls), $limit); + + for ($i = 0; $i < $total; $i++) { + $photoUrl = $photoUrls[$i]; + + try { + $fileName = time() . '_bk' . $hotelId . '_' . $i; + $fileExt = 'jpg'; + $tempPath = sys_get_temp_dir() . '/' . $fileName . '_orig.jpg'; + + // ── İndir ───────────────────────────────────────────────────────── + $this->downloadRawImage($photoUrl, $tempPath); + + // ── Intervention Image ile işle ─────────────────────────────────── + $image = Image::make($tempPath); + $imageWidth = $image->width(); + $imageHeight = $image->height(); + $fileSize = (int) ceil(filesize($tempPath) / 1024); + $quality = 80; + + // Orijinal (2000px üzeriyse küçült) + if ($imageHeight > 2000 || $imageWidth > 2000) { + if ($imageHeight > $imageWidth) { + $r = $imageHeight / 2000; + $image->fit((int)($imageWidth / $r), 2000); + } else { + $r = $imageWidth / 2000; + $image->fit(2000, (int)($imageHeight / $r)); + } + } + $image->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt); + + // _medium (max 1600x768) + $mediumImage = Image::make($tempPath); + $ratio = $imageHeight > 0 ? ($imageHeight / 768) : 1; + $resizeWidth = (int)($imageWidth / max($ratio, 1)); + if ($resizeWidth > 1599) { + $mediumImage->fit(1600, 768); + } else { + $mediumImage->fit(max($resizeWidth, 1), 768); + } + $mediumImage->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '_medium.' . $fileExt); + + // _thumbnail (300x300) + Image::make($tempPath) + ->fit(300, 300) + ->encode($fileExt, $quality) + ->orientate() + ->save($filePath . $fileName . '_thumbnail.' . $fileExt); + + // Temp dosyayı sil + if (File::exists($tempPath)) { + File::delete($tempPath); + } + + $isCompatible = ($imageWidth >= 1150 && $imageHeight >= 600) ? 1 : 0; + $isDefault = (!$hasDefault && $isFirstPhoto) ? 1 : 0; + $isFirstPhoto = false; + + // ── DB'ye kaydet ────────────────────────────────────────────────── + $photoRecord = PropertyPhoto::create(array( + 'property_id' => $propertyId, + 'property_photo_category_id' => 1, + 'photo_path' => $urlPath, + 'photo_name' => $fileName, + 'file_size' => $fileSize, + 'file_ext' => $fileExt, + 'photo_resolution' => $imageWidth . 'x' . $imageHeight, + 'is_default' => $isDefault, + 'is_compatible_with_myweb_slider' => $isCompatible, + 'photo_order' => 0, + 'photo_rank' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + )); + + $saved[] = array( + 'db_id' => $photoRecord->id, + 'file_name' => $fileName . '.' . $fileExt, + 'resolution' => $imageWidth . 'x' . $imageHeight, + 'source_url' => $photoUrl, + ); + } catch (Exception $e) { + Log::error('Bulut.photo.save [' . $i . ']: ' . $e->getMessage() . ' | ' . $photoUrl); + $saved[] = array('error' => $e->getMessage(), 'source_url' => $photoUrl); + } + } + + return array( + 'saved_count' => count(array_filter($saved, function ($s) { + return !isset($s['error']); + })), + 'total_in_api' => count($photoUrls), + 'limit_applied' => $total, + 'photos' => $saved, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // booking-com15 getHotelPhotos yanıtından URL listesi çıkar + // ───────────────────────────────────────────────────────────────────────────── + private function extractPhotoUrls(array $data) + { + $urls = array(); + + // Format 1: data[] dizisi – her elemanın url_original / url_max / url alanı + if (isset($data['data']) && is_array($data['data']) && !empty($data['data'])) { + foreach ($data['data'] as $item) { + if (!is_array($item)) { + continue; + } + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url_max'])) { + $urls[] = $item['url_max']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } elseif (!empty($item['photo']['url_original'])) { + $urls[] = $item['photo']['url_original']; + } + } + } + + // Format 2: data.photos[] + if (empty($urls) && isset($data['data']['photos']) && is_array($data['data']['photos'])) { + foreach ($data['data']['photos'] as $item) { + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } + } + } + + // Format 3: photos[] direkt root'ta + if (empty($urls) && isset($data['photos']) && is_array($data['photos'])) { + foreach ($data['photos'] as $item) { + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } + } + } + + return $urls; + } + + // ───────────────────────────────────────────────────────────────────────────── + // Görseli disk'e indir (GuzzleHttp sink kullan) + // ───────────────────────────────────────────────────────────────────────────── + private function downloadRawImage($url, $savePath) + { + $client = new Client(array( + 'timeout' => 30, + 'verify' => false, + 'headers' => array('User-Agent' => 'Mozilla/5.0'), + )); + + $response = $client->get($url, array('sink' => $savePath)); + + if ($response->getStatusCode() !== 200) { + throw new Exception('Image download failed HTTP ' . $response->getStatusCode() . ' | ' . $url); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // Public: GET /bulut/match-facilities?hotel_id=89675&property_id=1 + // ───────────────────────────────────────────────────────────────────────────── + public function matchFacilities(Request $request) + { + $hotelId = $request->query('hotel_id', ''); + $propertyId = $request->query('property_id', 1); + + if (!$hotelId) { + return response()->json(array('status' => false, 'message' => 'hotel_id gerekli'), 422); + } + + try { + $response = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelFacilities', + array('query' => array('hotel_id' => $hotelId)) + ); + + $data = json_decode($response->getBody()->getContents(), true); + $result = $this->matchAndLogFacilities( + isset($data['data']) ? $data['data'] : array(), + $hotelId, + $propertyId + ); + + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'result' => $result, + )); + } catch (Exception $e) { + Log::error('Bulut.matchFacilities error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // Private: API yanıtındaki facilitylerle property_fact tablosunu eşleştir + logla + // ───────────────────────────────────────────────────────────────────────────── + private function matchAndLogFacilities(array $detail, $hotelId, $propertyId) + { + // ── 1. API'den facility isimlerini topla ────────────────────────────────── + // getHotelFacilities yapısı: facilities[], accommodationHighlights[], highlights[] + // getHotelDetails yapısı (eski): facilities_block.facilities[], top_ufi_benefits[], property_highlight_strip[] + $apiNames = array(); + + $addUniq = function ($name) use (&$apiNames) { + $name = trim($name); + if ($name !== '' && !in_array($name, $apiNames)) { + $apiNames[] = $name; + } + }; + + // getHotelFacilities → facilities[].instances[].title (96 adet zengin veri) + if (isset($detail['facilities']) && is_array($detail['facilities'])) { + foreach ($detail['facilities'] as $fac) { + if (!empty($fac['instances']) && is_array($fac['instances'])) { + foreach ($fac['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + + // getHotelFacilities → accommodationHighlights[].title + if (isset($detail['accommodationHighlights']) && is_array($detail['accommodationHighlights'])) { + foreach ($detail['accommodationHighlights'] as $h) { + if (!empty($h['title'])) { + $addUniq($h['title']); + } + } + } + + // getHotelFacilities → highlights[].instances[].title + if (isset($detail['highlights']) && is_array($detail['highlights'])) { + foreach ($detail['highlights'] as $h) { + if (!empty($h['instances']) && is_array($h['instances'])) { + foreach ($h['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + + // getHotelDetails uyumluluğu — eski endpoint hâlâ çalışsın + if (isset($detail['facilities_block']['facilities']) && is_array($detail['facilities_block']['facilities'])) { + foreach ($detail['facilities_block']['facilities'] as $fac) { + if (!empty($fac['name'])) { + $addUniq($fac['name']); + } + } + } + if (isset($detail['top_ufi_benefits']) && is_array($detail['top_ufi_benefits'])) { + foreach ($detail['top_ufi_benefits'] as $ben) { + if (!empty($ben['translated_name'])) { + $addUniq($ben['translated_name']); + } + } + } + if (isset($detail['property_highlight_strip']) && is_array($detail['property_highlight_strip'])) { + foreach ($detail['property_highlight_strip'] as $strip) { + if (!empty($strip['name'])) { + $addUniq($strip['name']); + } + } + } + + $apiNames = array_values($apiNames); + + if (empty($apiNames)) { + return array( + 'matched' => array(), + 'unmatched' => array(), + 'message' => 'API yanıtında facility bulunamadı', + ); + } + + // ── 2. property_fact tablosundaki TÜM kayıtları çek ────────────────────── + $allFacts = PropertyFact::select(array('id', 'name', 'icon', 'parent_id', 'type'))->get(); + $exactIndex = array(); + foreach ($allFacts as $fact) { + $key = mb_strtolower(trim($fact->name)); + if (!isset($exactIndex[$key]) || $fact->type == 1) { + $exactIndex[$key] = $fact; + } + } + + // ── 3. Alias map — Booking.com adı ≠ DB adı olan terimler ─────────────── + $aliasMap = array( + // Internet + 'internet services' => 'wi-fi', + 'free wifi' => 'wi-fi', + 'wifi' => 'wi-fi', + 'wi-fi' => 'wi-fi', + 'wifi in all areas' => 'wi-fi', + 'free wi-fi' => 'wi-fi', + 'internet' => 'wi-fi', + 'internet access' => 'wi-fi', + // Ulaşım + 'airport shuttle' => 'airport transfer', + 'airport pick up' => 'airport to hotel transfer', + 'airport drop off' => 'hotel to airport transfer', + 'car hire' => 'rent a car', + 'car rental' => 'rent a car', + 'shuttle service' => 'airport transfer', + // Servis + '24-hour front desk' => 'reception', + 'concierge service' => 'concierge', + 'luggage storage' => 'luggage storage', + 'laundry' => 'cleaning service', + 'daily housekeeping' => 'housekeeping', + 'tour desk' => 'tour desk', + 'private check-in/check-out' => 'check-in service', + 'express check-in/check-out' => 'check-in service', + 'wake-up service' => 'wake up service', + 'dry cleaning' => 'dry cleaning', + 'currency exchange' => 'currency exchange', + // Engelli + 'facilities for disabled guests' => 'disabled', + 'wheelchair accessible' => 'wheelchair', + 'upper floors accessible by elevator' => 'elevator', + 'lower bathroom sink' => 'lower bathroom sink', + 'toilet with grab rails' => 'toilet with grab rails', + // Yiyecek + 'breakfast' => 'bed and breakfast', + 'snack bar' => 'snack bar', + 'meeting/banquet facilities' => 'meeting room', + 'business centre' => 'working area', + 'business center' => 'working area', + 'fax/photocopying' => 'photocopy', + // Oda + 'air conditioning' => 'air conditioner', + 'flat-screen tv' => 'tv', + 'flat screen tv' => 'tv', + 'bath or shower' => 'shower', + 'free toiletries' => 'shower', + 'single-room air conditioning for guest accommodation' => 'air conditioner', + 'minibar' => 'mini bar', + 'mini bar' => 'mini bar', + 'hairdryer' => 'hair dryer', + 'hair dryer' => 'hair dryer', + 'wardrobe or closet' => 'clothes cabinet', + 'socket near the bed' => 'planning electrical sockets', + 'family rooms' => 'family room', + 'clothes rack' => 'clotheshorse', + // Güvenlik + 'cctv in common areas' => 'security camera', + 'cctv outside property' => 'security camera', + 'smoke alarms' => 'smoke alarm', + 'safety deposit box' => 'safety deposit box', + '24-hour security' => 'security service', + 'key card access' => 'security service', + // Hijyen + 'hand sanitizer in guest accommodation and key areas' => 'hand sanitiser', + 'hand sanitiser' => 'hand sanitiser', + 'face masks for guests available' => 'protective masks for guests', + 'physical distancing rules followed' => 'social distancing regulations', + 'screens or physical barriers placed between staff and guests in appropriate areas' => 'protective hygiene screens', + 'guest accommodation is disinfected between stays' => 'disinfection in all rooms', + // Aktivite + 'tennis court' => 'tennis', + 'golf course' => 'golf', + 'table tennis' => 'ping pong', + 'jogging track' => 'jogging', + // Çevre + 'lift' => 'elevator', + 'elevator' => 'elevator', + ); + + // ── 4. Eşleştir ─────────────────────────────────────────────────────────── + $matched = array(); + $unmatched = array(); + + foreach ($apiNames as $apiName) { + $lower = mb_strtolower(trim($apiName)); + $searchKey = isset($aliasMap[$lower]) ? $aliasMap[$lower] : $lower; + + // ADIM 1: Alias → exact + if (isset($exactIndex[$searchKey])) { + $fact = $exactIndex[$searchKey]; + $tag = ($searchKey !== $lower) ? 'alias' : 'exact'; + $matched[] = array( + 'api_name' => $apiName, + 'fact_id' => $fact->id, + 'fact_name' => $fact->name, + 'match_type' => $tag, + ); + continue; + } + + // ADIM 2: DB LIKE — fact adı içinde api ismi geçiyor mu? + $likeResult = PropertyFact::where('type', 1) + ->whereRaw('LOWER(name) LIKE ?', array('%' . $lower . '%')) + ->orderByRaw('LENGTH(name) ASC') + ->first(); + + if ($likeResult) { + $matched[] = array( + 'api_name' => $apiName, + 'fact_id' => $likeResult->id, + 'fact_name' => $likeResult->name, + 'match_type' => 'like', + ); + continue; + } + + // ADIM 3: Ters LIKE — fact adı api isminin içinde mi? + $reverseResult = PropertyFact::where('type', 1) + ->whereRaw('LOWER(?) LIKE CONCAT(\'%\', LOWER(name), \'%\')', array($lower)) + ->whereRaw('LENGTH(name) >= 5') + ->orderByRaw('LENGTH(name) DESC') + ->first(); + + if ($reverseResult) { + $matched[] = array( + 'api_name' => $apiName, + 'fact_id' => $reverseResult->id, + 'fact_name' => $reverseResult->name, + 'match_type' => 'reverse_like', + ); + continue; + } + + $unmatched[] = $apiName; + } + + // ── 5. storage/fact.log — okunabilir format ─────────────────────────────── + $logPath = storage_path('fact.log'); + $ts = date('Y-m-d H:i:s'); + $divider = str_repeat('═', 80); + $thin = str_repeat('─', 80); + + $lines = array(); + $lines[] = $divider; + $lines[] = sprintf(' [%s] hotel_id=%-12s property_id=%s', $ts, $hotelId, $propertyId); + $lines[] = sprintf( + ' Toplam API facility: %d | Eşleşen: %d | Eşleşmeyen: %d', + count($apiNames), + count($matched), + count($unmatched) + ); + $lines[] = $divider; + $lines[] = ''; + + $lines[] = sprintf(' EŞLEŞENLER (%d)', count($matched)); + $lines[] = ' ' . $thin; + if (count($matched)) { + foreach ($matched as $m) { + $lines[] = sprintf( + ' [%-12s] %-45s → #%-5d %s', + $m['match_type'], + '"' . $m['api_name'] . '"', + $m['fact_id'], + $m['fact_name'] + ); + } + } else { + $lines[] = ' (eşleşen yok)'; + } + + $lines[] = ''; + $lines[] = sprintf(' EŞLEŞMEYENLEr (%d)', count($unmatched)); + $lines[] = ' ' . $thin; + if (count($unmatched)) { + foreach ($unmatched as $u) { + $lines[] = ' [?] ' . $u; + } + } else { + $lines[] = ' (tümü eşleşti — property_fact\'e eklenebilir)'; + } + + $lines[] = ''; + $lines[] = ''; + + file_put_contents($logPath, implode(PHP_EOL, $lines), FILE_APPEND | LOCK_EX); + + return array( + 'api_facilities_count' => count($apiNames), + 'matched_count' => count($matched), + 'unmatched_count' => count($unmatched), + 'matched' => $matched, + 'unmatched' => $unmatched, + 'log_file' => $logPath, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // AI Semantic Match: getHotelFacilities → string match → kalan unmatched'ları + // Gemini'ye gönder → "aynı kavram farklı isim mi?" veya "gerçekten eksik mi?" + // GET /bulut/ai-match?hotel_id=...&property_id=... + // ───────────────────────────────────────────────────────────────────────────── + public function aiMatch(Request $request) + { + $hotelId = $request->query('hotel_id', ''); + $propertyId = $request->query('property_id', 1); + + if (!$hotelId) { + return response()->json(array('status' => false, 'message' => 'hotel_id gerekli'), 422); + } + + $geminiKey = env('GEMINI_API_KEY', ''); + if (!$geminiKey) { + return response()->json(array('status' => false, 'message' => 'GEMINI_API_KEY .env\'de tanımlı değil'), 500); + } + + try { + // ── ADIM 1: Booking.com'dan tüm faciliteleri çek ───────────────────── + $response = $this->client()->get( + self::API_BASE . '/api/v1/hotels/getHotelFacilities', + array('query' => array('hotel_id' => $hotelId)) + ); + $data = json_decode($response->getBody()->getContents(), true); + $facilData = isset($data['data']) ? $data['data'] : array(); + + // Tüm API isimlerini topla + $apiNames = array(); + $addUniq = function ($name) use (&$apiNames) { + $name = trim($name); + if ($name !== '' && !in_array($name, $apiNames)) { + $apiNames[] = $name; + } + }; + + if (isset($facilData['facilities']) && is_array($facilData['facilities'])) { + foreach ($facilData['facilities'] as $fac) { + if (!empty($fac['instances']) && is_array($fac['instances'])) { + foreach ($fac['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + if (isset($facilData['accommodationHighlights']) && is_array($facilData['accommodationHighlights'])) { + foreach ($facilData['accommodationHighlights'] as $h) { + if (!empty($h['title'])) { + $addUniq($h['title']); + } + } + } + if (isset($facilData['highlights']) && is_array($facilData['highlights'])) { + foreach ($facilData['highlights'] as $h) { + if (!empty($h['instances']) && is_array($h['instances'])) { + foreach ($h['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + + if (empty($apiNames)) { + return response()->json(array('status' => false, 'message' => 'API\'den facility alınamadı'), 500); + } + + // ── ADIM 2: String tabanlı match (mevcut mantık) ───────────────────── + $stringResult = $this->matchAndLogFacilities($facilData, $hotelId, $propertyId); + $stringMatched = $stringResult['matched']; + $unmatched = $stringResult['unmatched']; + + if (empty($unmatched)) { + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'string_matched' => $stringMatched, + 'ai_matched' => array(), + 'truly_missing' => array(), + 'message' => 'Tüm facilityler string eşleştirme ile bulundu, AI çağrısı gerekmedi', + )); + } + + // ── ADIM 3: DB'deki tüm fact isimlerini çek ────────────────────────── + $allFactNames = PropertyFact::where('type', 1) + ->orderBy('name') + ->pluck('name', 'id') + ->toArray(); + + // Gemini'ye göndermek için isim → id lookup + $nameToId = array(); + foreach ($allFactNames as $id => $name) { + $nameToId[mb_strtolower(trim($name))] = array('id' => $id, 'name' => $name); + } + + // ── ADIM 4: Gemini prompt ───────────────────────────────────────────── + $unmatchedList = implode("\n", array_map(function ($n) { + return '- ' . $n; + }, $unmatched)); + $dbList = implode("\n", array_map(function ($n) { + return '- ' . $n; + }, $allFactNames)); + + $prompt = << 60, 'http_errors' => false)); + + // Sırayla farklı modeller dene (free tier kota sorunu için) + $geminiModels = array( + 'gemini-2.0-flash-lite', + 'gemini-2.0-flash', + 'gemini-flash-lite-latest', + 'gemini-flash-latest', + ); + + $rawText = null; + $lastStatus = 0; + + foreach ($geminiModels as $model) { + $geminiResponse = $geminiClient->post( + 'https://generativelanguage.googleapis.com/v1beta/models/' . $model . ':generateContent?key=' . $geminiKey, + array( + 'json' => array( + 'contents' => array( + array('parts' => array(array('text' => $prompt))) + ), + 'generationConfig' => array( + 'responseMimeType' => 'application/json', + 'temperature' => 0.1, + ), + ), + ) + ); + + $lastStatus = $geminiResponse->getStatusCode(); + + if ($lastStatus === 200) { + $geminiBody = json_decode($geminiResponse->getBody()->getContents(), true); + $rawText = isset($geminiBody['candidates'][0]['content']['parts'][0]['text']) + ? $geminiBody['candidates'][0]['content']['parts'][0]['text'] + : null; + break; + } + + // 429 = quota exceeded → bir sonraki modeli dene + if ($lastStatus !== 429) { + $errBody = $geminiResponse->getBody()->getContents(); + throw new Exception('Gemini API hatası (' . $model . '): HTTP ' . $lastStatus . ' → ' . substr($errBody, 0, 200)); + } + } + + if ($rawText === null) { + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'api_total' => count($apiNames), + 'string_matched' => array('count' => count($stringMatched), 'matches' => $stringMatched), + 'ai_matched' => array('count' => 0, 'matches' => array()), + 'truly_missing' => array('count' => count($unmatched), 'items' => $unmatched), + 'total_matched' => count($stringMatched), + 'warning' => 'Tüm Gemini modelleri 429 quota hatası verdi. String match sonuçları döndürüldü. Birkaç dakika bekleyip tekrar deneyin.', + )); + } + + $aiResult = json_decode($rawText, true); + if (!$aiResult) { + $aiResult = array('ai_matches' => array(), 'truly_missing' => $unmatched); + } + + $aiMatches = isset($aiResult['ai_matches']) ? $aiResult['ai_matches'] : array(); + $trulyMissing = isset($aiResult['truly_missing']) ? $aiResult['truly_missing'] : array(); + + // AI eşleşmelerine DB id'si ekle + foreach ($aiMatches as $idx => $m) { + $key = mb_strtolower(trim($m['db_name'])); + if (isset($nameToId[$key])) { + $aiMatches[$idx]['fact_id'] = $nameToId[$key]['id']; + $aiMatches[$idx]['fact_name'] = $nameToId[$key]['name']; + $aiMatches[$idx]['match_type'] = 'ai_semantic'; + } + } + + // ── ADIM 6: off_fact.log — TÜM liste: var olanlar + olmayanlar ────────── + $logPath = storage_path('off_fact.log'); + $ts = date('Y-m-d H:i:s'); + $eq = str_repeat('═', 90); + $dash = str_repeat('─', 90); + + // Tüm eşleşmeleri birleştir (string + AI) + $allMatched = $stringMatched; + foreach ($aiMatches as $am) { + $allMatched[] = array( + 'api_name' => $am['api_name'], + 'fact_id' => isset($am['fact_id']) ? $am['fact_id'] : '???', + 'fact_name' => isset($am['fact_name']) ? $am['fact_name'] : $am['db_name'], + 'match_type' => 'ai_semantic', + 'reason' => isset($am['reason']) ? $am['reason'] : '', + ); + } + + $logLines = array(); + $logLines[] = $eq; + $logLines[] = sprintf( + ' [%s] hotel_id: %-12s property_id: %s', + $ts, + $hotelId, + $propertyId + ); + $logLines[] = sprintf( + ' Booking.com\'dan gelen: %d | DB\'de VAR: %d | DB\'de YOK: %d', + count($apiNames), + count($allMatched), + count($trulyMissing) + ); + $logLines[] = $eq; + $logLines[] = ''; + + // ── VAR OLANLAR ─────────────────────────────────────────────────────── + $logLines[] = sprintf(' ✔ DB\'DE VAR (%d / %d)', count($allMatched), count($apiNames)); + $logLines[] = ' ' . $dash; + foreach ($allMatched as $m) { + $type = isset($m['match_type']) ? $m['match_type'] : 'exact'; + $line = sprintf( + ' [%-12s] %-50s → #%-5s %s', + $type, + '"' . $m['api_name'] . '"', + $m['fact_id'], + $m['fact_name'] + ); + $logLines[] = $line; + if (!empty($m['reason'])) { + $logLines[] = sprintf(' AI notu: %s', $m['reason']); + } + } + + $logLines[] = ''; + + // ── YOK OLANLAR ─────────────────────────────────────────────────────── + $logLines[] = sprintf(' ✘ DB\'DE YOK (%d / %d) — property_fact\'e eklenmesi değerlendirilebilir', count($trulyMissing), count($apiNames)); + $logLines[] = ' ' . $dash; + if (count($trulyMissing)) { + foreach ($trulyMissing as $missing) { + $logLines[] = ' [MISSING] "' . $missing . '"'; + } + } else { + $logLines[] = ' (tüm facilityler DB\'de mevcut)'; + } + + $logLines[] = ''; + $logLines[] = ''; + + file_put_contents($logPath, implode(PHP_EOL, $logLines), FILE_APPEND | LOCK_EX); + + return response()->json(array( + 'status' => true, + 'hotel_id' => $hotelId, + 'api_total' => count($apiNames), + 'string_matched' => array( + 'count' => count($stringMatched), + 'matches' => $stringMatched, + ), + 'ai_matched' => array( + 'count' => count($aiMatches), + 'matches' => $aiMatches, + ), + 'truly_missing' => array( + 'count' => count($trulyMissing), + 'items' => $trulyMissing, + ), + 'total_matched' => count($stringMatched) + count($aiMatches), + )); + } catch (Exception $e) { + Log::error('Bulut.aiMatch error: ' . $e->getMessage()); + return response()->json(array('status' => false, 'message' => $e->getMessage()), 500); + } + } +} diff --git a/app/Http/Controllers/propertyInsertController.php b/app/Http/Controllers/propertyInsertController.php new file mode 100644 index 0000000..757fb64 --- /dev/null +++ b/app/Http/Controllers/propertyInsertController.php @@ -0,0 +1,1786 @@ + 'wi-fi', + 'free wifi' => 'wi-fi', + 'wifi' => 'wi-fi', + 'wi-fi' => 'wi-fi', + 'wifi in all areas' => 'wi-fi', + 'free wi-fi' => 'wi-fi', + 'internet' => 'wi-fi', + 'internet access' => 'wi-fi', + 'airport shuttle' => 'airport transfer', + 'airport pick up' => 'airport to hotel transfer', + 'airport drop off' => 'hotel to airport transfer', + 'car hire' => 'rent a car', + 'car rental' => 'rent a car', + 'shuttle service' => 'airport transfer', + '24-hour front desk' => 'reception', + 'concierge service' => 'concierge', + 'luggage storage' => 'luggage storage', + 'laundry' => 'cleaning service', + 'daily housekeeping' => 'housekeeping', + 'tour desk' => 'tour desk', + 'private check-in/check-out' => 'check-in service', + 'express check-in/check-out' => 'check-in service', + 'wake-up service' => 'wake up service', + 'dry cleaning' => 'dry cleaning', + 'currency exchange' => 'currency exchange', + 'facilities for disabled guests' => 'disabled', + 'wheelchair accessible' => 'wheelchair', + 'upper floors accessible by elevator' => 'elevator', + 'lower bathroom sink' => 'lower bathroom sink', + 'toilet with grab rails' => 'toilet with grab rails', + 'breakfast' => 'bed and breakfast', + 'snack bar' => 'snack bar', + 'meeting/banquet facilities' => 'meeting room', + 'business centre' => 'working area', + 'business center' => 'working area', + 'fax/photocopying' => 'photocopy', + 'air conditioning' => 'air conditioner', + 'flat-screen tv' => 'tv', + 'flat screen tv' => 'tv', + 'bath or shower' => 'shower', + 'free toiletries' => 'shower', + 'single-room air conditioning for guest accommodation' => 'air conditioner', + 'single-room ac for guest accommodation' => 'air conditioner', + 'minibar' => 'mini bar', + 'hairdryer' => 'hair dryer', + 'hair dryer' => 'hair dryer', + 'wardrobe or closet' => 'clothes cabinet', + 'socket near the bed' => 'planning electrical sockets', + 'family rooms' => 'family room', + 'clothes rack' => 'clotheshorse', + 'cctv in common areas' => 'security camera', + 'cctv outside property' => 'security camera', + 'smoke alarms' => 'smoke alarm', + 'safety deposit box' => 'safety deposit box', + '24-hour security' => 'security service', + 'key card access' => 'security service', + 'hand sanitizer in guest accommodation and key areas' => 'hand sanitiser', + 'hand sanitiser' => 'hand sanitiser', + 'hand sanitizer' => 'hand sanitiser', + 'face masks for guests available' => 'protective masks for guests', + 'physical distancing rules followed' => 'social distancing regulations', + 'screens or physical barriers placed between staff and guests in appropriate areas' => 'protective hygiene screens', + 'guest accommodation is disinfected between stays' => 'disinfection in all rooms', + 'cashless payment available' => 'contactless payment', + 'food can be delivered to guest accommodation' => 'food delivery', + 'tennis court' => 'tennis', + 'golf course' => 'golf', + 'table tennis' => 'ping pong', + 'jogging track' => 'jogging', + 'lift' => 'elevator', + 'elevator' => 'elevator', + ); + + // ───────────────────────────────────────────────────────────────────────────── + // Oda olanaklarına özel alias: Booking.com oda facility adı → property_fact.name + // ───────────────────────────────────────────────────────────────────────────── + private $roomAliasMap = array( + 'safe' => 'safe box', + 'towels' => 'towel', + 'linens' => 'towel', + 'tea/coffee maker' => 'coffee maker', + 'coffee/tea maker' => 'coffee maker', + 'electric kettle' => 'kettle', + 'private bathroom' => 'bathroom', + 'telephone' => 'telephone', + 'toilet paper' => 'toilet', + 'free toiletries' => 'hair dryer', + 'slippers' => 'bathrobe', + 'bath or shower' => 'shower', + 'bathtub or shower' => 'shower', + 'shower only' => 'shower', + ); + + // ───────────────────────────────────────────────────────────────────────────── + // GuzzleHttp → Booking.com API + // ───────────────────────────────────────────────────────────────────────────── + private function bookingClient() + { + return new Client(array( + 'timeout' => 30, + 'headers' => array( + 'x-rapidapi-host' => env('BULUT_RAPIDAPI_HOST', self::API_HOST), + 'x-rapidapi-key' => env('BULUT_RAPIDAPI_KEY'), + 'Content-Type' => 'application/json', + ), + )); + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 0: Booking.com'dan otel verilerini çek + // ───────────────────────────────────────────────────────────────────────────── + private function fetchBookingData($hotelId, $checkin, $checkout) + { + $client = $this->bookingClient(); + + // Otel detayı (property bilgileri: isim, konum, dil, timezone vb.) + $detailResp = $client->get(self::API_BASE . '/api/v1/hotels/getHotelDetails', array( + 'query' => array( + 'hotel_id' => $hotelId, + 'arrival_date' => $checkin, + 'departure_date' => $checkout, + 'adults' => 1, + 'room_qty' => 1, + 'languagecode' => 'en-us', + 'currency_code' => 'USD', + 'units' => 'metric', + 'temperature_unit' => 'c', + ), + )); + $detail = json_decode($detailResp->getBody()->getContents(), true); + $detail = isset($detail['data']) ? $detail['data'] : array(); + + // Oda listesi — tüm oda tiplerini çek (getRoomList daha kapsamlı) + // getHotelDetails sadece o güne müsait odaları döndürür, getRoomList tüm tipleri verir + $checkinRooms = date('Y-m-d', strtotime('+30 days')); + $checkoutRooms = date('Y-m-d', strtotime('+37 days')); + $roomListResp = $client->get(self::API_BASE . '/api/v1/hotels/getRoomList', array( + 'query' => array( + 'hotel_id' => $hotelId, + 'arrival_date' => $checkinRooms, + 'departure_date' => $checkoutRooms, + 'adults' => 2, + 'room_qty' => 1, + 'currency_code' => 'EUR', + 'languagecode' => 'en-us', + ), + )); + $roomListData = json_decode($roomListResp->getBody()->getContents(), true); + $roomListData = isset($roomListData['data']) ? $roomListData['data'] : array(); + + // getRoomList'ten gelen block[] ve rooms[] ile detail'i zenginleştir + if (!empty($roomListData['block'])) { + $detail['block'] = $roomListData['block']; + } + if (!empty($roomListData['rooms'])) { + $detail['rooms'] = $roomListData['rooms']; + } + + // Facility listesi + $facilResp = $client->get(self::API_BASE . '/api/v1/hotels/getHotelFacilities', array( + 'query' => array('hotel_id' => $hotelId), + )); + $facilData = json_decode($facilResp->getBody()->getContents(), true); + $facilData = isset($facilData['data']) ? $facilData['data'] : array(); + + // Otel fotograflari + $photoResp = $client->get(self::API_BASE . '/api/v1/hotels/getHotelPhotos', array( + 'query' => array('hotel_id' => $hotelId), + )); + $photoData = json_decode($photoResp->getBody()->getContents(), true); + + return array('detail' => $detail, 'facilities' => $facilData, 'photos' => $photoData); + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 1: Kullanıcı + Property oluştur + // → user/register-user-with-property mantığı + // ───────────────────────────────────────────────────────────────────────────── + private function createUserAndProperty(array $params, $propertyName, $userId = null) + { + // Kullanıcı zaten varsa sadece property ekle + $userService = app(\App\Core\Service\UserService::class); + $propertyService = app(\App\Core\Service\PropertyService::class); + $userPropertyMappingService = app(\App\Core\Service\UserPropertyMappingService::class); + $productService = app(\App\Core\Service\ProductService::class); + $jwtService = app(\App\Core\Service\JwtService::class); + $apiAccessTokenService = app(\App\Core\Service\ApiAccessTokenService::class); + + // Kullanıcı oluştur + $userParams = array( + 'name' => $params['name'], + 'surname' => $params['surname'], + 'email' => $params['email'], + 'password' => $params['password'], + 'status' => 1, + 'user_type' => 1, + 'property_name' => $propertyName, + ); + $userCreate = $userService->create($userParams); + if ($userCreate['status'] != 'success') { + throw new ApiErrorException('Kullanıcı oluşturulamadı: ' . $userCreate['message']); + } + $user = $userCreate['data']; + + // UserService::create rastgele şifre üretiyor (Str::random(6)) + // Kullanıcının istediği şifreyi DB'ye doğrudan güncelle + DB::table('user') + ->where('id', $user['id']) + ->update(array('password' => \Illuminate\Support\Facades\Hash::make($params['password']))); + + // Property oluştur + $propertyCreate = $propertyService->create(array( + 'name' => $propertyName, + 'status' => 1, + 'created_by' => $user['id'], + 'updated_by' => $user['id'], + 'created_at' => time(), + 'updated_at' => time(), + )); + if ($propertyCreate['status'] != 'success') { + throw new ApiErrorException('Property oluşturulamadı: ' . $propertyCreate['message']); + } + $property = $propertyCreate['data']; + + // User-Property mapping + $mappingCreate = $userPropertyMappingService->create(array( + 'user_id' => $user['id'], + 'property_id' => $property['id'], + 'status' => 1, + 'created_by' => $user['id'], + 'updated_by' => $user['id'], + 'created_at' => time(), + 'updated_at' => time(), + )); + if ($mappingCreate['status'] != 'success') { + throw new ApiErrorException('Kullanıcı-Property eşleştirme hatası: ' . $mappingCreate['message']); + } + + // Default ürünleri ata + $productService->setDefaultPropertyProducts(array( + 'user_id' => $user['id'], + 'property_id' => $property['id'], + )); + + // JWT token al + $jwtResult = $jwtService->jwtCreate(array('user_id' => $user['id'])); + if ($jwtResult['status'] != 'success') { + throw new ApiErrorException('Token oluşturulamadı'); + } + $jwt = $jwtResult['data']; + + $apiAccessTokenService->create(array( + 'token' => md5(fillOnUndefined($jwt, 'token')), + 'expire_date' => fillOnUndefined($jwt, 'exp'), + 'user_id' => $user['id'], + 'invalidate' => fillOnUndefined($jwt, 'invalidate', 0), + )); + + return array( + 'user' => $user, + 'property_id' => $property['id'], + 'token' => $jwt['token'], + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 2: Property bilgilerini güncelle + // → property/info/update + // Booking.com detail → property_info, additional_info, locale + // ───────────────────────────────────────────────────────────────────────────── + private function updatePropertyInfo($propertyId, $userId, array $detail) + { + $propertyService = app(\App\Core\Service\PropertyService::class); + + $name = isset($detail['hotel_name']) ? $detail['hotel_name'] : null; + $raw = isset($detail['rawData']) ? $detail['rawData'] : array(); + + // Stars: rawData.accuratePropertyClass > rawData.propertyClass > rawData.qualityClass + $rating = null; + foreach (array('accuratePropertyClass', 'propertyClass', 'qualityClass') as $rk) { + if (!empty($raw[$rk])) { + $rating = (int) $raw[$rk]; + break; + } + } + + // Check-in/out: rawData.checkin.fromTime / rawData.checkout.untilTime + $checkIn = isset($raw['checkin']['fromTime']) ? $raw['checkin']['fromTime'] : null; + $checkOut = isset($raw['checkout']['untilTime']) ? $raw['checkout']['untilTime'] : null; + + // Ülke kodu (max 5 char) + $countryCode = null; + foreach (array('countryCode', 'countrycode', 'country_code') as $ck) { + if (!empty($raw[$ck])) { + $countryCode = strtoupper($raw[$ck]); + break; + } + } + if (!$countryCode && !empty($detail['countrycode'])) { + $countryCode = strtoupper($detail['countrycode']); + } + + // Konuşulan diller: "en-gb" → "en_gb", "tr" → "tr" + $spokenRaw = isset($detail['spoken_languages']) ? $detail['spoken_languages'] : array('en'); + $langCodes = array(); + foreach ($spokenRaw as $lang) { + $normalized = str_replace('-', '_', strtolower($lang)); + // Sadece 2 veya 5 harfli geçerli kodlar + if (preg_match('/^[a-z]{2}(_[a-z]{2})?$/', $normalized)) { + $langCodes[] = $normalized; + } + } + if (empty($langCodes)) { + $langCodes = array('en'); + } + + $updateParams = array( + 'property_id' => $propertyId, + 'user_id' => $userId, + 'locale' => 'en', + 'has_locale_name' => false, + 'property_language_spoken' => $langCodes, + 'property_info' => array( + 'name' => $name, + 'property_type_id' => 1, // 1 = Hotel + 'chain_id' => 1, // 1 = Independent + 'rating' => $rating, + 'country' => $countryCode, + ), + 'additional_info' => array( + 'checkin_time' => $checkIn, + 'checkout_time' => $checkOut, + 'number_of_rooms' => !empty($detail['number_of_rooms']) ? (string)$detail['number_of_rooms'] : null, + 'property_timezone' => !empty($detail['timezone']) + ? $this->resolveTimezoneId($detail['timezone']) + : null, + ), + ); + + $result = $propertyService->propertyUpdate($updateParams); + if ($result['status'] != 'success') { + throw new ApiErrorException('Property güncelleme hatası: ' . $result['message']); + } + + return $result['data']; + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 3: İletişim bilgilerini kaydet + // → property/contact/update + // ───────────────────────────────────────────────────────────────────────────── + private function updatePropertyContact($propertyId, $userId, array $detail, $phone = null) + { + $propertyContactService = app(\App\Core\Service\PropertyContactService::class); + + // Booking.com top-level alanlar + $email = isset($detail['email']) ? $detail['email'] : null; + $web = isset($detail['url']) ? $detail['url'] : null; + $address = isset($detail['address']) ? $detail['address'] : null; + $zip = isset($detail['zip']) ? $detail['zip'] : null; + $lat = isset($detail['latitude']) ? $detail['latitude'] : null; + $lng = isset($detail['longitude']) ? $detail['longitude'] : null; + + if (!$phone && isset($detail['phone'])) { + $phone = $detail['phone']; + } + + // Validator: email required|email — boşsa placeholder kullan + if (!$email) { + $email = 'property' . $propertyId . '@extranetwork.com'; + } + + // Validator: phone veya mobile gerekli + if (!$phone) { + $phone = '0000000000'; + } + + $contactParams = array( + 'property_id' => $propertyId, + 'user_id' => $userId, + 'contact' => array( + 'phone' => $phone, + 'email' => $email, + 'web' => $web, + 'address' => $address, + 'zip_code' => $zip, + 'latitude' => $lat, + 'longitude' => $lng, + ), + ); + + $result = $propertyContactService->propertyContactUpdateOrCreate($contactParams); + if ($result['status'] != 'success') { + throw new ApiErrorException('İletişim kaydetme hatası: ' . $result['message']); + } + + return $result['data']; + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 4: Facility eşleştir → property_fact_mapping'e ekle + // → property/fact-mapping/add + // ───────────────────────────────────────────────────────────────────────────── + private function mapAndSaveFacilities($propertyId, $userId, array $facilData) + { + $propertyFactMappingService = app(\App\Core\Service\PropertyFactMappingService::class); + + // Tüm API isimlerini topla + $apiNames = array(); + $addUniq = function ($name) use (&$apiNames) { + $name = trim($name); + if ($name !== '' && !in_array($name, $apiNames)) { + $apiNames[] = $name; + } + }; + + if (isset($facilData['facilities']) && is_array($facilData['facilities'])) { + foreach ($facilData['facilities'] as $fac) { + if (!empty($fac['instances'])) { + foreach ($fac['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + if (isset($facilData['accommodationHighlights']) && is_array($facilData['accommodationHighlights'])) { + foreach ($facilData['accommodationHighlights'] as $h) { + if (!empty($h['title'])) { + $addUniq($h['title']); + } + } + } + if (isset($facilData['highlights']) && is_array($facilData['highlights'])) { + foreach ($facilData['highlights'] as $h) { + if (!empty($h['instances'])) { + foreach ($h['instances'] as $inst) { + if (!empty($inst['title'])) { + $addUniq($inst['title']); + } + } + } + } + } + + // DB exact index + $allFacts = PropertyFact::select(array('id', 'name', 'type'))->get(); + $exactIndex = array(); + foreach ($allFacts as $fact) { + $key = mb_strtolower(trim($fact->name)); + if (!isset($exactIndex[$key]) || $fact->type == 1) { + $exactIndex[$key] = $fact; + } + } + + $saved = array(); + $skipped = array(); + + foreach ($apiNames as $apiName) { + $lower = mb_strtolower(trim($apiName)); + $searchKey = isset($this->aliasMap[$lower]) ? $this->aliasMap[$lower] : $lower; + $fact = null; + $matchType = 'none'; + + // 1. Exact / alias + if (isset($exactIndex[$searchKey])) { + $fact = $exactIndex[$searchKey]; + $matchType = ($searchKey !== $lower) ? 'alias' : 'exact'; + } + + // 2. DB LIKE + if (!$fact) { + $like = PropertyFact::where('type', 1) + ->whereRaw('LOWER(name) LIKE ?', array('%' . $lower . '%')) + ->orderByRaw('LENGTH(name) ASC') + ->first(); + if ($like) { + $fact = $like; + $matchType = 'like'; + } + } + + // 3. Ters LIKE + if (!$fact) { + $reverse = PropertyFact::where('type', 1) + ->whereRaw('LOWER(?) LIKE CONCAT(\'%\', LOWER(name), \'%\')', array($lower)) + ->whereRaw('LENGTH(name) >= 5') + ->orderByRaw('LENGTH(name) DESC') + ->first(); + if ($reverse) { + $fact = $reverse; + $matchType = 'reverse_like'; + } + } + + if ($fact) { + // Kaydet + $mappingResult = $propertyFactMappingService->addPropertyFactMapping(array( + 'property_id' => $propertyId, + 'user_id' => $userId, + 'data' => array( + array('id' => $fact->id), + ), + )); + $saved[] = array( + 'api_name' => $apiName, + 'fact_id' => $fact->id, + 'fact_name' => $fact->name, + 'match_type' => $matchType, + 'saved' => ($mappingResult['status'] == 'success'), + ); + } else { + $skipped[] = $apiName; + } + } + + return array( + 'api_total' => count($apiNames), + 'saved_count' => count($saved), + 'skipped_count' => count($skipped), + 'saved' => $saved, + 'skipped' => $skipped, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 5: Booking.com'daki oda bilgilerinden oda ekle + // → property/room/add-room-bed + // ───────────────────────────────────────────────────────────────────────────── + // ───────────────────────────────────────────────────────────────────────────── + // Booking.com bed_type ID → sistemdeki property_room_bed_type.id + // + // Booking.com standart IDs (DataCrawler API): + // 1=Twin 2=Double 3=King 4=Queen 5=Single 6=Sofa 7=Bunk 8=Futon + // Sistemdeki property_room_bed_type: + // 1=Bunk Bed 2=Double Bed 3=French Bed 4=Futon 5=King Bed + // 6=Queen Bed 7=Single Bed 8=Sofa Bed 9=Twin Bed 10=Foldable Bed + // 11=Sleeping Bag 12=Triple Bunk Bed 13=Extra bed 14=Cot + // ───────────────────────────────────────────────────────────────────────────── + private $bedTypeMap = array( + 1 => 9, // Twin Bed(s) → Twin Bed + 2 => 2, // Double Bed → Double Bed + 3 => 5, // King Bed → King Bed + 4 => 6, // Queen Bed → Queen Bed + 5 => 7, // Single Bed → Single Bed + 6 => 8, // Sofa Bed → Sofa Bed + 7 => 1, // Bunk Bed → Bunk Bed + 8 => 4, // Futon → Futon + 9 => 3, // French Bed → French Bed + 10 => 10, // Foldable Bed → Foldable Bed + 37 => 14, // Cot/Cribs → Cot + 40 => 13, // Extra Bed → Extra bed + ); + + // ───────────────────────────────────────────────────────────────────────────── + // Booking.com view adı (highlight.translated_name) → property_room_view_type.id + // ───────────────────────────────────────────────────────────────────────────── + private $viewTypeMap = array( + 'park view' => 1, + 'pool view' => 2, + 'river view' => 3, + 'sea view' => 4, + 'ocean view' => 22, + 'street view' => 5, + 'valley view' => 6, + 'monument view' => 7, + 'bay view' => 8, + 'beach view' => 9, + 'city view' => 10, + 'countryside view' => 11, + 'courtyard view' => 12, + 'garden view' => 13, + 'gulf view' => 14, + 'harbor view' => 15, + 'lagoon view' => 16, + 'lake view' => 17, + 'marina view' => 18, + 'mountain view' => 19, + 'nature view' => 20, + 'no window' => 21, + 'land view' => 23, + 'forest view' => 24, + 'island view' => 25, + 'golf course view' => 26, + 'landmark view' => 30, + 'sea view' => 4, + ); + + // ───────────────────────────────────────────────────────────────────────────── + // Booking.com oda adı keyword → property_room_type.id + // ───────────────────────────────────────────────────────────────────────────── + private $roomTypeKeywords = array( + 'standard' => 24, // Standard Room + 'standart' => 24, + 'single' => 42, // Single Room + 'double' => 43, // Double Room + 'twin' => 43, // Double Room (çoğu twin=double planı) + 'triple' => 44, // Triple Room + 'quad' => 45, // Quadruple Room + 'family' => 18, // Family Room + 'suite' => 25, // Suite + 'junior suite' => 20, + 'grand suite' => 19, + 'king suite' => 21, + 'deluxe' => 16, // Deluxe + 'superior' => 26, // Superior + 'executive' => 48, // Executive Room + 'villa' => 27, // Villa + 'bungalow' => 14, // Bungalow + 'loft' => 31, // Loft Room + 'studio' => 29, // Studio Room + 'apart' => 12, // Apartment + 'apartment' => 12, + 'penthouse' => 22, // Pent House + 'accessible' => 11, // Accessible Room + 'honeymoon' => 34, // Honeymoon Room + 'economy' => 17, // Economy + 'premium' => 23, // Premium Room + 'club' => 15, // Club Room + 'swim up' => 46, // Swim Up Room + 'swim-up' => 46, + 'corner' => 49, // Corner Room + 'large' => 47, // Standard Large Room + ); + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 5: Booking.com'daki oda bilgilerinden oda ekle + // + // Kaynak 1: detail['block'][] → room_name, max_occupancy, nr_adults, + // room_surface_in_m2, number_of_bathrooms + // Kaynak 2: detail['rooms'][id] → bed_configurations, highlights (view) + // ───────────────────────────────────────────────────────────────────────────── + private function insertRooms($propertyId, $userId, array $detail) + { + $propertyRoomService = app(\App\Core\Service\PropertyRoomService::class); + + // ── Kaynak 1: block[] → her room_id için tek kayıt ────────────────────── + $blockByRoomId = array(); + $blockRaw = isset($detail['block']) ? $detail['block'] : array(); + foreach ($blockRaw as $b) { + $rid = isset($b['room_id']) ? $b['room_id'] : null; + if ($rid && !isset($blockByRoomId[$rid])) { + $blockByRoomId[$rid] = $b; + } + } + + // ── Kaynak 2: rooms[room_id] → bed configs + view highlights ──────────── + $roomsRaw = isset($detail['rooms']) ? $detail['rooms'] : array(); + + // rooms[] boşsa sadece block verisini kullan + if (empty($roomsRaw) && empty($blockByRoomId)) { + // Hiç oda yoksa tek generic oda + $blockByRoomId = array( + 0 => array( + 'room_name' => 'Standard Room', + 'max_occupancy' => 2, + 'nr_adults' => 2, + 'room_surface_in_m2' => null, + 'number_of_bathrooms' => null, + ), + ); + } + + // rooms[] boşsa block ID'lerini rooms olarak kullan + if (empty($roomsRaw)) { + foreach ($blockByRoomId as $rid => $b) { + $roomsRaw[$rid] = array(); + } + } + if (empty($blockByRoomId)) { + foreach (array_keys($roomsRaw) as $rid) { + $blockByRoomId[$rid] = array(); + } + } + + // Distinct room_id birleşimi + $allRoomIds = array_unique(array_merge(array_keys($blockByRoomId), array_keys($roomsRaw))); + + $inserted = array(); + + foreach ($allRoomIds as $roomId) { + $block = isset($blockByRoomId[$roomId]) ? $blockByRoomId[$roomId] : array(); + $room = isset($roomsRaw[$roomId]) ? $roomsRaw[$roomId] : array(); + + // ── Oda adı ────────────────────────────────────────────────────────── + $roomName = trim(isset($block['room_name']) ? $block['room_name'] : 'Standard Room'); + + // ── room_type_id: oda adındaki anahtar kelimeye göre ───────────────── + $roomTypeId = $this->guessRoomTypeId($roomName); + + // ── Kapasite ───────────────────────────────────────────────────────── + $maxOccupancy = isset($block['max_occupancy']) ? (int)$block['max_occupancy'] : 2; + $maxAdult = isset($block['nr_adults']) ? (int)$block['nr_adults'] : $maxOccupancy; + $maxChild = isset($block['nr_children']) ? (int)$block['nr_children'] : 0; + + // ── Oda boyutu ─────────────────────────────────────────────────────── + // Validator required|max:30 → null yerine 0 gönder + $roomSizeRaw = isset($block['room_surface_in_m2']) ? (int)$block['room_surface_in_m2'] : 0; + $roomSize = $roomSizeRaw > 0 ? $roomSizeRaw : 0; + $roomSizeType = $roomSizeRaw > 0 ? 1 : 0; // 1 = m² + + // ── Oda adedi (kaç adet bu tipten var) ────────────────────────────── + $roomTypeCount = isset($block['room_count']) && $block['room_count'] > 0 + ? (int)$block['room_count'] : 1; + + // ── Banyo sayısı ───────────────────────────────────────────────────── + $bathroomCount = isset($block['number_of_bathrooms']) && $block['number_of_bathrooms'] > 0 + ? (int)$block['number_of_bathrooms'] : null; + + // ── Açıklama ───────────────────────────────────────────────────────── + $description = isset($room['description']) ? $room['description'] : null; + + // ── Yatak konfigürasyonları → room_bed_group ───────────────────────── + // Sistem formatı: [[{bed_type_id:9}, {bed_type_id:9}], [{bed_type_id:2}]] + // Her conf = bir grup, içindeki bed_types[].count kadar tekrar + $bedConfigs = isset($room['bed_configurations']) ? $room['bed_configurations'] : array(); + $roomBedGroup = array(); + + foreach ($bedConfigs as $conf) { + $groupBeds = array(); + $bedTypes = isset($conf['bed_types']) ? $conf['bed_types'] : array(); + foreach ($bedTypes as $bt) { + $bookingBedId = isset($bt['bed_type']) ? (int)$bt['bed_type'] : 0; + $ourBedTypeId = isset($this->bedTypeMap[$bookingBedId]) ? $this->bedTypeMap[$bookingBedId] : null; + $bedCount = isset($bt['count']) ? (int)$bt['count'] : 1; + if ($ourBedTypeId) { + for ($i = 0; $i < $bedCount; $i++) { + $groupBeds[] = array('bed_type_id' => $ourBedTypeId); + } + } + } + if (!empty($groupBeds)) { + $roomBedGroup[] = $groupBeds; + } + } + + // ── View tipleri → room_view_type ──────────────────────────────────── + // Booking.com highlights'daki "translated_name" → viewTypeMap eşleşmesi + // Eşleşmezse icon'a bak: "city"→10, "sea"→4, "pool"→2, "mountain"→19 + $iconViewMap = array( + 'city' => 10, + 'sea' => 4, + 'ocean' => 22, + 'pool' => 2, + 'mountain' => 19, + 'garden' => 13, + 'park' => 1, + 'river' => 3, + 'lake' => 17, + 'beach' => 9, + 'forest' => 24, + 'harbor' => 15, + 'marina' => 18, + 'eye' => 4, // Booking.com Sea view ikonu "eye" olarak geliyor + 'landmark' => 30, // Landmark view + ); + $highlights = isset($room['highlights']) ? $room['highlights'] : array(); + $roomViewType = array(); + foreach ($highlights as $h) { + $hName = mb_strtolower(trim(isset($h['translated_name']) ? $h['translated_name'] : '')); + $hIcon = mb_strtolower(trim(isset($h['icon']) ? $h['icon'] : '')); + $viewId = null; + // 1) Tam eşleşme: "city view" + if (isset($this->viewTypeMap[$hName])) { + $viewId = $this->viewTypeMap[$hName]; + } + // 2) Kısmi eşleşme: highlight adında keyword geçiyor + if (!$viewId) { + foreach ($this->viewTypeMap as $keyword => $vid) { + $base = str_replace(' view', '', $keyword); + if (strpos($hName, $base) !== false) { + $viewId = $vid; + break; + } + } + } + // 3) Icon eşleşmesi: "city" ikonu → 10 + if (!$viewId && isset($iconViewMap[$hIcon])) { + $viewId = $iconViewMap[$hIcon]; + } + if ($viewId && !in_array($viewId, $roomViewType)) { + $roomViewType[] = $viewId; + } + } + + // ── Service'e gönder ───────────────────────────────────────────────── + $roomParams = array( + 'property_id' => $propertyId, + 'user_id' => $userId, + 'locale' => 'en', + 'name' => $roomName, + 'room_type_id' => $roomTypeId, + 'max_occupancy' => $maxOccupancy, + 'max_adult' => $maxAdult, + 'max_child' => $maxChild, + 'occupancy_lock' => 0, + 'exclude_occupancy' => 0, + 'room_size' => $roomSize, + 'room_size_type' => $roomSizeType, + 'room_type_count' => $roomTypeCount, + 'bathroom_count' => $bathroomCount, + 'toilet_count' => null, + 'lounge_count' => null, + 'room_count' => null, + 'max_child_number' => null, + 'description' => array( + array('language_code' => 'en', 'description' => $description) + ), + 'room_bed_group' => $roomBedGroup, + 'room_view_type' => $roomViewType, + 'is_connected_room' => null, + 'is_connected_room_price' => null, + 'is_connected_room_availability' => null, + 'connected_rooms' => array(), + ); + + $result = $propertyRoomService->addPropertyRoomAndBed($roomParams); + $isSaved = ($result['status'] == 'success' || $result['status'] === true); + $facSummary = array(); + $photoSummary = array(); + + if ($isSaved) { + // addPropertyRoomAndBed data döndürmüyor — son eklenen room_id'yi çek + $newRoom = DB::table('property_room') + ->where('property_id', $propertyId) + ->where('name', $roomName) + ->orderBy('id', 'desc') + ->first(); + $newRoomId = $newRoom ? $newRoom->id : null; + + if ($newRoomId) { + // Oda olanakları → property_room_fact_mapping + if (!empty($room['facilities'])) { + $facSummary = $this->mapAndSaveRoomFacilities( + $newRoomId, + $propertyId, + $userId, + $room['facilities'] + ); + } + + // Oda fotoğrafları → property_photo + property_room_photo_mapping + if (!empty($room['photos'])) { + $photoSummary = $this->mapAndSaveRoomPhotos( + $newRoomId, + $propertyId, + $userId, + $room['photos'], + isset($detail['hotel_id']) ? $detail['hotel_id'] : 0 + ); + } + } + } + + $inserted[] = array( + 'room_id' => $roomId, + 'room_name' => $roomName, + 'room_type_id' => $roomTypeId, + 'beds' => array_map(function ($g) { + return $g; + }, $roomBedGroup), + 'views' => $roomViewType, + 'room_facts' => $facSummary, + 'room_photos' => $photoSummary, + 'saved' => $isSaved, + 'message' => !$isSaved ? $result['message'] : null, + ); + } + + return array( + 'room_count' => count($inserted), + 'rooms' => $inserted, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // Oda fotoğraflarını indir, property_photo'ya kaydet, room_photo_mapping'e bağla + // Booking.com: rooms[id]['photos'] → [{url_original, url_max750, ...}] + // ───────────────────────────────────────────────────────────────────────────── + private function mapAndSaveRoomPhotos($roomId, $propertyId, $userId, array $photos, $hotelId) + { + if (empty($photos)) { + return array('saved_count' => 0, 'skipped_count' => 0); + } + + $uploadRoot = rtrim(Config::get('app.fileSystemDriver'), '/'); + $urlPath = '/property-photos/' . $propertyId . '/'; + $filePath = $uploadRoot . $urlPath; + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + $saved = array(); + $skipped = array(); + $index = 0; + + foreach ($photos as $photo) { + // URL: url_original > url_max750 > url_max1280 > url_max300 + $url = ''; + foreach (array('url_original', 'url_max750', 'url_max1280', 'url_max300') as $key) { + if (!empty($photo[$key])) { + $url = $photo[$key]; + break; + } + } + if ($url === '') { + $skipped[] = 'empty_url'; + continue; + } + + try { + $photoId = isset($photo['photo_id']) ? $photo['photo_id'] : ''; + $fileName = time() . '_bk' . $hotelId . '_r' . $roomId . '_' . $index; + $fileExt = 'jpg'; + $tempPath = sys_get_temp_dir() . '/' . $fileName . '_orig.jpg'; + + $this->downloadRawImage($url, $tempPath); + + $image = Image::make($tempPath); + $imageWidth = $image->width(); + $imageHeight = $image->height(); + $fileSize = (int) ceil(filesize($tempPath) / 1024); + $quality = 80; + + // Orijinal — 2000px üzeriyse küçült + if ($imageHeight > 2000 || $imageWidth > 2000) { + if ($imageHeight > $imageWidth) { + $r = $imageHeight / 2000; + $image->fit((int)($imageWidth / $r), 2000); + } else { + $r = $imageWidth / 2000; + $image->fit(2000, (int)($imageHeight / $r)); + } + } + $image->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt); + + // _medium (max 1600x768) + $mediumImage = Image::make($tempPath); + $ratio = $imageHeight > 0 ? ($imageHeight / 768) : 1; + $resizeWidth = (int)($imageWidth / max($ratio, 1)); + if ($resizeWidth > 1599) { + $mediumImage->fit(1600, 768); + } else { + $mediumImage->fit(max($resizeWidth, 1), 768); + } + $mediumImage->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '_medium.' . $fileExt); + + // _thumbnail (300x300) + Image::make($tempPath) + ->fit(300, 300) + ->encode($fileExt, $quality) + ->orientate() + ->save($filePath . $fileName . '_thumbnail.' . $fileExt); + + if (File::exists($tempPath)) { + File::delete($tempPath); + } + + $isCompatible = ($imageWidth >= 1150 && $imageHeight >= 600) ? 1 : 0; + + $photoRecord = PropertyPhoto::create(array( + 'property_id' => $propertyId, + 'property_photo_category_id' => 1, + 'photo_path' => $urlPath, + 'photo_name' => $fileName, + 'file_size' => $fileSize, + 'file_ext' => $fileExt, + 'photo_resolution' => $imageWidth . 'x' . $imageHeight, + 'is_default' => 0, + 'is_compatible_with_myweb_slider' => $isCompatible, + 'photo_order' => 0, + 'photo_rank' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + )); + + // property_room_photo_mapping'e bağla + $alreadyLinked = DB::table('property_room_photo_mapping') + ->where('room_id', $roomId) + ->where('photo_id', $photoRecord->id) + ->exists(); + + if (!$alreadyLinked) { + DB::table('property_room_photo_mapping')->insert(array( + 'property_id' => $propertyId, + 'room_id' => $roomId, + 'photo_id' => $photoRecord->id, + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => time(), + 'updated_at' => time(), + )); + } + + $saved[] = array( + 'photo_id' => $photoRecord->id, + 'file_name' => $fileName . '.' . $fileExt, + 'resolution' => $imageWidth . 'x' . $imageHeight, + 'source_url' => $url, + ); + } catch (Exception $e) { + Log::error('propertyInsert.roomPhoto [room=' . $roomId . ', i=' . $index . ']: ' . $e->getMessage()); + $skipped[] = $url; + } + + $index++; + } + + return array( + 'saved_count' => count($saved), + 'skipped_count' => count($skipped), + 'photos' => $saved, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // Oda olanaklarını (room facilities) property_room_fact_mapping'e kaydet + // Booking.com: rooms[id]['facilities'] → [{id, name, alt_facilitytype_id, ...}] + // View tiplerini atla (viewTypeMap ile zaten ekleniyor) + // ───────────────────────────────────────────────────────────────────────────── + private function mapAndSaveRoomFacilities($roomId, $propertyId, $userId, array $facilities) + { + // View kategorisi facilitytype_id'leri (9=View, 14=View alt) — zaten view mapping'de ekleniyor + $skipFacilityTypeIds = array(9, 14); + + // Sistemdeki tüm fact'leri küçük harfli isimle index'e al (type=1: property/room fact) + $allFacts = PropertyFact::select(array('id', 'name', 'type'))->where('type', 1)->get(); + $exactIndex = array(); + foreach ($allFacts as $fact) { + $key = mb_strtolower(trim($fact->name)); + // Aynı isimde birden fazla fact varsa daha küçük id'liyi (ilk ekleneni) tut + if (!isset($exactIndex[$key])) { + $exactIndex[$key] = $fact; + } + } + + // roomAliasMap (oda özel) + aliasMap (genel) birleştir, room öncelikli + $combinedAlias = array_merge($this->aliasMap, $this->roomAliasMap); + + $saved = array(); + $skipped = array(); + + foreach ($facilities as $fac) { + // View tiplerini atla + $faciltypeId = isset($fac['facilitytype_id']) ? (int)$fac['facilitytype_id'] : 0; + $altFaciltypeId = isset($fac['alt_facilitytype_id']) ? (int)$fac['alt_facilitytype_id'] : 0; + if (in_array($faciltypeId, $skipFacilityTypeIds) || in_array($altFaciltypeId, $skipFacilityTypeIds)) { + continue; + } + + $name = trim(isset($fac['name']) ? $fac['name'] : ''); + if ($name === '') { + continue; + } + + $lower = mb_strtolower($name); + // Alias map'te varsa o karşılığı kullan, yoksa direkt ismi kullan + $searchKey = isset($combinedAlias[$lower]) ? mb_strtolower($combinedAlias[$lower]) : $lower; + $fact = null; + + // Sadece birebir eşleşme — tahmin yok, LIKE yok + if (isset($exactIndex[$searchKey])) { + $fact = $exactIndex[$searchKey]; + } + + if ($fact) { + // Yalnızca mevcut property_room_fact_mapping tablosuna yaz, yeni kayıt türü oluşturma + $exists = DB::table('property_room_fact_mapping') + ->where('property_id', $propertyId) + ->where('room_id', $roomId) + ->where('fact_id', $fact->id) + ->exists(); + + if (!$exists) { + DB::table('property_room_fact_mapping')->insert(array( + 'property_id' => $propertyId, + 'room_id' => $roomId, + 'fact_id' => $fact->id, + 'is_feature' => 0, + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => time(), + 'updated_at' => time(), + )); + } + + $saved[] = array( + 'booking_name' => $name, + 'fact_id' => $fact->id, + 'fact_name' => $fact->name, + 'via_alias' => ($searchKey !== $lower), + ); + } else { + // Eşleşme yok — sisteme kesinlikle bir şey yazma, sadece logla + Log::warning('propertyInsert.roomFacility.noMatch', array( + 'room_id' => $roomId, + 'property_id' => $propertyId, + 'booking_name' => $name, + 'search_key' => $searchKey, + 'hint' => 'roomAliasMap veya aliasMap\'e eklenebilir', + )); + $skipped[] = $name; + } + } + + return array( + 'saved_count' => count($saved), + 'skipped_count' => count($skipped), + 'saved' => $saved, + 'skipped' => $skipped, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // Oda adındaki anahtar kelimelere göre room_type_id tahmin et + // ───────────────────────────────────────────────────────────────────────────── + private function guessRoomTypeId($roomName) + { + $lower = mb_strtolower($roomName); + + // Önce çift kelimeli eşleşmeleri dene (daha spesifik) + foreach ($this->roomTypeKeywords as $keyword => $typeId) { + if (strpos($keyword, ' ') !== false && strpos($lower, $keyword) !== false) { + return $typeId; + } + } + // Sonra tek kelimeli + foreach ($this->roomTypeKeywords as $keyword => $typeId) { + if (strpos($keyword, ' ') === false && strpos($lower, $keyword) !== false) { + return $typeId; + } + } + + return 24; // Default: Standard Room + } + + // ───────────────────────────────────────────────────────────────────────────── + // ANA METOD: POST /bulut/property-insert + // ───────────────────────────────────────────────────────────────────────────── + public function insert(Request $request) + { + $hotelId = $request->input('hotel_id', ''); + $email = $request->input('email', ''); + $password = $request->input('password', ''); + $name = $request->input('name', ''); + $surname = $request->input('surname', ''); + $propertyName = $request->input('property_name', ''); + $phone = $request->input('phone', null); + $dryRun = (bool) $request->input('dry_run', false); + $checkin = $request->input('checkin', date('Y-m-d', strtotime('+30 days'))); + $checkout = $request->input('checkout', date('Y-m-d', strtotime('+31 days'))); + + // Zorunlu alan validasyonu + $required = array('hotel_id', 'email', 'password', 'name', 'surname', 'property_name'); + $missing = array(); + foreach ($required as $field) { + if (!$request->input($field)) { + $missing[] = $field; + } + } + if (count($missing)) { + return response()->json(array( + 'status' => false, + 'message' => 'Eksik alanlar: ' . implode(', ', $missing), + ), 422); + } + + $report = array( + 'hotel_id' => $hotelId, + 'dry_run' => $dryRun, + 'steps' => array(), + ); + + try { + DB::beginTransaction(); + + // ── ADIM 0: Booking.com'dan veri çek ───────────────────────────────── + $report['steps']['0_booking_fetch'] = array('status' => 'pending'); + $bookingData = $this->fetchBookingData($hotelId, $checkin, $checkout); + $detail = $bookingData['detail']; + $facilData = $bookingData['facilities']; + $photoData = $bookingData['photos']; + + $report['steps']['0_booking_fetch'] = array( + 'status' => 'success', + 'hotel_name' => isset($detail['hotel_name']) ? $detail['hotel_name'] : null, + 'facility_count' => $this->countFacilities($facilData), + 'photo_count' => count($this->extractPhotoUrls($photoData)), + ); + + // Eğer property_name boş geldiyse Booking.com adını kullan + if (!$propertyName && !empty($detail['hotel_name'])) { + $propertyName = $detail['hotel_name']; + } + + if ($dryRun) { + DB::rollBack(); + $report['dry_run_note'] = 'dry_run=true → DB\'ye hiçbir şey yazılmadı. Aşağıdaki veriler oluşturulacaktı.'; + $report['steps']['1_user_property'] = array('status' => 'skipped (dry_run)', 'email' => $email, 'property_name' => $propertyName); + $report['steps']['2_property_info'] = array('status' => 'skipped (dry_run)', 'data' => $this->previewPropertyInfo($detail)); + $report['steps']['3_contact'] = array('status' => 'skipped (dry_run)', 'phone' => $phone ?: (isset($detail['phone']) ? $detail['phone'] : null), 'email' => isset($detail['email']) ? $detail['email'] : null); + $report['steps']['4_fact_mapping'] = array('status' => 'skipped (dry_run)', 'facility_count' => $this->countFacilities($facilData)); + $report['steps']['5_rooms'] = array('status' => 'skipped (dry_run)'); + $report['steps']['6_photos'] = array('status' => 'skipped (dry_run)', 'photo_count' => count($this->extractPhotoUrls($photoData))); + return response()->json(array('status' => true, 'message' => 'Dry run tamamlandı', 'report' => $report)); + } + + // ── ADIM 1: Kullanıcı + Property oluştur ──────────────────────────── + $report['steps']['1_user_property'] = array('status' => 'pending'); + $userPropertyResult = $this->createUserAndProperty( + array('name' => $name, 'surname' => $surname, 'email' => $email, 'password' => $password), + $propertyName + ); + $createdUserId = $userPropertyResult['user']['id']; + $createdPropertyId = $userPropertyResult['property_id']; + + $report['steps']['1_user_property'] = array( + 'status' => 'success', + 'user_id' => $createdUserId, + 'property_id' => $createdPropertyId, + 'token' => $userPropertyResult['token'], + ); + + // ── ADIM 2: Property info güncelle ────────────────────────────────── + $report['steps']['2_property_info'] = array('status' => 'pending'); + $this->updatePropertyInfo($createdPropertyId, $createdUserId, $detail); + $raw2 = isset($detail['rawData']) ? $detail['rawData'] : array(); + $report['steps']['2_property_info'] = array( + 'status' => 'success', + 'hotel_name' => isset($detail['hotel_name']) ? $detail['hotel_name'] : null, + 'rating' => isset($raw2['accuratePropertyClass']) ? (int)$raw2['accuratePropertyClass'] : null, + 'country' => isset($detail['countrycode']) ? strtoupper($detail['countrycode']) : null, + 'checkin' => isset($raw2['checkin']['fromTime']) ? $raw2['checkin']['fromTime'] : null, + 'checkout' => isset($raw2['checkout']['untilTime']) ? $raw2['checkout']['untilTime'] : null, + 'languages' => isset($detail['spoken_languages']) ? $detail['spoken_languages'] : array(), + ); + + // ── ADIM 3: İletişim bilgilerini kaydet ────────────────────────────── + $report['steps']['3_contact'] = array('status' => 'pending'); + $this->updatePropertyContact($createdPropertyId, $createdUserId, $detail, $phone); + $report['steps']['3_contact'] = array( + 'status' => 'success', + 'phone' => $phone ?: (isset($detail['phone']) ? $detail['phone'] : null), + 'email' => isset($detail['email']) ? $detail['email'] : null, + ); + + // ── ADIM 4: Facility → Fact mapping ───────────────────────────────── + $report['steps']['4_fact_mapping'] = array('status' => 'pending'); + $facilityResult = $this->mapAndSaveFacilities($createdPropertyId, $createdUserId, $facilData); + $report['steps']['4_fact_mapping'] = array_merge(array('status' => 'success'), $facilityResult); + + // ── ADIM 5: Oda ekle ───────────────────────────────────────────────── + $report['steps']['5_rooms'] = array('status' => 'pending'); + $roomResult = $this->insertRooms($createdPropertyId, $createdUserId, $detail); + $report['steps']['5_rooms'] = array_merge(array('status' => 'success'), $roomResult); + + // ── ADIM 6: Görselleri indir ve kaydet ─────────────────────────────── + $report['steps']['6_photos'] = array('status' => 'pending'); + $photoLimit = $request->input('photo_limit', 20); + $photoResult = $this->processAndSavePhotos($photoData, $hotelId, $createdPropertyId, $photoLimit); + $report['steps']['6_photos'] = array_merge(array('status' => 'success'), $photoResult); + + DB::commit(); + + return response()->json(array( + 'status' => true, + 'message' => 'Property başarıyla oluşturuldu', + 'property_id' => $createdPropertyId, + 'user_id' => $createdUserId, + 'report' => $report, + )); + } catch (ApiErrorException $e) { + DB::rollBack(); + Log::error('propertyInsert.ApiError: ' . $e->getMessage()); + return response()->json(array( + 'status' => false, + 'message' => implode(', ', $e->getMessageArr()), + 'report' => $report, + ), 400); + } catch (Exception $e) { + DB::rollBack(); + Log::error('propertyInsert.Error: ' . $e->getFile() . ':' . $e->getLine() . ' ' . $e->getMessage()); + return response()->json(array( + 'status' => false, + 'message' => $e->getMessage(), + 'report' => $report, + ), 500); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // ADIM 6: Fotograflari indir, isle ve kaydet + // ───────────────────────────────────────────────────────────────────────────── + private function processAndSavePhotos(array $responseData, $hotelId, $propertyId, $limit = 20) + { + $photoUrls = $this->extractPhotoUrls($responseData); + + if (empty($photoUrls)) { + return array( + 'saved_count' => 0, + 'total_in_api' => 0, + 'message' => 'API yanitinda fotograf URL bulunamadi', + ); + } + + $uploadRoot = rtrim(Config::get('app.fileSystemDriver'), '/'); + $urlPath = '/property-photos/' . $propertyId . '/'; + $filePath = $uploadRoot . $urlPath; + + if (!File::exists($filePath)) { + File::makeDirectory($filePath, 0777, true); + } + + $hasDefault = PropertyPhoto::where('property_id', $propertyId) + ->where('status', 1) + ->where('is_default', 1) + ->exists(); + + $saved = array(); + $isFirstPhoto = true; + $total = min(count($photoUrls), $limit); + + for ($i = 0; $i < $total; $i++) { + $photoUrl = $photoUrls[$i]; + try { + $fileName = time() . '_bk' . $hotelId . '_' . $i; + $fileExt = 'jpg'; + $tempPath = sys_get_temp_dir() . '/' . $fileName . '_orig.jpg'; + + $this->downloadRawImage($photoUrl, $tempPath); + + $image = Image::make($tempPath); + $imageWidth = $image->width(); + $imageHeight = $image->height(); + $fileSize = (int) ceil(filesize($tempPath) / 1024); + $quality = 80; + + // Orijinal — 2000px uzeriyse kucult + if ($imageHeight > 2000 || $imageWidth > 2000) { + if ($imageHeight > $imageWidth) { + $r = $imageHeight / 2000; + $image->fit((int)($imageWidth / $r), 2000); + } else { + $r = $imageWidth / 2000; + $image->fit(2000, (int)($imageHeight / $r)); + } + } + $image->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '.' . $fileExt); + + // _medium (max 1600x768) + $mediumImage = Image::make($tempPath); + $ratio = $imageHeight > 0 ? ($imageHeight / 768) : 1; + $resizeWidth = (int)($imageWidth / max($ratio, 1)); + if ($resizeWidth > 1599) { + $mediumImage->fit(1600, 768); + } else { + $mediumImage->fit(max($resizeWidth, 1), 768); + } + $mediumImage->encode($fileExt, $quality)->orientate()->save($filePath . $fileName . '_medium.' . $fileExt); + + // _thumbnail (300x300) + Image::make($tempPath) + ->fit(300, 300) + ->encode($fileExt, $quality) + ->orientate() + ->save($filePath . $fileName . '_thumbnail.' . $fileExt); + + if (File::exists($tempPath)) { + File::delete($tempPath); + } + + $isCompatible = ($imageWidth >= 1150 && $imageHeight >= 600) ? 1 : 0; + $isDefault = (!$hasDefault && $isFirstPhoto) ? 1 : 0; + $isFirstPhoto = false; + + $photoRecord = PropertyPhoto::create(array( + 'property_id' => $propertyId, + 'property_photo_category_id' => 1, + 'photo_path' => $urlPath, + 'photo_name' => $fileName, + 'file_size' => $fileSize, + 'file_ext' => $fileExt, + 'photo_resolution' => $imageWidth . 'x' . $imageHeight, + 'is_default' => $isDefault, + 'is_compatible_with_myweb_slider' => $isCompatible, + 'photo_order' => 0, + 'photo_rank' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + )); + + $saved[] = array( + 'db_id' => $photoRecord->id, + 'file_name' => $fileName . '.' . $fileExt, + 'resolution' => $imageWidth . 'x' . $imageHeight, + 'source_url' => $photoUrl, + ); + } catch (Exception $e) { + Log::error('propertyInsert.photo [' . $i . ']: ' . $e->getMessage() . ' | ' . $photoUrl); + $saved[] = array('error' => $e->getMessage(), 'source_url' => $photoUrl); + } + } + + $okCount = count(array_filter($saved, function ($s) { + return !isset($s['error']); + })); + + return array( + 'saved_count' => $okCount, + 'total_in_api' => count($photoUrls), + 'limit_applied' => $total, + 'photos' => $saved, + ); + } + + private function extractPhotoUrls(array $data) + { + $urls = array(); + + // Format 1: data[] dizisi + if (isset($data['data']) && is_array($data['data']) && !empty($data['data'])) { + foreach ($data['data'] as $item) { + if (!is_array($item)) { + continue; + } + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url_max'])) { + $urls[] = $item['url_max']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } elseif (!empty($item['photo']['url_original'])) { + $urls[] = $item['photo']['url_original']; + } + } + } + + // Format 2: data.photos[] + if (empty($urls) && isset($data['data']['photos']) && is_array($data['data']['photos'])) { + foreach ($data['data']['photos'] as $item) { + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } + } + } + + // Format 3: photos[] root'ta + if (empty($urls) && isset($data['photos']) && is_array($data['photos'])) { + foreach ($data['photos'] as $item) { + if (!empty($item['url_original'])) { + $urls[] = $item['url_original']; + } elseif (!empty($item['url'])) { + $urls[] = $item['url']; + } + } + } + + return $urls; + } + + private function downloadRawImage($url, $savePath) + { + $client = new Client(array( + 'timeout' => 30, + 'verify' => false, + 'headers' => array('User-Agent' => 'Mozilla/5.0'), + )); + $response = $client->get($url, array('sink' => $savePath)); + if ($response->getStatusCode() !== 200) { + throw new Exception('Image download failed HTTP ' . $response->getStatusCode() . ' | ' . $url); + } + } + + // ───────────────────────────────────────────────────────────────────────────── + // Yardımcı: timezone string → general_timezone.id + // ───────────────────────────────────────────────────────────────────────────── + private function resolveTimezoneId($timezoneLocation) + { + $row = DB::table('general_timezone') + ->where('location', $timezoneLocation) + ->first(); + return $row ? (string)$row->id : null; + } + + // ───────────────────────────────────────────────────────────────────────────── + // Yardımcı: dry_run için property_info önizleme + // ───────────────────────────────────────────────────────────────────────────── + private function previewPropertyInfo(array $detail) + { + $raw = isset($detail['rawData']) ? $detail['rawData'] : array(); + $rating = null; + foreach (array('accuratePropertyClass', 'propertyClass', 'qualityClass') as $rk) { + if (!empty($raw[$rk])) { + $rating = (int)$raw[$rk]; + break; + } + } + return array( + 'name' => isset($detail['hotel_name']) ? $detail['hotel_name'] : null, + 'rating' => $rating, + 'country' => isset($detail['countrycode']) ? strtoupper($detail['countrycode']) : null, + 'address' => isset($detail['address']) ? $detail['address'] : null, + 'city' => isset($detail['city_name_en']) ? $detail['city_name_en'] : null, + 'district' => isset($detail['district']) ? $detail['district'] : null, + 'zip' => isset($detail['zip']) ? $detail['zip'] : null, + 'latitude' => isset($detail['latitude']) ? $detail['latitude'] : null, + 'longitude' => isset($detail['longitude']) ? $detail['longitude'] : null, + 'timezone' => isset($detail['timezone']) ? $detail['timezone'] : null, + 'checkin' => isset($raw['checkin']['fromTime']) ? $raw['checkin']['fromTime'] : null, + 'checkout' => isset($raw['checkout']['untilTime']) ? $raw['checkout']['untilTime'] : null, + 'languages' => isset($detail['spoken_languages']) ? $detail['spoken_languages'] : array(), + 'review_score' => isset($raw['reviewScore']) ? $raw['reviewScore'] : null, + ); + } + + // ───────────────────────────────────────────────────────────────────────────── + // Yardımcı: facility sayısını döndür + // ───────────────────────────────────────────────────────────────────────────── + private function countFacilities(array $facilData) + { + $count = 0; + if (isset($facilData['facilities'])) { + foreach ($facilData['facilities'] as $fac) { + $count += count(isset($fac['instances']) ? $fac['instances'] : array()); + } + } + return $count; + } + + // ───────────────────────────────────────────────────────────────────────────── + // GET /bulut/property-check?email=... + // Verilen email'e ait kullanıcı ve property bilgilerini döndür + // ───────────────────────────────────────────────────────────────────────────── + public function check(Request $request) + { + $email = trim($request->input('email', '')); + if (!$email) { + return response()->json(array('status' => false, 'message' => 'email parametresi gerekli'), 422); + } + + $user = DB::table('user')->where('email', $email)->first(); + if (!$user) { + return response()->json(array( + 'status' => false, + 'message' => 'Kullanıcı bulunamadı', + 'email' => $email, + )); + } + + // Kullanıcıya bağlı property'ler + $mappings = DB::table('user_property_mapping as upm') + ->join('property as p', 'p.id', '=', 'upm.property_id') + ->where('upm.user_id', $user->id) + ->select(array( + 'p.id as property_id', + 'p.name as property_name', + 'p.status as property_status', + 'upm.created_at', + )) + ->get(); + + $properties = array(); + foreach ($mappings as $m) { + $roomCount = DB::table('property_room')->where('property_id', $m->property_id)->count(); + $photoCount = DB::table('property_photo')->where('property_id', $m->property_id)->count(); + $factCount = DB::table('property_fact_mapping')->where('property_id', $m->property_id)->count(); + + $properties[] = array( + 'property_id' => $m->property_id, + 'property_name' => $m->property_name, + 'status' => $m->property_status, + 'room_count' => $roomCount, + 'photo_count' => $photoCount, + 'fact_count' => $factCount, + 'created_at' => date('Y-m-d H:i:s', $m->created_at), + ); + } + + return response()->json(array( + 'status' => true, + 'user_id' => $user->id, + 'email' => $user->email, + 'name' => $user->name . ' ' . $user->surname, + 'user_status' => $user->status, + 'properties' => $properties, + )); + } + + // ───────────────────────────────────────────────────────────────────────────── + // DELETE /bulut/property-delete + // Body: { "property_id": 123 } veya { "email": "..." } (emailde tüm property'ler) + // Odalar, fotoğraflar (dosya dahil), fact mapping, iletişim, user-property mapping, + // property kaydı ve kullanıcı silinir. + // ───────────────────────────────────────────────────────────────────────────── + public function delete(Request $request) + { + $propertyId = $request->input('property_id'); + $email = trim($request->input('email', '')); + + if (!$propertyId && !$email) { + return response()->json(array('status' => false, 'message' => 'property_id veya email gerekli'), 422); + } + + $report = array(); + + try { + DB::beginTransaction(); + + // Email ile geldiyse önce kullanıcı + property_id'leri bul + $userIdToDelete = null; + $propertyIds = array(); + + if ($email) { + $user = DB::table('user')->where('email', $email)->first(); + if (!$user) { + return response()->json(array('status' => false, 'message' => 'Kullanıcı bulunamadı')); + } + $userIdToDelete = $user->id; + $pids = DB::table('user_property_mapping') + ->where('user_id', $userIdToDelete) + ->pluck('property_id') + ->toArray(); + $propertyIds = $pids; + } else { + $propertyIds = array((int)$propertyId); + // Bu property'nin tek sahibi varsa onu da sil + $ownerCount = DB::table('user_property_mapping') + ->where('property_id', $propertyId) + ->count(); + if ($ownerCount === 1) { + $userIdToDelete = DB::table('user_property_mapping') + ->where('property_id', $propertyId) + ->value('user_id'); + } + } + + foreach ($propertyIds as $pid) { + $deleted = array('property_id' => $pid); + + // 1. Fotoğraf dosyalarını sil + $photos = DB::table('property_photo')->where('property_id', $pid)->get(); + $filesDeleted = 0; + $uploadRoot = rtrim(Config::get('app.fileSystemDriver'), '/'); + foreach ($photos as $photo) { + $base = $uploadRoot . $photo->photo_path . $photo->photo_name; + foreach (array('', '_medium', '_thumbnail') as $suffix) { + $path = $base . $suffix . '.' . $photo->file_ext; + if (File::exists($path)) { + File::delete($path); + $filesDeleted++; + } + } + } + $deleted['photos_db'] = DB::table('property_photo')->where('property_id', $pid)->delete(); + $deleted['photos_files'] = $filesDeleted; + + // 2. Oda ilişkileri + $roomIds = DB::table('property_room')->where('property_id', $pid)->pluck('id')->toArray(); + if (!empty($roomIds)) { + DB::table('property_room_bed')->whereIn('room_id', $roomIds)->delete(); + DB::table('property_room_view_mapping')->whereIn('room_id', $roomIds)->delete(); + DB::table('property_room_fact_mapping')->whereIn('room_id', $roomIds)->delete(); + DB::table('property_room_photo_mapping')->whereIn('room_id', $roomIds)->delete(); + } + $deleted['rooms'] = DB::table('property_room')->where('property_id', $pid)->delete(); + + // 3. Fact mapping + $deleted['fact_mapping'] = DB::table('property_fact_mapping')->where('property_id', $pid)->delete(); + + // 4. İletişim + $deleted['contact'] = DB::table('property_contact')->where('property_id', $pid)->delete(); + + // 5. Property info tabloları + DB::table('property_additional_info')->where('property_id', $pid)->delete(); + DB::table('property_language_spoken')->where('property_id', $pid)->delete(); + + // 6. User-property mapping + $deleted['user_mapping'] = DB::table('user_property_mapping')->where('property_id', $pid)->delete(); + + // 7. Property kaydı + $deleted['property'] = DB::table('property')->where('id', $pid)->delete(); + + $report[] = $deleted; + } + + // 8. Kullanıcıyı sil (başka property'si yoksa) + if ($userIdToDelete) { + $remaining = DB::table('user_property_mapping')->where('user_id', $userIdToDelete)->count(); + if ($remaining === 0) { + DB::table('api_access_token')->where('user_id', $userIdToDelete)->delete(); + DB::table('user')->where('id', $userIdToDelete)->delete(); + $report['user_deleted'] = $userIdToDelete; + } + } + + DB::commit(); + + return response()->json(array( + 'status' => true, + 'message' => 'Silme tamamlandı', + 'report' => $report, + )); + } catch (Exception $e) { + DB::rollBack(); + Log::error('propertyDelete.Error: ' . $e->getFile() . ':' . $e->getLine() . ' ' . $e->getMessage()); + return response()->json(array( + 'status' => false, + 'message' => $e->getMessage(), + 'report' => $report, + ), 500); + } + } +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..fc2dd11 --- /dev/null +++ b/app/Http/Middleware/Authenticate.php @@ -0,0 +1,44 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * @return mixed + */ + public function handle($request, Closure $next, $guard = null) + { + if ($this->auth->guard($guard)->guest()) { + return response('Unauthorized.', 401); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/BookingEngineTokenMiddleware.php b/app/Http/Middleware/BookingEngineTokenMiddleware.php new file mode 100644 index 0000000..bfa1ce4 --- /dev/null +++ b/app/Http/Middleware/BookingEngineTokenMiddleware.php @@ -0,0 +1,168 @@ +propertyWebService = $propertyWebService; + $this->channelService = $channelService; + $this->propertyChannelMappingService = $propertyChannelMappingService; + $this->propertyBookingEngineService = $propertyBookingEngineService; + $this->findCountryCodeService = $findCountryCodeService; + } + + public function handle($request, Closure $next, $guard = null) + { + $channelToken = $request->header('channelToken'); + $bookingEngineToken = $request->header('bookingEngineToken'); + + if (!$channelToken) { + return apiResponse(0, 'Token not provided.', null, 401); + } + + $channelRequest = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $channelToken], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $channelCheck = $this->channelService->select($channelRequest); + + if ($channelCheck['status'] != 'success' || empty($channelCheck['data'])) { + return apiResponse(0, 'Channel Token not found.', null, 401); + } + + + $bookingEnginePropertyId = null; + if (in_array($channelCheck['data']['channel_category_id'], [2, 3, 7])) { + + if (is_null($bookingEngineToken)) { + if (!in_array($channelCheck['data']['channel_category_id'], [7])) { + return apiResponse(0, 'Booking Engine Token not found.', null, 401); + } + } + + $bookingEngineRequest = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $bookingEngineToken], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'firstRow' => 1 + ]; + + $bookingEngineCheck = $this->propertyBookingEngineService->select($bookingEngineRequest); + + if ($bookingEngineCheck['status'] != 'success' || empty($bookingEngineCheck['data'])) { + if (!in_array($channelCheck['data']['channel_category_id'], [7])) { + return apiResponse(0, 'Booking Engine Token not found.', null, 401); + } + } + + $bookingEnginePropertyId = isset($bookingEngineCheck['data']['property_id']) ? $bookingEngineCheck['data']['property_id'] : null; + + + //channelToken Manipulation + $params = json_decode($request->getContent(), 1); + + if (fillOnUndefined($params, 'ipAddress') && fillOnUndefined($params,'referrer') != 'google') { + // Find Country Code with IP + $ipResponse = $this->findCountryCodeService->findCountryWithIpAddress($params['ipAddress']); + + if ($ipResponse['status'] == 'success') { + + $propertyChannelMappingParam = [ + 'criteria' => [ + ['field' => 'property_id', 'condition' => '=', 'value' => $bookingEnginePropertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['channel'], + ]; + + $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingParam); + + $ipCountryCode = isset($ipResponse['data']['code']) ? $ipResponse['data']['code'] : 'tr'; + + if ($propertyChannelMapping['status'] == 'success') { + + $propertyChannelMappingCollect = collect($propertyChannelMapping['data']); + $countryChannel = $propertyChannelMappingCollect + ->where('channel.channel_category_id', 3) + ->where('channel.country_code', $ipCountryCode) + ->where('channel.parent_id', 1) + ->first(); + + if (!empty($countryChannel)) { + $channelToken = $countryChannel['channel']['token']; + $channelCheck['data']['id'] = $countryChannel['channel']['id']; + } + + //countryCodeGroup + if (empty($countryChannel)) { + $countryChannelGroup = $propertyChannelMappingCollect + ->where('channel.channel_category_id', 3) + ->where('channel.country_code', 'group') + ->where('channel.parent_id', 1) + ->toArray(); + + if (!empty($countryChannelGroup)) { + foreach ($countryChannelGroup as $country) { + if (!empty($country['channel']['country_code_group'])) { + if (in_array($ipCountryCode, $country['channel']['countryCodeGroupArray'])) { + + $channelToken = $country['channel']['token']; + $channelCheck['data']['id'] = $country['channel']['id']; + + break; + } + } + } + } + } + //countryCodeGroup + + } + + } + //channelToken Manipulation + } + + } + + $request->channelId = $channelCheck['data']['id']; + $request->channelToken = $channelToken; + $request->bookingEngineToken = $bookingEngineToken; + $request->bookingEnginePropertyId = $bookingEnginePropertyId; + $request->bookingEngineChannelCategoryId = $channelCheck['data']['channel_category_id']; + + + return $next($request); + } +} diff --git a/app/Http/Middleware/CheckPropertyChannelConnectionMiddleware.php b/app/Http/Middleware/CheckPropertyChannelConnectionMiddleware.php new file mode 100644 index 0000000..647244e --- /dev/null +++ b/app/Http/Middleware/CheckPropertyChannelConnectionMiddleware.php @@ -0,0 +1,58 @@ +propertyChannelMappingService = $propertyChannelMappingService; + $this->request = $request; + $this->response = $response; + } + + + public function handle($request, Closure $next, $guard = null) + { + + //TODO: Buraya kanal (channel_id) ve kanal grupları (channel_group_id) için property için bir kontrol koyulacak + //dd($this->request->params['property_id']); + + /*$response = $next($request); + $propertyId = $request->property_id ? $request->property_id : fillOnUndefined($request->params, 'property_id'); + $channelId = fillOnUndefined($request->params, 'channel_id'); + + $checkParams = [ + 'property_id' => $propertyId, + 'channel_id' => $channelId, + + ] ; + + $checkMappingStatus =$this->propertyChannelMappingService->checkPropertyChannelMapping($checkParams); + if ($checkMappingStatus['status'] != 'success') { + return apiResponse(false, $checkMappingStatus['message'], null, 400); + } + + return $response;*/ + + return $next($request); + } + +} diff --git a/app/Http/Middleware/ContentWizardMiddleware.php b/app/Http/Middleware/ContentWizardMiddleware.php new file mode 100644 index 0000000..0dac122 --- /dev/null +++ b/app/Http/Middleware/ContentWizardMiddleware.php @@ -0,0 +1,56 @@ +propertyConfigService = $propertyConfigService; + $this->request = $request; + $this->response = $response; + } + + + public function handle($request, Closure $next, $guard = null) + { + $response = $next($request); + if ($response->getData()->status == 200) { + $params = $this->request->params; + $url = collect($this->request->route()); + $getNameArray = $url->where('as', '!=', null)->first(); + $routeAlias = fillOnUndefined($getNameArray, 'as'); + + if($routeAlias == 'Property.Contact.Update'){ + if(isset($params['contact']['address']) && isset($params['contact']['latitude']) && isset($params['contact']['longitude'])){ + $routeAlias = 'Property.Location.Update' ; + } + } + $rateParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $this->request->credentials->user_id, + 'property_rate_for' => $routeAlias, + ]; + $this->propertyConfigService->rateProperty(array_merge($params, $rateParams)); + } + return $response; + } + +} diff --git a/app/Http/Middleware/CorsMiddleware.php b/app/Http/Middleware/CorsMiddleware.php new file mode 100644 index 0000000..66209d2 --- /dev/null +++ b/app/Http/Middleware/CorsMiddleware.php @@ -0,0 +1,35 @@ + '*', + 'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE', + 'Access-Control-Allow-Credentials' => 'true', + 'Access-Control-Max-Age' => '86400', + 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With, language, authToken' + ]; + + $apiHeader = collect($request->headers)->toArray(); + + if ($request->isMethod('OPTIONS')) + { + return response()->json('{"method":"OPTIONS"}', 200, $headers); + } + $response = $next($request); + foreach($headers as $key => $value) + { + //$response->header($key, $value); + $response->headers->set($key, $value); + } + return $response; + } +} diff --git a/app/Http/Middleware/ExampleMiddleware.php b/app/Http/Middleware/ExampleMiddleware.php new file mode 100644 index 0000000..7e9b7a8 --- /dev/null +++ b/app/Http/Middleware/ExampleMiddleware.php @@ -0,0 +1,20 @@ +apiAccessTokenService = $apiAccessTokenService ; + } + + public function handle($request, Closure $next, $guard = null) + { + $token = $request->header('authToken'); + + if (!$token) { + return apiResponse(0, 'Token not provided.', null, 401); + } + + try { + $credentials = JWT::decode($token, Config::get('app.jwt.secret'), ['HS256']); + + $findTokenCriteria = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => md5($token) ], + ['field' => 'expire_date', 'condition' => '>', 'value' => time() ], + ['field' => 'user_id', 'condition' => '=', 'value' => $credentials->user_id ], + ['field' => 'invalidate', 'condition' => '=', 'value' => 0 ], + ], + 'firstRow' => 1 + ]; + $getTokenData = $this->apiAccessTokenService->select($findTokenCriteria); + if(!$getTokenData['data']){ + throw new ExpiredException(); + } + + } catch (ExpiredException $e) { + return apiResponse(0, lang('Token is expired.'), null, 401); + } catch (Exception $e) { + return apiResponse(0, lang('An error while decoding token.'), null, 500); + } + + + $inputs = json_decode($request->getContent(), true); + $inputs = is_array($inputs) ? $inputs : ["params" => []]; + + $user = User::find($credentials->user_id); + + // Now let's put the user in the request class so that you can grab it from there + $request->credentials = $credentials; + $request->body = $inputs; + $request->auth = $user; + return $next($request); + } +} diff --git a/app/Http/Middleware/LanguageSettingMiddleware.php b/app/Http/Middleware/LanguageSettingMiddleware.php new file mode 100644 index 0000000..d118b40 --- /dev/null +++ b/app/Http/Middleware/LanguageSettingMiddleware.php @@ -0,0 +1,27 @@ +headers)->toArray(); + if(!isset($apiHeader['language'])){ + return apiResponse(0, 'Language field is null.', null, 400); + } + $apiRequest = collect($request->params)->toArray(); + $apiRequest['locale'] = isset($apiRequest['locale']) ? $apiRequest['locale'] : reset($apiHeader['language']); + LanguageService::setCurrentLanguage(reset($apiHeader['language'])); + $request->params = $apiRequest; + app('translator')->setLocale(reset($apiHeader['language'])); + + return $next($request); + } +} diff --git a/app/Http/Middleware/MyWebTokenMiddleware.php b/app/Http/Middleware/MyWebTokenMiddleware.php new file mode 100644 index 0000000..7fed64e --- /dev/null +++ b/app/Http/Middleware/MyWebTokenMiddleware.php @@ -0,0 +1,67 @@ +propertyWebService = $propertyWebService ; + } + + public function handle($request, Closure $next, $guard = null) + { + $token = $request->header('authToken'); + + if (!$token) { + return apiResponse(0, 'Token not provided.', null, 401); + } + + try { + + $findTokenCriteria = [ + 'criteria' => [ + ['field' => 'token', 'condition' => '=', 'value' => $token], + ], + 'firstRow' => 1 + ]; + $getTokenData = $this->propertyWebService->select($findTokenCriteria); + + if(!$getTokenData['data']){ + throw new ExpiredException(); + } + + } catch (ExpiredException $e) { + return apiResponse(0, lang('Token is expired.'), null, 400); + } catch (Exception $e) { + return apiResponse(0, lang('An error while decoding token.'), null, 500); + + + } + $inputs = json_decode($request->getContent(), true); + $inputs = is_array($inputs) ? $inputs : ["params" => []]; + $inputs['params']['property_id'] = $getTokenData['data']['property_id']; + $inputs['params']['property_web_id'] = $getTokenData['data']['id']; + $inputs['params']['domain'] = $getTokenData['data']['domain']; + $inputs['params']['default_language'] = $getTokenData['data']['default_language']; + $inputs['params']['template_id'] = $getTokenData['data']['template_id']; + $request->body = $inputs; + + return $next($request); + } +} diff --git a/app/Http/Middleware/PropertyMiddleware.php b/app/Http/Middleware/PropertyMiddleware.php new file mode 100644 index 0000000..0cd2cc1 --- /dev/null +++ b/app/Http/Middleware/PropertyMiddleware.php @@ -0,0 +1,93 @@ +userPropertyMappingRepository = $userPropertyMappingRepository; + $this->serviceLogService = $serviceLogService; + } + + + public function handle($request, Closure $next, $guard = null) + { + $userId = $request->credentials->user_id; + + $propertyId = $request->property_id ? $request->property_id : fillOnUndefined($request->params, 'property_id'); + if (!$propertyId) { + return apiResponse(0, 'Property_id required.', null, 401); + } + $checkPropertyUserRequest = [ + 'criteria' => [ + ['field' => 'user_id', 'condition' => '=', 'value' => $userId], + ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], + ['field' => 'status', 'condition' => '=', 'value' => 1], + ], + 'with' => ['property'], + 'firstRow' => 1 + ]; + + $checkPropertyUser = $this->userPropertyMappingRepository->findByCriteria($checkPropertyUserRequest); + if (!$checkPropertyUser) { + return apiResponse(0, 'User not matched this property.', null, 400); + } + + if (!$checkPropertyUser['property']['status']) { + return apiResponse(0, 'User not matched this property.', null, 400); + } + + /** ServiceLog **/ + $request->serviceLogId = null; + $request->serviceLogRequestTime = microtime(true); + $selectedRoute = [ + //'Property.Dashboard', + 'Property.RoomRateMapping.RoomRateAvailabilityUpdate', + 'Property.RoomRateMapping.BulkUpdate', + 'RoomRateChannelPromotion.Update', + 'Property.Promotion.Update', + 'PA.Property.Quick-Pricing.Sync' + ]; + $route = $request->route(); + $routeName = isset($route[1]['as']) ? $route[1]['as'] : null; + $inputs = json_decode($request->getContent(), true); + if (in_array($routeName, $selectedRoute)) { + $serviceLogParam = [ + 'property_id' => $propertyId, + 'user_id' => $userId, + 'service' => $routeName, + 'request' => json_encode($inputs), + 'ip_address' => $request->ip(), + 'status' => 2 + ]; + + $serviceLog = $this->serviceLogService->create($serviceLogParam); + + if($serviceLog['status'] == 'success' && !empty($serviceLog['data'])) { + $request->serviceLogId = $serviceLog['data']['id']; + } + + } + /** ServiceLog **/ + + return $next($request); + + } + + +} diff --git a/app/Http/Middleware/UserRoutePermissionAuthorize.php b/app/Http/Middleware/UserRoutePermissionAuthorize.php new file mode 100644 index 0000000..102a261 --- /dev/null +++ b/app/Http/Middleware/UserRoutePermissionAuthorize.php @@ -0,0 +1,45 @@ +routePermissionAuthorize =$routePermissionAuthorize; + } + + public function handle($request, Closure $next, $guard = null) + { + + $params = $request->params; + $requestParams = [ + 'property_id' => fillOnUndefined($params, 'property_id'), + 'user_id' => $request->credentials->user_id, + ]; + + $result = $this->routePermissionAuthorize->isUserAuthorizedForCurrentRoute($requestParams); + + if ( !$result) + { + return apiResponse(0, "Your permission not authorised" , null, 400); + } + return $next($request); + } +} diff --git a/app/Jobs/ExampleJob.php b/app/Jobs/ExampleJob.php new file mode 100644 index 0000000..1e58741 --- /dev/null +++ b/app/Jobs/ExampleJob.php @@ -0,0 +1,26 @@ +propertyId = $propertyId; + $this->language = $language; + $this->email = $email; + } + + /** + * Execute the job. + */ + public function handle() + { + chdir(base_path()); + + Artisan::call('cron:property-catalog-service', [ + 'property_id' => $this->propertyId, + 'language' => $this->language, + '--email' => $this->email, + ]); + } +} diff --git a/app/Jobs/PropertyReviewAnalyzeServiceJob.php b/app/Jobs/PropertyReviewAnalyzeServiceJob.php new file mode 100644 index 0000000..2e844b7 --- /dev/null +++ b/app/Jobs/PropertyReviewAnalyzeServiceJob.php @@ -0,0 +1,32 @@ +reviewId = $reviewId; + } + + /** + * Execute the job. + */ + public function handle() + { + Artisan::call('cron:property-review-analyze-service', [ + 'review_id' => $this->reviewId, + ]); + } +} diff --git a/app/Jobs/PropertyReviewServiceJob.php b/app/Jobs/PropertyReviewServiceJob.php new file mode 100644 index 0000000..33cd243 --- /dev/null +++ b/app/Jobs/PropertyReviewServiceJob.php @@ -0,0 +1,35 @@ +propertyId = $propertyId; + $this->channelId = $channelId; + } + + /** + * Execute the job. + */ + public function handle() + { + Artisan::call('cron:property-review-service', [ + 'property_id' => $this->propertyId, + 'channel_id' => $this->channelId + ]); + } +} diff --git a/app/Jobs/SlackLogJob.php b/app/Jobs/SlackLogJob.php new file mode 100644 index 0000000..a86ad1d --- /dev/null +++ b/app/Jobs/SlackLogJob.php @@ -0,0 +1,52 @@ +slack = $slack; + } + + public function handle() + { + try { + + $client = new Client(); + $client->request('POST', config('app.log_slack'), + [ + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'body' => json_encode($this->slack), + ]); + + } catch (Exception $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error('--SlackLogJob RequestException--'); + Log::error($message); + } catch (RequestException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error('--SlackLogJob RequestException--'); + Log::error($message); + } catch (ApiErrorException $e) { + $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); + Log::error('--SlackLogJob ApiErrorException--'); + Log::error($message); + } + } + +} diff --git a/app/Listeners/ExampleListener.php b/app/Listeners/ExampleListener.php new file mode 100644 index 0000000..eff6e58 --- /dev/null +++ b/app/Listeners/ExampleListener.php @@ -0,0 +1,31 @@ +hasOne('App\Models\User', 'id', 'user_id'); + } + + + public function getExpireTimeAttribute() + { + try { + return date('Y-m-d H:i:s', $this->expire_date); + } catch (Exception $e) { + return null; + } + } + + +} diff --git a/app/Models/AwardsCertificateCategory.php b/app/Models/AwardsCertificateCategory.php new file mode 100644 index 0000000..a4e9465 --- /dev/null +++ b/app/Models/AwardsCertificateCategory.php @@ -0,0 +1,39 @@ +hasMany('App\Models\PropertyAwardsCertificate','category_id', 'id') + ->select('id', 'property_id', 'category_id', 'name', 'date', 'url', 'file_path', 'file_type', 'status'); + } + + +} diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php new file mode 100644 index 0000000..5cd8ebf --- /dev/null +++ b/app/Models/BaseModel.php @@ -0,0 +1,113 @@ +appends; + if ( ! is_array ( $this->appends )) + { + return $origin; + } + + if(isset(self::$removeAppends[0]) && self::$removeAppends[0] == "*") + { + $this->appends = []; + return $this->appends; + } + + foreach ($this->appends as $key => $perAppend) + { + if (in_array ( $perAppend, self::$removeAppends )) + { + unset( $this->appends[ $key ] ); + } + } + return $this->appends; + } catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + } + + } + + private function _addAppends() + { + try + { + foreach (self::$addAppends as $perAppend) + { + $methodMakeUp = "get".strtolower($perAppend)."attribute"; + if(method_exists($this,$methodMakeUp)) + { + $this->append($perAppend); + } + } + } catch ( Exception $e ) + { + $message = $e->getFile()." ".$e->getLine()." ".$e->getMessage(); + Log::error($message); + } + } + + /*private function _addWith () + { + foreach (self::$addWith as &$perWith) + { + try { + $this->load($perWith); + } catch (Exception $e) { + continue; + } + + /* + if (method_exists($this,$perWith)) + { + $this->load($perWith); + } + } + }*/ + + + protected function getArrayableAppends() + { + /*$this->_addWith();*/ + $this->_removeAppends(); + $this->_addAppends(); + return $this->appends; + } + +} diff --git a/app/Models/Booking.php b/app/Models/Booking.php new file mode 100644 index 0000000..c7dbc00 --- /dev/null +++ b/app/Models/Booking.php @@ -0,0 +1,163 @@ +hasOne('App\Models\BookingContact', 'booking_id', 'id') + ->select(['id', 'booking_id', 'name', 'surname', 'phone_code', 'phone_number', 'email', 'note', 'extra_param', 'language_code', 'country_code', 'invoice_request', 'invoice']); + } + + public function bookingChannel() + { + return $this->hasOne('App\Models\PropertyChannel', 'id', 'channel_id') + ->select(['id', 'name', 'official_name', 'channel_category_id', 'description', 'country_code', 'default_currency', 'logo']); + } + + public function channelManager() + { + return $this->hasOne('App\Models\ChannelManager', 'id', 'channel_manager_id') + ->select(['id', 'name', 'status']); + } + + public function bookingPaymentType() + { + return $this->hasOne('App\Models\PropertyBookingPaymentType', 'code', 'payment_type_code') + ->select(['name', 'language_key', 'code']); + } + + public function bookingRoom() + { + return $this->hasMany('App\Models\BookingRoom', 'booking_id', 'id') + ->select(['id', 'booking_id', 'occupancy_code', 'checkin_date', 'checkout_date', 'availability_code', 'room_id', 'room_name', + 'room_rate_name', 'room_rate_mapping_id', 'cancellation_policy', 'rate_detail', 'extra_param', 'daily_amount', 'amount', 'discount_amount', + 'total', 'currency_code', 'property_room_bed_id', 'property_room_bed_group_id', 'smoking_fact_id', 'status']); + } + + public function bookingRoomSummary() + { + return $this->hasMany('App\Models\BookingRoom', 'booking_id', 'id') + ->select(['id', 'booking_id', 'occupancy_code', 'checkin_date', 'checkout_date', 'room_id', 'room_name', 'room_rate_name', 'total', 'currency_code', 'status']); + } + + public function bookingRoomPax() + { + return $this->hasMany('App\Models\BookingRoomPax', 'booking_id', 'id') + ->select(['id', 'booking_id', 'booking_room_id', 'type', 'name', 'surname', 'gender', 'citizen', 'birth_date', 'status']); + } + + public function bookingAddon() + { + return $this->hasMany('App\Models\BookingAddon', 'booking_id', 'id') + ->select(['id', 'booking_id', 'property_channel_addon_id', 'count', 'amount', 'total', 'currency_code', 'attribute']); + } + + public function bookingPayment() + { + return $this->hasOne('App\Models\BookingPayment', 'booking_id', 'id')->orderByDesc('id'); + } + + public function bookingPaymentData() + { + return $this->hasMany('App\Models\BookingPaymentData', 'booking_id', 'id')->orderByDesc('id') + ->select(['id', 'booking_id', 'type', 'data']); + } + + public function bookingPaymentDataCheck() + { + return $this->hasMany('App\Models\BookingPaymentDataCheck', 'booking_id', 'id')->orderBy('id'); + } + + public function bookingProperty() + { + return $this->hasOne('App\Models\Property', 'id', 'property_id') + ->select(['id', 'name', 'country', 'official_name', 'tax_office', 'tax_number', 'commission', 'commission_offline', 'commission_channel', 'commission_wholesaler']); + } + + public function propertyBookingEngine() + { + return $this->hasOne('App\Models\PropertyBookingEngine', 'property_id', 'property_id') + ->select(['id', 'property_id', 'channel_id', 'token']) + ->where('channel_id', '=', 1); + } + + public function propertyBookingChannel() + { + return $this->hasOne('App\Models\PropertyChannel', 'id', 'channel_id') + ->select(["id", "parent_id", "name", "official_name", "token", "description", "channel_category_id", "country_code", "currency_code", "default_currency", "logo", "address", "zip_code", "email", "phone", "phone2", "fax", "score"]); + } + + public function bookingPropertyWeb() + { + return $this->hasOne('App\Models\PropertyWeb', 'property_id', 'property_id'); + } + + public function bookingPaymentTransaction() + { + return $this->hasMany('App\Models\PaymentTransaction', 'order_id', 'booking_code') + ->orderByDesc('id'); + } + + public function bookingStatus() + { + return $this->hasOne('App\Models\BookingStatus', 'id', 'status') + ->select(['name', 'language_key', 'id'])->where('status', 1); + } + + public function property() + { + return $this->hasOne("App\Models\Property", 'id', 'property_id')->select(['id', 'name']); + } + + public function bookingActiveMessageCount() + { + return $this->hasMany('App\Models\BookingTicket', 'booking_id', 'id') + ->select(['id', 'booking_id', 'code', 'parent_id']) + ->where('status', 1)->where('user_id', null)->where('is_viewed', null) + ->where('is_log', null); + } + + public function propertyChannelMapping() + { + return $this->hasOne('App\Models\PropertyChannelMapping', 'property_id', 'property_id') + ->where('channel_id', '=', 1) + ->select("id", "property_id", "channel_id", "currency_code", "channel_tax_id", "status"); + } + + + public function propertyBookingEngineSearch() + { + return $this->hasOne('App\Models\PropertyBookingEngineSearch', 'search_key', 'search_key') + ->where('channel_id', '=', 1)->select(); + } + + public function channelManagerBooking() + { + return $this->hasMany('App\Models\ChannelManagerBooking', 'booking_id', 'id') + ->select(['id', 'property_id', 'booking_id','channel_manager_id', 'type', 'is_pushed', 'status']); + } +} diff --git a/app/Models/BookingAddon.php b/app/Models/BookingAddon.php new file mode 100644 index 0000000..051f72f --- /dev/null +++ b/app/Models/BookingAddon.php @@ -0,0 +1,38 @@ +hasOne('App\Models\PropertyChannelAddon','id', 'property_channel_addon_id') + ->select(['id','title', 'description','property_addon_id','min_stay','type','amount']); + } + + public function propertyAddon(){ + return $this->hasOne('App\Models\PropertyAddon','id', 'property_addon_id') + ->select(['id','fact_id', 'title', 'attribute']); + } + +} diff --git a/app/Models/BookingContact.php b/app/Models/BookingContact.php new file mode 100644 index 0000000..36300c0 --- /dev/null +++ b/app/Models/BookingContact.php @@ -0,0 +1,46 @@ +name . ' ' . $this->surname; + } + + public function getPhoneFormattedAttribute() + { + return $this->phone_code . '' . $this->phone_number; + } + + public function getInvoiceArrayAttribute() + { + if (!is_null($this->invoice)) { + return json_decode($this->invoice, 1); + } else { + return null; + } + } +} diff --git a/app/Models/BookingPayment.php b/app/Models/BookingPayment.php new file mode 100644 index 0000000..3dbdf55 --- /dev/null +++ b/app/Models/BookingPayment.php @@ -0,0 +1,34 @@ +hasOne('App\Models\PropertyBookingPaymentType', 'code', 'payment_type_code')->select(['code','name','language_key']); + } + + + +} diff --git a/app/Models/BookingPaymentData.php b/app/Models/BookingPaymentData.php new file mode 100644 index 0000000..2b34ec2 --- /dev/null +++ b/app/Models/BookingPaymentData.php @@ -0,0 +1,35 @@ +hasOne('App\Models\Booking', 'id', 'booking_id') + ->select(['id', 'channel_id', 'channel_manager_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']); + } + +} diff --git a/app/Models/BookingPaymentDataCheck.php b/app/Models/BookingPaymentDataCheck.php new file mode 100644 index 0000000..dc8e81e --- /dev/null +++ b/app/Models/BookingPaymentDataCheck.php @@ -0,0 +1,30 @@ +hasMany('App\Models\BookingRoomPax', 'booking_room_id', 'id'); + } + + public function roomRateMapping() + { + return $this->hasOne('App\Models\PropertyRoomRateMapping','id', 'room_rate_mapping_id')->select(); + } + + public function propertyRoomBed() + { + return $this->hasOne('App\Models\PropertyRoomBed', 'id', 'property_room_bed_id')->select(); + } + + public function smokingFact() + { + return $this->hasOne('App\Models\PropertyFact', 'id', 'smoking_fact_id')->select(); + } + + +} diff --git a/app/Models/BookingRoomPax.php b/app/Models/BookingRoomPax.php new file mode 100644 index 0000000..a1e921b --- /dev/null +++ b/app/Models/BookingRoomPax.php @@ -0,0 +1,34 @@ +hasOne('App\Models\Country', 'country_code', 'citizen') + ->select(['id', 'name', 'language_key', 'country_code', 'phone_code']) ; + } + +} diff --git a/app/Models/BookingStatus.php b/app/Models/BookingStatus.php new file mode 100644 index 0000000..19c7878 --- /dev/null +++ b/app/Models/BookingStatus.php @@ -0,0 +1,22 @@ +created_at)->toDateTimeString(); + } + + public function user() + { + return $this->hasOne('App\Models\User', 'id', 'user_id')->select(['id','name','surname']); + } + +} diff --git a/app/Models/ChannelManager.php b/app/Models/ChannelManager.php new file mode 100644 index 0000000..7fdc9bc --- /dev/null +++ b/app/Models/ChannelManager.php @@ -0,0 +1,20 @@ +hasOne('App\Models\Booking', 'id', 'booking_id') + ->select([ + 'id', 'channel_id', 'channel_manager_id', 'property_id', 'booking_code','channel_booking_code', 'checkin_date', 'checkout_date', 'rooms', + 'payment_type_code', 'room_amount', 'addon_amount', 'discount_amount', 'total', 'currency_code', 'extra_param', 'created_at', 'updated_at', 'status' + ]); + } + + public function channelManager() + { + return $this->hasOne('App\Models\ChannelManager', 'id', 'channel_manager_id')->select(['id', 'name', 'status']); + } +} diff --git a/app/Models/ChannelManagerLog.php b/app/Models/ChannelManagerLog.php new file mode 100644 index 0000000..783bd07 --- /dev/null +++ b/app/Models/ChannelManagerLog.php @@ -0,0 +1,20 @@ +hasOne("App\Models\PropertyChannel", 'id', 'property_channel_id')->select(['id', 'name']); + } + +} diff --git a/app/Models/ChannelManagerPropertyMapping.php b/app/Models/ChannelManagerPropertyMapping.php new file mode 100644 index 0000000..e955820 --- /dev/null +++ b/app/Models/ChannelManagerPropertyMapping.php @@ -0,0 +1,29 @@ +hasMany("App\Models\ChannelManagerPropertyRateMapping", 'channel_manager_property_mapping_id', 'id') + ->select(['id','channel_manager_property_mapping_id','property_room_rate_mapping_id','channel_manager_room_id', 'channel_manager_room_rate_id','included_occupancy']); + } + + public function property(){ + return $this->hasOne('App\Models\Property','id', 'property_id') + ->select(['id', 'name','country','destination_id','property_type_id','status']); + } +} diff --git a/app/Models/ChannelManagerPropertyRateMapping.php b/app/Models/ChannelManagerPropertyRateMapping.php new file mode 100644 index 0000000..8ee4085 --- /dev/null +++ b/app/Models/ChannelManagerPropertyRateMapping.php @@ -0,0 +1,24 @@ +hasOne("App\Models\PropertyRoomRateMapping", 'id', 'property_room_rate_mapping_id')->select(['id','room_id','room_rate_id','status']); + } + +} diff --git a/app/Models/Country.php b/app/Models/Country.php new file mode 100644 index 0000000..740dfc4 --- /dev/null +++ b/app/Models/Country.php @@ -0,0 +1,18 @@ +hasOne('App\Models\IpNationCountries','code', 'country'); + } + +} diff --git a/app/Models/IpNationCountries.php b/app/Models/IpNationCountries.php new file mode 100644 index 0000000..108acf6 --- /dev/null +++ b/app/Models/IpNationCountries.php @@ -0,0 +1,25 @@ +hasMany('App\Models\OfferAccommodationMapping', 'offer_id', 'id')->select("id", "offer_id", "property_accommodation_id"); + } + + public function offerCancellationPolicy() + { + return $this->hasMany('App\Models\OfferCancellationPolicy', 'offer_id', 'id')->select("id", "offer_id", "days_before", "type", "value"); + } + + public function offerContactMapping() + { + return $this->hasMany('App\Models\OfferContactMapping', 'offer_id', 'id') + ->select("id", "offer_id", "property_executive_id", "status") + ->where("status", "=", 1); + } + + public function offerFactMapping() + { + return $this->hasMany('App\Models\OfferFactMapping', 'offer_id', 'id')->select("id", + "offer_id", + "category_id", + "property_fact_parent_id", + "property_fact_id" + ); + } + + public function offerImportantNotes() + { + return $this->hasMany('App\Models\OfferImportantNotes', 'offer_id', 'id')->select("id", + "offer_id", + "note" + ); + } + + public function offerPhotoMapping() + { + return $this->hasMany('App\Models\OfferPhotoMapping', 'offer_id', 'id')->select("id", + "offer_id", + "property_photo_id", + "is_cover" + ); + } + + public function offerPrice() + { + return $this->hasMany('App\Models\OfferPrice', 'offer_id', 'id')->select("id", + "offer_id", + "date", + "property_room_id", + "property_accommodation_id", + "number_of_rooms", + "currency", + "amount", + "total_amount" + ); + } + + public function offerRoomMapping() + { + return $this->hasMany('App\Models\OfferRoomMapping', 'offer_id', 'id')->select("id", + "offer_id", + "property_room_id" + ); + } + + public function offerLanguage() + { + return $this->hasOne('App\Models\Language', 'code', 'language')->select( + "code", + "name", + "language_key" + ); + } + + public function offerAcceptStatus() + { + return $this->hasOne('App\Models\OfferAcceptStatus', 'id', 'accept_status')->select("id", "name", "language_key"); + } + + public function createUser() + { + return $this->hasOne('App\Models\User', 'id', 'created_by')->select("id", "name", "surname", "email"); + } + + public function property() + { + return $this->hasOne("App\Models\Property", 'id', 'property_id')->select(['id', 'name']); + } + + public function paymentTransaction() + { + return $this->hasMany('App\Models\PaymentTransaction', 'order_id', 'payment_transaction_order_id') + ->select("id", "code", "order_id", "base_amount", "base_currency", "status"); + } + + +} diff --git a/app/Models/OfferAcceptStatus.php b/app/Models/OfferAcceptStatus.php new file mode 100644 index 0000000..04f54df --- /dev/null +++ b/app/Models/OfferAcceptStatus.php @@ -0,0 +1,30 @@ +hasOne('App\Models\PropertyFact','id', 'property_accommodation_id') + ->select( + "id", + "name", + "parent_id", + "type", + "order_number", + "icon", + "status", + "language_key" + + ); + } + + +} diff --git a/app/Models/OfferCancellationPolicy.php b/app/Models/OfferCancellationPolicy.php new file mode 100644 index 0000000..28a7ac1 --- /dev/null +++ b/app/Models/OfferCancellationPolicy.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyExecutive','id', 'property_executive_id'); + } + +} diff --git a/app/Models/OfferFactMapping.php b/app/Models/OfferFactMapping.php new file mode 100644 index 0000000..50996e8 --- /dev/null +++ b/app/Models/OfferFactMapping.php @@ -0,0 +1,36 @@ +hasOne('App\Models\PropertyFact','id', 'property_fact_id'); + } +} diff --git a/app/Models/OfferImportantNotes.php b/app/Models/OfferImportantNotes.php new file mode 100644 index 0000000..e9b51ba --- /dev/null +++ b/app/Models/OfferImportantNotes.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyPhoto','id', 'property_photo_id'); + } + +} diff --git a/app/Models/OfferPrice.php b/app/Models/OfferPrice.php new file mode 100644 index 0000000..f987fde --- /dev/null +++ b/app/Models/OfferPrice.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyRoom','id', 'property_room_id') + ->select( + "id", + "property_id", + "name", + "room_type_id", + "max_occupancy", + "max_adult", + "max_child", + "exclude_occupancy", + "room_size", + 'room_size_type', + 'room_type_count', + 'room_count', + 'bathroom_count', + 'toilet_count', + 'lounge_count', + 'max_child_number' +); + } + + +} diff --git a/app/Models/PaymentBinNumber.php b/app/Models/PaymentBinNumber.php new file mode 100644 index 0000000..35a85f4 --- /dev/null +++ b/app/Models/PaymentBinNumber.php @@ -0,0 +1,29 @@ +params)) { + return json_decode($this->params, 1); + } else { + return null; + } + } + + public function getExtraParamsArrayAttribute() + { + if (!is_null($this->extra_params)) { + return json_decode($this->extra_params, 1); + } else { + return null; + } + } + + public function getResponseArrayAttribute() + { + if (!is_null($this->response)) { + return json_decode($this->response, 1); + } else { + return null; + } + } + + public function getManuelPaymentLinkAttribute() + { + if (!is_null($this->transaction_type == 'LNK')) { + return Config::get('app.paymentFormLink') . $this['order_id']; + } else { + return null; + } + } + + public function paymentTypeMapping() + { + return $this->hasOne('App\Models\PropertyPaymentMapping', 'id', 'payment_type_mapping_id'); + } + + public function bookingDetail() + { + return $this->hasMany('App\Models\Booking', 'booking_code', 'order_id') + ->select(['id', 'channel_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']); + } + + public function relatedTransactions() + { + return $this->hasMany('App\Models\PaymentTransaction', 'order_id', 'order_id')->where('code', '<>', null)->orderByDesc('id'); + } + + public function paymentTransactionStatus() + { + return $this->hasOne('App\Models\PaymentTransactionStatus', 'id', 'status'); + } + + public function parentTransaction() + { + return $this->hasOne('App\Models\PaymentTransaction', 'order_id', 'order_id')->where('code', '=', null); + } + + public function paymentUser() + { + return $this->hasOne('App\Models\User', 'id', 'created_by')->select(['id', 'name', 'surname', 'email', 'user_type', 'language', 'phone']); + } + + public function property() + { + return $this->belongsTo("App\Models\Property", "property_id"); + } +} diff --git a/app/Models/PaymentTransactionStatus.php b/app/Models/PaymentTransactionStatus.php new file mode 100644 index 0000000..cefd186 --- /dev/null +++ b/app/Models/PaymentTransactionStatus.php @@ -0,0 +1,30 @@ +params)) { + return json_decode($this->params,1); + } else { + return null; + } + } + + +} diff --git a/app/Models/Permission.php b/app/Models/Permission.php new file mode 100644 index 0000000..881b7c6 --- /dev/null +++ b/app/Models/Permission.php @@ -0,0 +1,36 @@ +hasOne("\App\Models\PermissionGroupMapping","permission_id"); + } + + + +} diff --git a/app/Models/PermissionGroup.php b/app/Models/PermissionGroup.php new file mode 100644 index 0000000..7d898ed --- /dev/null +++ b/app/Models/PermissionGroup.php @@ -0,0 +1,40 @@ +parameter_rules, true); + } + catch (Exception $e) + { + return null; + } + } + +} diff --git a/app/Models/PermissionGroupMapping.php b/app/Models/PermissionGroupMapping.php new file mode 100644 index 0000000..a4f3030 --- /dev/null +++ b/app/Models/PermissionGroupMapping.php @@ -0,0 +1,38 @@ +belongsTo("App\Models\PermissionGroup","permission_group_id"); + } + + public function permission () + { + return $this->belongsTo("App\Models\Permission","permission_id"); + } + +} diff --git a/app/Models/PermissionGroupUserMapping.php b/app/Models/PermissionGroupUserMapping.php new file mode 100644 index 0000000..525b4e2 --- /dev/null +++ b/app/Models/PermissionGroupUserMapping.php @@ -0,0 +1,88 @@ +belongsTo("App\Models\User","created_by"); + } + + public function property () + { + return $this->belongsTo("App\Models\Property","property_id"); + } + + public function user () + { + return $this->belongsTo("App\Models\User","user_id"); + } + + public function permissionGroup () + { + return $this->belongsTo("App\Models\PermissionGroup","permission_group_id"); + } + + public function permissionGroupMapping () + { + return $this->hasMany("\App\Models\PermissionGroupMapping","permission_group_id","permission_group_id"); + } + + public function getRelatedParametersArrayAttribute () + { + try + { + return json_decode ( $this->related_parameters,true ); + } catch ( Exception $e ) + { + return []; + } + } + + public function getRelatedParametersEmployeeDepartmentsAttribute () + { + try + { + $departments = []; + $relatedParameters = $this->getRelatedParametersArrayAttribute (); + + if ( !$relatedParameters) + { + return null; + } + + foreach ($relatedParameters["employee_departments"] as $perParameter) + { + $departments[] = $perParameter["department_id"]; + } + + return $departments; + } catch ( Exception $e ) + { + return null; + } + } + +} diff --git a/app/Models/PermissionMenuModel.php b/app/Models/PermissionMenuModel.php new file mode 100644 index 0000000..f2e12c8 --- /dev/null +++ b/app/Models/PermissionMenuModel.php @@ -0,0 +1,79 @@ +hasMany("\App\Models\PermissionMenuModel","parent_id","id") + ->with("children"); + } + + + protected function getHasLinkAttribute () + { + return $this->url?true:false; + } + + + + public function getMenuDetailArrayAttribute () + { + try + { + return json_decode ( $this->menu_detail, true ); + } catch ( Exception $e ) + { + return []; + } + } + + public function getUrlAttribute ( ) + { + try + { + return $this->menuDetailArray[ "url" ]; + } catch ( Exception $e ) + { + return null; + } + } + + public function getComponentAttribute ( ) + { + try + { + return $this->menuDetailArray[ "component" ]; + } catch ( Exception $e ) + { + return null; + } + } + +} diff --git a/app/Models/PhotoGoogleLabel.php b/app/Models/PhotoGoogleLabel.php new file mode 100644 index 0000000..3dc3274 --- /dev/null +++ b/app/Models/PhotoGoogleLabel.php @@ -0,0 +1,41 @@ +hasOne('App\Models\PropertyPhotoCategoryLabelMapping','photo_google_label_id', 'id'); + + } + +} diff --git a/app/Models/PlaceCategoryField.php b/app/Models/PlaceCategoryField.php new file mode 100644 index 0000000..ea21485 --- /dev/null +++ b/app/Models/PlaceCategoryField.php @@ -0,0 +1,42 @@ +hasMany('App\Models\PlaceCategoryFieldOptionFieldMapping','field_id', 'id') + ->select("id", "field_id", "field_option_id", "order_number", "status") + ->where('status','=',1) + ->orderBy('order_number'); + + } + +} diff --git a/app/Models/PlaceCategoryFieldMapping.php b/app/Models/PlaceCategoryFieldMapping.php new file mode 100644 index 0000000..b6e1db4 --- /dev/null +++ b/app/Models/PlaceCategoryFieldMapping.php @@ -0,0 +1,48 @@ +hasOne('App\Models\PropertyPlaceCategory','id', 'property_place_category_id') + ->select("id", "name", "language_key", "parent_id", "level","order_number","icon") ; + + } + + + public function placeCategoryField() + { + return $this->hasOne('App\Models\PlaceCategoryField','id', 'property_place_category_field_id') + ->select("id", "name", "language_key", "label", "element","type","field_attribute", "status") ; + + } + +} diff --git a/app/Models/PlaceCategoryFieldOption.php b/app/Models/PlaceCategoryFieldOption.php new file mode 100644 index 0000000..b6317e7 --- /dev/null +++ b/app/Models/PlaceCategoryFieldOption.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PlaceCategoryFieldOption','id', 'field_option_id') + ->select("id", "name", "language_key", "status") + ->where('status','=',1) ; + + } + +} diff --git a/app/Models/Product.php b/app/Models/Product.php new file mode 100644 index 0000000..1efd361 --- /dev/null +++ b/app/Models/Product.php @@ -0,0 +1,30 @@ +hasOne(ProductParameter::class, 'id', 'product_parameter_id'); + } + +} diff --git a/app/Models/PromotionType.php b/app/Models/PromotionType.php new file mode 100644 index 0000000..5b95d37 --- /dev/null +++ b/app/Models/PromotionType.php @@ -0,0 +1,37 @@ +hasOne('App\Models\PromotionType', 'id', 'parent_id') + ->select(['id', 'name', 'language_key', 'parent_id', 'type_code', 'order_number', 'status']); + } + +} diff --git a/app/Models/Property.php b/app/Models/Property.php new file mode 100644 index 0000000..cf50272 --- /dev/null +++ b/app/Models/Property.php @@ -0,0 +1,202 @@ +hasMany('App\Models\PropertyPhoto', 'property_id', 'id') + ->where('status', '=', 1); + } + + public function propertyExecutive() + { + return $this->hasMany('App\Models\PropertyExecutive', 'property_id', 'id'); + } + + public function propertyUser() + { + return $this->hasMany('App\Models\UserPropertyMapping', 'property_id', 'id'); + } + + public function propertyContractUser() + { + return $this->hasOne('App\Models\User', 'id', 'contract_user_id'); + } + + public function propertyType() + { + return $this->belongsTo('App\Models\PropertyType', 'property_type_id', 'id') + ->select('id', 'name', 'language_key'); + } + + + public function defaultPropertyPhoto() + { + return $this->hasOne('App\Models\PropertyPhoto', 'property_id', 'id') + ->where('is_default', '=', 1); + } + + + public function propertyChain() + { + return $this->hasOne('App\Models\PropertyChain', 'id', 'chain_id') + ->select('id', 'name'); + } + + public function propertyDestination() + { + return $this->hasOne('App\Models\Destination', 'id', 'destination_id')->select('id', 'name'); + } + + public function propertyRooms() + { + return $this->hasMany('App\Models\PropertyRoom', 'property_id', 'id') + ->select( + 'id', 'property_id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'max_child_number', + 'exclude_occupancy', 'room_type_count', 'room_size', 'room_size_type', 'room_count', 'bathroom_count', 'lounge_count' + ) + ->where('status', '=', 1); + + } + + public function propertyBrand() + { + return $this->hasOne('App\Models\PropertyBrand', 'property_id', 'id')->select(['id', 'property_id', 'title', 'color_codes', 'logo_name', 'logo_file_ext']); + } + + + public function propertyContact() + { + return $this->hasOne('App\Models\PropertyContact', 'property_id', 'id') + ->select(['id', 'property_id', 'phone_code', 'phone', 'mobile_code', 'mobile', 'mobile2_code', 'mobile2', 'fax_code', 'fax', 'email', 'web', 'meta', 'social_media_addresses', 'zip_code', 'address', 'latitude', 'longitude']); + } + + public function propertyWeb() + { + return $this->hasOne('App\Models\PropertyWeb', 'property_id', 'id') + ->select(['id', 'property_id', 'domain', 'default_language', 'template_id', 'token', 'status', 'is_dns_checked', 'is_ssl_active', 'is_published']) + ->orderBy('id', 'DESC'); + } + + public function propertyWebRooms() + { + return $this->hasMany('App\Models\PropertyWebRoomMapping', 'property_id', 'id') + ->select('id', 'property_id', 'property_room_id') + ->where('status', '=', 1); + } + + public function propertyBookingEngineGroupMapping() + { + return $this->hasMany('App\Models\PropertyGroupMapping', 'property_id', 'id') + ->select(['id', 'property_id', 'property_group_id', 'order_number', 'status']) + ->where('status', '=', 1); + } + + public function propertyBookingEngineToken() + { + return $this->hasOne('App\Models\PropertyBookingEngine', 'property_id', 'id') + ->select(['id', 'property_id', 'channel_id', 'token', 'status']) + ->where('channel_id', '=', 1) + ->where('status', '=', 1); + } + + public function propertyBookingEngines() + { + return $this->hasMany('App\Models\PropertyBookingEngine', 'property_id', 'id') + ->select(['id', 'property_id', 'channel_id', 'token', 'status']) + ->where('status', '=', 1); + } + + public function propertyLanguageSpoken() + { + return $this->hasMany('App\Models\PropertyLanguageSpoken', 'property_id', 'id') + ->select('id', 'property_id', 'language_code', 'status') + ->where('status', '=', 1); + + } + + public function propertyAwardsCertificates() + { + return $this->hasMany('App\Models\PropertyAwardsCertificate', 'property_id', 'id') + ->select('id', 'property_id', 'category_id', 'name', 'date', 'url', 'file_path', 'file_type', 'language_code', 'status'); + + } + + public function propertyAdditionalInfos() + { + return $this->hasMany('App\Models\PropertyAdditionalInfo', 'property_id', 'id')->select('id', 'property_id', 'additional_info_key_id', 'value'); + + } + + public function propertyProductMapping() + { + return $this->hasMany('App\Models\PropertyProductMapping', 'property_id', 'id')->select('id', 'property_id', 'product_id', 'expiration_date', 'status'); + } + + public function userPropertyMapping() + { + return $this->hasMany('App\Models\UserPropertyMapping', 'property_id', 'id')->select('id', 'property_id', 'user_id', 'status')->where('status', '=', 1); + } + + public function propertyPlace() + { + return $this->hasMany('App\Models\PropertyPlace', 'property_id', 'id')->select('id', 'property_id', 'name', 'place_category_id', 'description', 'status')->where('status', '=', 1); + } + + public function country() + { + return $this->hasOne('App\Models\Country', 'country_code', 'country')->select('name', 'language_key', 'country_code'); + } + + public function propertyWebComponent() + { + return $this->hasMany('App\Models\PropertyWebComponentMapping', 'property_id', 'id')->select('id', 'property_id', 'channel_id', 'component_id', 'status')->where('status', '=', 1); + } + + public function propertyPromotionMapping() + { + return $this->hasMany('App\Models\PropertyPromotionMapping', 'property_id', 'id')->select('id', 'property_id', 'room_rate_channel_mapping_id', 'property_promotion_id', 'status')->where('status', '=', 1); + } + + public function propertyFactMapping() + { + return $this->hasMany('App\Models\PropertyFactMapping', 'property_id', 'id')->select('id', 'property_id', 'fact_id'); + } + + public function propertyPaymentMapping() + { + return $this->hasMany('App\Models\PropertyPaymentMapping', 'property_id', 'id')->select('id', 'property_id', 'payment_type_id', 'status'); + } + + public function propertyStatus() + { + return $this->hasOne('App\Models\PropertyStatus', 'id', 'status')->select('id', 'name', 'status'); + } + +} diff --git a/app/Models/PropertyAdditionalInfo.php b/app/Models/PropertyAdditionalInfo.php new file mode 100644 index 0000000..ed60b45 --- /dev/null +++ b/app/Models/PropertyAdditionalInfo.php @@ -0,0 +1,26 @@ +hasOne("App\Models\PropertyAdditionalInfoKey", 'id', 'additional_info_key_id')->select(['id' , 'additional_info_key', 'language_key' ]); + } + +} diff --git a/app/Models/PropertyAdditionalInfoKey.php b/app/Models/PropertyAdditionalInfoKey.php new file mode 100644 index 0000000..7eda919 --- /dev/null +++ b/app/Models/PropertyAdditionalInfoKey.php @@ -0,0 +1,24 @@ +hasMany('App\Models\PropertyAdditionalInfoKeyLocale','additional_info_key_id','id'); + } +} diff --git a/app/Models/PropertyAddon.php b/app/Models/PropertyAddon.php new file mode 100644 index 0000000..3516a72 --- /dev/null +++ b/app/Models/PropertyAddon.php @@ -0,0 +1,36 @@ +attribute)) { + $attribute = json_decode($this->attribute, 1); + } + return $attribute; + } + + public function fact() + { + return $this->hasOne("App\Models\PropertyFact", 'id', 'fact_id')->select('id', 'parent_id', 'name', 'icon', 'language_key'); + } + +} diff --git a/app/Models/PropertyAvailabilityType.php b/app/Models/PropertyAvailabilityType.php new file mode 100644 index 0000000..652af49 --- /dev/null +++ b/app/Models/PropertyAvailabilityType.php @@ -0,0 +1,30 @@ +hasOne('App\Models\AwardsCertificateCategory','id', 'category_id') + ->select("id", "name", "language_key", "country_code", "logo", "type", "status"); + } + + +} diff --git a/app/Models/PropertyBookingEngine.php b/app/Models/PropertyBookingEngine.php new file mode 100644 index 0000000..facf2e4 --- /dev/null +++ b/app/Models/PropertyBookingEngine.php @@ -0,0 +1,76 @@ +parameters)) { + $parametersArray = json_decode($this->parameters, 1); + if (is_array($parametersArray)) { + $parameters = $parametersArray; + } + } + + return $parameters; + } + + public function property() + { + return $this->hasOne("App\Models\Property", 'id', 'property_id') + ->select(['id', 'name', 'country', 'destination_id','property_type_id','mapping']); + } + + public function channel() + { + return $this->hasOne("App\Models\PropertyChannel", 'id', 'channel_id')->select(['id', 'name', 'token', 'channel_category_id', 'contact']); + } + + public function propertyWeb() + { + return $this->hasOne('App\Models\PropertyWeb', 'property_id', 'property_id') + ->where('status', '=', 1) + ->select("id", "property_id", "domain", "default_language", "template_id", "token"); + } + + public function propertyChannelMapping() + { + return $this->hasOne('App\Models\PropertyChannelMapping', 'property_id', 'property_id') + ->where('channel_id', '=', 1) + ->select("id", "property_id", "channel_id", "currency_code", "channel_tax_id", "status"); + } + + public function propertyWebComponent() + { + return $this->hasMany('App\Models\PropertyWebComponentMapping','property_id', 'property_id') + ->select('id','property_id','channel_id','component_id','parameter','language','status')->where('status',1); + } + +} diff --git a/app/Models/PropertyBookingEngineSearch.php b/app/Models/PropertyBookingEngineSearch.php new file mode 100644 index 0000000..79436d1 --- /dev/null +++ b/app/Models/PropertyBookingEngineSearch.php @@ -0,0 +1,30 @@ +logo_name)) { + $logoUrl = Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/logo/' . $this->logo_name . '_250x250.' . $this->logo_file_ext; + } + + return $logoUrl; + } + +} diff --git a/app/Models/PropertyCancellationPolicy.php b/app/Models/PropertyCancellationPolicy.php new file mode 100644 index 0000000..05a7aff --- /dev/null +++ b/app/Models/PropertyCancellationPolicy.php @@ -0,0 +1,21 @@ +id . '.png'; + return Config::get('app.client_server') . '/assets/img/brands/' . $this->logo; + } + + public function getCountryCodeGroupArrayAttribute() + { + if (!is_null($this->country_code_group)) { + return json_decode($this->country_code_group, 1); + } else { + return null; + } + } + + + public function propertyChannelCategory() + { + return $this->hasOne('App\Models\PropertyChannelCategory', 'id', 'channel_category_id')->select(['id', 'name', 'language_key']); + } + + public function parentChannel() + { + return $this->hasOne('App\Models\PropertyChannel', 'id', 'parent_id')->select(['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'country_code', 'currency_code', 'default_currency', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']); + } +} diff --git a/app/Models/PropertyChannelAddon.php b/app/Models/PropertyChannelAddon.php new file mode 100644 index 0000000..9920b18 --- /dev/null +++ b/app/Models/PropertyChannelAddon.php @@ -0,0 +1,37 @@ +description)) { + $description = json_decode($this->description, 1); + } + return $description; + } + + public function propertyAddon() + { + return $this->hasOne("App\Models\PropertyAddon", 'id', 'property_addon_id')->select('id','fact_id','title','attribute'); + } + + +} diff --git a/app/Models/PropertyChannelBookingPaymentSetup.php b/app/Models/PropertyChannelBookingPaymentSetup.php new file mode 100644 index 0000000..438fa53 --- /dev/null +++ b/app/Models/PropertyChannelBookingPaymentSetup.php @@ -0,0 +1,45 @@ +cancellation_policy)) { + return json_decode($this->cancellation_policy, 1); + } else { + return null; + } + } + + public function paymentType() + { + return $this->hasOne("App\Models\PropertyBookingPaymentType", 'id', 'payment_type_id')->select(['id', 'name', 'language_key', 'code', 'status']); + } +} diff --git a/app/Models/PropertyChannelCategory.php b/app/Models/PropertyChannelCategory.php new file mode 100644 index 0000000..6ffc823 --- /dev/null +++ b/app/Models/PropertyChannelCategory.php @@ -0,0 +1,33 @@ +hasMany('App\Models\PropertyChannelGroupChannelMapping','channel_group_id','id')->where('status',1); + } +} diff --git a/app/Models/PropertyChannelGroupChannelMapping.php b/app/Models/PropertyChannelGroupChannelMapping.php new file mode 100644 index 0000000..eba3d7a --- /dev/null +++ b/app/Models/PropertyChannelGroupChannelMapping.php @@ -0,0 +1,32 @@ +hasOne("App\Models\PropertyChannel",'id', 'channel_id')->select(['id', 'name', 'token' ]); + } +} diff --git a/app/Models/PropertyChannelMapping.php b/app/Models/PropertyChannelMapping.php new file mode 100644 index 0000000..ddbc4a6 --- /dev/null +++ b/app/Models/PropertyChannelMapping.php @@ -0,0 +1,74 @@ +hasOne("App\Models\Property", 'id', 'property_id')->select(['id' , 'name']); + } + + public function channel() + { + return $this->hasOne("App\Models\PropertyChannel", 'id', 'channel_id')->select(['id', 'parent_id', 'token','name', 'official_name', 'description', 'channel_category_id', 'country_code', 'country_code_group', 'currency_code', 'default_currency', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'contact', 'status']); + } + + public function channelBookingType() + { + return $this->hasOne("App\Models\PropertyBookingType", 'id', 'property_booking_type_id')->select(['id', 'name', 'language_key', 'code', 'status']); + } + + public function channelAvailabilityType() + { + return $this->hasOne("App\Models\PropertyAvailabilityType", 'id', 'property_availability_type_id')->select(['id', 'name', 'language_key', 'code', 'status']); + } + + public function channelRoomPricingType() + { + return $this->hasOne("App\Models\PropertyRoomPricingType", 'id', 'property_room_pricing_type_id')->select(['id', 'name', 'language_key', 'code', 'status']); + } + + public function channelBookingPaymentType() + { + return $this->hasMany("App\Models\PropertyChannelBookingPaymentSetup", 'property_channel_mapping_id', 'id')->select(['id', 'property_channel_mapping_id', 'payment_type_id', 'cancellation_policy', 'is_affected_price', 'is_get_payment_data','action_type', 'value_type', 'value', 'is_selected', 'status']); + } + + public function channelContact() + { + return $this->hasMany("App\Models\PropertyChannelContact", 'property_channel_mapping_id', 'id')->select(['id', 'property_channel_mapping_id','name', 'email', 'status']); + } + + + public function channelTax() + { + return $this->hasOne("App\Models\PropertyChannelTax", 'id', 'channel_tax_id')->select(['id', 'name', 'language_key', 'code', 'status']); + } + + public function currency() + { + return $this->hasOne("App\Models\Currency", 'code', 'currency_code')->select(['id', 'code', 'symbol', 'name', 'language_key', 'status']); + } +} diff --git a/app/Models/PropertyChannelRoomRateCancellationPolicyMapping.php b/app/Models/PropertyChannelRoomRateCancellationPolicyMapping.php new file mode 100644 index 0000000..55dd7db --- /dev/null +++ b/app/Models/PropertyChannelRoomRateCancellationPolicyMapping.php @@ -0,0 +1,25 @@ +hasOne('App\Models\PropertyCancellationPolicy', 'id', 'cancellation_policy_id') + ->select(['id', 'property_id', 'name', 'before_arrival', 'is_nonrefundable', 'is_free_cancellation', 'type', 'value', 'is_affected_price', 'affect_price_action_type', 'affect_price_type', 'affect_price_value', 'is_date_range', 'start_date', 'finish_date', 'status']); + } + +} diff --git a/app/Models/PropertyChannelRoomRatePricingPolicyAdultMapping.php b/app/Models/PropertyChannelRoomRatePricingPolicyAdultMapping.php new file mode 100644 index 0000000..ed54395 --- /dev/null +++ b/app/Models/PropertyChannelRoomRatePricingPolicyAdultMapping.php @@ -0,0 +1,40 @@ +hasOne('App\Models\PropertyPricingPolicyAdult', 'id', 'pricing_policy_adult_id') + ->select("id", "property_id", "name", "adult_action_type", "adult", "action_type", "type", "value", "reservation_start_date", "reservation_end_date", "status"); + } + + +} diff --git a/app/Models/PropertyChannelRoomRatePricingPolicyChildMapping.php b/app/Models/PropertyChannelRoomRatePricingPolicyChildMapping.php new file mode 100644 index 0000000..a316faa --- /dev/null +++ b/app/Models/PropertyChannelRoomRatePricingPolicyChildMapping.php @@ -0,0 +1,41 @@ +hasOne('App\Models\PropertyPricingPolicyChild', 'id','pricing_policy_child_id') + ->select("id", "property_id", "name","adult", "child_order","child_age_start","child_age_end","type","value","reservation_start_date", "reservation_end_date","status"); + } + +} diff --git a/app/Models/PropertyChannelTax.php b/app/Models/PropertyChannelTax.php new file mode 100644 index 0000000..e677d78 --- /dev/null +++ b/app/Models/PropertyChannelTax.php @@ -0,0 +1,33 @@ +belongsTo('App\Models\Property', 'property_id', 'id'); + } +} diff --git a/app/Models/PropertyCompetitorGroupMapping.php b/app/Models/PropertyCompetitorGroupMapping.php new file mode 100644 index 0000000..87b36bc --- /dev/null +++ b/app/Models/PropertyCompetitorGroupMapping.php @@ -0,0 +1,22 @@ +phone,'444') !== false) { + $phoneNumber = $this->phone; + preg_match_all('/(444).*/m', $this->phone, $matchesPhone, PREG_SET_ORDER, 0); + $matchesPhone = reset($matchesPhone); + $matchesPhone = reset($matchesPhone); + $matchesPhone = str_replace(' ','', $matchesPhone); + + $phoneNumber = substr($matchesPhone,0,3).' '.substr($matchesPhone,3,1).' '.substr($matchesPhone,4,3); + + return $phoneNumber; + } + + if ($this->phone == null || $this->phone == "" || strlen($this->phone) < self::CHARACTER_LENGTH) { + return null; + } + + if ($this->phone_code) { + $response = strpos($this->phone_code, '+') === false ? '+' . $this->phone_code . $this->phone : $this->phone_code . $this->phone; + } else { + $response = strpos($this->phone, '+') === false ? '+' . $this->phone : $this->phone; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + public function getViewFullMobileAttribute() + { + try { + $response = null; + + if ($this->mobile == null || $this->mobile == "" || strlen($this->mobile) < self::CHARACTER_LENGTH) { + return null; + } + if ($this->mobile_code) { + $response = strpos($this->mobile_code, '+') === false ? '+' . $this->mobile_code . $this->mobile : $this->mobile_code . $this->mobile; + } else { + $response = strpos($this->mobile, '+') === false ? '+' . $this->mobile : $this->mobile; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + + public function getViewFullMobile2Attribute() + { + try { + $response = null; + if ($this->mobile2 == null || $this->mobile2 == "" || strlen($this->mobile2) < self::CHARACTER_LENGTH) { + return null; + } + + if ($this->mobile2_code) { + $response = strpos($this->mobile2_code, '+') === false ? '+' . $this->mobile2_code . $this->mobile2 : $this->mobile2_code . $this->mobile2; + } else { + $response = strpos($this->mobile2, '+') === false ? '+' . $this->mobile2 : $this->mobile2; + } + return $response; + + } catch (Exception $e) { + return null; + } + } + + + public function getViewFullFaxAttribute() + { + try { + $response = null; + if ($this->fax == null || $this->fax == "" || strlen($this->fax) < self::CHARACTER_LENGTH) { + return null; + } + if ($this->fax_code) { + $response = strpos($this->fax_code, '+') === false ? '+' . $this->fax_code . $this->fax : $this->fax_code . $this->fax; + } else { + $response = strpos($this->fax, '+') === false ? '+' . $this->fax : $this->fax; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + public function getFormattedMobileNumberAttribute() + { + try { + $mobilePhoneNumber = null; + if ($this->mobile == null || $this->mobile == "" || strlen($this->mobile) < self::CHARACTER_LENGTH) { + return null; + } + if ($this->mobile) { + $this->mobile = preg_replace('/[^0-9,.]+/i', '', $this->mobile); + $mobilePhoneNumber = $this->mobile_code . $this->mobile; + } + return $mobilePhoneNumber; + } catch (Exception $e) { + return null; + } + } + + +} diff --git a/app/Models/PropertyContent.php b/app/Models/PropertyContent.php new file mode 100644 index 0000000..23f293e --- /dev/null +++ b/app/Models/PropertyContent.php @@ -0,0 +1,36 @@ +hasMany('App\Models\PropertyContentCategory','id'); + } + +} diff --git a/app/Models/PropertyContentCategory.php b/app/Models/PropertyContentCategory.php new file mode 100644 index 0000000..77505d0 --- /dev/null +++ b/app/Models/PropertyContentCategory.php @@ -0,0 +1,35 @@ +hasMany('App\Models\PropertyContentCategoryLocale','content_category_id', 'id'); + } +} diff --git a/app/Models/PropertyExecutive.php b/app/Models/PropertyExecutive.php new file mode 100644 index 0000000..17998ee --- /dev/null +++ b/app/Models/PropertyExecutive.php @@ -0,0 +1,98 @@ +phone == null || $this->phone == "" || strlen( $this->phone) < self::CHARACTER_LENGTH){ + return null ; + } + if($this->phone_code){ + $response = strpos($this->phone_code, '+') === false ? '+'.$this->phone_code.$this->phone : $this->phone_code.$this->phone; + }else{ + $response = strpos($this->phone, '+') === false ? '+'.$this->phone : $this->phone; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + public function getViewFullMobileAttribute() + { + try { + $response = null ; + if($this->mobile == null || $this->mobile == "" || strlen( $this->mobile) < self::CHARACTER_LENGTH){ + return null ; + } + if($this->mobile_code){ + $response = strpos($this->mobile_code, '+') === false ? '+'.$this->mobile_code.$this->mobile : $this->mobile_code.$this->mobile; + }else{ + $response = strpos($this->mobile, '+') === false ? '+'.$this->mobile : $this->mobile; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + + public function getViewFullFaxAttribute() + { + try { + $response = null ; + if($this->fax == null || $this->fax == "" || strlen( $this->fax) < self::CHARACTER_LENGTH){ + return null ; + } + if($this->fax_code){ + $response = strpos($this->fax_code, '+') === false ? '+'.$this->fax_code.$this->fax : $this->fax_code.$this->fax; + }else{ + $response = strpos($this->fax, '+') === false ? '+'.$this->fax : $this->fax; + } + return $response; + } catch (Exception $e) { + return null; + } + } + + public function executiveType() + { + return $this->hasOne('App\Models\PropertyExecutiveType','id', 'executive_type_id')->select('id', 'name', 'language_key', 'icon'); + } + + + /*public function PropertyContentCategories() + { + return $this->hasMany('App\Models\PropertyContentCategory','id'); + }*/ +} diff --git a/app/Models/PropertyExecutiveType.php b/app/Models/PropertyExecutiveType.php new file mode 100644 index 0000000..6e0704f --- /dev/null +++ b/app/Models/PropertyExecutiveType.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyFact','id', 'parent_id')->select('id', 'parent_id', 'name', 'language_key', 'title_language_key', 'order_number'); + } +} diff --git a/app/Models/PropertyFactAttribute.php b/app/Models/PropertyFactAttribute.php new file mode 100644 index 0000000..2b72402 --- /dev/null +++ b/app/Models/PropertyFactAttribute.php @@ -0,0 +1,33 @@ +description)) { + $description = json_decode($this->description, 1); + } + return $description; + } + + public function fact() + { + return $this->hasOne("App\Models\PropertyFact", 'id', 'fact_id')->select('id', 'parent_id', 'name', 'icon', 'language_key'); + } + +} diff --git a/app/Models/PropertyGroup.php b/app/Models/PropertyGroup.php new file mode 100644 index 0000000..0fbbdb1 --- /dev/null +++ b/app/Models/PropertyGroup.php @@ -0,0 +1,24 @@ +hasMany('App\Models\PropertyGroupMapping','property_group_id', 'id') + ->select([ "id","property_id","property_group_id", "order_number", "status"]) + ->where("status" , "=", 1); + } + +} diff --git a/app/Models/PropertyGroupMapping.php b/app/Models/PropertyGroupMapping.php new file mode 100644 index 0000000..8383034 --- /dev/null +++ b/app/Models/PropertyGroupMapping.php @@ -0,0 +1,29 @@ +hasOne('App\Models\PropertyGroup','id', 'property_group_id') + ->select(['id', 'name', 'type', 'status']); + } + + public function property(){ + return $this->hasOne('App\Models\Property','id', 'property_id') + ->select(['id', 'name', 'content_code']); + } + +} diff --git a/app/Models/PropertyInvoice.php b/app/Models/PropertyInvoice.php new file mode 100644 index 0000000..423cae1 --- /dev/null +++ b/app/Models/PropertyInvoice.php @@ -0,0 +1,18 @@ +hasOne('App\Models\Property','property_id', 'id'); + } + + + public function language(){ + return $this->hasOne('App\Models\Language','language_code', 'id'); + } + + public function languageCode(){ + return $this->hasOne('App\Models\Language','code', 'language_code'); + } + +} diff --git a/app/Models/PropertyMeta.php b/app/Models/PropertyMeta.php new file mode 100644 index 0000000..97a5202 --- /dev/null +++ b/app/Models/PropertyMeta.php @@ -0,0 +1,35 @@ +param)) { + return json_decode($this->param,1); + } else { + return null; + } + } + + public function property() + { + return $this->hasOne("App\Models\Property",'id','property_id')->select(['id', 'name', 'country']); + } + +} diff --git a/app/Models/PropertyMetaRoomRate.php b/app/Models/PropertyMetaRoomRate.php new file mode 100644 index 0000000..09b8d28 --- /dev/null +++ b/app/Models/PropertyMetaRoomRate.php @@ -0,0 +1,22 @@ +hasOne("App\Models\PropertyMetaRoomRate",'code','code')->select(); + } + + +} diff --git a/app/Models/PropertyMetaRoomRatePrice.php b/app/Models/PropertyMetaRoomRatePrice.php new file mode 100644 index 0000000..9261fe7 --- /dev/null +++ b/app/Models/PropertyMetaRoomRatePrice.php @@ -0,0 +1,22 @@ +hasOne('App\Models\PropertyModule','id', 'property_module_id'); + } +} diff --git a/app/Models/PropertyNonrefundable.php b/app/Models/PropertyNonrefundable.php new file mode 100644 index 0000000..d04b53a --- /dev/null +++ b/app/Models/PropertyNonrefundable.php @@ -0,0 +1,45 @@ +hasOne('App\Models\PropertyChannel','id', 'channel_id') + ->select(['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']); + } + + public function propertyRoomRateMapping() + { + return $this->hasOne('App\Models\PropertyRoomRateMapping','id', 'room_rate_mapping_id') + ->select('id', 'room_id', 'room_rate_id', 'description', 'rack_rate', 'included_occupancy'); + } + +} diff --git a/app/Models/PropertyPaymentInstallment.php b/app/Models/PropertyPaymentInstallment.php new file mode 100644 index 0000000..13c0aae --- /dev/null +++ b/app/Models/PropertyPaymentInstallment.php @@ -0,0 +1,30 @@ +params)) { + return json_decode($this->params,1); + } else { + return null; + } + } + + public function paymentType() + { + return $this->hasOne('App\Models\PaymentType','id', 'payment_type_id'); + } + + public function propertyPaymentMappingInstallments() + { + return $this->hasMany('App\Models\PropertyPaymentInstallment','property_payment_mapping_id', 'id' ) + ->select('id', 'property_id', 'property_payment_mapping_id', 'installment', 'commission', 'status'); + } +} diff --git a/app/Models/PropertyPhoto.php b/app/Models/PropertyPhoto.php new file mode 100644 index 0000000..1135d23 --- /dev/null +++ b/app/Models/PropertyPhoto.php @@ -0,0 +1,69 @@ +property_id . '/' . $this->photo_name . '_1024x768.' . $this->file_ext; + $photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . '/property-photos/' . $this->property_id . '/' . $this->photo_name . '_200x200.' . $this->file_ext; + + if (File::exists($photoUrlFilePath)) { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/' . $this->photo_name .'_1024x768.' . $this->file_ext; + }else { + $photoUrlFilePath = Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/' . $this->photo_name .'_medium.' . $this->file_ext; + } + + if (File::exists($photoUrlThumbFilePath)) { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/' . $this->photo_name .'_200x200.'. $this->file_ext; + }else { + $photoUrlThumbFilePath = Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/' . $this->photo_name .'_thumbnail.'. $this->file_ext; + } + $photoTypes = [ + 'default' => Config::get('app.imageUrl') . '/property-photos/' . $this->property_id . '/' . $this->photo_name . '.' . $this->file_ext, + 'thumb' => $photoUrlThumbFilePath, + 'fixed' => $photoUrlFilePath, + + ]; + + return $photoTypes; + } + + // Config::get('app.imageUrl') . '/property-photos/' . $params['property_id'] . '/' .$value['property_photo']['photo_name'] . '.' . $value['property_photo']['file_ext'] + + public function propertyRooms() + { + return $this->hasMany('App\Models\PropertyRoomPhotoMapping', 'photo_id', 'id'); + } + + public function propertyPlaces() + { + return $this->hasMany('App\Models\PropertyPlacePhotoMapping', 'photo_id', 'id'); + } +} diff --git a/app/Models/PropertyPhotoCategory.php b/app/Models/PropertyPhotoCategory.php new file mode 100644 index 0000000..5daea56 --- /dev/null +++ b/app/Models/PropertyPhotoCategory.php @@ -0,0 +1,37 @@ +hasMany('App\Models\PropertyPhoto','property_photo_category_id','id'); + } + +} diff --git a/app/Models/PropertyPhotoCategoryLabelMapping.php b/app/Models/PropertyPhotoCategoryLabelMapping.php new file mode 100644 index 0000000..647fb0a --- /dev/null +++ b/app/Models/PropertyPhotoCategoryLabelMapping.php @@ -0,0 +1,35 @@ +hasOne('App\Models\PropertyPhotoCategory','id', 'property_photo_category_id'); + + } + +} diff --git a/app/Models/PropertyPlace.php b/app/Models/PropertyPlace.php new file mode 100644 index 0000000..5748d9f --- /dev/null +++ b/app/Models/PropertyPlace.php @@ -0,0 +1,84 @@ +language_name)) { + $languageName = json_decode($this->language_name, 1); + } + return $languageName; + } + + function getSlugAttribute() + { + return '/place/' . Str::slug($this->name, $separator = '-', $language = 'en') . '-' . $this->id; + } + + //$propertyPlace['route'] = '/place/' . Str::slug($propertyPlace['name'], $separator = '-', $language = 'en') . '-' . $propertyPlace['id']; + + public function propertyPlaceCategory() + { + return $this->hasOne('App\Models\PropertyPlaceCategory','id', 'place_category_id') + ->where('status', '=', 1) + ->select("id", "name", "language_key", "parent_id", "level", "order_number","icon","status"); + } + + public function propertyPlaceWorkingHour() + { + return $this->hasOne('App\Models\PropertyPlaceWorkingHour','id', 'place_working_hour_id') + ->where('status', '=', 1) + ->select("id", "name", "language_key", "status"); + } + + public function propertyPlacePhotoMapping() + { + return $this->hasMany('App\Models\PropertyPlacePhotoMapping','place_id', 'id') ; + } + + public function propertyPlaceFactMapping() + { + return $this->hasMany('App\Models\PropertyPlaceFactMapping','property_place_id', 'id') ; + } + + public function propertyPlaceCategoryFieldValue() + { + return $this->hasMany('App\Models\PropertyPlaceCategoryFieldValue','place_id', 'id') ; + } + + public function propertyWebPlaceMapping() + { + return $this->hasMany('App\Models\PropertyWebPlaceMapping', 'property_place_id', 'id')->select(['id', 'property_id', 'property_web_id', 'property_place_id']); + } + +} diff --git a/app/Models/PropertyPlaceCategory.php b/app/Models/PropertyPlaceCategory.php new file mode 100644 index 0000000..79bd089 --- /dev/null +++ b/app/Models/PropertyPlaceCategory.php @@ -0,0 +1,34 @@ +hasOne('App\Models\PlaceCategoryField','id', 'place_category_field_id') ; + } + + public function unitValue() + { + return $this->hasOne('App\Models\PropertyUnit','id', 'unit_value') ; + } + + + public function optionValue() + { + return $this->hasOne('App\Models\PlaceCategoryFieldOption','id', 'option_value') ; + } + + +} diff --git a/app/Models/PropertyPlaceFact.php b/app/Models/PropertyPlaceFact.php new file mode 100644 index 0000000..ee2c24e --- /dev/null +++ b/app/Models/PropertyPlaceFact.php @@ -0,0 +1,33 @@ +hasOne('App\Models\propertyPlaceFactTitleFactMapping', 'id', 'place_fact_title_fact_mapping_id'); + } + + +} diff --git a/app/Models/PropertyPlaceFactTitle.php b/app/Models/PropertyPlaceFactTitle.php new file mode 100644 index 0000000..6f4335e --- /dev/null +++ b/app/Models/PropertyPlaceFactTitle.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyPlaceCategory','id', 'place_category_id') + ->select("id", "name", "language_key", "parent_id", "level", "order_number", "icon", "status"); + } + + public function placeFactTitle() + { + return $this->hasOne('App\Models\PropertyPlaceFactTitle','id', 'place_fact_title_id') + ->select("id", "name", "language_key", "icon", "status"); + } + + public function placeFact() + { + return $this->hasOne('App\Models\PropertyPlaceFact','id', 'place_fact_id') + ->select("id", "name", "language_key", "icon", "status"); + } + + +} diff --git a/app/Models/PropertyPlacePhotoMapping.php b/app/Models/PropertyPlacePhotoMapping.php new file mode 100644 index 0000000..9cee6f4 --- /dev/null +++ b/app/Models/PropertyPlacePhotoMapping.php @@ -0,0 +1,44 @@ +hasOne('App\Models\PropertyPhoto','id', 'photo_id'); + } + + + public function propertyPlace() + { + return $this->hasOne('App\Models\PropertyPlace','id', 'place_id'); + } +} diff --git a/app/Models/PropertyPlaceWorkingHour.php b/app/Models/PropertyPlaceWorkingHour.php new file mode 100644 index 0000000..9540ab5 --- /dev/null +++ b/app/Models/PropertyPlaceWorkingHour.php @@ -0,0 +1,34 @@ +data)) { + return json_decode($this->data, 1); + } else { + return null; + } + } + + public function propertyDetail() + { + return $this->hasOne('App\Models\Property', 'id', 'property_id') + ->select(['id', 'name', 'country', 'official_name', 'tax_office', 'tax_number', 'commission', 'commission_offline', 'commission_channel', 'commission_wholesaler','contract_user_id']); + } +} diff --git a/app/Models/PropertyPricingPolicyAdult.php b/app/Models/PropertyPricingPolicyAdult.php new file mode 100644 index 0000000..bf9af73 --- /dev/null +++ b/app/Models/PropertyPricingPolicyAdult.php @@ -0,0 +1,40 @@ +hasMany('App\Models\PropertyChannelRoomRatePricingPolicyAdultMapping','pricing_policy_adult_id', 'id')->select("id", "property_id", "room_rate_channel_mapping_id", "pricing_policy_adult_id", "status"); + } + + + +} diff --git a/app/Models/PropertyPricingPolicyChild.php b/app/Models/PropertyPricingPolicyChild.php new file mode 100644 index 0000000..aff980a --- /dev/null +++ b/app/Models/PropertyPricingPolicyChild.php @@ -0,0 +1,40 @@ +hasMany('App\Models\PropertyChannelRoomRatePricingPolicyChildMapping','pricing_policy_child_id', 'id')->select("id", "property_id", "room_rate_channel_mapping_id", "pricing_policy_child_id", "status"); + } + + + +} diff --git a/app/Models/PropertyProductMapping.php b/app/Models/PropertyProductMapping.php new file mode 100644 index 0000000..60f3b1d --- /dev/null +++ b/app/Models/PropertyProductMapping.php @@ -0,0 +1,38 @@ +parameter)) { + $attribute = json_decode($this->parameter, 1); + } + return $attribute; + } + + +} diff --git a/app/Models/PropertyProductOffer.php b/app/Models/PropertyProductOffer.php new file mode 100644 index 0000000..93b31ee --- /dev/null +++ b/app/Models/PropertyProductOffer.php @@ -0,0 +1,50 @@ +detail)) { + $parametersArray = json_decode($this->detail, 1); + if (is_array($parametersArray)) { + $parameters = $parametersArray; + } + } + + return $parameters; + } + + + public function getOfferTimeFormattedAttribute() + { + try { + return Carbon::parse($this->offer_date)->format('d.m.Y H:i:s'); + } catch (Exception $e) { + return null; + } + } + + public function getOfferExpireTimeFormattedAttribute() + { + try { + return Carbon::parse($this->offer_expire_date)->format('d.m.Y H:i:s'); + } catch (Exception $e) { + return null; + } + } +} diff --git a/app/Models/PropertyPromotion.php b/app/Models/PropertyPromotion.php new file mode 100644 index 0000000..c5c53da --- /dev/null +++ b/app/Models/PropertyPromotion.php @@ -0,0 +1,55 @@ +hasOne('App\Models\PromotionType', 'id', 'promotion_type_id') + ->select(['id', 'name', 'language_key', 'parent_id', 'type_code', 'order_number', 'status']); + } + + public function getDaysArrayAttribute() + { + if (!is_null($this->days)) { + return json_decode($this->days, 1); + } else { + return null; + } + } + + public function getExcludeDatesArrayAttribute() + { + if (!is_null($this->exclude_dates)) { + return json_decode($this->exclude_dates, 1); + } else { + return null; + } + } +} diff --git a/app/Models/PropertyPromotionMapping.php b/app/Models/PropertyPromotionMapping.php new file mode 100644 index 0000000..34d102e --- /dev/null +++ b/app/Models/PropertyPromotionMapping.php @@ -0,0 +1,43 @@ +hasOne('App\Models\PropertyPromotion', 'id', 'property_promotion_id') + ->select(['id', 'property_id', 'promotion_type_id', 'start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', 'exclude_dates', 'is_time', 'start_time', 'end_time', 'day_before', 'amount', 'min_stay', 'is_mobile', 'days', 'params', 'detail', 'status']); + } + + public function propertyRoomRateChannelMapping() + { + return $this->hasOne('App\Models\PropertyRoomRateChannelMapping', 'id', 'room_rate_channel_mapping_id') + ->select(['id', 'property_id', 'room_rate_mapping_id', 'channel_id', 'status']); + } +} diff --git a/app/Models/PropertyQuickPricingMapping.php b/app/Models/PropertyQuickPricingMapping.php new file mode 100644 index 0000000..d65873e --- /dev/null +++ b/app/Models/PropertyQuickPricingMapping.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyRoomRateChannelMapping', 'id', 'room_rate_channel_mapping_id') + ->select(['id', 'property_id', 'room_rate_mapping_id', 'channel_id', 'status']); + } +} diff --git a/app/Models/PropertyReview.php b/app/Models/PropertyReview.php new file mode 100644 index 0000000..2075ce4 --- /dev/null +++ b/app/Models/PropertyReview.php @@ -0,0 +1,51 @@ +sentiment == 1) { + $sentimentText = 'Positive'; + } elseif ($this->sentiment == 0 && !is_null($this->sentiment)) { + $sentimentText = 'Negative'; + } + + return $sentimentText; + + } + + public function channel() + { + return $this->hasOne('App\Models\PropertyReviewChannel', 'id', 'channel_id')->select(['id', 'name', 'logo']); + } + + public function property() + { + return $this->hasOne('App\Models\Property', 'id', 'property_id')->select(['id', 'name', 'status']); + } + + public function categoryMapping() + { + return $this->hasMany('App\Models\PropertyReviewCategoryMapping', 'review_id', 'id')->select(['id', 'review_id', 'category_id', 'sentiment']); + } + + public function keywordMapping() + { + return $this->hasMany('App\Models\PropertyReviewKeywordMapping', 'review_id', 'id')->select(['id', 'review_id', 'channel_id', 'keyword', 'sentiment']); + } +} diff --git a/app/Models/PropertyReviewCategory.php b/app/Models/PropertyReviewCategory.php new file mode 100644 index 0000000..d561bd0 --- /dev/null +++ b/app/Models/PropertyReviewCategory.php @@ -0,0 +1,19 @@ +sentiment == 1) { + $sentimentText = 'Positive'; + } elseif ($this->sentiment == 0 && !is_null($this->sentiment)) { + $sentimentText = 'Negative'; + } + + return $sentimentText; + + } + public function category() + { + return $this->hasOne('App\Models\PropertyReviewCategory', 'id', 'category_id')->select(['id', 'name', 'language_key']); + } +} diff --git a/app/Models/PropertyReviewChannel.php b/app/Models/PropertyReviewChannel.php new file mode 100644 index 0000000..d271757 --- /dev/null +++ b/app/Models/PropertyReviewChannel.php @@ -0,0 +1,35 @@ +parameter)) { + $attribute = json_decode($this->parameter, 1); + } + return $attribute; + } + + public function getLogoUrlAttribute() + { + return config('app.url') . '/img/channel-icons/' . $this->logo; + + } + + +} diff --git a/app/Models/PropertyReviewChannelMapping.php b/app/Models/PropertyReviewChannelMapping.php new file mode 100644 index 0000000..53362dd --- /dev/null +++ b/app/Models/PropertyReviewChannelMapping.php @@ -0,0 +1,42 @@ +parameter)) { + return json_decode($this->parameter, 1); + } else { + return null; + } + } + + public function channel() + { + return $this->hasOne('App\Models\PropertyReviewChannel', 'id', 'channel_id')->select(['id', 'name', 'parameter', 'status']); + } + + public function property() + { + return $this->hasOne('App\Models\Property', 'id', 'property_id')->select(['id', 'name', 'status']); + } + + public function fetchStatus() + { + return $this->hasOne('App\Models\PropertyReviewFetchStatus', 'id', 'fetch_status')->select(['id', 'name', 'language_key', 'status']); + } +} diff --git a/app/Models/PropertyReviewFetchStatus.php b/app/Models/PropertyReviewFetchStatus.php new file mode 100644 index 0000000..bd8ce6d --- /dev/null +++ b/app/Models/PropertyReviewFetchStatus.php @@ -0,0 +1,20 @@ + 'm²', + 'ft' => 'ft² sq' + ]; + + $roomSizeType = isset($roomSizeTypes[$this->room_size_type]) && !empty($this->room_size_type) ? $roomSizeTypes[$this->room_size_type] : $this->room_size_type; + + return $roomSizeType; + } + + + public function propertyRoomType() + { + return $this->hasOne('App\Models\PropertyRoomType', 'id', 'room_type_id')->select(['id', 'name', 'status', 'language_key']); + } + + public function propertyRoomRateMapping() + { + return $this->hasMany('App\Models\PropertyRoomRateMapping', 'room_id', 'id')->select(['id', 'room_id', 'room_rate_id', 'description', 'rack_rate', 'included_occupancy','connected_rate_id','is_affected_price','affect_price_action_type','affect_price_type','affect_price_value']); + } + + public function propertyRoomBedGroup() + { + return $this->hasMany('App\Models\PropertyRoomBed', 'room_id', 'id')->select(['id', 'room_id', 'bed_group', 'count', 'bed_type_id', 'status']); + } + + public function propertyRoomFactMapping() + { + return $this->hasMany('App\Models\PropertyRoomFactMapping', 'room_id', 'id')->select(['id', 'room_id', 'fact_id', 'property_id', 'is_feature']); + } + + public function propertyRoomPhotoMapping() + { + return $this->hasMany('App\Models\PropertyRoomPhotoMapping', 'room_id', 'id')->select(['id', 'room_id', 'photo_id', 'property_id']); + } + + public function propertyRoomDefaultPhoto() + { + return $this->hasOne('App\Models\PropertyRoomPhotoMapping', 'room_id', 'id')->select(['id', 'room_id', 'photo_id', 'property_id']); + } + + public function propertyRoomViewMapping() + { + return $this->hasMany('App\Models\PropertyRoomViewMapping', 'room_id', 'id')->select(['id', 'room_id', 'room_view_type_id']); + } + + public function propertyRoomConnected() + { + return $this->hasMany('App\Models\PropertyRoomConnected', 'room_id', 'id')->select(['id', 'room_id', 'connected_room_id']); + } + + public function propertyWebRoomMapping() + { + return $this->hasOne('App\Models\PropertyWebRoomMapping', 'property_room_id', 'id')->select(['id', 'property_id', 'property_web_id', 'property_room_id']); + } + + public function smokingPreference() + { + return $this->hasMany('App\Models\PropertyRoomFactMapping', 'room_id', 'id') + ->whereIn('fact_id', [684,685])->select(); + } +} diff --git a/app/Models/PropertyRoomAvailability.php b/app/Models/PropertyRoomAvailability.php new file mode 100644 index 0000000..2a325b2 --- /dev/null +++ b/app/Models/PropertyRoomAvailability.php @@ -0,0 +1,37 @@ +hasOne('App\Models\PropertyRoom','id', 'property_room_id')->select(); + } + +} diff --git a/app/Models/PropertyRoomAvailabilityQueue.php b/app/Models/PropertyRoomAvailabilityQueue.php new file mode 100644 index 0000000..9350499 --- /dev/null +++ b/app/Models/PropertyRoomAvailabilityQueue.php @@ -0,0 +1,42 @@ +hasOne("App\Models\Property", 'id', 'property_id')->select(['id', 'name', 'country']); + } + + public function propertyChannelManager() + { + return $this->hasOne("App\Models\ChannelManagerPropertyMapping", 'property_id', 'property_id')->select(['id', 'property_id', 'channel_manager_id', 'channel_manager_property_id']); + } + +} diff --git a/app/Models/PropertyRoomBed.php b/app/Models/PropertyRoomBed.php new file mode 100644 index 0000000..d39f370 --- /dev/null +++ b/app/Models/PropertyRoomBed.php @@ -0,0 +1,41 @@ +hasMany('App\Models\PropertyRoom','id', 'room_id')->select(['id', 'name', 'status']); + } + + public function propertyRoomBedType() + { + return $this->hasOne('App\Models\PropertyRoomBedType','id', 'bed_type_id')->select(['id', 'name', 'status','icon', 'language_key']); + } +} diff --git a/app/Models/PropertyRoomBedType.php b/app/Models/PropertyRoomBedType.php new file mode 100644 index 0000000..9eff021 --- /dev/null +++ b/app/Models/PropertyRoomBedType.php @@ -0,0 +1,39 @@ +icon; + } + +} diff --git a/app/Models/PropertyRoomConnected.php b/app/Models/PropertyRoomConnected.php new file mode 100644 index 0000000..3936b83 --- /dev/null +++ b/app/Models/PropertyRoomConnected.php @@ -0,0 +1,33 @@ +hasOne('App\Models\PropertyRoom','id', 'room_id')->select(); + } + +} diff --git a/app/Models/PropertyRoomFactMapping.php b/app/Models/PropertyRoomFactMapping.php new file mode 100644 index 0000000..cd8e268 --- /dev/null +++ b/app/Models/PropertyRoomFactMapping.php @@ -0,0 +1,47 @@ +hasOne('App\Models\PropertyFact','id', 'fact_id') + ->select("id", + "name", + "language_key", + "parent_id", + "type", + "order_number", + "icon", + "status" +); + } + + +} diff --git a/app/Models/PropertyRoomPhotoMapping.php b/app/Models/PropertyRoomPhotoMapping.php new file mode 100644 index 0000000..53d07f0 --- /dev/null +++ b/app/Models/PropertyRoomPhotoMapping.php @@ -0,0 +1,43 @@ +hasOne('App\Models\PropertyPhoto','id', 'photo_id'); + } + + + public function propertyRoom() + { + return $this->hasOne('App\Models\PropertyRoom','id', 'room_id'); + } +} diff --git a/app/Models/PropertyRoomPricingType.php b/app/Models/PropertyRoomPricingType.php new file mode 100644 index 0000000..83e1550 --- /dev/null +++ b/app/Models/PropertyRoomPricingType.php @@ -0,0 +1,20 @@ +description)) { + $description = json_decode($this->description, 1); + } + return $description; + } + + public function propertyRoomRateInclusionMapping() + { + return $this->hasMany('App\Models\PropertyRoomRateInclusionMapping','room_rate_id', 'id')->select('id', 'room_rate_id', 'fact_id'); + } + + public function propertyRoomRateAccommodation() + { + return $this->hasOne('App\Models\PropertyFact', 'id', 'accommodation_type')->select('id', 'name', 'language_key'); + } +} diff --git a/app/Models/PropertyRoomRateChannelMapping.php b/app/Models/PropertyRoomRateChannelMapping.php new file mode 100644 index 0000000..4eb8124 --- /dev/null +++ b/app/Models/PropertyRoomRateChannelMapping.php @@ -0,0 +1,68 @@ +hasOne('App\Models\PropertyChannel','id', 'channel_id')->select(['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']); + } + + public function propertyRoomRateMapping() + { + return $this->hasOne('App\Models\PropertyRoomRateMapping','id', 'room_rate_mapping_id')->select(['id', 'room_id', 'room_rate_id', 'rack_rate', 'included_occupancy','status']); + } + + public function propertyRoomRateChannelCancellationPolicy() + { + return $this->hasMany('App\Models\PropertyChannelRoomRateCancellationPolicyMapping','room_rate_channel_mapping_id', 'id')->select(['id', 'property_id', 'room_rate_channel_mapping_id', 'cancellation_policy_id','status']); + } + + public function propertyRoomRateChannelPricingAdultPolicy() + { + return $this->hasMany('App\Models\PropertyChannelRoomRatePricingPolicyAdultMapping','room_rate_channel_mapping_id', 'id')->select(['id', 'property_id', 'room_rate_channel_mapping_id', 'pricing_policy_adult_id']); + } + + public function propertyRoomRateChannelPricingChildPolicy() + { + return $this->hasMany('App\Models\PropertyChannelRoomRatePricingPolicyChildMapping','room_rate_channel_mapping_id', 'id')->select(['id', 'property_id', 'room_rate_channel_mapping_id', 'pricing_policy_child_id']); + } + + public function propertyRoomRateChannelPromotion() + { + return $this->hasMany('App\Models\PropertyPromotionMapping','room_rate_channel_mapping_id', 'id')->select(['id', 'property_id', 'room_rate_channel_mapping_id', 'property_promotion_id', 'status']); + } + + public function propertyRoomRateQuickPricingMapping() + { + return $this->hasOne('App\Models\PropertyQuickPricingMapping','room_rate_channel_mapping_id','id'); + } + +} diff --git a/app/Models/PropertyRoomRateInclusionMapping.php b/app/Models/PropertyRoomRateInclusionMapping.php new file mode 100644 index 0000000..89735e0 --- /dev/null +++ b/app/Models/PropertyRoomRateInclusionMapping.php @@ -0,0 +1,38 @@ +hasOne('App\Models\PropertyFact','id', 'fact_id')->select(['id', 'name', 'parent_id', 'language_key', 'type', 'order_number', 'icon']); + } + +} diff --git a/app/Models/PropertyRoomRateMapping.php b/app/Models/PropertyRoomRateMapping.php new file mode 100644 index 0000000..fe320e7 --- /dev/null +++ b/app/Models/PropertyRoomRateMapping.php @@ -0,0 +1,55 @@ +hasOne('App\Models\PropertyRoomRate','id', 'room_rate_id')->select(['id', 'name', 'description', 'min_stay', 'max_stay','accommodation_type']); + } + + public function propertyRoom() + { + return $this->hasOne('App\Models\PropertyRoom','id', 'room_id')->select(['id', 'name', 'room_type_id', 'max_occupancy', 'max_adult', 'max_child', 'max_child_number', 'exclude_occupancy','occupancy_lock', 'room_type_count', 'room_size', 'room_size_type','status']); + } + + + public function propertyRoomRateChannel() + { + return $this->hasMany('App\Models\PropertyRoomRateChannelMapping','room_rate_mapping_id', 'id')->select(['id', 'channel_id', 'room_rate_mapping_id', 'has_date', 'start_date', 'end_date', 'status']); + } + + public function connectedRate() + { + return $this->hasOne('App\Models\PropertyRoomRate','id', 'connected_rate_id')->select(['id', 'name', 'description']); + } + + +} diff --git a/app/Models/PropertyRoomRateMappingSetup.php b/app/Models/PropertyRoomRateMappingSetup.php new file mode 100644 index 0000000..e88493e --- /dev/null +++ b/app/Models/PropertyRoomRateMappingSetup.php @@ -0,0 +1,34 @@ +hasOne('App\Models\PropertyRoomRateMapping','id', 'room_rate_mapping_id')->select(); + } + +} diff --git a/app/Models/PropertyRoomRatePriceQueue.php b/app/Models/PropertyRoomRatePriceQueue.php new file mode 100644 index 0000000..cfcc330 --- /dev/null +++ b/app/Models/PropertyRoomRatePriceQueue.php @@ -0,0 +1,42 @@ +hasOne("App\Models\Property", 'id', 'property_id')->select(['id', 'name', 'country']); + } + + public function propertyChannelManager() + { + return $this->hasOne("App\Models\ChannelManagerPropertyMapping", 'property_id', 'property_id')->select(['id', 'property_id', 'channel_manager_id', 'channel_manager_property_id']); + } + +} diff --git a/app/Models/PropertyRoomSizeType.php b/app/Models/PropertyRoomSizeType.php new file mode 100644 index 0000000..b0d5935 --- /dev/null +++ b/app/Models/PropertyRoomSizeType.php @@ -0,0 +1,18 @@ +hasOne('App\Models\PropertyRoomViewType','id', 'room_view_type_id')->select(['id', 'name', 'language_key']); + } +} diff --git a/app/Models/PropertyRoomViewType.php b/app/Models/PropertyRoomViewType.php new file mode 100644 index 0000000..c7c7c41 --- /dev/null +++ b/app/Models/PropertyRoomViewType.php @@ -0,0 +1,32 @@ +is_ssl_active) { + $webProtocol = 'https://'; + } + return $webProtocol . $this->domain; + } + + public function propertyWebTemplate() + { + return $this->hasOne('App\Models\PropertyWebTemplate', 'id', 'template_id')->select("id", "name", "folder_name", "status"); + } + + public function propertyWebLanguage() + { + return $this->hasOne('App\Models\Language', 'code', 'default_language')->select("code", "name", "language_key"); + } + + public function propertyBookingEngine() + { + return $this->hasOne('App\Models\PropertyBookingEngine', 'property_id', 'property_id') + ->where('status', '=', 1) + ->select("id", "property_id", "channel_id", "token"); + } + + public function propertyWebMenuMenuMapping() + { + return $this->hasMany('App\Models\PropertyWebMenuMapping', 'property_id', 'property_id') + ->select("id", "property_id", "property_web_id", "property_web_menu_id", "order_number", "status", "type", "menu_code") + ->orderBy("order_number", "ASC"); + } + + public function propertyWebLanguageMapping() + { + return $this->hasMany('App\Models\PropertyWebLanguageMapping', 'property_id', 'property_id') + ->select("id", "property_id", "property_web_id", "language_code", "status"); + } + + public function propertyGroupMapping() + { + return $this->hasMany('App\Models\PropertyGroupMapping', 'property_id', 'property_id') + ->select("id", "property_id", "property_group_id", "order_number", "status") + ->where('status', 1); + } + + public function propertyWebPhotoMapping() + { + return $this->hasMany('App\Models\PropertyWebPhotoMapping', 'property_web_id', 'id') + ->where('status', '=', 1); + } + + public function property() + { + return $this->hasOne('App\Models\Property', 'id', 'property_id') + ->select('id', 'country', 'name', 'property_type_id', 'chain_id', 'official_name', + 'tax_office', 'tax_number', 'currency_type', 'country', 'content_code', 'status'); + } + + public function propertyWebAbout() + { + return $this->hasMany('App\Models\PropertyWebAboutUs', 'property_id', 'property_id')->select('id', 'property_id', 'language_code', 'value'); + } + + public function propertyWebPopup() + { + return $this->hasMany('App\Models\PropertyWebPopup', 'property_id', 'property_id') + ->select('id', 'property_id', 'language_code', 'code', 'title', 'start_date', 'url', 'end_date', 'image')->where('status', 1); + } + + public function propertyWebWeather() + { + return $this->hasOne('App\Models\PropertyWebWeather', 'property_id', 'property_id')->select('id', 'property_id', 'date', 'location', 'temp', 'conditions', 'icon'); + } + + + public function propertyWebComponent() + { + return $this->hasMany('App\Models\PropertyWebComponentMapping', 'property_id', 'property_id') + ->select('id', 'property_id', 'channel_id', 'component_id', 'parameter', 'language', 'status')->where('status', 1); + } + + public function propertyWebRoomMapping() + { + return $this->hasMany('App\Models\PropertyWebRoomMapping', 'property_web_id', 'id') + ->select("id", "property_id", "property_web_id", "property_room_id", "status") + ->where('status', 1); + } + + public function propertyWebPlaceMapping() + { + return $this->hasMany('App\Models\PropertyWebPlaceMapping', 'property_web_id', 'id') + ->select("id", "property_id", "property_web_id", "property_place_id", "status") + ->where('status', 1); + } + + public function propertyWebColorMapping() + { + return $this->hasMany('App\Models\PropertyWebColorMapping', 'property_web_id', 'id') + ->select('id', 'property_id', 'property_web_id', 'color_code', 'order_number') + ->where('status', 1) + ->orderBy('order_number'); + } + + public function propertyWebContent() + { + return $this->hasMany('App\Models\PropertyWebContent', 'property_id', 'property_id') + ->select('id', 'property_id', 'content_category_id', 'title', 'slug', 'language_code', 'content', 'image', 'status')->where('status', 1); + } + + public function propertyWebContentSummary() + { + return $this->hasMany('App\Models\PropertyWebContent', 'property_id', 'property_id') + ->select('id', 'property_id', 'content_category_id', 'title', 'slug', 'language_code', 'image', 'status')->where('status', 1); + } + + public function propertyWebMetaMapping() + { + return $this->hasMany('App\Models\PropertyWebMetaMapping', 'property_web_id', 'id') + ->where('status', 1); + } + +} diff --git a/app/Models/PropertyWebAboutUs.php b/app/Models/PropertyWebAboutUs.php new file mode 100644 index 0000000..68bad5e --- /dev/null +++ b/app/Models/PropertyWebAboutUs.php @@ -0,0 +1,24 @@ +parameter)) { + $attribute = json_decode($this->parameter, 1); + } + return $attribute; + } + + public function getIconUrlAttribute() + { + return config('app.url') . '/img/component-icons/' . $this->icon; + + } +} diff --git a/app/Models/PropertyWebComponentMapping.php b/app/Models/PropertyWebComponentMapping.php new file mode 100644 index 0000000..adafdaf --- /dev/null +++ b/app/Models/PropertyWebComponentMapping.php @@ -0,0 +1,45 @@ +parameter)) { + $attribute = json_decode($this->parameter, 1); + } + return $attribute; + } + + function getLanguageArrayAttribute() + { + $attribute = []; + if (!empty($this->language)) { + $attribute = json_decode($this->language, 1); + } + return $attribute; + } + + public function webComponent() + { + return $this->hasOne('App\Models\PropertyWebComponent', 'id', 'component_id')->select(['id', 'component', 'name','parameter','icon']); + } + +} diff --git a/app/Models/PropertyWebContent.php b/app/Models/PropertyWebContent.php new file mode 100644 index 0000000..89fe55d --- /dev/null +++ b/app/Models/PropertyWebContent.php @@ -0,0 +1,60 @@ +image; + + if (!empty($image)) { + $imageExplode = explode('.', $image, 2); + + $imageFileName = $imageExplode[0]; + $imageFileExtensionName = $imageExplode[1]; + + $imageUrl = [ + 'default' => Config::get('app.imageUrl') . '/property-web-content/' . $this->property_id . '/' . $imageFileName . '.' . $imageFileExtensionName, + 'thumb' => Config::get('app.imageUrl') . '/property-web-content/' . $this->property_id . '/' . $imageFileName . '_thumbnail.' . $imageFileExtensionName, + 'fixed' => Config::get('app.imageUrl') . '/property-web-content/' . $this->property_id . '/' . $imageFileName . '_medium.' . $imageFileExtensionName, + ]; + + } + + return $imageUrl; + } + + public function ContentCategory() + { + return $this->hasOne('App\Models\PropertyWebContentCategory', 'id', 'content_category_id')->select('id', 'name', 'language_key'); + } + + +} diff --git a/app/Models/PropertyWebContentCategory.php b/app/Models/PropertyWebContentCategory.php new file mode 100644 index 0000000..1fa1c57 --- /dev/null +++ b/app/Models/PropertyWebContentCategory.php @@ -0,0 +1,29 @@ +logo)) { + $logoUrl = Config::get('app.url') . '/property-group/' . $this->logo; + } + + return $logoUrl; + } + + public function propertyWebLanguage() + { + return $this->hasOne('App\Models\Language', 'code', 'default_language')->select("code", "name", "language_key"); + } + + public function propertyGroupMapping() + { + return $this->hasMany('App\Models\PropertyGroupMapping', 'property_group_id', 'property_group_id') + ->select("id", "property_id", "property_group_id", "order_number", "status") + ->where('status', 1); + } + +} diff --git a/app/Models/PropertyWebLanguageMapping.php b/app/Models/PropertyWebLanguageMapping.php new file mode 100644 index 0000000..3bd8054 --- /dev/null +++ b/app/Models/PropertyWebLanguageMapping.php @@ -0,0 +1,20 @@ +hasOne('App\Models\IpNationCountries','code', 'country_code')->select("code", "country"); + } + +} diff --git a/app/Models/PropertyWebMenu.php b/app/Models/PropertyWebMenu.php new file mode 100644 index 0000000..9c43b90 --- /dev/null +++ b/app/Models/PropertyWebMenu.php @@ -0,0 +1,20 @@ +hasOne('App\Models\PropertyWebMenu','id', 'property_web_menu_id') + ->select("id", "parent_id", "name", "language_key", "alias", "route", "type", "order_number", "icon", "status"); + } +} diff --git a/app/Models/PropertyWebMeta.php b/app/Models/PropertyWebMeta.php new file mode 100644 index 0000000..b54ae8e --- /dev/null +++ b/app/Models/PropertyWebMeta.php @@ -0,0 +1,26 @@ +hasOne('App\Models\Property', 'id', 'property_id'); + } + + public function propertyWeb() + { + return $this->hasOne('App\Models\PropertyWeb', 'id', 'property_web_id'); + } + + public function propertyWebMetaTag() + { + return $this->hasOne('App\Models\PropertyWebMetaTag', 'id', 'property_web_meta_tag_id'); + } + + public function propertyWebMeta() + { + return $this->hasOne('App\Models\PropertyWebMeta', 'id', 'property_web_meta_id'); + } + + public function getTextArrayAttribute() + { + return json_decode($this->text, true); + } +} diff --git a/app/Models/PropertyWebMetaTag.php b/app/Models/PropertyWebMetaTag.php new file mode 100644 index 0000000..f60af5e --- /dev/null +++ b/app/Models/PropertyWebMetaTag.php @@ -0,0 +1,26 @@ +hasOne('App\Models\PropertyPhoto','id', 'property_photo_id'); + } + + +} diff --git a/app/Models/PropertyWebPlaceMapping.php b/app/Models/PropertyWebPlaceMapping.php new file mode 100644 index 0000000..bf30245 --- /dev/null +++ b/app/Models/PropertyWebPlaceMapping.php @@ -0,0 +1,24 @@ +hasOne('App\Models\PropertyPlace','id', 'property_place_id')->select(); + } +} diff --git a/app/Models/PropertyWebPopup.php b/app/Models/PropertyWebPopup.php new file mode 100644 index 0000000..9b579be --- /dev/null +++ b/app/Models/PropertyWebPopup.php @@ -0,0 +1,55 @@ +image; + + if (!empty($image)) { + $imageExplode = explode('.', $image, 2); + + $imageFileName = $imageExplode[0]; + $imageFileExtensionName = $imageExplode[1]; + + $imageUrl = [ + 'default' => Config::get('app.imageUrl') . '/property-web-popup/' . $this->property_id . '/' . $imageFileName . '.' . $imageFileExtensionName, + 'thumb' => Config::get('app.imageUrl') . '/property-web-popup/' . $this->property_id . '/' . $imageFileName . '_thumbnail.' . $imageFileExtensionName, + 'fixed' => Config::get('app.imageUrl') . '/property-web-popup/' . $this->property_id . '/' . $imageFileName . '_medium.' . $imageFileExtensionName, + ]; + + } + + return $imageUrl; + } + + +} diff --git a/app/Models/PropertyWebReview.php b/app/Models/PropertyWebReview.php new file mode 100644 index 0000000..096de20 --- /dev/null +++ b/app/Models/PropertyWebReview.php @@ -0,0 +1,39 @@ +time)->format('d.m.Y H:i:s'); + } + +} diff --git a/app/Models/PropertyWebRoomMapping.php b/app/Models/PropertyWebRoomMapping.php new file mode 100644 index 0000000..314114a --- /dev/null +++ b/app/Models/PropertyWebRoomMapping.php @@ -0,0 +1,24 @@ +hasOne('App\Models\PropertyRoom','id', 'property_room_id')->select(); + } +} diff --git a/app/Models/PropertyWebSetup.php b/app/Models/PropertyWebSetup.php new file mode 100644 index 0000000..03d6f33 --- /dev/null +++ b/app/Models/PropertyWebSetup.php @@ -0,0 +1,19 @@ + config('app.url') . '/img/weather-icons/' . $this->icon . '.png', + 'monochrome' => config('app.url') . '/img/weather-icons-monochrome/' . $this->icon . '.png' + ]; + + return $iconSet; + + } + + public function getLanguageKeyAttribute() + { + + return 'property_web_weather-'.$this->icon; + + } + +} diff --git a/app/Models/ServiceLog.php b/app/Models/ServiceLog.php new file mode 100644 index 0000000..62cf6ad --- /dev/null +++ b/app/Models/ServiceLog.php @@ -0,0 +1,28 @@ +name . ' ' . $this->surname; + } + +} diff --git a/app/Models/UserPropertyMapping.php b/app/Models/UserPropertyMapping.php new file mode 100644 index 0000000..fd98bd9 --- /dev/null +++ b/app/Models/UserPropertyMapping.php @@ -0,0 +1,40 @@ +hasOne("App\Models\Property", 'id', 'property_id'); + } + + public function user() + { + return $this->hasOne("App\Models\User", 'id', 'user_id') + ->where('status', '=', 1); + } + +} diff --git a/app/Models/VWDestination.php b/app/Models/VWDestination.php new file mode 100644 index 0000000..b1be2a0 --- /dev/null +++ b/app/Models/VWDestination.php @@ -0,0 +1,29 @@ +hasOne('App\Models\BookingStatus', 'id', 'status') + ->select(['name', 'language_key', 'id'])->where('status', 1); + } + +} diff --git a/app/Notifications/DirectPushNotificationUser.php b/app/Notifications/DirectPushNotificationUser.php new file mode 100644 index 0000000..3a95c90 --- /dev/null +++ b/app/Notifications/DirectPushNotificationUser.php @@ -0,0 +1,80 @@ +param = $param; + } + + public function via($notifyRoutes) + { + return [OneSignalChannel::class]; + } + + public function toOneSignal($notifyRoutes) + { + + /*$param = [ + 'subject' => 'Otel Bilgileri Güncelleme', + 'message' => $params['property_info']['name']. ' Otel Bilgileri Güncellendi.', + 'oneSignalPlayerIds' => ['5931bd16-daac-43f4-824c-c953b8902e96'] + + ]; + Notification::route('OneSignal', null)->notify(new DirectPushNotificationUser($param));*/ + + $oneSignalService = App::make("App\Core\Service\OneSignalService"); + + $restUrl = 'https://onesignal.com/api/v1/notifications'; + + if (!empty($this->param['oneSignalPlayerIds'])) { + + $payloadJson = [ + 'include_player_ids' => $this->param['oneSignalPlayerIds'], + 'headings' => [ + 'en' => $this->param['subject'] + ], + 'contents' => [ + 'en' => $this->param['message'] + ] + ]; + + if (isset($this->param['subtitle'])) { + $payloadJson['subtitle'] = [ + 'en' => $this->param['subtitle'] + ]; + } + + if (isset($this->param['url'])) { + //$payloadJson['url'] = $this->param['url']; + $payloadJson['data']['url'] = $this->param['url']; + } + + + $sendOneSignalPushNotification = $oneSignalService->sendOneSignalPushNotification($restUrl, $payloadJson); + + } + + } +} + + diff --git a/app/Notifications/NewUserNotification.php b/app/Notifications/NewUserNotification.php new file mode 100644 index 0000000..c524721 --- /dev/null +++ b/app/Notifications/NewUserNotification.php @@ -0,0 +1,50 @@ +notificationParam = $notificationParam; + + } + + public function via($notificationReceiver) + { + return ['mail']; + } + + public function toMail($notificationReceiver) + { + + $notificationParam = $this->notificationParam; + + $MailMessage = (new MailMessage) + ->subject('Extranetwork New User') + ->from(config('mail.from.address'), config('mail.from.name')) + ->greeting('Extranetwork App New User') + ->line(new HtmlString('
Name Surname: '.$notificationParam['name'].' '.$notificationParam['surname'])) + ->line(new HtmlString('Property Name: '.$notificationParam['property_name'])) + ->line(new HtmlString('E-Mail: '.$notificationParam['email'])) + ->line(new HtmlString('Phone: '.$notificationParam['phone'])) + ->line(new HtmlString('Language: '.$notificationParam['language'])) + ->line(new HtmlString('Time: '. Carbon::now()->format('d.m.Y H:i:s'))); + + //echo $MailMessage->render(); die(); + + return $MailMessage; + } + + +} diff --git a/app/Notifications/PushNotificationPropertyUser.php b/app/Notifications/PushNotificationPropertyUser.php new file mode 100644 index 0000000..7df6b16 --- /dev/null +++ b/app/Notifications/PushNotificationPropertyUser.php @@ -0,0 +1,91 @@ +param = $param; + } + + public function via($notifyRoutes) + { + return [OneSignalChannel::class]; + } + + public function toOneSignal($notifyRoutes) + { + + $oneSignalService = App::make("App\Core\Service\OneSignalService"); + $userPropertyMappingService = App::make("App\Core\Service\UserPropertyMappingService"); + + $restUrl = 'https://onesignal.com/api/v1/notifications'; + + if (isset($this->param['property_id']) && !empty($this->param['property_id'])) { + + $propertyUserListRequest = [ + 'criteria' => [ + ['field' => 'status', 'condition' => '=', 'value' => 1], + ['field' => 'property_id', 'condition' => '=', 'value' => $this->param['property_id']], + ], + 'with' => ['user'] + ]; + $propertyUserList = $userPropertyMappingService->select($propertyUserListRequest); + + if ($propertyUserList['status'] == 'success') { + $propertyUserListCollection = collect($propertyUserList['data']); + $oneSignalPlayerIds = $propertyUserListCollection->where('user.onesignal_key', '!=', null)->pluck('user.onesignal_key')->toArray(); + + if (!empty($oneSignalPlayerIds)) { + + $payloadJson = [ + 'include_player_ids' => $oneSignalPlayerIds, + 'headings' => [ + 'en' => $this->param['subject'] + ], + 'contents' => [ + 'en' => $this->param['message'] + ] + ]; + + if (isset($this->param['subtitle'])) { + $payloadJson['subtitle'] = [ + 'en' => $this->param['subtitle'] + ]; + } + + if (isset($this->param['url'])) { + //$payloadJson['url'] = $this->param['url']; + $payloadJson['data']['url'] = $this->param['url']; + } + + $sendOneSignalPushNotification = $oneSignalService->sendOneSignalPushNotification($restUrl, $payloadJson); + + } + + + } + + + } + + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..bdce120 --- /dev/null +++ b/app/Providers/AppServiceProvider.php @@ -0,0 +1,20 @@ +app['auth']->viaRequest('api', function ($request) { + if ($request->input('api_token')) { + return Users::where('api_token', $request->input('api_token'))->first(); + } + }); + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php new file mode 100644 index 0000000..95b029b --- /dev/null +++ b/app/Providers/EventServiceProvider.php @@ -0,0 +1,19 @@ + [ + 'App\Listeners\ExampleListener', + ], + ]; +} diff --git a/artisan b/artisan new file mode 100644 index 0000000..35c9141 --- /dev/null +++ b/artisan @@ -0,0 +1,35 @@ +#!/usr/bin/env php +make( + 'Illuminate\Contracts\Console\Kernel' +); + +exit($kernel->handle(new ArgvInput, new ConsoleOutput)); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..5b1720f --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,133 @@ +bootstrap(); + +/* +|-------------------------------------------------------------------------- +| Create The Application +|-------------------------------------------------------------------------- +| +| Here we will load the environment and create the application instance +| that serves as the central piece of this framework. We'll use this +| application as an "IoC" container and router for this framework. +| +*/ + +$app = new Laravel\Lumen\Application( + dirname(__DIR__) +); + +//$app->withFacades(false); +$app->withFacades(true, [ + 'Illuminate\Support\Facades\Event' => 'LumenEvent', +]); + +$app->configure('app'); +$app->configure('mail'); +$app->configure('languageSupport'); +$app->configure('language-pack-en'); +$app->configure('language-pack-tr'); +$app->configure('language-pack-de'); +$app->make('queue'); + + +$app->withEloquent(); + +/* +|-------------------------------------------------------------------------- +| Register Container Bindings +|-------------------------------------------------------------------------- +| +| Now we will register a few bindings in the service container. We will +| register the exception handler and the console kernel. You may add +| your own bindings here if you like or you can make another file. +| +*/ + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +/* +|-------------------------------------------------------------------------- +| Register Middleware +|-------------------------------------------------------------------------- +| +| Next, we will register the middleware with the application. These can +| be global middleware that run before and after each request into a +| route or middleware that'll be assigned to some specific routes. +| +*/ + +$app->middleware([ + 'cors' => App\Http\Middleware\CorsMiddleware::class, +]); + +$app->routeMiddleware([ + 'jwt.auth' => App\Http\Middleware\JwtMiddleware::class, + 'cors' => App\Http\Middleware\CorsMiddleware::class, + 'userRoutePermissionAuthorize' => App\Http\Middleware\UserRoutePermissionAuthorize::class, + 'property' => App\Http\Middleware\PropertyMiddleware::class, + 'contentWizard' => App\Http\Middleware\ContentWizardMiddleware::class, + 'checkPropertyChannelConnection' => App\Http\Middleware\CheckPropertyChannelConnectionMiddleware::class, + 'LanguageSetting' => App\Http\Middleware\LanguageSettingMiddleware::class, + 'myWebToken' => App\Http\Middleware\MyWebTokenMiddleware::class, + 'bookingEngineToken' => App\Http\Middleware\BookingEngineTokenMiddleware::class, + +]); + +/* +|-------------------------------------------------------------------------- +| Register Service Providers +|-------------------------------------------------------------------------- +| +| Here we will register all of the application's service providers which +| are used to bind services into the container. Service providers are +| totally optional, so you are not required to uncomment this line. +| +*/ + +// $app->register(App\Providers\AppServiceProvider::class); +// $app->register(App\Providers\AuthServiceProvider::class); +// $app->register(App\Providers\EventServiceProvider::class); + +/* +|-------------------------------------------------------------------------- +| Load The Application Routes +|-------------------------------------------------------------------------- +| +| Next we will include the routes file so that they can all be added to +| the application. This will provide all of the URLs the application +| can respond to, as well as the controllers that may handle them. +| +*/ + +$app->register(Illuminate\Redis\RedisServiceProvider::class); +$app->register(Intervention\Image\ImageServiceProviderLumen::class); +$app->register(Illuminate\Mail\MailServiceProvider::class); +$app->register(Illuminate\Notifications\NotificationServiceProvider::class); +$app->register(Maatwebsite\Excel\ExcelServiceProvider::class); + + +$app->alias('mailer', Illuminate\Mail\Mailer::class); +$app->alias('mailer', Illuminate\Contracts\Mail\Mailer::class); +$app->alias('mailer', Illuminate\Contracts\Mail\MailQueue::class); +$app->alias('Excel', Maatwebsite\Excel\Facades\Excel::class); + +$app->router->group([ + 'namespace' => 'App\Http\Controllers', +], function ($router) { + require __DIR__ . '/../routes/web.php'; +}); + +return $app; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..2046570 --- /dev/null +++ b/composer.json @@ -0,0 +1,60 @@ +{ + "name": "laravel/lumen", + "description": "The Laravel Lumen Framework.", + "keywords": ["framework", "laravel", "lumen"], + "license": "MIT", + "type": "project", + "require": { + "php": ">=7.1.3", + "barryvdh/laravel-dompdf": "^0.8.7", + "firebase/php-jwt": "^5.0", + "google/cloud-vision": "^0.24.0", + "illuminate/mail": "5.8.*", + "illuminate/notifications": "^5.5", + "illuminate/redis": "5.8.*", + "intervention/image": "^2.5", + "laravel/lumen-framework": "5.8.*", + "league/flysystem": "^1.0", + "maatwebsite/excel": "^3.1", + "predis/predis": "^1.1", + "ramsey/uuid": "^4.1", + "stripe/stripe-php": "^7.66", + "symfony/serializer": "^5.2", + "symfony/translation": "4.4.1" + }, + "require-dev": { + "fzaninotto/faker": "^1.4", + "phpunit/phpunit": "^7.0", + "mockery/mockery": "^1.0" + }, + "autoload": { + "classmap": [ + "database/seeds", + "database/factories" + ], + "psr-4": { + "App\\": "app/" + }, + "files": [ + "app/Core/Helper/helpers.php", + "app/Core/Helper/compat_l5.php" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/" + ] + }, + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ] + }, + "config": { + "preferred-install": "dist", + "sort-packages": true, + "optimize-autoloader": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..a6d3ff6 --- /dev/null +++ b/config/app.php @@ -0,0 +1,53 @@ + '1.5.22', + 'name' => env('APP_NAME', 'ExtraNetWork'), + 'env' => env('APP_ENV', 'production'), + 'client_server' => env('CLIENT_SERVER', 'https://app.extranetwork.com'), + 'debug' => env('APP_DEBUG', false), + 'url' => env('APP_URL', 'https://api.extranetwork.com'), + 'webUrl' => env('WEB_URL', 'https://www.extranetwork.com'), + 'timezone' => env('APP_TIMEZONE', 'Europe/Istanbul'), + 'locale' => env('APP_LOCALE', 'en'), + 'fallback_locale' => 'en', + 'jwt' => [ + 'secret' => env('JWT_SECRET', 'JhbGciOiJIUzI1N0eXAiOiJKV1QiLC'), + ], + 'fileSystemDriver' => env('FILESYSTEM_DRIVER', '/Users/bulutkuru/Desktop/uploads/'), + 'imageUrl' => env('IMAGE_URL', 'http://cdn.extranetwork.com.test'), + 'googleApplicationCredentials' => env('GOOGLE_APPLICATION_CREDENTIALS', ''), + 'log_slack' => env('LOG_SLACK_WEBHOOK_URL', 'https://hooks.slack.com/services/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'), + 'appLanguageJsonStoredFolder' => env('APP_LANGUAGE_JSON_STORED_FOLDER', '/home/project/app.extranetwork.com/build_public'), // for application language filepath + 'myWebLanguageJsonStoredFolder' => env('MYWEB_LANGUAGE_JSON_STORED_FOLDER', '/home/project/myweb.extranetwork.com/resources/lang/'), // for myweb language filepath + 'wwwLanguageJsonStoredFolder' => env('WWW_LANGUAGE_JSON_STORED_FOLDER', '/home/project/www.extranetwork.com/resources/lang/'), // for www language filepath + 'bookingEngineLanguageJsonStoredFolder' => env('BOOKING_ENGINE_LANGUAGE_JSON_STORED_FOLDER', '/home/project/be.extranetwork.com/resources/lang/'), // for booking.engine language filepath + 'mainHostAddress' => env('MAIN_HOST_ADDRESS', 'https://myweb.extranetwork.com'), // main host address + 'getMyWebCNAME' => 'myweb.extranetwork.com', // MyWeb CNAME Hosting Alias + "myIP" => "88.247.112.165", + "bookingEngineUrl" => env('BOOKING_ENGINE_URL', 'https://be.extranetwork.com'), + "zipFilesUrl" => env('ZIP_FILES_URL', 'https://api.extranetwork.com/property-zip-files/'), + "propertyFilesUrl" => env('PROPERTY_FILES_URL', 'https://cdn.extranetwork.com/property-files/'), + "mailSenderAddress" => 'noreply@extranetwork.com', + "logMailAddress" => 'burhan@extranetwork.com', + "paymentFormLink" => env('PAYMENT_FORM_LINK', 'https://be.extranetwork.com/link/'), + "enwContactFormMailTo" => env('ENW_CONTACT_FORM_MAILTO', 'info@extranetwork.com'), + 'channelManager' => [ + 'reseliva' => [ + 'userId' => 'apiuser@extranetwork.com', + 'userPassword' => 'ExtrntWrk21*!' + ] + ], + 'stripeENWKey' => env('STRIPE_ENWKEY', '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'), + 'key' => 'mWx0BnBvK5rp95PXjIiLHxc29nxSkG0X', //z8IQfoLXSrIPk7gwnh3EbOos8wkzHIzY, vPdC6dXrK8LWbLxrYNxDXUGcggGg58ff + 'cipher' => 'AES-256-CBC', + 'taxOptions' => [ + 'TR' => [ + 'title' => 'Accommodation Tax', + 'language_key' => 'api-tax-accommodation_tax', + 'rate' => '%2', + ] + ], + 'openAISecretKey' => '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' +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..6291f86 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,101 @@ + env('CACHE_DRIVER', 'redis'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'cache', + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', 'extranetworkApiCache'), + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..8de402c --- /dev/null +++ b/config/database.php @@ -0,0 +1,135 @@ + env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => env('DB_PREFIX', ''), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', 'mysql-master'), + 'port' => env('DB_PORT', 3306), + 'database' => env('DB_DATABASE', 'extranetwork'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', 'QgARrezer_1'), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => env('DB_PREFIX', ''), + 'strict' => env('DB_STRICT_MODE', true), + 'engine' => env('DB_ENGINE', null), + //'timezone' => env('DB_TIMEZONE', '+00:00'), + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', 5432), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => env('DB_PREFIX', ''), + 'schema' => env('DB_SCHEMA', 'public'), + 'sslmode' => env('DB_SSL_MODE', 'prefer'), + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', 1433), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => env('DB_PREFIX', ''), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer set of commands than a typical key-value systems + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'predis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'predis'), + 'prefix' => env('REDIS_PREFIX', 'api:'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', 'redis'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_DB', 0), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', 'redis'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_DB', 0), + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..02880c1 --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,69 @@ + env('FILESYSTEM_DRIVER', 'local'), + + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ + + 'cloud' => env('FILESYSTEM_CLOUD', 's3'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + 'public' => [ + 'driver' => 'local', + 'root' => public_path(), + 'url' => config('app.url'), + 'visibility' => 'public', + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + ], + + ], + +]; diff --git a/config/language-pack-de.php b/config/language-pack-de.php new file mode 100644 index 0000000..9545803 --- /dev/null +++ b/config/language-pack-de.php @@ -0,0 +1,90 @@ +"en", + "availableLanguages" => ["tr", "en", "de" ] + ]; \ No newline at end of file diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..4e47388 --- /dev/null +++ b/config/mail.php @@ -0,0 +1,125 @@ + env('MAIL_DRIVER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Address + |-------------------------------------------------------------------------- + | + | Here you may provide the host address of the SMTP server used by your + | applications. A default option is provided that is compatible with + | the Mailgun mail service which will provide reliable deliveries. + | + */ + + 'host' => env('MAIL_HOST', 'smtp.gmail.com'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Port + |-------------------------------------------------------------------------- + | + | This is the SMTP port used by your application to deliver e-mails to + | users of the application. Like the host we have set this value to + | stay compatible with the Mailgun e-mail application by default. + | + */ + + 'port' => env('MAIL_PORT', 587), + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => ['address' => 'noreply@extranetwork.com', 'name' => 'ExtraNetWork'], + + /* + |-------------------------------------------------------------------------- + | E-Mail Encryption Protocol + |-------------------------------------------------------------------------- + | + | Here you may specify the encryption protocol that should be used when + | the application send e-mail messages. A sensible default using the + | transport layer security protocol should provide great security. + | + */ + + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Username + |-------------------------------------------------------------------------- + | + | If your SMTP server requires a username for authentication, you should + | set it here. This will get used to authenticate with your server on + | connection. You may also set the "password" value below this one. + | + */ + + 'username' => env('MAIL_USERNAME','noreply@extranetwork.com'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Password + |-------------------------------------------------------------------------- + | + | Here you may set the password required by your SMTP server to send out + | messages from your application. This will be given to the server on + | connection so that the application will be able to send messages. + | + */ + + 'password' => env('MAIL_PASSWORD','jodgrovwibymcetb'), + //8KSLQzxuGg4vEfSFkaA4m + + /* + |-------------------------------------------------------------------------- + | Sendmail System Path + |-------------------------------------------------------------------------- + | + | When using the "sendmail" driver to send e-mails, we will need to know + | the path to where Sendmail lives on this server. A default path has + | been provided here, which will work well on most of your systems. + | + */ + + 'sendmail' => '/usr/sbin/sendmail -bs', + + /* + |-------------------------------------------------------------------------- + | Mail "Pretend" + |-------------------------------------------------------------------------- + | + | When this option is enabled, e-mail will not actually be sent over the + | web and will instead be written to your application's logs files so + | you may inspect the message. This is great for local development. + | + */ + + 'pretend' => false, + +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..f9bc39c --- /dev/null +++ b/config/queue.php @@ -0,0 +1,86 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Lumen. You are free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => env('QUEUE_TABLE', 'jobs'), + 'queue' => 'default', + 'retry_after' => 90, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'retry_after' => 90, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('SQS_KEY', 'your-public-key'), + 'secret' => env('SQS_SECRET', 'your-secret-key'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'your-queue-name'), + 'region' => env('SQS_REGION', 'us-east-1'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('QUEUE_REDIS_CONNECTION', 'default'), + 'queue' => 'default', + 'retry_after' => 90, + 'block_for' => null, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => env('QUEUE_FAILED_TABLE', 'failed_jobs'), + ], + +]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php new file mode 100644 index 0000000..61cd36b --- /dev/null +++ b/database/factories/ModelFactory.php @@ -0,0 +1,21 @@ +define(App\Models\Users::class, function (Faker\Generator $faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->unique()->email, + 'password' => Hash::make('12345'), + ]; +}); diff --git a/database/migrations/.gitkeep b/database/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/database/migrations/2019_09_17_103201_create_user_table.php b/database/migrations/2019_09_17_103201_create_user_table.php new file mode 100644 index 0000000..a150d82 --- /dev/null +++ b/database/migrations/2019_09_17_103201_create_user_table.php @@ -0,0 +1,51 @@ +increments('id'); + $table->string('gender',1); + $table->string('name', 255); + $table->string('surname',255); + $table->char('email',128); + $table->string('password',255); + $table->string('phone',100)->nullable(); + $table->integer('user_type')->default(1); + $table->string('locale',2)->default('en'); + $table->tinyInteger('status')->default(0)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('user', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique('email'); + }); + } + + + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user'); + } +} diff --git a/database/migrations/2019_09_17_103202_create_language_table.php b/database/migrations/2019_09_17_103202_create_language_table.php new file mode 100644 index 0000000..4b4a93c --- /dev/null +++ b/database/migrations/2019_09_17_103202_create_language_table.php @@ -0,0 +1,68 @@ +increments('id'); + $table->string('code', 2); + $table->string('name', 45); + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('language', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique('code'); + }); + + + Schema::create('language_locale', function (Blueprint $table) { + $table->increments('id'); + $table->string('language_code',2); + $table->string('name', 45); + $table->string('locale',2); + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + }); + + Schema::table('language_locale', function (Blueprint $table) { + $table->foreign('language_code')->references('code')->on('language'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['language_code','locale']); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('language_locale'); + Schema::dropIfExists('language'); + } +} diff --git a/database/migrations/2019_09_17_103203_create_property_chain_table.php b/database/migrations/2019_09_17_103203_create_property_chain_table.php new file mode 100644 index 0000000..ebeb8b1 --- /dev/null +++ b/database/migrations/2019_09_17_103203_create_property_chain_table.php @@ -0,0 +1,42 @@ +increments('id'); + $table->string('name',100); + $table->string('loyalty',30)->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_chain',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_chain'); + } +} diff --git a/database/migrations/2019_09_17_103204_create_currency_table.php b/database/migrations/2019_09_17_103204_create_currency_table.php new file mode 100644 index 0000000..4477df6 --- /dev/null +++ b/database/migrations/2019_09_17_103204_create_currency_table.php @@ -0,0 +1,66 @@ +increments('id'); + $table->string('code', 3)->unique(); + $table->string('name', 45); + + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('currency', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('currency_locale', function (Blueprint $table) { + $table->increments('id'); + $table->string('currency_code', 3); + $table->string('name', 45); + $table->string('locale', 2); + + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + }); + Schema::table('currency_locale', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('currency_code')->references('code')->on('currency'); + $table->foreign('locale')->references('code')->on('language'); + $table->unique(['currency_code','locale']); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('currency_locale'); + Schema::dropIfExists('currency'); + } +} diff --git a/database/migrations/2019_09_17_103205_create_property_type_table.php b/database/migrations/2019_09_17_103205_create_property_type_table.php new file mode 100644 index 0000000..e4f27ed --- /dev/null +++ b/database/migrations/2019_09_17_103205_create_property_type_table.php @@ -0,0 +1,64 @@ +increments('id'); + $table->string('name',200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::create('property_type_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('type_id'); + $table->string('name',200); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + /** + * Table Relations + */ + Schema::table('property_type',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::table('property_type_locale',function (Blueprint $table) { + $table->foreign('type_id')->references('id')->on('property_type'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_type_locale'); + Schema::dropIfExists('property_type'); + } +} diff --git a/database/migrations/2019_09_17_103610_create_property_table.php b/database/migrations/2019_09_17_103610_create_property_table.php new file mode 100644 index 0000000..637e0c8 --- /dev/null +++ b/database/migrations/2019_09_17_103610_create_property_table.php @@ -0,0 +1,55 @@ +increments('id'); + $table->string('name',255); + $table->unsignedInteger('destination_id')->nullable(); + $table->unsignedInteger('property_type_id')->nullable(); + $table->unsignedInteger('chain_id')->nullable(); + $table->double('rating')->nullable(); + $table->string('official_name',255)->nullable(); + $table->string('tax_office',255)->nullable(); + $table->string('tax_number',255)->nullable(); + $table->string('currency_type', 3)->nullable(); + $table->string('checkin_time', 50)->nullable(); + $table->string('checkout_time', 50)->nullable(); + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property', function (Blueprint $table) { + + $table->foreign('property_type_id')->references('id')->on('property_type'); + $table->foreign('chain_id')->references('id')->on('property_chain'); + $table->foreign('currency_type')->references('code')->on('currency'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property'); + } +} diff --git a/database/migrations/2019_09_17_110258_create_temp_property_table.php b/database/migrations/2019_09_17_110258_create_temp_property_table.php new file mode 100644 index 0000000..cd67f15 --- /dev/null +++ b/database/migrations/2019_09_17_110258_create_temp_property_table.php @@ -0,0 +1,41 @@ +integerIncrements('id'); + $table->string('name',255); + $table->integer('destination_id'); + //TODO: Giata_id int mi olacak string mi olacak. + $table->string('giata_id',50); + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by')->nullable(); + $table->unsignedInteger('updated_by')->nullable(); + $table->integer('created_at')->nullable(); + $table->integer('updated_at')->nullable(); + }); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('temp_property'); + } +} diff --git a/database/migrations/2019_09_17_121431_create_user_property_mapping_table.php b/database/migrations/2019_09_17_121431_create_user_property_mapping_table.php new file mode 100644 index 0000000..02c0584 --- /dev/null +++ b/database/migrations/2019_09_17_121431_create_user_property_mapping_table.php @@ -0,0 +1,46 @@ +increments('id'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('property_id'); + $table->tinyInteger('status')->default(1)->index(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::table('user_property_mapping', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('user_id')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->unique(['user_id','property_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_property_mapping'); + } +} diff --git a/database/migrations/2019_09_25_112056_create_property_content_category_table.php b/database/migrations/2019_09_25_112056_create_property_content_category_table.php new file mode 100644 index 0000000..ce7e25e --- /dev/null +++ b/database/migrations/2019_09_25_112056_create_property_content_category_table.php @@ -0,0 +1,65 @@ +increments('id'); + $table->string('name'); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_content_category', function (Blueprint $table) { + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('property_content_category_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('content_category_id'); + $table->string('name'); + $table->string('locale',2); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_content_category_locale', function (Blueprint $table) { + + $table->foreign('content_category_id')->references('id')->on('property_content_category'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['content_category_id', 'locale'],'language_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_content_category_locale'); + + Schema::dropIfExists('property_content_category'); + } +} diff --git a/database/migrations/2019_09_26_123443_create_property_content_table.php b/database/migrations/2019_09_26_123443_create_property_content_table.php new file mode 100644 index 0000000..a5e490c --- /dev/null +++ b/database/migrations/2019_09_26_123443_create_property_content_table.php @@ -0,0 +1,52 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('content_category_id'); + $table->mediumText('content')->nullable(); + $table->string('locale',2); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_content', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('content_category_id')->references('id')->on('property_content_category'); + $table->foreign('locale')->references('code')->on('language'); + $table->unique(['property_id', 'content_category_id', 'locale'],'content_unique'); + }); + + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + Schema::dropIfExists('property_content'); + } +} diff --git a/database/migrations/2019_09_30_130301_create_property_fact_table.php b/database/migrations/2019_09_30_130301_create_property_fact_table.php new file mode 100644 index 0000000..32c9142 --- /dev/null +++ b/database/migrations/2019_09_30_130301_create_property_fact_table.php @@ -0,0 +1,68 @@ +increments('id'); + $table->string('name','250'); + $table->integer('parent_id',false,true)->nullable(); + $table->tinyInteger('type')->default(0); + $table->tinyInteger('order_number')->default(0); + $table->string('icon')->nullable(); + $table->tinyInteger('status',false,true)->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_fact_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('fact_id'); + $table->string('name'); + $table->string('locale',2); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + /** + * Table Relations + */ + Schema::table('property_fact',function (Blueprint $table) { + $table->foreign('parent_id')->references('id')->on('property_fact'); + }); + + Schema::table('property_fact_locale',function (Blueprint $table) { + $table->foreign('fact_id')->references('id')->on('property_fact'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['fact_id', 'locale'],'pfl_language_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_fact_locale'); + Schema::dropIfExists('property_fact'); + } +} diff --git a/database/migrations/2019_09_30_130303_create_property_unit_table.php b/database/migrations/2019_09_30_130303_create_property_unit_table.php new file mode 100644 index 0000000..1dee2d3 --- /dev/null +++ b/database/migrations/2019_09_30_130303_create_property_unit_table.php @@ -0,0 +1,60 @@ +increments('id'); + $table->string('name',100); + $table->string('short_name',45); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_unit_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('unit_id'); + $table->string('name'); + $table->string('locale',2); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + /** + * Table Relation + */ + Schema::table('property_unit_locale',function (Blueprint $table) { + $table->foreign('unit_id')->references('id')->on('property_unit'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['unit_id', 'locale'],'pul_language_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_unit_locale'); + Schema::dropIfExists('property_unit'); + } +} diff --git a/database/migrations/2019_09_30_130304_create_property_fact_attribute_table.php b/database/migrations/2019_09_30_130304_create_property_fact_attribute_table.php new file mode 100644 index 0000000..dfb1240 --- /dev/null +++ b/database/migrations/2019_09_30_130304_create_property_fact_attribute_table.php @@ -0,0 +1,69 @@ +increments('id'); + $table->string('name','250'); + $table->integer('unit_id',false,true)->default(0); + $table->tinyInteger('type')->default(0); + $table->tinyInteger('order_number')->default(0); + $table->tinyInteger('status',false,true)->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::create('property_fact_attribute_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('attribute_id'); + $table->string('name'); + $table->string('locale',2); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + /** + * Table Relations + */ + + Schema::table('property_fact_attribute',function (Blueprint $table) { + $table->foreign('unit_id')->references('id')->on('property_unit'); + }); + + Schema::table('property_fact_attribute_locale',function (Blueprint $table) { + $table->foreign('attribute_id')->references('id')->on('property_fact_attribute'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['attribute_id', 'locale'],'pfal_language_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_fact_attribute_locale'); + Schema::dropIfExists('property_fact_attribute'); + } +} diff --git a/database/migrations/2019_09_30_131650_create_property_fact_attribute_mapping_table.php b/database/migrations/2019_09_30_131650_create_property_fact_attribute_mapping_table.php new file mode 100644 index 0000000..e190fd9 --- /dev/null +++ b/database/migrations/2019_09_30_131650_create_property_fact_attribute_mapping_table.php @@ -0,0 +1,41 @@ +increments('id'); + $table->integer('fact_id')->unsigned(); + $table->integer('attribute_id')->unsigned(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_fact_attribute_mapping',function (Blueprint $table) { + $table->foreign('fact_id')->references('id')->on('property_fact'); + $table->foreign('attribute_id')->references('id')->on('property_fact_attribute'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_fact_attribute_mapping'); + } +} diff --git a/database/migrations/2019_09_30_132133_create_property_fact_mapping_table.php b/database/migrations/2019_09_30_132133_create_property_fact_mapping_table.php new file mode 100644 index 0000000..ea2c7ef --- /dev/null +++ b/database/migrations/2019_09_30_132133_create_property_fact_mapping_table.php @@ -0,0 +1,47 @@ +increments('id'); + $table->integer('property_id')->unsigned(); + $table->integer('fact_id')->unsigned(); + $table->integer('attribute_id')->unsigned()->nullable(); + $table->integer('unit_id')->unsigned()->nullable(); + $table->string('value',100)->nullable()->default(null); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_fact_mapping',function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('fact_id')->references('id')->on('property_fact'); + $table->foreign('attribute_id')->references('id')->on('property_fact_attribute'); + $table->foreign('unit_id')->references('id')->on('property_unit'); + $table->unique(['property_id', 'fact_id','attribute_id'],'pfam_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_fact_mapping'); + } +} diff --git a/database/migrations/2019_10_02_111700_create_property_contact_table.php b/database/migrations/2019_10_02_111700_create_property_contact_table.php new file mode 100644 index 0000000..8bbc966 --- /dev/null +++ b/database/migrations/2019_10_02_111700_create_property_contact_table.php @@ -0,0 +1,56 @@ +increments('id'); + $table->integer('property_id')->unsigned(); + $table->string('phone',50)->nullable(); + $table->string('phone_code',10)->nullable(); + $table->string('mobile',50)->nullable(); + $table->string('mobile_code',10)->nullable(); + $table->string('fax',50)->nullable(); + $table->string('fax_code',10)->nullable(); + $table->string('email',100)->nullable(); + $table->integer('destination_id')->unsigned(); + $table->string('web',100)->nullable(); + $table->string('zip_code',20)->nullable(); + $table->string('address',200)->nullable(); + $table->double('latitude',10,6)->nullable(); + $table->double('longitude',10,6)->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_contact',function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['property_id'],'pc_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_contact'); + } +} diff --git a/database/migrations/2019_10_02_120109_create_property_executive_type_table.php b/database/migrations/2019_10_02_120109_create_property_executive_type_table.php new file mode 100644 index 0000000..cbcb26c --- /dev/null +++ b/database/migrations/2019_10_02_120109_create_property_executive_type_table.php @@ -0,0 +1,64 @@ +increments('id'); + $table->string('name',200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_executive_type_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('executive_id'); + $table->string('name',200); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + /** + * Table Relations + */ + Schema::table('property_executive_type',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::table('property_executive_type_locale',function (Blueprint $table) { + $table->foreign('executive_id')->references('id')->on('property_executive_type'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_executive_type_locale'); + Schema::dropIfExists('property_executive_type'); + } +} diff --git a/database/migrations/2019_10_02_120724_create_property_executive_table.php b/database/migrations/2019_10_02_120724_create_property_executive_table.php new file mode 100644 index 0000000..bb338e7 --- /dev/null +++ b/database/migrations/2019_10_02_120724_create_property_executive_table.php @@ -0,0 +1,53 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('executive_type_id'); + $table->string('name_surname',200)->nullable(); + $table->string('email',100)->nullable(); + $table->string('phone_code',10)->nullable(); + $table->string('phone',50)->nullable(); + $table->string('mobile_code',10)->nullable(); + $table->string('mobile',50)->nullable(); + $table->string('fax_code',10)->nullable(); + $table->string('fax',50)->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_executive',function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('executive_type_id')->references('id')->on('property_executive_type'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['property_id', 'executive_type_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_executive'); + } +} diff --git a/database/migrations/2019_10_02_133201_create_property_additional_info_key_table.php b/database/migrations/2019_10_02_133201_create_property_additional_info_key_table.php new file mode 100644 index 0000000..1e56f40 --- /dev/null +++ b/database/migrations/2019_10_02_133201_create_property_additional_info_key_table.php @@ -0,0 +1,63 @@ +increments('id'); + $table->string('additional_info_key',100); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_additional_info_key_locale', function (Blueprint $table) { + + $table->increments('id'); + $table->unsignedInteger('additional_info_key_id'); + $table->string('additional_info_key',200); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_additional_info_key', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['additional_info_key'],'padilk_unique'); + }); + + Schema::table('property_additional_info_key_locale', function (Blueprint $table) { + $table->foreign('additional_info_key_id','paikl_additional_info_key_id_fk')->references('id')->on('property_additional_info_key'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['additional_info_key_id','locale'],'padilkl_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_additional_info_key_locale'); + Schema::dropIfExists('property_additional_info_key'); + } +} diff --git a/database/migrations/2019_10_02_134621_create_property_additional_info_table.php b/database/migrations/2019_10_02_134621_create_property_additional_info_table.php new file mode 100644 index 0000000..c352673 --- /dev/null +++ b/database/migrations/2019_10_02_134621_create_property_additional_info_table.php @@ -0,0 +1,46 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('additional_info_key_id'); + $table->string('value',100)->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_additional_info',function (Blueprint $table){ + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('additional_info_key_id')->references('id')->on('property_additional_info_key'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['property_id','additional_info_key_id' ],'pai_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_additional_info'); + } +} diff --git a/database/migrations/2019_10_07_141400_create_property_photo_table.php b/database/migrations/2019_10_07_141400_create_property_photo_table.php new file mode 100644 index 0000000..653c816 --- /dev/null +++ b/database/migrations/2019_10_07_141400_create_property_photo_table.php @@ -0,0 +1,135 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('property_photo_category_id')->nullable(); + $table->string('photo_path'); + $table->string('photo_name',200); + $table->double('photo_rank')->nullable(); + $table->string('file_size')->nullable(); + $table->string('file_ext')->nullable(); + $table->string('photo_resolution')->nullable(); + $table->integer('photo_order')->nullable(); + $table->tinyInteger('is_default')->default(0); + $table->tinyInteger('is_temp')->default(1); + $table->tinyInteger('status',false,true)->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_photo_category', function (Blueprint $table) { + $table->increments('id'); + $table->string('category_name',50)->unique(); + $table->tinyInteger('status',false,true)->default(0); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_photo_category_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('property_photo_category_id'); + $table->string('category_name'); + $table->string('locale',2); + $table->tinyInteger('status',false,true)->default(0); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('photo_google_label', function (Blueprint $table) { + $table->increments('id'); + $table->string('label', 50)->unique(); + $table->tinyInteger('status',false,true)->default(0); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::create('property_photo_category_label_mapping', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('property_photo_category_id'); + $table->unsignedInteger('photo_google_label_id'); + $table->tinyInteger('status',false,true)->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + /** + * Table Relations + */ + Schema::table('property_photo',function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('property_photo_category_id','pp_property_photo_category_id')->references('id')->on('property_photo_category'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + + /** + * Table Relations + */ + Schema::table('property_photo_category_label_mapping',function (Blueprint $table) { + $table->foreign('property_photo_category_id','ppclm_property_photo_category_id')->references('id')->on('property_photo_category'); + $table->foreign('photo_google_label_id','ppclm_photo_google_label_id')->references('id')->on('photo_google_label'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + /** + * Table Relations + */ + Schema::table('property_photo_category',function (Blueprint $table) { + $table->unique('category_name','pr_ph_ctg_name'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + /** + * Table Relations + */ + Schema::table('property_photo_category_locale',function (Blueprint $table) { + $table->foreign('property_photo_category_id','ppcl_property_photo_category_id')->references('id')->on('property_photo_category'); + $table->unique(['property_photo_category_id', 'locale'],'ppcl_category_id_locale'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_photo'); + Schema::dropIfExists('property_photo_category_label_mapping'); + Schema::dropIfExists('property_photo_category_locale'); + Schema::dropIfExists('property_photo_category'); + Schema::dropIfExists('photo_google_label'); + } +} diff --git a/database/migrations/2019_10_11_121418_create_property_config_table.php b/database/migrations/2019_10_11_121418_create_property_config_table.php new file mode 100644 index 0000000..7883cbf --- /dev/null +++ b/database/migrations/2019_10_11_121418_create_property_config_table.php @@ -0,0 +1,46 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->string('config_key',64); + $table->text('config_value_json') ; + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::table('property_config', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->unique(['property_id', 'config_key'],'config_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_config'); + } +} diff --git a/database/migrations/2019_10_14_111402_create_property_module_table.php b/database/migrations/2019_10_14_111402_create_property_module_table.php new file mode 100644 index 0000000..446c485 --- /dev/null +++ b/database/migrations/2019_10_14_111402_create_property_module_table.php @@ -0,0 +1,64 @@ +increments('id'); + $table->string('name',200); + $table->tinyInteger('point')->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_module',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + + Schema::create('property_module_mapping', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('property_module_id'); + $table->unsignedInteger('property_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_module_mapping',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('property_module_id')->references('id')->on('property_module'); + + $table->unique(['property_module_id','property_id'], 'mapping_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_module_mapping'); + Schema::dropIfExists('property_module'); + } +} diff --git a/database/migrations/2019_10_18_102754_create_permission_table.php b/database/migrations/2019_10_18_102754_create_permission_table.php new file mode 100644 index 0000000..cd79501 --- /dev/null +++ b/database/migrations/2019_10_18_102754_create_permission_table.php @@ -0,0 +1,133 @@ +increments('id'); + $table->string('name',128); + $table->string('code',128)->unique(); + $table->unsignedInteger('parent_id')->nullable(); + $table->tinyInteger('is_menu')->nullable()->default(0); + $table->string('menu_detail', 255)->nullable(); + $table->tinyInteger('menu_order')->nullable()->default(0); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('permission',function (Blueprint $table) { + $table->foreign('parent_id')->references('id')->on('permission'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + + Schema::create('permission_group', function (Blueprint $table) { + $table->increments('id'); + $table->string('name',128); + $table->tinyInteger('is_admin')->nullable()->default(0); + $table->string('parameter_rules', 255)->nullable(); + $table->tinyInteger('is_private_permission')->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('permission_group',function (Blueprint $table) { + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + + Schema::create('permission_group_mapping', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('permission_group_id'); + $table->unsignedInteger('permission_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('permission_group_mapping',function (Blueprint $table) { + $table->foreign('permission_group_id')->references('id')->on('permission_group'); + $table->foreign('permission_id')->references('id')->on('permission'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['permission_group_id', 'permission_id'], 'pgm_unique'); + }); + + Schema::create('permission_group_user_mapping', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('permission_group_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('permission_group_user_mapping',function (Blueprint $table) { + $table->foreign('permission_group_id')->references('id')->on('permission_group'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('user_id')->references('id')->on('user'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['permission_group_id', 'property_id', 'user_id'], 'pgu_unique'); + + }); + + Schema::create('permission_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('permission_id'); + $table->string('name',128); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('permission_locale', function (Blueprint $table) { + $table->foreign('permission_id')->references('id')->on('permission'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['permission_id', 'locale'],'language_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permission_group_user_mapping'); + Schema::dropIfExists('permission_group_mapping'); + Schema::dropIfExists('permission_group'); + Schema::dropIfExists('permission_locale'); + Schema::dropIfExists('permission'); + } +} diff --git a/database/migrations/2019_11_06_103124_create_api_access_token_table.php b/database/migrations/2019_11_06_103124_create_api_access_token_table.php new file mode 100644 index 0000000..0a163b3 --- /dev/null +++ b/database/migrations/2019_11_06_103124_create_api_access_token_table.php @@ -0,0 +1,40 @@ +<bigIncrements('id'); + $table->string('token','64')->unique(); + $table->integer('expire_date'); + $table->unsignedInteger('user_id'); + $table->tinyInteger('invalidate'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('api_access_token',function (Blueprint $table) { + $table->foreign('user_id')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('api_access_token'); + } +} diff --git a/database/migrations/2019_11_14_174036_add_hash_key_to_user.php b/database/migrations/2019_11_14_174036_add_hash_key_to_user.php new file mode 100644 index 0000000..b9affd3 --- /dev/null +++ b/database/migrations/2019_11_14_174036_add_hash_key_to_user.php @@ -0,0 +1,34 @@ +string('hash_key', 255)->after('locale'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('user', function (Blueprint $table) { + $table->dropColumn(['hash_key']); + }); + } +} diff --git a/database/migrations/2019_11_15_151514_create_jobs_table.php b/database/migrations/2019_11_15_151514_create_jobs_table.php new file mode 100644 index 0000000..bfe09dc --- /dev/null +++ b/database/migrations/2019_11_15_151514_create_jobs_table.php @@ -0,0 +1,47 @@ +bigIncrements('id'); + $table->string('queue'); + $table->longText('payload'); + $table->tinyInteger('attempts')->unsigned(); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + $table->index(['queue', 'reserved_at']); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->increments('id'); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('jobs'); + Schema::dropIfExists('failed_jobs'); + } +} diff --git a/database/migrations/2019_12_18_104857_create_site_config_table.php b/database/migrations/2019_12_18_104857_create_site_config_table.php new file mode 100644 index 0000000..757f020 --- /dev/null +++ b/database/migrations/2019_12_18_104857_create_site_config_table.php @@ -0,0 +1,45 @@ +increments('id'); + $table->string('config_key',64); + $table->text('config_value_json') ; + $table->string('key_comment',64)->nullable(); + $table->tinyInteger('status'); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::table('site_config', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['config_key'],'config_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('site_config'); + } +} diff --git a/database/migrations/2019_12_24_101312_create_property_room_type_table.php b/database/migrations/2019_12_24_101312_create_property_room_type_table.php new file mode 100644 index 0000000..e0b00d6 --- /dev/null +++ b/database/migrations/2019_12_24_101312_create_property_room_type_table.php @@ -0,0 +1,68 @@ +increments('id'); + $table->string('name',255); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + Schema::create('property_room_type_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('room_type_id'); + $table->string('name',255); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + + /*************** + * Table Relations + ****************/ + Schema::table('property_room_type',function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::table('property_room_type_locale',function (Blueprint $table) { + $table->foreign('room_type_id')->references('id')->on('property_room_type'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['room_type_id','locale'],'prt_locale_unique'); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_type_locale'); + Schema::dropIfExists('property_room_type'); + } +} diff --git a/database/migrations/2019_12_24_162318_create_property_room_table.php b/database/migrations/2019_12_24_162318_create_property_room_table.php new file mode 100644 index 0000000..042e569 --- /dev/null +++ b/database/migrations/2019_12_24_162318_create_property_room_table.php @@ -0,0 +1,50 @@ +bigIncrements('id'); + $table->unsignedInteger('property_id'); + $table->string('name', 200); + $table->mediumText('description')->nullable(); + $table->unsignedInteger('room_type_id'); + $table->integer('max_occupancy'); + $table->integer('max_adult'); + $table->integer('max_child'); + + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('room_type_id')->references('id')->on('property_room_type'); + $table->foreign('property_id')->references('id')->on('property'); + }); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room'); + } +} diff --git a/database/migrations/2019_12_25_173749_create_property_room_bed_type_table.php b/database/migrations/2019_12_25_173749_create_property_room_bed_type_table.php new file mode 100644 index 0000000..04fd556 --- /dev/null +++ b/database/migrations/2019_12_25_173749_create_property_room_bed_type_table.php @@ -0,0 +1,58 @@ +increments('id'); + $table->string('name',200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('property_room_bed_type_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('bed_type_id'); + $table->string('name',255); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('bed_type_id')->references('id')->on('property_room_bed_type'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['bed_type_id','locale'],'pbt_locale_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_bed_type_locale'); + Schema::dropIfExists('property_room_bed_type'); + } +} diff --git a/database/migrations/2019_12_26_094857_create_property_room_bed_table.php b/database/migrations/2019_12_26_094857_create_property_room_bed_table.php new file mode 100644 index 0000000..97ae903 --- /dev/null +++ b/database/migrations/2019_12_26_094857_create_property_room_bed_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + $table->unsignedBigInteger('room_id'); + $table->tinyInteger('bed_group'); + $table->tinyInteger('count'); + $table->unsignedInteger('bed_type_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('room_id')->references('id')->on('property_room'); + $table->foreign('bed_type_id')->references('id')->on('property_room_bed_type'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_bed'); + } +} diff --git a/database/migrations/2019_12_27_111441_create_property_channel_category_table.php b/database/migrations/2019_12_27_111441_create_property_channel_category_table.php new file mode 100644 index 0000000..eb7855b --- /dev/null +++ b/database/migrations/2019_12_27_111441_create_property_channel_category_table.php @@ -0,0 +1,59 @@ +increments('id'); + $table->string('name',200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + + Schema::create('property_channel_category_locale', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedInteger('channel_category_id'); + $table->string('name',255); + $table->string('locale',2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('channel_category_id')->references('id')->on('property_channel_category'); + $table->foreign('locale')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_channel_category_locale'); + Schema::dropIfExists('property_channel_category'); + } +} diff --git a/database/migrations/2019_12_27_135558_create_property_channel_table.php b/database/migrations/2019_12_27_135558_create_property_channel_table.php new file mode 100644 index 0000000..a7adc46 --- /dev/null +++ b/database/migrations/2019_12_27_135558_create_property_channel_table.php @@ -0,0 +1,47 @@ +increments('id'); + $table->string('name', 200); + $table->mediumText('description'); + $table->string('type', 5); + $table->unsignedInteger('channel_category_id'); + $table->string('country_code', 5)->nullable(); + $table->string('currency_code', 3); + + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('channel_category_id')->references('id')->on('property_channel_category'); + $table->foreign('currency_code')->references('code')->on('currency'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_channel'); + } +} diff --git a/database/migrations/2019_12_27_171704_create_property_channel_mapping_table.php b/database/migrations/2019_12_27_171704_create_property_channel_mapping_table.php new file mode 100644 index 0000000..2e8db43 --- /dev/null +++ b/database/migrations/2019_12_27_171704_create_property_channel_mapping_table.php @@ -0,0 +1,44 @@ +increments('id'); + $table->unsignedInteger('property_id'); + $table->unsignedInteger('channel_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('channel_id')->references('id')->on('property_channel'); + $table->unique(['property_id', 'channel_id'], 'property_channel_unique'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_channel_mapping'); + } +} diff --git a/database/migrations/2019_12_30_160355_create_property_room_rate_table.php b/database/migrations/2019_12_30_160355_create_property_room_rate_table.php new file mode 100644 index 0000000..f10388b --- /dev/null +++ b/database/migrations/2019_12_30_160355_create_property_room_rate_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + $table->unsignedInteger('property_id'); + $table->string('name',200); + $table->mediumText('description'); + $table->tinyInteger('min_stay'); + $table->tinyInteger('is_manually_input'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate'); + } +} diff --git a/database/migrations/2019_12_31_104604_create_property_room_rate_mapping_table.php b/database/migrations/2019_12_31_104604_create_property_room_rate_mapping_table.php new file mode 100644 index 0000000..0ddea8e --- /dev/null +++ b/database/migrations/2019_12_31_104604_create_property_room_rate_mapping_table.php @@ -0,0 +1,50 @@ +bigIncrements('id'); + $table->unsignedBigInteger('room_id'); + $table->unsignedBigInteger('room_rate_id'); + $table->mediumText('description'); + $table->double('rack_rate',10,2); + $table->tinyInteger('included_occupancy'); + $table->tinyInteger('independent_availability'); + $table->tinyInteger('default_stop_sell'); + $table->tinyInteger('booking_on_request'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('room_id')->references('id')->on('property_room'); + $table->foreign('room_rate_id')->references('id')->on('property_room_rate'); + $table->unique(['room_id', 'room_rate_id'], 'room_room_rate_mapping'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate_mapping'); + } +} diff --git a/database/migrations/2019_12_31_134435_create_property_room_rate_inclusion_mapping_table.php b/database/migrations/2019_12_31_134435_create_property_room_rate_inclusion_mapping_table.php new file mode 100644 index 0000000..d39266e --- /dev/null +++ b/database/migrations/2019_12_31_134435_create_property_room_rate_inclusion_mapping_table.php @@ -0,0 +1,43 @@ +bigIncrements('id'); + $table->unsignedBigInteger('room_rate_id'); + $table->unsignedInteger('fact_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('room_rate_id')->references('id')->on('property_room_rate'); + $table->foreign('fact_id')->references('id')->on('property_fact'); + $table->unique(['room_rate_id', 'fact_id'], 'room_rate_fact_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate_inclusion_mapping'); + } +} diff --git a/database/migrations/2020_01_02_110521_create_property_room_rate_channel_mapping_table.php b/database/migrations/2020_01_02_110521_create_property_room_rate_channel_mapping_table.php new file mode 100644 index 0000000..3df0e4a --- /dev/null +++ b/database/migrations/2020_01_02_110521_create_property_room_rate_channel_mapping_table.php @@ -0,0 +1,44 @@ +bigIncrements('id'); + $table->unsignedInteger('channel_id'); + $table->unsignedBigInteger('room_rate_mapping_id'); + + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('channel_id')->references('id')->on('property_channel'); + $table->foreign('room_rate_mapping_id')->references('id')->on('property_room_rate_mapping'); + $table->unique(['channel_id', 'room_rate_mapping_id'], 'room_rate_channel_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate_channel_mapping'); + } +} diff --git a/database/migrations/2020_01_02_140905_create_property_room_rate_mapping_setup_table.php b/database/migrations/2020_01_02_140905_create_property_room_rate_mapping_setup_table.php new file mode 100644 index 0000000..a8ebedf --- /dev/null +++ b/database/migrations/2020_01_02_140905_create_property_room_rate_mapping_setup_table.php @@ -0,0 +1,47 @@ +bigIncrements('id'); + $table->unsignedBigInteger('room_rate_mapping_id'); + $table->string('setup_type', 100)->comment('EXT_ADULT, EXT_CHILD, DIS_GUEST'); + $table->string('value_type', 100)->comment('FIX, PER'); + $table->double('value', 10,2); + + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('room_rate_mapping_id')->references('id')->on('property_room_rate_mapping'); + $table->unique(['room_rate_mapping_id', 'setup_type'], 'room_rate_setup_unique'); + + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate_mapping_setup'); + } +} diff --git a/database/migrations/2020_01_02_170939_create_property_room_rate_price_table.php b/database/migrations/2020_01_02_170939_create_property_room_rate_price_table.php new file mode 100644 index 0000000..d1dd231 --- /dev/null +++ b/database/migrations/2020_01_02_170939_create_property_room_rate_price_table.php @@ -0,0 +1,57 @@ +bigIncrements('id'); + $table->unsignedInteger('property_id'); + $table->unsignedBigInteger('property_room_id'); + $table->unsignedBigInteger('room_rate_mapping_id'); + $table->unsignedBigInteger('offer_id')->nullable(); + $table->unsignedInteger('channel_id')->nullable(); + $table->tinyInteger('min_stay'); + $table->tinyInteger('max_stay'); + $table->tinyInteger('stop_sell'); + $table->tinyInteger('booking_on_request'); + $table->date('date'); + $table->double('amount',10,2); + $table->string('currency',3); + + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('property_room_id')->references('id')->on('property_room'); + $table->foreign('room_rate_mapping_id')->references('id')->on('property_room_rate_mapping'); + $table->foreign('channel_id')->references('id')->on('property_channel'); + $table->foreign('currency')->references('code')->on('currency'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_rate_price'); + } +} diff --git a/database/migrations/2020_01_03_124014_create_property_room_availability_table.php b/database/migrations/2020_01_03_124014_create_property_room_availability_table.php new file mode 100644 index 0000000..87516c1 --- /dev/null +++ b/database/migrations/2020_01_03_124014_create_property_room_availability_table.php @@ -0,0 +1,47 @@ +bigIncrements('id'); + $table->unsignedInteger('property_id'); + $table->unsignedBigInteger('property_room_id'); + $table->unsignedBigInteger('room_rate_mapping_id')->nullable(); + $table->unsignedBigInteger('offer_id')->nullable(); + $table->date('date'); + $table->integer('availability')->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('property_room_id')->references('id')->on('property_room'); + $table->foreign('room_rate_mapping_id')->references('id')->on('property_room_rate_mapping'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_availability'); + } +} diff --git a/database/migrations/2020_01_07_122454_add_max_stay_to_property_room_rate.php b/database/migrations/2020_01_07_122454_add_max_stay_to_property_room_rate.php new file mode 100644 index 0000000..8387da6 --- /dev/null +++ b/database/migrations/2020_01_07_122454_add_max_stay_to_property_room_rate.php @@ -0,0 +1,32 @@ +tinyInteger('max_stay')->after('min_stay'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_room_rate', function (Blueprint $table) { + $table->dropColumn(['max_stay']); + }); + } +} diff --git a/database/migrations/2020_01_15_165436_add_image_to_property_channel.php b/database/migrations/2020_01_15_165436_add_image_to_property_channel.php new file mode 100644 index 0000000..ce57550 --- /dev/null +++ b/database/migrations/2020_01_15_165436_add_image_to_property_channel.php @@ -0,0 +1,32 @@ +string('image', 255)->after('currency_code')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_channel', function (Blueprint $table) { + $table->dropColumn(['image']); + }); + } +} diff --git a/database/migrations/2020_02_13_145243_drop_unique_to_property_executive.php b/database/migrations/2020_02_13_145243_drop_unique_to_property_executive.php new file mode 100644 index 0000000..5e14c0e --- /dev/null +++ b/database/migrations/2020_02_13_145243_drop_unique_to_property_executive.php @@ -0,0 +1,44 @@ +dropForeign('property_executive_ibfk_1'); + $table->dropForeign('property_executive_ibfk_2'); + $table->dropForeign('property_executive_ibfk_3'); + $table->dropForeign('property_executive_ibfk_4'); + $table->dropIndex('property_executive_updated_by_foreign'); + $table->dropIndex('property_executive_created_by_foreign'); + $table->dropIndex('property_executive_executive_type_id_foreign'); + $table->dropIndex('property_executive_property_id_executive_type_id_unique'); + }); + + Schema::table('property_executive',function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('executive_type_id')->references('id')->on('property_executive_type'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + +} diff --git a/database/migrations/2020_02_18_113758_add_mobile2_to_property_contact.php b/database/migrations/2020_02_18_113758_add_mobile2_to_property_contact.php new file mode 100644 index 0000000..70b2599 --- /dev/null +++ b/database/migrations/2020_02_18_113758_add_mobile2_to_property_contact.php @@ -0,0 +1,36 @@ +string('mobile2_code',10)->after('mobile')->nullable(); + $table->string('mobile2',50)->after('mobile2_code')->nullable(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_contact', function (Blueprint $table) { + $table->dropColumn('mobile2_code'); + $table->dropColumn('mobile2'); + + }); + } +} diff --git a/database/migrations/2020_02_18_153248_add_social_media_addresses_to_property_contact.php b/database/migrations/2020_02_18_153248_add_social_media_addresses_to_property_contact.php new file mode 100644 index 0000000..27393b8 --- /dev/null +++ b/database/migrations/2020_02_18_153248_add_social_media_addresses_to_property_contact.php @@ -0,0 +1,32 @@ +string('social_media_addresses',512)->after('web')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_contact', function (Blueprint $table) { + $table->dropColumn('social_media_addresses'); + }); + } +} diff --git a/database/migrations/2020_05_18_154634_create_offer_table.php b/database/migrations/2020_05_18_154634_create_offer_table.php new file mode 100644 index 0000000..e2cec8a --- /dev/null +++ b/database/migrations/2020_05_18_154634_create_offer_table.php @@ -0,0 +1,236 @@ +bigIncrements('id'); + $table->unsignedInteger('property_id'); + $table->string('title',200); + $table->mediumText('description')->nullable(); + $table->date('expire_date'); + $table->string('language',2); + $table->string('currency',3); + $table->double('total',10,2)->nullable(); + $table->integer('payment_type_id')->nullable(); // TODO İlişki Kurulmadı + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer', function (Blueprint $table) { + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + + + Schema::create('offer_accommodation_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedInteger('property_accommodation_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->dateTime('created_at'); + $table->dateTime('updated_at'); + }); + + Schema::table('offer_accommodation_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_accommodation_id')->references('id')->on('property_fact'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_cancellation_policy', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->date('start_date'); + $table->date('end_date'); + $table->integer('days_before'); + $table->string('type',3); + $table->double('value',10,2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_cancellation_policy', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_contact_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedInteger('property_executive_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_contact_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_executive_id')->references('id')->on('property_executive'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_fact_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedInteger('category_id'); + $table->unsignedInteger('property_fact_parent_id'); + $table->unsignedInteger('property_fact_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_fact_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('category_id')->references('id')->on('property_fact'); + $table->foreign('property_fact_parent_id')->references('parent_id')->on('property_fact'); + $table->foreign('property_fact_id')->references('id')->on('property_fact'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_important_notes', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->mediumText('note')->nullable(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_important_notes', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_payment_type', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('name',200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_payment_type', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_photo_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedInteger('property_photo_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_photo_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_photo_id')->references('id')->on('property_photo'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_price', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->date('date'); + $table->unsignedBigInteger('property_room_id'); + $table->unsignedInteger('property_accommodation_id'); + $table->unsignedInteger('number_of_rooms'); + $table->string('currency',3); + $table->double('amount',10,2); + $table->double('total_amount',10,2); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_price', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_room_id')->references('id')->on('property_room'); + $table->foreign('property_accommodation_id')->references('id')->on('property_fact'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::create('offer_room_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedBigInteger('property_room_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('offer_room_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_room_id')->references('id')->on('property_room'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + Schema::dropIfExists('offer_room_mapping'); + Schema::dropIfExists('offer_price'); + Schema::dropIfExists('offer_photo_mapping'); + Schema::dropIfExists('offer_payment_type'); + Schema::dropIfExists('offer_important_notes'); + Schema::dropIfExists('offer_fact_mapping'); + Schema::dropIfExists('offer_contact_mapping'); + Schema::dropIfExists('offer_cancellation_policy'); + Schema::dropIfExists('offer_accommodation_mapping'); + Schema::dropIfExists('offer'); + + } +} diff --git a/database/migrations/2020_05_27_174534_create_property_room_fact_mapping_table.php b/database/migrations/2020_05_27_174534_create_property_room_fact_mapping_table.php new file mode 100644 index 0000000..336612e --- /dev/null +++ b/database/migrations/2020_05_27_174534_create_property_room_fact_mapping_table.php @@ -0,0 +1,43 @@ +bigIncrements('id'); + $table->integer('property_id')->unsigned(); + $table->bigInteger('room_id')->unsigned(); + $table->integer('fact_id')->unsigned(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('room_id')->references('id')->on('property_room'); + $table->foreign('fact_id')->references('id')->on('property_fact'); + $table->unique(['property_id', 'fact_id','room_id'],'pfr_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_fact_mapping'); + } +} diff --git a/database/migrations/2020_05_28_123105_create_property_room_photo_mapping_table.php b/database/migrations/2020_05_28_123105_create_property_room_photo_mapping_table.php new file mode 100644 index 0000000..47e43ac --- /dev/null +++ b/database/migrations/2020_05_28_123105_create_property_room_photo_mapping_table.php @@ -0,0 +1,48 @@ +statement("ALTER TABLE `offer_photo_mapping`DROP FOREIGN KEY `offer_photo_mapping_property_photo_id_foreign`;"); + DB::connection()->statement("ALTER TABLE `property_photo` MODIFY COLUMN `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT FIRST"); + DB::connection()->statement("ALTER TABLE `offer_photo_mapping` MODIFY COLUMN `property_photo_id` bigint(20) UNSIGNED NOT NULL"); + DB::connection()->statement("ALTER TABLE `offer_photo_mapping` ADD CONSTRAINT `offer_photo_mapping_property_photo_id_foreign` FOREIGN KEY (`property_photo_id`) REFERENCES `property_photo` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT"); + + Schema::create('property_room_photo_mapping', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->integer('property_id')->unsigned(); + $table->bigInteger('room_id')->unsigned(); + $table->bigInteger('photo_id')->unsigned(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('room_id')->references('id')->on('property_room'); + $table->foreign('photo_id')->references('id')->on('property_photo'); + $table->unique(['property_id', 'photo_id', 'room_id'],'ppr_unique'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_photo_mapping'); + } +} diff --git a/database/migrations/2020_05_28_203313_create_property_brand_table.php b/database/migrations/2020_05_28_203313_create_property_brand_table.php new file mode 100644 index 0000000..bec3431 --- /dev/null +++ b/database/migrations/2020_05_28_203313_create_property_brand_table.php @@ -0,0 +1,48 @@ +increments('id'); + $table->integer('property_id')->unsigned(); + $table->string('title', 250); + $table->string('color_code_1', 50); + $table->string('color_code_2', 50); + $table->string('color_code_3', 50); + $table->string('logo_path'); + $table->string('logo_name', 200); + + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + $table->unique(['property_id'],'property_unique'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_brand'); + } +} diff --git a/database/migrations/2020_06_01_201830_change_offer_accommodation_mapping_date_format.php b/database/migrations/2020_06_01_201830_change_offer_accommodation_mapping_date_format.php new file mode 100644 index 0000000..4e4d4fe --- /dev/null +++ b/database/migrations/2020_06_01_201830_change_offer_accommodation_mapping_date_format.php @@ -0,0 +1,44 @@ +bigIncrements('id'); + $table->unsignedBigInteger('offer_id'); + $table->unsignedInteger('property_accommodation_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + Schema::table('offer_accommodation_mapping', function (Blueprint $table) { + $table->foreign('offer_id')->references('id')->on('offer'); + $table->foreign('property_accommodation_id')->references('id')->on('property_fact'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_05_114115_add_column_offer_table_offer_code.php b/database/migrations/2020_06_05_114115_add_column_offer_table_offer_code.php new file mode 100644 index 0000000..0f9963d --- /dev/null +++ b/database/migrations/2020_06_05_114115_add_column_offer_table_offer_code.php @@ -0,0 +1,23 @@ +string('offer_code',50)->unique()->nullable(); + }); + } + + + public function down() + { + Schema::table('offer', function (Blueprint $table) { + $table->dropColumn('offer_code'); + }); + } +} diff --git a/database/migrations/2020_06_05_162856_add_column_offer_table_accept_status_column.php b/database/migrations/2020_06_05_162856_add_column_offer_table_accept_status_column.php new file mode 100644 index 0000000..cd4a31a --- /dev/null +++ b/database/migrations/2020_06_05_162856_add_column_offer_table_accept_status_column.php @@ -0,0 +1,24 @@ +tinyInteger('accept_status')->after('status')->default(0)->comment(' 0 pending, 1 accepted, 2 canceled'); + + }); + } + + + public function down() + { + Schema::table('offer', function (Blueprint $table) { + $table->dropColumn('accept_status'); + }); + } +} diff --git a/database/migrations/2020_06_09_095128_add_is_cover_photo_to_offer_photo_mapping.php b/database/migrations/2020_06_09_095128_add_is_cover_photo_to_offer_photo_mapping.php new file mode 100644 index 0000000..858283a --- /dev/null +++ b/database/migrations/2020_06_09_095128_add_is_cover_photo_to_offer_photo_mapping.php @@ -0,0 +1,34 @@ +tinyInteger('is_cover')->after('property_photo_id')->default(0)->comment(' 0 false, 1 true (use for cover photo)'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('offer_photo_mapping', function (Blueprint $table) { + $table->dropColumn('is_cover'); + + }); + } +} diff --git a/database/migrations/2020_06_09_135659_change_offer_table_status_and_accept_status_fields.php b/database/migrations/2020_06_09_135659_change_offer_table_status_and_accept_status_fields.php new file mode 100644 index 0000000..e611928 --- /dev/null +++ b/database/migrations/2020_06_09_135659_change_offer_table_status_and_accept_status_fields.php @@ -0,0 +1,31 @@ +where('id',1)->update(['icon' => '']); // General Amenities + DB::table('property_fact')->where('id',257)->update(['icon' => 'fas fa-hot-tub']); // Spa Wellness + DB::table('property_fact')->where('id',2)->update(['icon' => '']); // Payment Type + DB::table('property_fact')->where('id',258)->update(['icon' => 'fas fa-spa']); // Spa, Wellness & Care + DB::table('property_fact')->where('id',9)->update(['icon' => '']); // Accommodation Type + DB::table('property_fact')->where('id',10)->update(['icon' => 'fas fa-hotel']); // All inclusive + DB::table('property_fact')->where('id',16)->update(['icon' => '']); // Accommodation Services + DB::table('property_fact')->where('id',17)->update(['icon' => 'fas fa-concierge-bell']); // Reception + DB::table('property_fact')->where('id',26)->update(['icon' => 'fas fa-tv']); // Internet and TV + DB::table('property_fact')->where('id',27)->update(['icon' => 'fas fa-wifi']); // Wireless Internet + DB::table('property_fact')->where('id',30)->update(['icon' => '']); // Working Area + DB::table('property_fact')->where('id',31)->update(['icon' => 'fas fa-briefcase']); // Business Center + DB::table('property_fact')->where('id',292)->update(['icon' => '']); // Room Amenities + DB::table('property_fact')->where('id',37)->update(['icon' => 'fas fa-shuttle-van']); // Transportation Services + DB::table('property_fact')->where('id',293)->update(['icon' => '']); // Common Amenities of Rooms + DB::table('property_fact')->where('id',38)->update(['icon' => 'fas fa-car']); // Rent a car + DB::table('property_fact')->where('id',44)->update(['icon' => '']); // Facility Amenities + DB::table('property_fact')->where('id',45)->update(['icon' => '']); // Activities + DB::table('property_fact')->where('id',114)->update(['icon' => '']); // Entertainment on Facility + DB::table('property_fact')->where('id',115)->update(['icon' => 'fas fa-sun']); // Outdoor Activities + DB::table('property_fact')->where('id',142)->update(['icon' => 'fas fa-swimmer']); // Pool + DB::table('property_fact')->where('id',143)->update(['icon' => 'fas fa-swimming-pool']); // Aqua Park + DB::table('property_fact')->where('id',154)->update(['icon' => 'fas fa-utensils']); // Food and Beverage, Restaurant + DB::table('property_fact')->where('id',182)->update(['icon' => '']); // Public Areas and Facilitiesa + DB::table('property_fact')->where('id',183)->update(['icon' => 'fas fa-arrows-alt-v']); // Elevator + DB::table('property_fact')->where('id',222)->update(['icon' => 'fas fa-wheelchair']); // Children and Disabled + DB::table('property_fact')->where('id',223)->update(['icon' => 'fas fa-baby']); // Baby and Child + + DB::table('property_fact')->where('id',27)->update(['icon' => 'fas fa-wifi']); + DB::table('property_fact')->where('id',64)->update(['icon' => 'fas fa-bullseye']); + DB::table('property_fact')->where('id',66)->update(['icon' => 'fas fa-golf-ball']); + DB::table('property_fact')->where('id',65)->update(['icon' => 'fas fa-ship']); + DB::table('property_fact')->where('id',158)->update(['icon' => 'fas fa-glass-martini']); + DB::table('property_fact')->where('id',156)->update(['icon' => 'fas fa-beer']); + DB::table('property_fact')->where('id',166)->update(['icon' => 'fas fa-wine-bottle']); + DB::table('property_fact')->where('id',160)->update(['icon' => 'fas fa-glass-whiskey']); + DB::table('property_fact')->where('id',162)->update(['icon' => 'fas fa-cocktail']); + DB::table('property_fact')->where('id',148)->update(['icon' => 'fas fa-umbrella-beach']); + DB::table('property_fact')->where('id',226)->update(['icon' => 'fas fa-child']); + DB::table('property_fact')->where('id',227)->update(['icon' => 'fas fa-swimming-pool']); + DB::table('property_fact')->where('id',303)->update(['icon' => 'fas fa-border-none']); + DB::table('property_fact')->where('id',320)->update(['icon' => 'fas fa-washer']); + DB::table('property_fact')->where('id',313)->update(['icon' => 'fas fa-tshirt']); + DB::table('property_fact')->where('id',346)->update(['icon' => 'fas fa-border-all']); + DB::table('property_fact')->where('id',335)->update(['icon' => 'fas fa-bolt']); + DB::table('property_fact')->where('id',372)->update(['icon' => 'fas fa-swimming-pool']); + DB::table('property_fact')->where('id',186)->update(['name' => 'Coffee / Tea Maker']); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_16_093408_drop_column_from_offer_cancellation_policy.php b/database/migrations/2020_06_16_093408_drop_column_from_offer_cancellation_policy.php new file mode 100644 index 0000000..f457403 --- /dev/null +++ b/database/migrations/2020_06_16_093408_drop_column_from_offer_cancellation_policy.php @@ -0,0 +1,34 @@ +dropColumn('start_date'); + $table->dropColumn('end_date'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('offer_cancellation_policy', function (Blueprint $table) { + $table->date('start_date')->default('2020-01-01'); + $table->date('end_date')->default('2020-01-01');; + }); + } +} diff --git a/database/migrations/2020_06_16_171417_update_fact_order.php b/database/migrations/2020_06_16_171417_update_fact_order.php new file mode 100644 index 0000000..ce8f484 --- /dev/null +++ b/database/migrations/2020_06_16_171417_update_fact_order.php @@ -0,0 +1,46 @@ +statement("UPDATE property_fact SET order_number = 1 WHERE id = 9"); + DB::connection()->statement("UPDATE property_fact SET order_number = 2 WHERE id = 16"); + DB::connection()->statement("UPDATE property_fact SET order_number = 3 WHERE id = 26"); + DB::connection()->statement("UPDATE property_fact SET order_number = 4 WHERE id = 30 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 5 WHERE id = 37 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 6 WHERE id = 243"); + DB::connection()->statement("UPDATE property_fact SET order_number = 7 WHERE id = 2 "); + + // facility + DB::connection()->statement("UPDATE property_fact SET order_number = 1 WHERE id = 45 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 2 WHERE id = 154 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 3 WHERE id = 114 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 4 WHERE id = 142"); + DB::connection()->statement("UPDATE property_fact SET order_number = 5 WHERE id = 257 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 6 WHERE id = 182 "); + DB::connection()->statement("UPDATE property_fact SET order_number = 7 WHERE id = 223"); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_17_145049_update_fact_parent.php b/database/migrations/2020_06_17_145049_update_fact_parent.php new file mode 100644 index 0000000..b668516 --- /dev/null +++ b/database/migrations/2020_06_17_145049_update_fact_parent.php @@ -0,0 +1,46 @@ +statement("UPDATE property_fact SET parent_id = 44 WHERE id = 223"); + DB::connection()->statement("UPDATE property_fact SET parent_id = 1 WHERE id = 243"); + DB::connection()->statement("UPDATE property_fact SET type = 0 WHERE id = 243"); + DB::connection()->statement("UPDATE property_fact SET parent_id = 44 WHERE id = 257"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE property_fact_id = 222"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE property_fact_parent_id = 222"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE category_id = 222"); + DB::connection()->statement("DELETE FROM property_fact_attribute_mapping WHERE fact_id = 222"); + DB::connection()->statement("DELETE FROM property_fact_mapping WHERE fact_id = 222"); + DB::connection()->statement("DELETE FROM property_room_fact_mapping WHERE fact_id = 222"); + DB::connection()->statement("DELETE FROM property_fact_locale WHERE fact_id = 222"); + DB::connection()->statement("DELETE FROM property_fact WHERE id = 222"); + +$updateData = <<where('id',1)->update(['config_value_json' => $updateData]); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_17_150913_create_country_table.php b/database/migrations/2020_06_17_150913_create_country_table.php new file mode 100644 index 0000000..a0e161d --- /dev/null +++ b/database/migrations/2020_06_17_150913_create_country_table.php @@ -0,0 +1,37 @@ +increments('id'); + $table->string('name', 100)->unique(); + $table->string('country_code',5)->unique(); + $table->string('phone_code',10)->nullable(); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('country'); + } +} diff --git a/database/migrations/2020_06_18_103740_update_property_fact_data.php b/database/migrations/2020_06_18_103740_update_property_fact_data.php new file mode 100644 index 0000000..d19bdbf --- /dev/null +++ b/database/migrations/2020_06_18_103740_update_property_fact_data.php @@ -0,0 +1,36 @@ +statement("UPDATE property_fact SET parent_id = 44, order_number = 5 WHERE id = 258"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE property_fact_id = 257"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE property_fact_parent_id = 257"); + DB::connection()->statement("DELETE FROM offer_fact_mapping WHERE category_id = 257"); + DB::connection()->statement("DELETE FROM property_fact_attribute_mapping WHERE fact_id = 257"); + DB::connection()->statement("DELETE FROM property_fact_mapping WHERE fact_id = 257"); + DB::connection()->statement("DELETE FROM property_room_fact_mapping WHERE fact_id = 257"); + DB::connection()->statement("DELETE FROM property_fact_locale WHERE fact_id = 257"); + DB::connection()->statement("DELETE FROM property_fact WHERE id = 257"); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_18_132804_country_table_add_data.php b/database/migrations/2020_06_18_132804_country_table_add_data.php new file mode 100644 index 0000000..6b7ba81 --- /dev/null +++ b/database/migrations/2020_06_18_132804_country_table_add_data.php @@ -0,0 +1,272 @@ +statement("INSERT INTO `country` VALUES (1, 'Aruba', 'AW', '297', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (2, 'Afghanistan', 'AF', '93', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (3, 'Angola', 'AO', '244', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (4, 'Anguilla', 'AI', '1264', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (5, 'Ãland Islands', 'AX', '358', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (6, 'Albania', 'AL', '355', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (7, 'Andorra', 'AD', '376', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (8, 'United Arab Emirates', 'AE', '971', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (9, 'Argentina', 'AR', '54', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (10, 'Armenia', 'AM', '374', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (11, 'American Samoa', 'AS', '1684', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (12, 'Antigua and Barbuda', 'AG', '1268', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (13, 'Australia', 'AU', '61', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (14, 'Austria', 'AT', '43', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (15, 'Azerbaijan', 'AZ', '994', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (16, 'Burundi', 'BI', '257', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (17, 'Belgium', 'BE', '32', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (18, 'Benin', 'BJ', '229', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (19, 'Burkina Faso', 'BF', '226', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (20, 'Bangladesh', 'BD', '880', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (21, 'Bulgaria', 'BG', '359', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (22, 'Bahrain', 'BH', '973', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (23, 'Bahamas', 'BS', '1242', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (24, 'Bosnia and Herzegovina', 'BA', '387', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (25, 'Saint Barthélemy', 'BL', '590', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (26, 'Belarus', 'BY', '375', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (27, 'Belize', 'BZ', '501', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (28, 'Bermuda', 'BM', '1441', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (29, 'Bolivia', 'BO', '591', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (30, 'Brazil', 'BR', '55', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (31, 'Barbados', 'BB', '1246', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (32, 'Brunei', 'BN', '673', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (33, 'Bhutan', 'BT', '975', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (34, 'Botswana', 'BW', '267', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (35, 'Central African Republic', 'CF', '236', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (36, 'Canada', 'CA', '1', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (37, 'Cocos (Keeling) Islands', 'CC', '61', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (38, 'Switzerland', 'CH', '41', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (39, 'Chile', 'CL', '56', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (40, 'China', 'CN', '86', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (41, 'Ivory Coast', 'CI', '225', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (42, 'Cameroon', 'CM', '237', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (43, 'DR Congo', 'CD', '243', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (44, 'Republic of the Congo', 'CG', '242', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (45, 'Cook Islands', 'CK', '682', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (46, 'Colombia', 'CO', '57', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (47, 'Comoros', 'KM', '269', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (48, 'Cape Verde', 'CV', '238', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (49, 'Costa Rica', 'CR', '506', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (50, 'Cuba', 'CU', '53', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (51, 'Curaçao', 'CW', '5999', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (52, 'Christmas Island', 'CX', '61', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (53, 'Cayman Islands', 'KY', '1345', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (54, 'Cyprus', 'CY', '357', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (55, 'Czechia', 'CZ', '420', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (56, 'Germany', 'DE', '49', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (57, 'Djibouti', 'DJ', '253', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (58, 'Dominica', 'DM', '1767', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (59, 'Denmark', 'DK', '45', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (60, 'Dominican Republic', 'DO', '1809', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (61, 'Algeria', 'DZ', '213', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (62, 'Ecuador', 'EC', '593', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (63, 'Egypt', 'EG', '20', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (64, 'Eritrea', 'ER', '291', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (65, 'Western Sahara', 'EH', '212', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (66, 'Spain', 'ES', '34', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (67, 'Estonia', 'EE', '372', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (68, 'Ethiopia', 'ET', '251', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (69, 'Finland', 'FI', '358', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (70, 'Fiji', 'FJ', '679', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (71, 'Falkland Islands', 'FK', '500', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (72, 'France', 'FR', '33', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (73, 'Faroe Islands', 'FO', '298', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (74, 'Micronesia', 'FM', '691', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (75, 'Gabon', 'GA', '241', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (76, 'United Kingdom', 'GB', '44', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (77, 'Georgia', 'GE', '995', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (78, 'Guernsey', 'GG', '44', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (79, 'Ghana', 'GH', '233', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (80, 'Gibraltar', 'GI', '350', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (81, 'Guinea', 'GN', '224', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (82, 'Guadeloupe', 'GP', '590', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (83, 'Gambia', 'GM', '220', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (84, 'Guinea-Bissau', 'GW', '245', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (85, 'Equatorial Guinea', 'GQ', '240', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (86, 'Greece', 'GR', '30', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (87, 'Grenada', 'GD', '1473', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (88, 'Greenland', 'GL', '299', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (89, 'Guatemala', 'GT', '502', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (90, 'French Guiana', 'GF', '594', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (91, 'Guam', 'GU', '1671', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (92, 'Guyana', 'GY', '592', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (93, 'Hong Kong', 'HK', '852', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (94, 'Honduras', 'HN', '504', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (95, 'Croatia', 'HR', '385', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (96, 'Haiti', 'HT', '509', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (97, 'Hungary', 'HU', '36', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (98, 'Indonesia', 'ID', '62', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (99, 'Isle of Man', 'IM', '44', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (100, 'India', 'IN', '91', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (101, 'British Indian Ocean Territory', 'IO', '246', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (102, 'Ireland', 'IE', '353', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (103, 'Iran', 'IR', '98', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (104, 'Iraq', 'IQ', '964', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (105, 'Iceland', 'IS', '354', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (106, 'Israel', 'IL', '972', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (107, 'Italy', 'IT', '39', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (108, 'Jamaica', 'JM', '1876', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (109, 'Jersey', 'JE', '44', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (110, 'Jordan', 'JO', '962', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (111, 'Japan', 'JP', '81', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (112, 'Kazakhstan', 'KZ', '77', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (113, 'Kenya', 'KE', '254', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (114, 'Kyrgyzstan', 'KG', '996', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (115, 'Cambodia', 'KH', '855', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (116, 'Kiribati', 'KI', '686', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (117, 'Saint Kitts and Nevis', 'KN', '1869', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (118, 'South Korea', 'KR', '82', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (119, 'Kosovo', 'XK', '383', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (120, 'Kuwait', 'KW', '965', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (121, 'Laos', 'LA', '856', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (122, 'Lebanon', 'LB', '961', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (123, 'Liberia', 'LR', '231', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (124, 'Libya', 'LY', '218', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (125, 'Saint Lucia', 'LC', '1758', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (126, 'Liechtenstein', 'LI', '423', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (127, 'Sri Lanka', 'LK', '94', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (128, 'Lesotho', 'LS', '266', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (129, 'Lithuania', 'LT', '370', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (130, 'Luxembourg', 'LU', '352', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (131, 'Latvia', 'LV', '371', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (132, 'Macau', 'MO', '853', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (133, 'Saint Martin', 'MF', '590', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (134, 'Morocco', 'MA', '212', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (135, 'Monaco', 'MC', '377', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (136, 'Moldova', 'MD', '373', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (137, 'Madagascar', 'MG', '261', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (138, 'Maldives', 'MV', '960', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (139, 'Mexico', 'MX', '52', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (140, 'Marshall Islands', 'MH', '692', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (141, 'Macedonia', 'MK', '389', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (142, 'Mali', 'ML', '223', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (143, 'Malta', 'MT', '356', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (144, 'Myanmar', 'MM', '95', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (145, 'Montenegro', 'ME', '382', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (146, 'Mongolia', 'MN', '976', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (147, 'Northern Mariana Islands', 'MP', '1670', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (148, 'Mozambique', 'MZ', '258', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (149, 'Mauritania', 'MR', '222', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (150, 'Montserrat', 'MS', '1664', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (151, 'Martinique', 'MQ', '596', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (152, 'Mauritius', 'MU', '230', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (153, 'Malawi', 'MW', '265', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (154, 'Malaysia', 'MY', '60', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (155, 'Mayotte', 'YT', '262', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (156, 'Namibia', 'NA', '264', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (157, 'New Caledonia', 'NC', '687', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (158, 'Niger', 'NE', '227', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (159, 'Norfolk Island', 'NF', '672', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (160, 'Nigeria', 'NG', '234', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (161, 'Nicaragua', 'NI', '505', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (162, 'Niue', 'NU', '683', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (163, 'Netherlands', 'NL', '31', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (164, 'Norway', 'NO', '47', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (165, 'Nepal', 'NP', '977', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (166, 'Nauru', 'NR', '674', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (167, 'New Zealand', 'NZ', '64', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (168, 'Oman', 'OM', '968', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (169, 'Pakistan', 'PK', '92', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (170, 'Panama', 'PA', '507', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (171, 'Pitcairn Islands', 'PN', '64', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (172, 'Peru', 'PE', '51', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (173, 'Philippines', 'PH', '63', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (174, 'Palau', 'PW', '680', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (175, 'Papua New Guinea', 'PG', '675', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (176, 'Poland', 'PL', '48', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (177, 'Puerto Rico', 'PR', '1787', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (178, 'North Korea', 'KP', '850', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (179, 'Portugal', 'PT', '351', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (180, 'Paraguay', 'PY', '595', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (181, 'Palestine', 'PS', '970', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (182, 'French Polynesia', 'PF', '689', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (183, 'Qatar', 'QA', '974', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (184, 'Réunion', 'RE', '262', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (185, 'Romania', 'RO', '40', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (186, 'Russia', 'RU', '7', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (187, 'Rwanda', 'RW', '250', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (188, 'Saudi Arabia', 'SA', '966', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (189, 'Sudan', 'SD', '249', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (190, 'Senegal', 'SN', '221', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (191, 'Singapore', 'SG', '65', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (192, 'South Georgia', 'GS', '500', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (193, 'Svalbard and Jan Mayen', 'SJ', '4779', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (194, 'Solomon Islands', 'SB', '677', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (195, 'Sierra Leone', 'SL', '232', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (196, 'El Salvador', 'SV', '503', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (197, 'San Marino', 'SM', '378', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (198, 'Somalia', 'SO', '252', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (199, 'Saint Pierre and Miquelon', 'PM', '508', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (200, 'Serbia', 'RS', '381', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (201, 'South Sudan', 'SS', '211', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (202, 'São Tomé and Príncipe', 'ST', '239', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (203, 'Suriname', 'SR', '597', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (204, 'Slovakia', 'SK', '421', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (205, 'Slovenia', 'SI', '386', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (206, 'Sweden', 'SE', '46', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (207, 'Swaziland', 'SZ', '268', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (208, 'Sint Maarten', 'SX', '1721', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (209, 'Seychelles', 'SC', '248', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (210, 'Syria', 'SY', '963', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (211, 'Turks and Caicos Islands', 'TC', '1649', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (212, 'Chad', 'TD', '235', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (213, 'Togo', 'TG', '228', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (214, 'Thailand', 'TH', '66', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (215, 'Tajikistan', 'TJ', '992', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (216, 'Tokelau', 'TK', '690', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (217, 'Turkmenistan', 'TM', '993', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (218, 'Timor-Leste', 'TL', '670', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (219, 'Tonga', 'TO', '676', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (220, 'Trinidad and Tobago', 'TT', '1868', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (221, 'Tunisia', 'TN', '216', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (222, 'Turkey', 'TR', '90', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (223, 'Tuvalu', 'TV', '688', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (224, 'Taiwan', 'TW', '886', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (225, 'Tanzania', 'TZ', '255', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (226, 'Uganda', 'UG', '256', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (227, 'Ukraine', 'UA', '380', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (228, 'Uruguay', 'UY', '598', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (229, 'United States', 'US', '1', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (230, 'Uzbekistan', 'UZ', '998', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (231, 'Vatican City', 'VA', '379', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (232, 'Saint Vincent and the Grenadines', 'VC', '1784', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (233, 'Venezuela', 'VE', '58', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (234, 'British Virgin Islands', 'VG', '1284', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (235, 'United States Virgin Islands', 'VI', '1340', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (236, 'Vietnam', 'VN', '84', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (237, 'Vanuatu', 'VU', '678', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (238, 'Wallis and Futuna', 'WF', '681', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (239, 'Samoa', 'WS', '685', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (240, 'Yemen', 'YE', '967', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (241, 'South Africa', 'ZA', '27', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (242, 'Zambia', 'ZM', '260', 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `country` VALUES (243, 'Zimbabwe', 'ZW', '263', 1, 1, 1, 1)"); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + } +} diff --git a/database/migrations/2020_06_18_162035_drop_column_checkin_from_property_table.php b/database/migrations/2020_06_18_162035_drop_column_checkin_from_property_table.php new file mode 100644 index 0000000..56fd915 --- /dev/null +++ b/database/migrations/2020_06_18_162035_drop_column_checkin_from_property_table.php @@ -0,0 +1,60 @@ +dropColumn('checkin_time'); + $table->dropColumn('checkout_time'); + }); + + DB::table('property_additional_info_key')->insert( + [ + [ + 'additional_info_key' => 'checkin_time', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'additional_info_key' => 'checkout_time', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + + ); + + DB::connection()->statement("UPDATE property_additional_info_key SET status = 0 WHERE additional_info_key = 'pet' "); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property', function (Blueprint $table) { + $table->string('checkin_time',50)->nullable(); + $table->string('checkout_time',50)->nullable(); + }); + } +} diff --git a/database/migrations/2020_06_18_162612_add_column_property_table_country_field.php b/database/migrations/2020_06_18_162612_add_column_property_table_country_field.php new file mode 100644 index 0000000..a05ab7d --- /dev/null +++ b/database/migrations/2020_06_18_162612_add_column_property_table_country_field.php @@ -0,0 +1,26 @@ +string('country',5)->after('destination_id')->nullable(); + + }); + + Schema::table('property', function (Blueprint $table) { + $table->foreign('country')->references('country_code')->on('country'); + }); + } + + + public function down() + { + + } +} diff --git a/database/migrations/2020_06_18_173416_add_column_country_table_status_field.php b/database/migrations/2020_06_18_173416_add_column_country_table_status_field.php new file mode 100644 index 0000000..dde2fd1 --- /dev/null +++ b/database/migrations/2020_06_18_173416_add_column_country_table_status_field.php @@ -0,0 +1,33 @@ +tinyInteger('status')->after('phone_code')->default(1); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('country', function (Blueprint $table) { + $table->dropColumn('status'); + }); + } +} diff --git a/database/migrations/2020_06_19_093503_change_columns_property_table.php b/database/migrations/2020_06_19_093503_change_columns_property_table.php new file mode 100644 index 0000000..cb690de --- /dev/null +++ b/database/migrations/2020_06_19_093503_change_columns_property_table.php @@ -0,0 +1,38 @@ +string('extension', 10)->after('phone')->nullable(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_executive', function (Blueprint $table) { + $table->dropColumn('extension'); + }); + } +} diff --git a/database/migrations/2020_06_19_105603_add_columns_to_user_table.php b/database/migrations/2020_06_19_105603_add_columns_to_user_table.php new file mode 100644 index 0000000..5d6909a --- /dev/null +++ b/database/migrations/2020_06_19_105603_add_columns_to_user_table.php @@ -0,0 +1,35 @@ +string('exclude_occupancy', 500)->after('max_child')->nullable(); + }); + } + + + public function down() + { + Schema::table('property_room', function (Blueprint $table) { + $table->dropColumn('exclude_occupancy'); + }); + } +} diff --git a/database/migrations/2020_06_25_162442_change_columns_property_executive_table.php b/database/migrations/2020_06_25_162442_change_columns_property_executive_table.php new file mode 100644 index 0000000..17ca8ad --- /dev/null +++ b/database/migrations/2020_06_25_162442_change_columns_property_executive_table.php @@ -0,0 +1,39 @@ +tinyInteger('is_application')->after('status')->default(0); + $table->tinyInteger('is_published')->after('is_application')->default(0); + }); + + DB::statement("ALTER TABLE language MODIFY COLUMN code VARCHAR(10) NOT NULL"); + + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('language')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::connection()->statement("INSERT INTO `language` VALUES (1, 'af', 'Afrikaans', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (2, 'af_ZA', 'Afrikaans (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (3, 'ar', 'Arabic', 1, 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (4, 'ar_AE', 'Arabic (U.A.E.)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (5, 'ar_BH', 'Arabic (Bahrain)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (6, 'ar_DZ', 'Arabic (Algeria)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (7, 'ar_EG', 'Arabic (Egypt)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (8, 'ar_IQ', 'Arabic (Iraq)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (9, 'ar_JO', 'Arabic (Jordan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (10, 'ar_KW', 'Arabic (Kuwait)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (11, 'ar_LB', 'Arabic (Lebanon)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (12, 'ar_LY', 'Arabic (Libya)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (13, 'ar_MA', 'Arabic (Morocco)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (14, 'ar_OM', 'Arabic (Oman)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (15, 'ar_QA', 'Arabic (Qatar)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (16, 'ar_SA', 'Arabic (Saudi Arabia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (17, 'ar_SY', 'Arabic (Syria)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (18, 'ar_TN', 'Arabic (Tunisia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (19, 'ar_YE', 'Arabic (Yemen)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (20, 'az', 'Azeri (Latin)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (21, 'az_AZ', 'Azeri (Cyrillic) (Azerbaijan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (22, 'be', 'Belarusian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (23, 'be_BY', 'Belarusian (Belarus)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (24, 'bg', 'Bulgarian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (25, 'bg_BG', 'Bulgarian (Bulgaria)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (26, 'bs_BA', 'Bosnian (Bosnia and Herzegovina)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (27, 'ca', 'Catalan', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (28, 'ca_ES', 'Catalan (Spain)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (29, 'cs', 'Czech', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (30, 'cs_CZ', 'Czech (Czech Republic)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (31, 'cy', 'Welsh', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (32, 'cy_GB', 'Welsh (United Kingdom)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (33, 'da', 'Danish', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (34, 'da_DK', 'Danish (Denmark)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (35, 'de', 'German', 1, 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (36, 'de_AT', 'German (Austria)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (37, 'de_CH', 'German (Switzerland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (38, 'de_DE', 'German (Germany)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (39, 'de_LI', 'German (Liechtenstein)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (40, 'de_LU', 'German (Luxembourg)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (41, 'dv', 'Divehi', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (42, 'dv_MV', 'Divehi (Maldives)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (43, 'el', 'Greek', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (44, 'el_GR', 'Greek (Greece)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (45, 'en', 'English', 1, 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (46, 'en_AU', 'English (Australia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (47, 'en_BZ', 'English (Belize)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (48, 'en_CA', 'English (Canada)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (49, 'en_CB', 'English (Caribbean)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (50, 'en_GB', 'English (United Kingdom)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (51, 'en_IE', 'English (Ireland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (52, 'en_JM', 'English (Jamaica)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (53, 'en_NZ', 'English (New Zealand)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (54, 'en_PH', 'English (Republic of the Philippines)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (55, 'en_TT', 'English (Trinidad and Tobago)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (56, 'en_US', 'English (United States)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (57, 'en_ZA', 'English (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (58, 'en_ZW', 'English (Zimbabwe)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (59, 'eo', 'Esperanto', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (60, 'es', 'Spanish', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (61, 'es_AR', 'Spanish (Argentina)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (62, 'es_BO', 'Spanish (Bolivia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (63, 'es_CL', 'Spanish (Chile)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (64, 'es_CO', 'Spanish (Colombia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (65, 'es_CR', 'Spanish (Costa Rica)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (66, 'es_DO', 'Spanish (Dominican Republic)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (67, 'es_EC', 'Spanish (Ecuador)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (68, 'es_ES', 'Spanish (Spain)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (69, 'es_GT', 'Spanish (Guatemala)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (70, 'es_HN', 'Spanish (Honduras)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (71, 'es_MX', 'Spanish (Mexico)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (72, 'es_NI', 'Spanish (Nicaragua)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (73, 'es_PA', 'Spanish (Panama)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (74, 'es_PE', 'Spanish (Peru)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (75, 'es_PR', 'Spanish (Puerto Rico)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (76, 'es_PY', 'Spanish (Paraguay)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (77, 'es_SV', 'Spanish (El Salvador)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (78, 'es_UY', 'Spanish (Uruguay)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (79, 'es_VE', 'Spanish (Venezuela)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (80, 'et', 'Estonian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (81, 'et_EE', 'Estonian (Estonia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (82, 'eu', 'Basque', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (83, 'eu_ES', 'Basque (Spain)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (84, 'fa', 'Farsi', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (85, 'fa_IR', 'Farsi (Iran)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (86, 'fi', 'Finnish', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (87, 'fi_FI', 'Finnish (Finland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (88, 'fo', 'Faroese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (89, 'fo_FO', 'Faroese (Faroe Islands)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (90, 'fr', 'French', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (91, 'fr_BE', 'French (Belgium)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (92, 'fr_CA', 'French (Canada)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (93, 'fr_CH', 'French (Switzerland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (94, 'fr_FR', 'French (France)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (95, 'fr_LU', 'French (Luxembourg)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (96, 'fr_MC', 'French (Principality of Monaco)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (97, 'gl', 'Galician', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (98, 'gl_ES', 'Galician (Spain)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (99, 'gu', 'Gujarati', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (100, 'gu_IN', 'Gujarati (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (101, 'he', 'Hebrew', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (102, 'he_IL', 'Hebrew (Israel)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (103, 'hi', 'Hindi', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (104, 'hi_IN', 'Hindi (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (105, 'hr', 'Croatian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (106, 'hr_BA', 'Croatian (Bosnia and Herzegovina)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (107, 'hr_HR', 'Croatian (Croatia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (108, 'hu', 'Hungarian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (109, 'hu_HU', 'Hungarian (Hungary)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (110, 'hy', 'Armenian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (111, 'hy_AM', 'Armenian (Armenia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (112, 'id', 'Indonesian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (113, 'id_ID', 'Indonesian (Indonesia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (114, 'is', 'Icelandic', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (115, 'is_IS', 'Icelandic (Iceland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (116, 'it', 'Italian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (117, 'it_CH', 'Italian (Switzerland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (118, 'it_IT', 'Italian (Italy)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (119, 'ja', 'Japanese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (120, 'ja_JP', 'Japanese (Japan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (121, 'ka', 'Georgian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (122, 'ka_GE', 'Georgian (Georgia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (123, 'kk', 'Kazakh', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (124, 'kk_KZ', 'Kazakh (Kazakhstan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (125, 'kn', 'Kannada', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (126, 'kn_IN', 'Kannada (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (127, 'ko', 'Korean', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (128, 'ko_KR', 'Korean (Korea)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (129, 'kok', 'Konkani', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (130, 'kok_IN', 'Konkani (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (131, 'ky', 'Kyrgyz', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (132, 'ky_KG', 'Kyrgyz (Kyrgyzstan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (133, 'lt', 'Lithuanian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (134, 'lt_LT', 'Lithuanian (Lithuania)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (135, 'lv', 'Latvian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (136, 'lv_LV', 'Latvian (Latvia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (137, 'mi', 'Maori', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (138, 'mi_NZ', 'Maori (New Zealand)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (139, 'mk', 'FYRO Macedonian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (140, 'mk_MK', 'FYRO Macedonian (Former Yugoslav Republic of ', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (141, 'mn', 'Mongolian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (142, 'mn_MN', 'Mongolian (Mongolia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (143, 'mr', 'Marathi', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (144, 'mr_IN', 'Marathi (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (145, 'ms', 'Malay', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (146, 'ms_BN', 'Malay (Brunei Darussalam)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (147, 'ms_MY', 'Malay (Malaysia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (148, 'mt', 'Maltese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (149, 'mt_MT', 'Maltese (Malta)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (150, 'nb', 'Norwegian (Bokm?l)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (151, 'nb_NO', 'Norwegian (Bokm?l) (Norway)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (152, 'nl', 'Dutch', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (153, 'nl_BE', 'Dutch (Belgium)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (154, 'nl_NL', 'Dutch (Netherlands)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (155, 'nn_NO', 'Norwegian (Nynorsk) (Norway)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (156, 'ns', 'Northern Sotho', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (157, 'ns_ZA', 'Northern Sotho (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (158, 'pa', 'Punjabi', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (159, 'pa_IN', 'Punjabi (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (160, 'pl', 'Polish', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (161, 'pl_PL', 'Polish (Poland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (162, 'ps', 'Pashto', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (163, 'ps_AR', 'Pashto (Afghanistan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (164, 'pt', 'Portuguese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (165, 'pt_BR', 'Portuguese (Brazil)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (166, 'pt_PT', 'Portuguese (Portugal)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (167, 'qu', 'Quechua', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (168, 'qu_BO', 'Quechua (Bolivia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (169, 'qu_EC', 'Quechua (Ecuador)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (170, 'qu_PE', 'Quechua (Peru)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (171, 'ro', 'Romanian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (172, 'ro_RO', 'Romanian (Romania)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (173, 'ru', 'Russian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (174, 'ru_RU', 'Russian (Russia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (175, 'sa', 'Sanskrit', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (176, 'sa_IN', 'Sanskrit (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (177, 'se', 'Sami (Northern)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (178, 'se_FI', 'Sami (Northern) (Finland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (179, 'se_NO', 'Sami (Northern) (Norway)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (180, 'se_SE', 'Sami (Northern) (Sweden)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (181, 'sk', 'Slovak', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (182, 'sk_SK', 'Slovak (Slovakia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (183, 'sl', 'Slovenian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (184, 'sl_SI', 'Slovenian (Slovenia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (185, 'sq', 'Albanian', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (186, 'sq_AL', 'Albanian (Albania)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (187, 'sr_BA', 'Serbian (Cyrillic) (Bosnia and Herzegovina)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (188, 'sr_SP', 'Serbian (Cyrillic) (Serbia and Montenegro)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (189, 'sv', 'Swedish', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (190, 'sv_FI', 'Swedish (Finland)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (191, 'sv_SE', 'Swedish (Sweden)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (192, 'sw', 'Swahili', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (193, 'sw_KE', 'Swahili (Kenya)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (194, 'syr', 'Syriac', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (195, 'syr_SY', 'Syriac (Syria)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (196, 'ta', 'Tamil', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (197, 'ta_IN', 'Tamil (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (198, 'te', 'Telugu', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (199, 'te_IN', 'Telugu (India)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (200, 'th', 'Thai', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (201, 'th_TH', 'Thai (Thailand)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (202, 'tl', 'Tagalog', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (203, 'tl_PH', 'Tagalog (Philippines)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (204, 'tn', 'Tswana', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (205, 'tn_ZA', 'Tswana (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (206, 'tr', 'Turkish', 1, 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (207, 'tr_TR', 'Turkish (Turkey)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (208, 'ts', 'Tsonga', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (209, 'tt', 'Tatar', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (210, 'tt_RU', 'Tatar (Russia)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (211, 'uk', 'Ukrainian', 1, 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (212, 'uk_UA', 'Ukrainian (Ukraine)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (213, 'ur', 'Urdu', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (214, 'ur_PK', 'Urdu (Islamic Republic of Pakistan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (215, 'uz', 'Uzbek (Latin)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (216, 'uz_UZ', 'Uzbek (Cyrillic) (Uzbekistan)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (217, 'vi', 'Vietnamese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (218, 'vi_VN', 'Vietnamese (Viet Nam)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (219, 'xh', 'Xhosa', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (220, 'xh_ZA', 'Xhosa (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (221, 'zh', 'Chinese', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (222, 'zh_CN', 'Chinese (S)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (223, 'zh_HK', 'Chinese (Hong Kong)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (224, 'zh_MO', 'Chinese (Macau)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (225, 'zh_SG', 'Chinese (Singapore)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (226, 'zh_TW', 'Chinese (T)', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (227, 'zu', 'Zulu', 1, 0, 0, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `language` VALUES (228, 'zu_ZA', 'Zulu (South Africa)', 1, 0, 0, 1, 1, 1, 1)"); + + Schema::create('language_base', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('key',100)->unique(); + $table->string('hashed',45)->nullable(); + $table->string('code',10); + $table->mediumText('text'); + $table->mediumText('description')->nullable(); + $table->tinyInteger('status')->default(0); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('language_base', function (Blueprint $table) { + $table->foreign('code')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + + Schema::create('language_translate', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedBigInteger('base_id'); + $table->string('key',100); + $table->string('code',10); + $table->mediumText('text')->nullable(); + $table->tinyInteger('status')->default(0); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('language_translate', function (Blueprint $table) { + $table->foreign('base_id')->references('id')->on('language_base'); + $table->foreign('key')->references('key')->on('language_base'); + $table->foreign('code')->references('code')->on('language'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_29_111217_add_data_to_property_additional_info_key.php b/database/migrations/2020_06_29_111217_add_data_to_property_additional_info_key.php new file mode 100644 index 0000000..06749e6 --- /dev/null +++ b/database/migrations/2020_06_29_111217_add_data_to_property_additional_info_key.php @@ -0,0 +1,48 @@ +insert( + [ + [ + 'additional_info_key' => 'locale_name_language', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'additional_info_key' => 'locale_name', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::connection()->statement("DELETE FROM property_additional_info_key WHERE additional_info_key = 'locale_name_language' "); + DB::connection()->statement("DELETE FROM property_additional_info_key WHERE additional_info_key = 'locale_name' "); + } +} diff --git a/database/migrations/2020_06_30_171839_add_column_room_bed_type.php b/database/migrations/2020_06_30_171839_add_column_room_bed_type.php new file mode 100644 index 0000000..5b26bcd --- /dev/null +++ b/database/migrations/2020_06_30_171839_add_column_room_bed_type.php @@ -0,0 +1,32 @@ +string('icon',30)->after('name')->nullable(); + }); + + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 1"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 2"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 3"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 4"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 5"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 6"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 7"); + DB::connection()->statement("UPDATE property_room_bed_type SET icon = '1.png' WHERE id = 8"); + } + + + public function down() + { + Schema::table('property_room_bed_type', function (Blueprint $table) { + $table->dropColumn('icon'); + }); + } +} diff --git a/database/migrations/2020_06_30_174837_change_columns_executive_contact_name_and_property_id_fields.php b/database/migrations/2020_06_30_174837_change_columns_executive_contact_name_and_property_id_fields.php new file mode 100644 index 0000000..27f88da --- /dev/null +++ b/database/migrations/2020_06_30_174837_change_columns_executive_contact_name_and_property_id_fields.php @@ -0,0 +1,34 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + Schema::table('property_executive', function (Blueprint $table) { + $table->unique(['property_id', 'name_surname']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_06_30_182422_update_data_to_site_config.php b/database/migrations/2020_06_30_182422_update_data_to_site_config.php new file mode 100644 index 0000000..8b1f779 --- /dev/null +++ b/database/migrations/2020_06_30_182422_update_data_to_site_config.php @@ -0,0 +1,37 @@ +where('config_key' , 'profile_rate_mapping')->update(['config_value_json' => $profileRateMapping]); + DB::table('site_config')->where('config_key' , 'hint_list')->update(['config_value_json' => $profileHint]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + } +} diff --git a/database/migrations/2020_07_02_092052_drop_locale_tables.php b/database/migrations/2020_07_02_092052_drop_locale_tables.php new file mode 100644 index 0000000..4a95c2c --- /dev/null +++ b/database/migrations/2020_07_02_092052_drop_locale_tables.php @@ -0,0 +1,45 @@ +dropColumn('destination_id'); + }); + Schema::dropIfExists('currency_locale'); + Schema::dropIfExists('language_locale'); + Schema::dropIfExists('permission_locale'); + Schema::dropIfExists('property_additional_info_key_locale'); + Schema::dropIfExists('property_channel_category_locale'); + Schema::dropIfExists('property_content_category_locale'); + Schema::dropIfExists('property_executive_type_locale'); + Schema::dropIfExists('property_fact_attribute_locale'); + Schema::dropIfExists('property_fact_locale'); + Schema::dropIfExists('property_photo_category_locale'); + Schema::dropIfExists('property_room_bed_type_locale'); + Schema::dropIfExists('property_room_type_locale'); + Schema::dropIfExists('property_type_locale'); + Schema::dropIfExists('property_unit_locale'); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_07_03_143603_add_language_key_to_tables.php b/database/migrations/2020_07_03_143603_add_language_key_to_tables.php new file mode 100644 index 0000000..bade28c --- /dev/null +++ b/database/migrations/2020_07_03_143603_add_language_key_to_tables.php @@ -0,0 +1,75 @@ +string('language_key',128)->after('name')->nullable(); + }); + Schema::table('language', function (Blueprint $table) { + $table->string('language_key',128)->after('name')->nullable(); + }); + Schema::table('property_channel_category', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_content_category', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_executive_type', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_fact_attribute', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_fact', function (Blueprint $table) { + $table->string('language_key',250)->after('name')->nullable(); + }); + Schema::table('property_photo_category', function (Blueprint $table) { + $table->string('language_key',80)->after('category_name')->nullable(); + }); + Schema::table('property_room_bed_type', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_room_type', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_type', function (Blueprint $table) { + $table->string('language_key',255)->after('name')->nullable(); + }); + Schema::table('property_unit', function (Blueprint $table) { + $table->string('language_key',128)->after('name')->nullable(); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('currency', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('language', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_channel_category', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_content_category', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_executive_type', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_fact_attribute', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_fact', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_photo_category', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_room_bed_type', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_room_type', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_type', function (Blueprint $table) { $table->dropColumn('language_key'); }); + Schema::table('property_unit', function (Blueprint $table) { $table->dropColumn('language_key'); }); + } +} diff --git a/database/migrations/2020_07_07_093527_create_table_property_room_view_table.php b/database/migrations/2020_07_07_093527_create_table_property_room_view_table.php new file mode 100644 index 0000000..93ee25f --- /dev/null +++ b/database/migrations/2020_07_07_093527_create_table_property_room_view_table.php @@ -0,0 +1,42 @@ +bigIncrements('id'); + $table->string('name',100); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_room_view_type', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_view_type'); + } +} diff --git a/database/migrations/2020_07_07_094356_create_property_room_view_mapping_table.php b/database/migrations/2020_07_07_094356_create_property_room_view_mapping_table.php new file mode 100644 index 0000000..087a5b7 --- /dev/null +++ b/database/migrations/2020_07_07_094356_create_property_room_view_mapping_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + $table->unsignedBigInteger('room_id'); + $table->unsignedBigInteger('room_view_type_id'); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + }); + + Schema::table('property_room_view_mapping', function (Blueprint $table) { + $table->unique(['room_id','room_view_type_id']); + $table->foreign('room_id')->references('id')->on('property_room'); + $table->foreign('room_view_type_id')->references('id')->on('property_room_view_type'); + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_room_view_mapping'); + } +} diff --git a/database/migrations/2020_07_07_134958_add_data_property_type_table.php b/database/migrations/2020_07_07_134958_add_data_property_type_table.php new file mode 100644 index 0000000..e487383 --- /dev/null +++ b/database/migrations/2020_07_07_134958_add_data_property_type_table.php @@ -0,0 +1,327 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::table('property_type')->insert( + [ + [ + 'name' => '1 Star Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => '2 Star Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => '3 Star Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => '4 Star Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => '5 Star Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Apart Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Boutique Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Bungolow', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Cabin', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Capsule hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Castle', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Chalet', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Condo', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Cottage', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Country house', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Farm stay', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Guest house', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Hostel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Lodge', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Love hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Motel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Pansion', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Private Holiday Home', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Ranch', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Residence', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Resort', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Ryokan', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Safari tentalow', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Suit Hotel', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Thermal Facility ', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Town House', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Tree House ', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + } +} + diff --git a/database/migrations/2020_07_07_143007_add_data_property_room_type_table.php b/database/migrations/2020_07_07_143007_add_data_property_room_type_table.php new file mode 100644 index 0000000..62541d2 --- /dev/null +++ b/database/migrations/2020_07_07_143007_add_data_property_room_type_table.php @@ -0,0 +1,255 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::table('property_room_type')->insert( + [ + [ + 'name' => 'Accessible Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Apartment', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Attic', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Bungalow', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Club Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Deluxe', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Economy', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Family Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Grand Suite', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Junior Suite', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'King suite', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Pent House', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Premium Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Standart Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Suite', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Superior', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Villa', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Connection Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Studio Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Roh Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Loft Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Cabana Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Dublex Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Honeymoon Room', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + + ); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_room_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + } +} diff --git a/database/migrations/2020_07_07_144833_add_data_property_room_bed_type_table.php b/database/migrations/2020_07_07_144833_add_data_property_room_bed_type_table.php new file mode 100644 index 0000000..f574e90 --- /dev/null +++ b/database/migrations/2020_07_07_144833_add_data_property_room_bed_type_table.php @@ -0,0 +1,145 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::table('property_room_bed_type')->insert( + [ + [ + 'name' => 'Bunk Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Double Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'French Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Futon', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'King Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Queen Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Single Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Sofa Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Twin Bed', + 'language_key' => '', + 'icon' => '1.png', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + + ] + + ); + + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_executive_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + $result = DB::table('property_executive_type')->insert( + [ + 'name' => 'Accounting', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_room_bed_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + } +} diff --git a/database/migrations/2020_07_07_145651_create_property_web_table.php b/database/migrations/2020_07_07_145651_create_property_web_table.php new file mode 100644 index 0000000..07f5dfd --- /dev/null +++ b/database/migrations/2020_07_07_145651_create_property_web_table.php @@ -0,0 +1,73 @@ +increments('id'); + $table->string('name', 128)->unique(); + $table->string('folder_name', 200); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + }); + + + Schema::create('property_web', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->integer('property_id')->unsigned(); + $table->string('domain', 50)->unique(); + $table->string('default_language', 10)->default('en_EN'); + $table->unsignedInteger('template_id')->default(1); + $table->string('token',128)->unique(); + $table->tinyInteger('status')->default(1); + $table->unsignedInteger('created_by'); + $table->unsignedInteger('updated_by'); + $table->integer('created_at'); + $table->integer('updated_at'); + + $table->foreign('property_id')->references('id')->on('property'); + $table->foreign('template_id')->references('id')->on('property_web_template'); + + }); + + DB::table('property_web_template')->insert( + [ + [ + 'name' => 'Default Template', + 'folder_name' => 'default', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + ] + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('property_web'); + Schema::dropIfExists('property_web_template'); + } +} diff --git a/database/migrations/2020_07_07_152015_add_data_property_executive_type_table.php b/database/migrations/2020_07_07_152015_add_data_property_executive_type_table.php new file mode 100644 index 0000000..0a0ea6d --- /dev/null +++ b/database/migrations/2020_07_07_152015_add_data_property_executive_type_table.php @@ -0,0 +1,119 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::table('property_executive_type')->insert( + [ + [ + 'name' => 'Accounting', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Activity', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Finance', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Front Office', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Group', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Manager', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Reservation', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Sales and Marketing', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Others', + 'language_key' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_executive_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + } +} diff --git a/database/migrations/2020_07_08_102336_clear_unique_property_executive_table.php b/database/migrations/2020_07_08_102336_clear_unique_property_executive_table.php new file mode 100644 index 0000000..9a89466 --- /dev/null +++ b/database/migrations/2020_07_08_102336_clear_unique_property_executive_table.php @@ -0,0 +1,30 @@ +dropUnique(['property_id', 'name_surname']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_07_08_114601_change_property_chain_table.php b/database/migrations/2020_07_08_114601_change_property_chain_table.php new file mode 100644 index 0000000..f7b084a --- /dev/null +++ b/database/migrations/2020_07_08_114601_change_property_chain_table.php @@ -0,0 +1,3378 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + Schema::table('property_chain', function (Blueprint $table) { + $table->integer('priority')->after('loyalty')->nullable(); + }); + + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1, 'Independent', 'null', 1, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2, '118 Hotel', 'null', 2, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3, '13 Coins Hotels & Resorts', 'null', 3, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (4, '1589 Hotels', 'null', 4, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (5, '1834 Hotels', 'null', 5, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (6, '1st Arabat hotel', 'null', 6, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (7, '1st for Orlando', 'null', 7, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (8, '1st Inn Hotel', 'null', 8, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (9, '226 Hospitality', 'null', 9, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (10, '22nd Residences', 'null', 10, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (11, '24 Guesthouse', 'null', 11, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (12, '2Home_JSC', 'null', 12, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (13, '2ndhomes_C', 'null', 13, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (14, '3 Tranches Home', 'null', 14, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (15, '5 Star Bali Villa', 'null', 15, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (16, '5 Star Villa Holidays_C', 'null', 16, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (17, '5 Yue Hotel Group', 'null', 17, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (18, '5Footway.Inn', 'null', 18, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (19, '7Heaven Vacation_C', 'null', 19, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (20, '8 Residence', 'null', 20, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (21, '85 Sky Tower CTraveller Suit', 'null', 21, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (22, '8Hotels Collection', 'null', 22, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (23, '9 square', 'null', 23, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (24, 'A and C housing', 'null', 24, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (25, 'A Perfect Stay', 'null', 25, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (26, 'A&EM Hotel Group', 'null', 28, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (27, 'A&O Hotels and Hostels', 'null', 29, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (28, 'A.T. Home', 'null', 26, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (29, 'Abadi Sewa Apartemen', 'null', 30, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (30, 'Abba Hoteles', 'null', 31, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (31, 'Abby Hotel', 'null', 32, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (32, 'ABC Accommodation', 'null', 33, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (33, 'abcds', 'null', 34, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (34, 'Abdi jaya Homestay', 'null', 35, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (35, 'Abdi Property Indonesia', 'null', 36, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (36, 'Abhijitanimation Property', 'null', 37, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (37, 'Abhinaya Wisata Bali', 'null', 38, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (38, 'Abidos Hotels', 'null', 39, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (39, 'Abode Homes', 'null', 40, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (40, 'Aboy', 'null', 41, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (41, 'AbraCasa Goa_C', 'null', 42, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (42, 'Absolute Resort & Hotels', 'null', 43, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (43, 'Abu Dhabi National Hotels', 'null', 44, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (44, 'Acappella', 'null', 45, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (45, 'Access', 'null', 46, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (46, 'Accom Noosa', 'null', 47, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (47, 'Accom Whitsundays', 'null', 48, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (48, 'Accomodation Sydney City', 'null', 49, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (49, 'Accor Hotels', 'null', 50, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (50, 'Ace Hotel', 'null', 51, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (51, 'Ace Residences', 'null', 52, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (52, 'ACHAT Hotels', 'null', 53, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (53, 'ACO Vacation Homes', 'null', 54, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (54, 'Acta Hotels', 'null', 55, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (55, 'Actual Paseo de Gracia', 'null', 56, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (56, 'Ada Waktu Villa', 'null', 57, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (57, 'Adaaran Resorts', 'null', 58, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (58, 'Adam Jyota', 'null', 59, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (59, 'Adam Villa Puncak', 'null', 60, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (60, 'Adamson', 'null', 61, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (61, 'Adaru', 'null', 62, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (62, 'Adelaide City Apartments', 'null', 63, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (63, 'Adi Hartawan Property', 'null', 64, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (64, 'Adi Kost', 'null', 65, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (65, 'Adimas Group', 'null', 66, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (66, 'Adina Apartments', 'null', 67, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (67, 'Adiwana Hotels & Resorts', 'null', 68, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (68, 'Advantage Vacation Homes_C', 'null', 69, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (69, 'Advena Hotels', 'null', 70, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (70, 'Adya Hotel', 'null', 71, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (71, 'Aero Hotels', 'null', 72, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (72, 'Aero Space', 'null', 73, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (73, 'AFP Apartment', 'null', 74, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (74, 'Afra Adjie', 'null', 75, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (75, 'Afribode', 'null', 76, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (76, 'Afribode Accomodation', 'null', 77, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (77, 'African Fiesta', 'null', 78, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (78, 'African Sky Hotels, Spa and Resorts', 'null', 79, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (79, 'Agency Bridge', 'null', 80, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (80, 'Agency Test', 'null', 81, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (81, 'Agnes Pro', 'null', 82, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (82, 'Agnis_JP', 'null', 83, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (83, 'Agus', 'null', 84, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (84, 'AHA', 'null', 85, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (85, 'Ahmad Ripai', 'null', 86, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (86, 'AIRHOST', 'null', 94, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (87, 'Ain House', 'null', 87, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (88, 'AinB Apartments', 'null', 88, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (89, 'Airbest', 'null', 89, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (90, 'AirBnB Osaka', 'null', 90, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (91, 'Airbnbkirinji_JP', 'null', 91, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (92, 'Airbnbnb_JP', 'null', 92, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (93, 'Airhome_C', 'null', 93, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (94, 'AirM8 Apartments', 'null', 95, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (95, 'Airmanaged_C', 'null', 96, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (96, 'AirProfit_JP', 'null', 97, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (97, 'AirSapo', 'null', 98, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (98, 'Airxpress', 'null', 99, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (99, 'Aitken Spence Hotels', 'null', 100, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (100, 'Aiueo Real Estate', 'null', 101, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (101, 'AJ InterBridge Inc.', 'null', 102, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (102, 'Akihiro Nakakita', 'null', 103, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (103, 'Akiyama', 'null', 104, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (104, 'Akkaranand Property', 'null', 105, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (105, 'AKOM Apartments', 'null', 106, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (106, 'Al Ansar Group', 'null', 107, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (107, 'Al Aseel Group', 'null', 108, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (108, 'Al Diar Hotels', 'null', 109, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (109, 'Al Diyafah Group', 'null', 110, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (110, 'Al Eairy Group', 'null', 111, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (111, 'Al Farhan Group', 'null', 112, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (112, 'Al Hamra Group', 'null', 113, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (113, 'Al Khoory Group', 'null', 114, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (114, 'Al Massa Group', 'null', 115, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (115, 'Al Mohandes Group', 'null', 116, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (116, 'Al Muhaideb Hotels', 'null', 117, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (117, 'Al Mukhtara Group', 'null', 118, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (118, 'Al Nabarees Group', 'null', 119, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (119, 'Al Nahdi Group', 'null', 120, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (120, 'Al Yamama Group', 'null', 121, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (121, 'Alabama', 'null', 122, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (122, 'Alagon Hotels and Spa Group', 'null', 123, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (123, 'Alan Pasotto', 'null', 124, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (124, 'Alang Alang Indonesia', 'null', 125, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (125, 'Alegher Kata', 'null', 126, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (126, 'Alex Pattaya Properties', 'null', 127, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (127, 'Alexandre Hotels', 'null', 128, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (128, 'Alfonso\'s Place', 'null', 129, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (129, 'ALH Group', 'null', 130, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (130, 'Ali Fahmi', 'null', 131, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (131, 'Alila', 'null', 132, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (132, 'Alina Apartment', 'null', 133, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (133, 'Alissie Property', 'null', 134, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (134, 'Alkoclar Hotels', 'null', 135, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (135, 'All about furano', 'null', 136, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (136, 'All Phuket Real Estate', 'null', 137, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (137, 'Allen House', 'null', 138, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (138, 'Allo Maisons', 'null', 139, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (139, 'Allurepark Thijmse Berg_C', 'null', 140, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (140, 'Almira Kost Eksklusif', 'null', 141, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (141, 'Aloha Saigon', 'null', 142, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (142, 'Alona Treats & Travel Corporation', 'null', 143, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (143, 'Alotz', 'null', 144, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (144, 'Alpha Hotel Management', 'null', 145, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (145, 'Alpha Hotels and Resorts', 'null', 146, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (146, 'Alpha Solid', 'null', 147, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (147, 'Altis Hotels', 'null', 148, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (148, 'Alur natura Apartment', 'null', 149, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (149, 'Alva', 'null', 150, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (150, 'Alysia Aman', 'null', 151, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (151, 'AM Japan', 'null', 152, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (152, 'AM Resorts', 'null', 153, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (153, 'Amami Viaggi_C', 'null', 154, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (154, 'Aman Resorts', 'null', 155, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (155, 'Amanda Property', 'null', 156, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (156, 'Amaranth s.r.o.', 'null', 157, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (157, 'Amaya Resorts', 'null', 158, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (158, 'Amaze Balls', 'null', 159, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (159, 'Amazing Homes', 'null', 160, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (160, 'Amazing Revolution', 'null', 161, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (161, 'Amber Hotels', 'null', 162, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (162, 'Amelly', 'null', 163, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (163, 'Ameri Tel Inns', 'null', 164, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (164, 'Amerian Hoteles', 'null', 165, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (165, 'AmericInn', 'null', 166, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (166, 'Ameristar Casinos', 'null', 167, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (167, 'Amhsa Marina Hotels & Resorts', 'null', 168, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (168, 'Amora Hotels & Resorts', 'null', 169, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (169, 'Amore Mio Travel', 'null', 170, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (170, 'Amra', 'null', 171, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (171, 'AMResorts', 'null', 172, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (172, 'Amsterdam Hospitality', 'null', 173, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (173, 'AN Apartment HCMC', 'null', 174, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (174, 'An Nguyen Building Hanoi', 'null', 175, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (175, 'An Nhien', 'null', 176, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (176, 'An Phuoc Hung', 'null', 177, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (177, 'An Villa', 'null', 178, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (178, 'ANA Crowne Plaza', 'null', 179, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (179, 'Anabuki Space Share', 'null', 180, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (180, 'Anang Property', 'null', 181, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (181, 'Ancasa', 'null', 182, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (182, 'Anchor Abode', 'null', 183, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (183, 'And Chill_C', 'null', 184, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (184, 'Andes', 'null', 185, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (185, 'Anemon Hotels', 'null', 186, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (186, 'Anest', 'null', 187, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (187, 'Aneto Iznajar', 'null', 188, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (188, 'Angel Fredericha', 'null', 189, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (189, 'Angela Ylagan', 'null', 190, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (190, 'Anggit Group', 'null', 191, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (191, 'Anggrek Room', 'null', 192, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (192, 'Anggun Bromo Homestay', 'null', 193, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (193, 'Angiri Resorts', 'null', 194, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (194, 'Aninuan Apartment', 'null', 195, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (195, 'Anjani', 'null', 196, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (196, 'Anlink', 'null', 197, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (197, 'Anna Maria Island Beach Rentals_C', 'null', 198, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (198, 'Antoine\'s Apartments', 'null', 199, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (199, 'Antony Lee Property', 'null', 200, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (200, 'Anwar', 'null', 201, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (201, 'Anyaa Property', 'null', 202, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (202, 'Aonanta Pool Villa', 'null', 203, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (203, 'APA Hotels', 'null', 204, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (204, 'Apartemen Gading Nias Residence', 'null', 205, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (205, 'Aparteon', 'null', 206, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (206, 'ApartLux', 'null', 207, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (207, 'Apartmani Nedjeljko_C', 'null', 208, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (208, 'Apartment Group by 4 Property', 'null', 209, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (209, 'Apartment Maller_C', 'null', 210, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (210, 'Apartment Rukonic', 'null', 211, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (211, 'Apartment Service', 'null', 212, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (212, 'Apartment Tamansari Panoramic Group', 'null', 213, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (213, 'Apartment2c', 'null', 214, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (214, 'Apartments Villa Mariel', 'null', 215, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (215, 'Apavou Hotels-Resorts & Spa', 'null', 216, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (216, 'Apex Hotels', 'null', 217, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (217, 'Apip', 'null', 218, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (218, 'Appart\'City', 'null', 219, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (219, 'Apple 1', 'null', 220, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (220, 'Apple Apartments Group', 'null', 221, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (221, 'Aqua Hotels and Resorts', 'null', 222, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (222, 'Aqua-Aston Hospitality', 'null', 223, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (223, 'Aqueen Hotel & Resorts', 'null', 224, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (224, 'Aquis Hotels and Resorts', 'null', 225, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (225, 'Ara & Maru', 'null', 226, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (226, 'Araia Room', 'null', 227, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (227, 'Aranwa Hotels Resorts & Spas', 'null', 228, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (228, 'Aravis Holidays_C', 'null', 229, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (229, 'Arc Avenue Hotels', 'null', 230, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (230, 'Arcadia Hotels', 'null', 231, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (231, 'Arcantis Hotels', 'null', 232, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (232, 'Arcat Houser SL - APKEYS', 'null', 233, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (233, 'Archipelago International', 'null', 234, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (234, 'Arcotel Hotels', 'null', 235, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (235, 'Arenaa', 'null', 236, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (236, 'ARENDAIZRAIL Apartments', 'null', 237, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (237, 'Arenty', 'null', 238, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (238, 'Arfan Maulana', 'null', 239, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (239, 'Arfe Room', 'null', 240, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (240, 'Argyle Group', 'null', 241, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (241, 'Ari', 'null', 242, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (242, 'Ari Wiryastini', 'null', 243, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (243, 'Ariasa Made', 'null', 244, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (244, 'Ario Yosinarta', 'null', 245, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (245, 'Ariyanti Tamansari Panorama', 'null', 246, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (246, 'Arnatt Property', 'null', 247, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (247, 'ARRA Accommodation Group', 'null', 248, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (248, 'Arsya Rooms', 'null', 249, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (249, 'Art Series Hotels', 'null', 250, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (250, 'Arthawidyan Homestay', 'null', 251, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (251, 'ARTIST', 'null', 253, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (252, 'Artis Suite & Villa', 'null', 252, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (253, 'Artotel', 'null', 254, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (254, 'Aryaduta Puncak Resort', 'null', 255, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (255, 'A\'s Azotea De Bohol', 'null', 27, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (256, 'As Usual', 'null', 256, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (257, 'Asa Property', 'null', 257, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (258, 'Asa Villas Property', 'null', 258, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (259, 'Ascott International', 'null', 259, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (260, 'Asep Rian', 'null', 260, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (261, 'Ashok Group', 'null', 261, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (262, 'Asia Holiday Retreats', 'null', 262, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (263, 'Asistee Business', 'null', 263, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (264, 'Aspen Parks', 'null', 264, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (265, 'Assetrive', 'null', 265, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (266, 'Assign Tax', 'null', 266, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (267, 'Assign Tax - India', 'null', 267, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (268, 'Assign Tax - Malay', 'null', 268, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (269, 'Assign Tax - SG', 'null', 269, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (270, 'Aston Hotels And Resorts', 'null', 270, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (271, 'Aston International', 'null', 271, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (272, 'Astotel', 'null', 272, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (273, 'ASURE Accommodation', 'null', 273, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (274, 'at Hotel Group', 'null', 274, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (275, 'Atahotels', 'null', 275, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (276, 'Atelier de Hoteles', 'null', 276, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (277, 'Athaya Homestay', 'null', 277, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (278, 'Atiram Hotels', 'null', 278, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (279, 'Atlas', 'null', 279, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (280, 'Atlas 46 Ramblas', 'null', 280, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (281, 'Atour Hotel', 'null', 281, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (282, 'atstushi nomoto', 'null', 282, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (283, 'Attitude Resorts', 'null', 283, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (284, 'Audrey Group', 'null', 284, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (285, 'Australian Home Away', 'null', 285, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (286, 'Australian Luxury Stays', 'null', 286, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (287, 'Austria Trend Hotels & Resorts', 'null', 287, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (288, 'Avantgarde Collection', 'null', 288, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (289, 'Avari Hotels', 'null', 289, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (290, 'AVE Hotels', 'null', 290, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (291, 'Avenida Tourist Homes SL', 'null', 291, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (292, 'Avilla Hospitality', 'null', 292, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (293, 'Avillion Group', 'null', 293, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (294, 'Axel Hotels', 'null', 294, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (295, 'Ayre Hoteles', 'null', 295, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (296, 'Ayu Destiana Group', 'null', 296, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (297, 'Ayu Group', 'null', 297, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (298, 'Ayu Place', 'null', 298, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (299, 'Azcarya Villa', 'null', 299, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (300, 'Azimut Hotels', 'null', 300, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (301, 'Azure Condotel Staycation', 'null', 301, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (302, 'Azure Online Marketing LTO', 'null', 302, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (303, 'B Vietnam', 'null', 303, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (304, 'B&B 22 House', 'null', 304, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (305, 'B&B Hotels', 'null', 305, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (306, 'B2 Hotel Group', 'null', 306, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (307, 'Baan Marwin Pool Villa Hua Hin', 'null', 307, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (308, 'Baan Natcha', 'null', 308, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (309, 'Baan Sabai Rama IV Service Apartment', 'null', 309, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (310, 'Baan Thai Lanna Pattaya', 'null', 310, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (311, 'Baan Tong Thip', 'null', 311, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (312, 'Baansawasdee', 'null', 312, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (313, 'Babylon Apartment', 'null', 313, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (314, 'Backpackers Haven', 'null', 314, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (315, 'Bacohome3', 'null', 315, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (316, 'Badra House', 'null', 316, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (317, 'Baguio Foggy Hills', 'null', 317, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (318, 'Bagus Home', 'null', 318, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (319, 'Bagus management', 'null', 319, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (320, 'Bahasa Villa', 'null', 320, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (321, 'Bahia Principe Hotels & Resorts', 'null', 321, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (322, 'Bai zhonghua', 'null', 322, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (323, 'Balai Condominiums', 'null', 323, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (324, 'Bali Dream Villa', 'null', 324, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (325, 'Bali Exception', 'null', 325, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (326, 'Bali Family Hospitality', 'null', 326, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (327, 'Bali Golden Living', 'null', 327, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (328, 'Bali Green Villa', 'null', 328, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (329, 'Bali Home', 'null', 329, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (330, 'Bali Home Holiday', 'null', 330, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (331, 'Bali Inside', 'null', 331, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (332, 'Bali Management Villas', 'null', 332, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (333, 'Bali Options', 'null', 333, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (334, 'Bali Sanur Home', 'null', 334, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (335, 'Bali Smart Management', 'null', 335, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (336, 'Bali Studio Apartment Group', 'null', 336, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (337, 'Bali Unique Stay', 'null', 337, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (338, 'Bali Villa Getaways', 'null', 338, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (339, 'Bali Villa Management', 'null', 339, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (340, 'Bali Villa Manager', 'null', 340, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (341, 'Bali Villas HVR', 'null', 341, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (342, 'Bali Villas R Us', 'null', 342, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (343, 'BaliOn Villas', 'null', 343, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (344, 'Baliwid Villa', 'null', 344, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (345, 'Balkondes Kembanglimus', 'null', 345, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (346, 'Balladins', 'null', 346, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (347, 'Balloon Group Global', 'null', 347, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (348, 'Balqis Group', 'null', 348, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (349, 'Bamboo Hotel Ubud', 'null', 349, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (350, 'Bamboo House Homestay', 'null', 350, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (351, 'Bamboo Nest', 'null', 351, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (352, 'Ban Tai Estate_C', 'null', 352, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (353, 'Banbridge Properties', 'null', 353, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (354, 'BangTaiestate', 'null', 354, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (355, 'Banhakeura', 'null', 355, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (356, 'Bans City', 'null', 356, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (357, 'Banyan Tree Hotels & Resorts', 'null', 357, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (358, 'Banyu Riris Villa', 'null', 358, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (359, 'Barceló Hotels & Resorts', 'null', 359, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (360, 'Barcelona Best Services_C', 'null', 360, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (361, 'BarcelonaForRent Apartments_C', 'null', 361, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (362, 'Barefoot Luxury Villas', 'null', 362, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (363, 'Baron Hotels & Resorts', 'null', 363, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (364, 'Bas Apartments', 'null', 364, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (365, 'Base Planning', 'null', 365, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (366, 'Basezero', 'null', 366, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (367, 'Basma Group', 'null', 367, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (368, 'Bastion Hotels', 'null', 368, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (369, 'Batiqa Hotels', 'null', 369, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (370, 'Batu Permai', 'null', 370, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (371, 'Batur Sunrise Guesthouse', 'null', 371, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (372, 'Bay Of Islands Holiday Homes', 'null', 372, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (373, 'Bay Point Golf Resort & Spa', 'null', 373, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (374, 'Bay Residence', 'null', 374, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (375, 'Bayu Pro', 'null', 375, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (376, 'Bayview International Hotels & Resorts', 'null', 376, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (377, 'BB', 'null', 377, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (378, 'BCN Stop', 'null', 378, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (379, 'BCN Urban Hotels', 'null', 379, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (380, 'Be happy', 'null', 380, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (381, 'Be Home', 'null', 381, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (382, 'Be Hostels', 'null', 382, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (383, 'BE LIVE HOTELS', 'null', 383, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (384, 'BEACH INN MAKASSAR', 'null', 384, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (385, 'Beach Retreats Vic', 'null', 385, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (386, 'Beachcomber Hotels', 'null', 386, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (387, 'Beachside Breaks', 'null', 387, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (388, 'Beds and Bars', 'null', 388, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (389, 'Bedsolving', 'null', 389, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (390, 'Beheermijnhuis_C', 'null', 390, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (391, 'Beinte Singko De Marso', 'null', 391, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (392, 'Bel Air Collection Resorts', 'null', 392, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (393, 'Bella Property', 'null', 393, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (394, 'Bella Villa Group', 'null', 394, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (395, 'Bella Vista Accommodation', 'null', 395, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (396, 'Bella Vista Waterfront', 'null', 396, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (397, 'Belmond', 'null', 397, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (398, 'Bengawan Residence 66', 'null', 398, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (399, 'Benikea', 'null', 399, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (400, 'Benx Napoli', 'null', 400, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (401, 'Berawa Beach Estate', 'null', 401, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (402, 'Berjaya Group', 'null', 402, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (403, 'Berjaya Hotels & Resorts', 'null', 403, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (404, 'Berlin Nawaputra', 'null', 404, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (405, 'Bernbon Condounit', 'null', 405, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (406, 'Bespoke Hotels', 'null', 406, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (407, 'Bespoke Residences', 'null', 407, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (408, 'Best Hotels', 'null', 408, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (409, 'Best inn Okinawa', 'null', 409, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (410, 'Best of Magnetic', 'null', 410, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (411, 'Best View Hotel', 'null', 411, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (412, 'Best Western International', 'null', 412, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (413, 'Bestbnb (Sogi)', 'null', 413, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (414, 'Beta Management', 'null', 414, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (415, 'Better Stay', 'null', 415, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (416, 'Better Vacations_C', 'null', 416, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (417, 'Bettoja Hotels', 'null', 417, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (418, 'Beyond a Room_C', 'null', 418, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (419, 'Bhadur Group', 'null', 419, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (420, 'BHMA Hotels and Resorts', 'null', 420, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (421, 'BHome Kim Ma', 'null', 421, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (422, 'BIG4 Holiday Parks', 'null', 424, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (423, 'Bicheno Holiday Rentals', 'null', 422, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (424, 'Big Apple Management, LLC_C', 'null', 423, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (425, 'Biliq Coliving', 'null', 425, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (426, 'Bill Knaggs Real Estate', 'null', 426, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (427, 'Billy PDS', 'null', 427, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (428, 'Biltmore Hotels', 'null', 428, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (429, 'Bin Majid Hotels & Resorts', 'null', 429, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (430, 'Bingo', 'null', 430, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (431, 'Binh An Home', 'null', 431, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (432, 'Bintan Property', 'null', 432, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (433, 'Bintang Property', 'null', 433, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (434, 'Bjorn', 'null', 434, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (435, 'BK-Property', 'null', 435, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (436, 'BK\'s Motel Group', 'null', 436, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (437, 'Black Pearl & Co', 'null', 437, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (438, 'BLDG 1587', 'null', 438, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (439, 'Blessing Mansion', 'null', 439, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (440, 'Blessing Property', 'null', 440, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (441, 'BLG Condo Rentals', 'null', 441, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (442, 'Bloq Apartments', 'null', 442, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (443, 'Blossom Hill Inn', 'null', 443, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (444, 'Blue Diamond Resorts', 'null', 444, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (445, 'Blue Group BV_C', 'null', 445, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (446, 'Blue Horizon', 'null', 446, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (447, 'Blue Mountains Getaways_C', 'null', 447, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (448, 'Blue Sands', 'null', 448, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (449, 'Blue Sapphire Property Management', 'null', 449, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (450, 'Blue Sea Hotels & Resorts', 'null', 450, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (451, 'Blue Seagull', 'null', 451, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (452, 'Blue Views Villas and Apartments', 'null', 452, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (453, 'BluelineBenidorm_C', 'null', 453, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (454, 'Blueseagull_JP', 'null', 454, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (455, 'BnB Lord_C', 'null', 455, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (456, 'BnB Manager_C', 'null', 456, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (457, 'Bnbbuddy_C', 'null', 457, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (458, 'BNBHost_C', 'null', 458, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (459, 'Bnbme1', 'null', 459, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (460, 'bnbprofits', 'null', 460, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (461, 'Boas Swiss Hotel', 'null', 461, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (462, 'BoerenBed_C', 'null', 462, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (463, 'Bogor Valley', 'null', 463, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (464, 'Bohemian Hostels', 'null', 464, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (465, 'Bonanova Ako', 'null', 465, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (466, 'Bonavista', 'null', 466, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (467, 'Bondi Group', 'null', 467, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (468, 'Bondia Hotels', 'null', 468, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (469, 'Bonsella Hotel Groups', 'null', 469, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (470, 'Bonzela', 'null', 470, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (471, 'Bookerator_C', 'null', 471, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (472, 'Booking Helpers_C', 'null', 472, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (473, 'Booking Lettings_C', 'null', 473, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (474, 'BookingTeam', 'null', 474, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (475, 'Boonchai Property', 'null', 475, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (476, 'Borges Chiado', 'null', 476, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (477, 'Boudl Hotels', 'null', 477, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (478, 'Bouganvillia Homes & Villas_C', 'null', 478, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (479, 'Boustead Hotels & Resorts', 'null', 479, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (480, 'Boutique Stays', 'null', 480, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (481, 'Brancom', 'null', 481, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (482, 'Brawa Groove Villa', 'null', 482, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (483, 'Breakfast_JP', 'null', 483, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (484, 'BreakPL Real Estate Consultancy', 'null', 484, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (485, 'Breezbay Hotel Group', 'null', 485, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (486, 'Bridal Tea House', 'null', 486, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (487, 'BridgeStreet', 'null', 487, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (488, 'Brighton Getaways Limited', 'null', 488, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (489, 'Brisas Hotels and Resorts', 'null', 489, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (490, 'Britannia Hotels', 'null', 490, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (491, 'BRO', 'null', 491, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (492, 'Bruces Hideout', 'null', 492, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (493, 'Bruny Island Accommodation Services', 'null', 493, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (494, 'Bruny Island Holiday Rentals', 'null', 494, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (495, 'Brustar', 'null', 495, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (496, 'BTP GROUP', 'null', 496, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (497, 'Bubica Zlatibor_C', 'null', 497, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (498, 'Budaraa', 'null', 498, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (499, 'Budget Motel Chain', 'null', 499, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (500, 'Budget Suites of America', 'null', 500, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (501, 'Budgetel', 'null', 501, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (502, 'Budi Susan Property', 'null', 502, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (503, 'Buenaventura Yape', 'null', 503, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (504, 'Buho Group', 'null', 504, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (505, 'Bui Vien Miss Home', 'null', 505, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (506, 'Bukit Vista', 'null', 506, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (507, 'Bunda Homestay', 'null', 507, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (508, 'Bundit properties', 'null', 508, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (509, 'Bunga Jabe Beach', 'null', 509, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (510, 'Bunk\'D Backpackers Villa', 'null', 510, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (511, 'Burj Holidays', 'null', 511, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (512, 'Butterfly Hospitality Group', 'null', 512, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (513, 'ButternutTreeTownhomes', 'null', 513, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (514, 'By Concierge', 'null', 514, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (515, 'Byblos Hotels', 'null', 515, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (516, 'Byron Bay Accom', 'null', 516, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (517, 'C Hotels', 'null', 517, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (518, 'Ca s\'amitger', 'null', 518, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (519, 'Cactus Space', 'null', 519, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (520, 'Caesar Park Hotels & Resorets Group', 'null', 520, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (521, 'Caesars Entertainment Corporation', 'null', 521, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (522, 'Café & Homestay 1986 Designer', 'null', 522, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (523, 'Calvin', 'null', 523, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (524, 'Camelia Bali Villa', 'null', 524, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (525, 'Camino Real Hotels', 'null', 525, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (526, 'CANDEO HOTELS', 'null', 526, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (527, 'Candra Group', 'null', 527, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (528, 'Cao Hang', 'null', 528, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (529, 'Cape & Kantary Hotels', 'null', 529, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (530, 'Cape Town Holiday Apartments', 'null', 530, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (531, 'Cape Town Life', 'null', 531, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (532, 'Capstone Hotels', 'null', 532, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (533, 'Carino Hotels and Resorts Worldwide', 'null', 533, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (534, 'Carla Group', 'null', 534, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (535, 'Carlton Hotel Mangement Group', 'null', 535, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (536, 'Casa Amore', 'null', 536, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (537, 'Casa Corsa_C', 'null', 537, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (538, 'Casa Floridian LLC', 'null', 538, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (539, 'Casa Melhor', 'null', 539, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (540, 'Casa Mitger_C', 'null', 540, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (541, 'casablanca homestay', 'null', 541, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (542, 'CasaGuest_C', 'null', 542, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (543, 'Casaterra', 'null', 543, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (544, 'Castle Resorts & Hotels', 'null', 544, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (545, 'CC House Khao Yai', 'null', 545, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (546, 'Ccresidences', 'null', 546, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (547, 'Cebu Rooms Condotels', 'null', 547, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (548, 'Cecylia Agustine', 'null', 548, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (549, 'Celebrity city hotel', 'null', 549, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (550, 'Celebrity Room', 'null', 550, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (551, 'Celestial Works', 'null', 551, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (552, 'Celyn Group of Hotels', 'null', 552, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (553, 'Centara Hotels & Resorts', 'null', 553, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (554, 'Centau Property', 'null', 554, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (555, 'Center Hotels', 'null', 555, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (556, 'Center Parcs', 'null', 556, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (557, 'Central Apartments & Hotels', 'null', 557, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (558, 'Central Hotels', 'null', 558, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (559, 'Central Stays', 'null', 559, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (560, 'Centre Point Hospitality', 'null', 560, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (561, 'Centro Hotels', 'null', 561, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (562, 'Centurion Hotels & Resorts', 'null', 562, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (563, 'Centurion Hotels International', 'null', 563, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (564, 'Century 21', 'null', 564, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (565, 'Chaaya Hotels & Resorts', 'null', 565, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (566, 'Chariton Hotel', 'null', 566, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (567, 'Charlie\'s Home', 'null', 567, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (568, 'Charming City Hotels Group', 'null', 568, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (569, 'Chateaux et Hotels Collection', 'null', 569, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (570, 'Chatra Property', 'null', 570, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (571, 'Chatrium Hotels and Residences', 'null', 571, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (572, 'Chattha', 'null', 572, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (573, 'Chaz Everitt Holiday Rentals', 'null', 573, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (574, 'Cherry Homes Residence', 'null', 574, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (575, 'Chez Bonbons', 'null', 575, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (576, 'Chez Hotels', 'null', 576, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (577, 'Chilling', 'null', 577, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (578, 'Chit Chat Café', 'null', 578, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (579, 'Chitpol', 'null', 579, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (580, 'CHM Hotels', 'null', 580, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (581, 'Choice Hotels', 'null', 581, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (582, 'Chrismar Hotels', 'null', 582, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (583, 'Chuan House', 'null', 583, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (584, 'Cibubur Village', 'null', 584, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (585, 'CibuburVillage', 'null', 585, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (586, 'Cijantung Residence', 'null', 586, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (587, 'Cilandak Residence', 'null', 587, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (588, 'Cinnamon Hotels and Resorts', 'null', 588, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (589, 'Cinque Terre Riviera', 'null', 589, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (590, 'Citihome', 'null', 590, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (591, 'Cititel Group', 'null', 591, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (592, 'Citra Prima', 'null', 592, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (593, 'Citradream Hotels', 'null', 593, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (594, 'Citrus Hotels', 'null', 594, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (595, 'Citrus Tree Holidays', 'null', 595, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (596, 'City 118', 'null', 596, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (597, 'City Apartment Saigon', 'null', 597, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (598, 'City Apartments Auckland', 'null', 598, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (599, 'City Edge', 'null', 599, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (600, 'City Express', 'null', 600, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (601, 'City House Saigon', 'null', 601, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (602, 'City Inn', 'null', 602, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (603, 'City Lights Apartment Group', 'null', 603, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (604, 'City Lodge', 'null', 604, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (605, 'City Premiere Group', 'null', 605, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (606, 'City Seasons Group of Hotels', 'null', 606, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (607, 'City Stay Hospitality', 'null', 607, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (608, 'City View', 'null', 608, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (609, 'Cityhotels', 'null', 609, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (610, 'Citymax Hotels', 'null', 610, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (611, 'Civitel Hotels & Resorts', 'null', 611, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (612, 'Clarks Group of Hotels', 'null', 612, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (613, 'Classic British Hotels', 'null', 613, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (614, 'Clavarly Gain', 'null', 614, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (615, 'Clearwater Samui', 'null', 615, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (616, 'Click&Flat', 'null', 616, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (617, 'Cloverph', 'null', 617, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (618, 'Club Balai Isabel Inc', 'null', 618, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (619, 'Club Hotels Israel', 'null', 619, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (620, 'Club Mahindra Holidays', 'null', 620, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (621, 'Club Med', 'null', 621, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (622, 'Club Quarters', 'null', 622, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (623, 'Coast and Country Getaways', 'null', 623, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (624, 'Coast Hotels & Resorts', 'null', 624, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (625, 'Coastal Properties Realty', 'null', 625, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (626, 'Coastbreakz Group', 'null', 626, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (627, 'Coastlands Hotel Group', 'null', 627, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (628, 'Coastlines International_C', 'null', 628, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (629, 'CoBnB', 'null', 629, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (630, 'Coco Stay', 'null', 630, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (631, 'Coconut Group', 'null', 631, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (632, 'CocoonR_C', 'null', 632, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (633, 'CocoRacco_JP', 'null', 633, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (634, 'Cocorolife_JP', 'null', 634, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (635, 'CoDE Hostels', 'null', 635, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (636, 'Cohaus.co', 'null', 636, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (637, 'Come Stay', 'null', 637, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (638, 'Comfort Hotel', 'null', 638, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (639, 'Comfy Clouds', 'null', 639, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (640, 'Commit', 'null', 640, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (641, 'Common Share', 'null', 641, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (642, 'Commundo Tagungshotels', 'null', 642, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (643, 'COMO Hotels and Resorts', 'null', 643, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (644, 'Company Vauban', 'null', 644, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (645, 'Compass Hospitality', 'null', 645, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (646, 'Concept Hospitality', 'null', 646, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (647, 'Condes/Espana/Monument', 'null', 647, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (648, 'Conlon & Co', 'null', 648, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (649, 'Constance Hotels Experience', 'null', 649, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (650, 'Container group', 'null', 650, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (651, 'Continental', 'null', 651, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (652, 'Cool Bali Villas', 'null', 652, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (653, 'CoolRooms', 'null', 653, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (654, 'Copenhagen Hospitality_C', 'null', 654, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (655, 'Coral Hotels & Resorts', 'null', 655, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (656, 'CORE', 'null', 656, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (657, 'Corinthia Hotels International', 'null', 657, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (658, 'Cornel Home', 'null', 658, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (659, 'Corus', 'null', 659, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (660, 'Cosmo Bridge', 'null', 660, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (661, 'Cosmopolitan', 'null', 661, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (662, 'Cosmos Hotel Management', 'null', 662, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (663, 'Cosmos Hotel& Resorts', 'null', 663, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (664, 'Costay', 'null', 664, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (665, 'Cottesloe Beach House Stays', 'null', 665, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (666, 'Country Garden Phoenix', 'null', 666, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (667, 'Court Hotels', 'null', 667, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (668, 'Cozrum Group', 'null', 668, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (669, 'Cozy Bali Holiday', 'null', 669, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (670, 'Cozy House', 'null', 670, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (671, 'Cozy Palm', 'null', 671, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (672, 'Cozy Property_C', 'null', 672, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (673, 'CP', 'null', 673, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (674, 'CPG Hotels', 'null', 674, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (675, 'CPI Hotels', 'null', 675, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (676, 'CPM', 'null', 676, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (677, 'Crazy Bee JP', 'null', 677, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (678, 'Creasion', 'null', 678, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (679, 'Crerar Hotels', 'null', 679, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (680, 'Cresta Hotels', 'null', 680, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (681, 'Crete Villas 4 U', 'null', 681, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (682, 'Cristina Dela Cruz House Rental', 'null', 682, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (683, 'Cristina L. Dela Cruz House Rental', 'null', 683, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (684, 'Cross hotels and resorts', 'null', 684, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (685, 'Cross Life', 'null', 685, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (686, 'Cross One', 'null', 686, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (687, 'Crossroad', 'null', 687, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (688, 'Crown & Champa Resorts', 'null', 688, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (689, 'Crown Regency Hotels & Resorts', 'null', 689, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (690, 'Crystal Crown', 'null', 690, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (691, 'Crystal Hotels', 'null', 691, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (692, 'Crystalbrook Collection', 'null', 692, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (693, 'CS corporation (HQ Coto)', 'null', 693, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (694, 'CSJ', 'null', 694, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (695, 'Cube', 'null', 695, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (696, 'Cube Hotels Group', 'null', 696, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (697, 'CY House', 'null', 697, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (698, 'Cynthia', 'null', 698, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (699, 'Cyprus Holiday Group_C', 'null', 699, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (700, 'D Collection', 'null', 700, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (701, 'D Lin Property', 'null', 701, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (702, 'D2 Villas', 'null', 707, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (703, 'Daebakinae', 'null', 708, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (704, 'Dafam Hotels', 'null', 709, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (705, 'Daiichi Hotel Group', 'null', 710, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (706, 'Dailyflats', 'null', 711, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (707, 'Daisen', 'null', 712, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (708, 'Daiwa Royal Hotel', 'null', 713, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (709, 'Daiwa Roynet Hotels', 'null', 714, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (710, 'Dalata Hotel Group', 'null', 715, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (711, 'Dalia May', 'null', 716, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (712, 'DAMAC Group', 'null', 717, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (713, 'Damar Emas', 'null', 718, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (714, 'Dan Hotels', 'null', 719, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (715, 'Danat Hotel & Resorts', 'null', 720, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (716, 'Dandeli', 'null', 721, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (717, 'Dandori', 'null', 722, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (718, 'Dang Nguyen Da Lat', 'null', 723, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (719, 'Dani Sulistyo Properties', 'null', 724, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (720, 'Danubius Hotels Group', 'null', 725, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (721, 'Dar Al Eiman Group', 'null', 726, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (722, 'Darayu Bali', 'null', 727, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (723, 'Das Wohnhause Property', 'null', 728, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (724, 'Dasiri Group', 'null', 729, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (725, 'Daylesford Accommodation Escapes', 'null', 730, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (726, 'Days Apartment', 'null', 731, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (727, 'Dazzle Sukhumvit 7', 'null', 732, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (728, 'D\'Cepeh', 'null', 702, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (729, 'De Art', 'null', 733, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (730, 'De Hostel', 'null', 734, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (731, 'De Inn', 'null', 735, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (732, 'De Kraal Estate', 'null', 736, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (733, 'De palma', 'null', 737, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (734, 'de Prisha', 'null', 738, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (735, 'De Tropen Jogja', 'null', 739, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (736, 'De Uptown', 'null', 740, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (737, 'Dealchaser Da Nang', 'null', 741, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (738, 'Debali Villas', 'null', 742, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (739, 'Dedeman Hotels', 'null', 743, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (740, 'Dedy Sandiarsa', 'null', 744, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (741, 'Deefly Hotels & Resorts', 'null', 745, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (742, 'Delaware North Companies Australia & New Zealand', 'null', 746, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (743, 'Delfos Group', 'null', 747, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (744, 'Della Silviana', 'null', 748, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (745, 'Delta Hotels & Resort', 'null', 749, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (746, 'Deluca Homes', 'null', 750, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (747, 'Deluxe Holiday Homes', 'null', 751, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (748, 'Demanus', 'null', 752, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (749, 'Denihan Hospitality Group (DHG)', 'null', 753, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (750, 'Derby Hotels Collection', 'null', 754, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (751, 'Deris Clarke', 'null', 755, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (752, 'Desa Bahasa Borobudur', 'null', 756, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (753, 'Desa Kemiren', 'null', 757, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (754, 'Desa Penglipuran', 'null', 758, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (755, 'Desa Wisata Gabugan', 'null', 759, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (756, 'Desa Wisata Kembang Arum', 'null', 760, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (757, 'Desa Wisata Pentingsari', 'null', 761, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (758, 'Design Hotels', 'null', 762, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (759, 'Design Suites Miami_C', 'null', 763, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (760, 'DesignerStay_C', 'null', 764, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (761, 'Destada Properties', 'null', 765, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (762, 'Destination Hotels & Resorts', 'null', 766, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (763, 'Destiny Student', 'null', 767, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (764, 'Deutsche Hospitality', 'null', 768, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (765, 'Devara Pool Villa', 'null', 769, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (766, 'Device Agency', 'null', 770, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (767, 'Deville Hotels', 'null', 771, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (768, 'Dewa Made Widiana', 'null', 772, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (769, 'Dharma Gita Guest House', 'null', 773, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (770, 'Dhevatara', 'null', 774, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (771, 'DISCOVERY HOMESTAY', 'null', 790, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (772, 'Di Bandung Villa', 'null', 775, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (773, 'Diamond Apartments', 'null', 776, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (774, 'Diamond Resort Europe', 'null', 777, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (775, 'Diamond Resorts International', 'null', 778, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (776, 'Diamond Suite Group', 'null', 779, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (777, 'Diamond Villa', 'null', 780, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (778, 'Diana Group', 'null', 781, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (779, 'Diana\'s Guest House', 'null', 782, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (780, 'Dicky Andrian', 'null', 783, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (781, 'Dieng Kledung Pass', 'null', 784, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (782, 'Dimentiondots', 'null', 785, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (783, 'Dio Rama', 'null', 786, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (784, 'Dipro', 'null', 787, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (785, 'Direct Hotels', 'null', 788, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (786, 'Discovery Holiday Parks', 'null', 789, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (787, 'Discovery Hotels & Resorts', 'null', 791, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (788, 'Distinction Hotels NZ', 'null', 792, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (789, 'District One', 'null', 793, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (790, 'Dita Rent Apartment', 'null', 794, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (791, 'Divan Hotels', 'null', 795, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (792, 'Diyar Group', 'null', 796, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (793, 'Diyar Villas', 'null', 797, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (794, 'Djitu Hospitality', 'null', 798, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (795, 'Djitu Hospitality Solution', 'null', 799, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (796, 'Djohan Anggono', 'null', 800, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (797, 'DKost Baloi', 'null', 801, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (798, 'DMARC CONDOS', 'null', 802, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (799, 'DNU', 'null', 803, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (800, 'Do it Consulting', 'null', 804, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (801, 'DO NOT USE', 'null', 805, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (802, 'Do not use', 'null', 806, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (803, 'd\'Oasis', 'null', 703, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (804, 'Dolce Hotels and Resorts', 'null', 807, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (805, 'Doma Hotels', 'null', 808, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (806, 'Domo Management', 'null', 809, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (807, 'Domohotel_JP', 'null', 810, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (808, 'Dorint Hotels & Resorts', 'null', 811, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (809, 'DORMERO', 'null', 812, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (810, 'Dormitels PH', 'null', 813, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (811, 'Dormy Inn', 'null', 814, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (812, 'Dorsett Hospitality International', 'null', 815, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (813, 'Dossen', 'null', 816, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (814, 'Dot', 'null', 817, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (815, 'DownSouth Holiday Homes', 'null', 818, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (816, 'D\'Paragon', 'null', 704, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (817, 'D\'Phoenix', 'null', 705, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (818, 'd\'primahotel', 'null', 706, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (819, 'Dream Algarve_C', 'null', 819, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (820, 'Dream Apartments', 'null', 820, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (821, 'Dream Espana_C', 'null', 821, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (822, 'Dream Hotels & Resorts', 'null', 822, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (823, 'Dream House', 'null', 823, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (824, 'Dream Inn Holiday Homes', 'null', 824, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (825, 'Dream Property Samui', 'null', 825, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (826, 'DreamInn', 'null', 826, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (827, 'Dreamtime Resorts', 'null', 827, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (828, 'Driven Properties', 'null', 828, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (829, 'Drury Hotels', 'null', 829, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (830, 'DT Hotelier.org', 'null', 830, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (831, 'Dubai Apartments', 'null', 831, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (832, 'Dubai Grand Hotel by fortune', 'null', 832, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (833, 'Dubai Stay', 'null', 833, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (834, 'Dunes Express Inn', 'null', 834, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (835, 'Dunsborough Holiday Homes', 'null', 835, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (836, 'Duri Residence Group', 'null', 836, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (837, 'Dusit Hotels and Resorts', 'null', 837, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (838, 'Dusun Ubud Property', 'null', 838, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (839, 'E&T Holiday Homes', 'null', 840, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (840, 'Ease by Emaar', 'null', 841, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (841, 'Eastin Hotels', 'null', 842, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (842, 'Eastiny Hotel Group', 'null', 843, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (843, 'Easy BnB', 'null', 844, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (844, 'Easy Busy Guest House', 'null', 845, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (845, 'Easy Go', 'null', 846, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (846, 'easyHotel', 'null', 847, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (847, 'Eaton Hotels', 'null', 848, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (848, 'Eats and Retreats', 'null', 849, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (849, 'ECFA Hotels Group', 'null', 850, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (850, 'EchoDom', 'null', 851, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (851, 'ECJ Suites @ Horizons 101 Condo', 'null', 852, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (852, 'Eclectic Villas', 'null', 853, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (853, 'Eco Hotels', 'null', 854, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (854, 'Ecohomz', 'null', 855, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (855, 'ECS', 'null', 856, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (856, 'Eddy\'s Place & Travel Tours', 'null', 857, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (857, 'Eden Holiday Rentals', 'null', 858, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (858, 'Eden Hotel Group', 'null', 859, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (859, 'Eden Pelayo', 'null', 860, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (860, 'Edinburgh Collection', 'null', 861, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (861, 'Eever', 'null', 862, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (862, 'Ejoysleep', 'null', 863, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (863, 'Eki Mambrasar', 'null', 864, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (864, 'Ekka Baan', 'null', 865, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (865, 'El Cid Resorts', 'null', 866, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (866, 'EL Cielito Hotels', 'null', 867, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (867, 'El Luxury', 'null', 868, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (868, 'EL Nido Resorts', 'null', 869, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (869, 'Elaf Group', 'null', 870, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (870, 'Electus Home', 'null', 871, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (871, 'Elegancia Hotels', 'null', 872, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (872, 'Element Escapes', 'null', 873, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (873, 'Elite Club Vacanze', 'null', 874, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (874, 'Elite Estates Bali', 'null', 875, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (875, 'Elite Group', 'null', 876, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (876, 'Elite Havens', 'null', 877, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (877, 'Elite Heaven ( Non NHA)', 'null', 878, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (878, 'Elite Holiday Homes', 'null', 879, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (879, 'Elite Hospitality Group', 'null', 880, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (880, 'Elite Island Resorts', 'null', 881, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (881, 'Elite Virtual Brokerage_C', 'null', 882, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (882, 'Elite World Hotels', 'null', 883, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (883, 'ELMCAPITAL_JP', 'null', 884, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (884, 'Elmira Group Apartment', 'null', 885, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (885, 'Emaar Hospitality', 'null', 886, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (886, 'Embrace Place', 'null', 887, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (887, 'Empire Group', 'null', 888, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (888, 'Empire Hotel Group', 'null', 889, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (889, 'Emz Apartments', 'null', 890, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (890, 'Enagazalble', 'null', 891, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (891, 'Enchanted garden', 'null', 892, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (892, 'Encore Reunion_C', 'null', 893, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (893, 'Enderun Hotels', 'null', 894, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (894, 'Endo Chendiawan', 'null', 895, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (895, 'Endo Michi', 'null', 896, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (896, 'Enno Apartment', 'null', 897, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (897, 'Epiphany_JP', 'null', 898, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (898, 'Eppley Hotel Company', 'null', 899, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (899, 'Equinoxe', 'null', 900, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (900, 'ErdiGroup', 'null', 901, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (901, 'E-Red Hotel', 'null', 839, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (902, 'Eresin Hotels', 'null', 902, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (903, 'Erik Vokel Apartments', 'null', 903, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (904, 'ESA Serviced Apartments', 'null', 905, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (905, 'Escala Condominium Cebu', 'null', 906, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (906, 'ESCEMO', 'null', 907, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (907, 'Espace Holiday Homes', 'null', 908, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (908, 'Espahotels', 'null', 909, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (909, 'Espai Barcelona_C', 'null', 910, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (910, 'Espresso Apartments', 'null', 911, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (911, 'Esprit de France', 'null', 912, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (912, 'Es-sense', 'null', 904, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (913, 'Estate One', 'null', 913, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (914, 'Estay YJ Baoli Yintan', 'null', 914, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (915, 'Estelar', 'null', 915, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (916, 'Eton Collection', 'null', 916, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (917, 'Etrebe Holdings', 'null', 917, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (918, 'Euro Hotels', 'null', 918, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (919, 'Eurohotel', 'null', 919, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (920, 'Europea Luxury Residences', 'null', 920, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (921, 'European Hotels Private Collection', 'null', 921, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (922, 'Eurotel', 'null', 922, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (923, 'EV world', 'null', 923, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (924, 'Evaco Holiday Resorts', 'null', 924, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (925, 'Evenia Hotels', 'null', 925, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (926, 'Everly Group', 'null', 926, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (927, 'Evy Handayani', 'null', 927, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (928, 'EXCELLENCE GROUP LUXURY HOTELS & RESORTS', 'null', 928, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (929, 'Exclusive Hotels', 'null', 929, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (930, 'Exe Hotels', 'null', 930, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (931, 'Executive Villas Florida', 'null', 931, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (932, 'Exon', 'null', 932, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (933, 'Exotic Hideaway', 'null', 933, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (934, 'Expo & Torre', 'null', 934, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (935, 'Express Holiday Homes', 'null', 935, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (936, 'Extended Stay America', 'null', 936, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (937, 'Extraordinary', 'null', 937, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (938, 'F Home Danang', 'null', 938, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (939, 'FabHotels', 'null', 940, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (940, 'Fahrenheit', 'null', 941, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (941, 'Faircity Hotels', 'null', 942, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (942, 'Fairmont Raffles Hotels International', 'null', 943, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (943, 'Fairyland Hotels', 'null', 944, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (944, 'Fajr Group', 'null', 945, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (945, 'Fame Villa', 'null', 946, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (946, 'Faminect', 'null', 947, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (947, 'Fanqielaile', 'null', 948, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (948, 'FanssMoreJapan', 'null', 949, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (949, 'Far East Hospitality', 'null', 950, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (950, 'Far East Serviced Residences', 'null', 951, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (951, 'Far Home', 'null', 952, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (952, 'Farway Homes', 'null', 953, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (953, 'Fassbind Hotels', 'null', 954, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (954, 'Fathurrahman Imran', 'null', 955, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (955, 'FATMAWATI', 'null', 956, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (956, 'Fatmawati Group', 'null', 957, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (957, 'Fattal Hotels', 'null', 958, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (958, 'FAU', 'null', 959, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (959, 'Favstay', 'null', 960, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (960, 'Favstay_Local', 'null', 961, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (961, 'Faye & Lowell', 'null', 962, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (962, 'FC Sotetsu Fresa Inn', 'null', 963, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (963, 'FCAC_JP', 'null', 964, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (964, 'Febow', 'null', 965, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (965, 'Federal Group', 'null', 966, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (966, 'Feel Great Condotels', 'null', 967, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (967, 'Feel Japan', 'null', 968, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (968, 'Felda Residences', 'null', 969, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (969, 'Felice Group', 'null', 970, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (970, 'Felipe Martinval', 'null', 971, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (971, 'Feng Jia Window', 'null', 972, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (972, 'Feng Xi Property', 'null', 973, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (973, 'Fengchia Europe', 'null', 974, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (974, 'Fengchia Love Heart', 'null', 975, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (975, 'Fengchia Random', 'null', 976, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (976, 'Fenix Hotels', 'null', 977, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (977, 'FERGUS', 'null', 978, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (978, 'Fersal Hotel Group', 'null', 979, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (979, 'Festiva Resorts', 'null', 980, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (980, 'Festival', 'null', 981, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (981, 'fforward', 'null', 982, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (982, 'FG Properties', 'null', 983, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (983, 'Fiesta hotels', 'null', 984, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (984, 'Firmdale Hotels', 'null', 985, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (985, 'First Cabin', 'null', 986, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (986, 'Fiz Apartment', 'null', 987, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (987, 'Flamingo ShortLets', 'null', 988, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (988, 'Flatguest_C', 'null', 989, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (989, 'Flatotel Hotels', 'null', 990, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (990, 'Flats 4 U Moscow', 'null', 991, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (991, 'Flatsaway_C', 'null', 992, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (992, 'Fletcher Hotels', 'null', 993, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (993, 'Flexstay Hotel Management', 'null', 994, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (994, 'Flora Hospitality', 'null', 995, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (995, 'Florida Star Vacations_C', 'null', 996, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (996, 'Floris Hotel Collection', 'null', 997, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (997, 'Flow America Homes_C', 'null', 998, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (998, 'Flow Art', 'null', 999, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (999, 'Flower Group Of Hotels', 'null', 1000, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1000, 'Focus Hotels', 'null', 1001, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1001, 'Foliday of Fosun Group', 'null', 1002, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1002, 'Fontainebleau Resorts', 'null', 1003, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1003, 'Fontana Residencia', 'null', 1004, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1004, 'Forestdale Hotels', 'null', 1005, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1005, 'Fortune Group', 'null', 1006, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1006, 'Fortune Group of Hotels', 'null', 1007, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1007, 'Fortune Park Hotels', 'null', 1008, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1008, 'Four Seasons Hotels and Resorts', 'null', 1009, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1009, 'FPD Global Integrated Services Inc.', 'null', 1010, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1010, 'F-Plus', 'null', 939, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1011, 'Fragrance Hotel', 'null', 1011, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1012, 'Framework Family', 'null', 1012, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1013, 'France Patrimoine', 'null', 1013, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1014, 'Francesco Property', 'null', 1014, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1015, 'Frank Porter_C', 'null', 1015, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1016, 'Franklin Ginanjar', 'null', 1016, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1017, 'Franko', 'null', 1017, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1018, 'Fraser Hospitality', 'null', 1018, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1019, 'FreeSpirit Holiday Parks', 'null', 1019, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1020, 'Friendly & Alex Group Co., Ltd', 'null', 1020, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1021, 'Frost Villas', 'null', 1021, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1022, 'Fu Yuning Property', 'null', 1022, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1023, 'Fujinaga', 'null', 1023, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1024, 'Fujita Kanko Inc Hotels & Resorts', 'null', 1024, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1025, 'fukuoka f connect', 'null', 1025, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1026, 'Fukuoka Hotel', 'null', 1026, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1027, 'Fukuoka Properties', 'null', 1027, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1028, 'Fulcrum Lettings Management (Thailand) Co., Ltd', 'null', 1028, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1029, 'Full House Homestay Saigon', 'null', 1029, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1030, 'Full Rooms Phuket', 'null', 1030, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1031, 'Fulmar Residence Group', 'null', 1031, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1032, 'Fun_world_RealEstate', 'null', 1032, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1033, 'Funkey', 'null', 1033, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1034, 'Furama Hotels International', 'null', 1034, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1035, 'Furnished Properties', 'null', 1035, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1036, 'FX Hotels Group', 'null', 1036, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1037, 'G Feel', 'null', 1037, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1038, 'G1 Holiday Properties', 'null', 1038, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1039, 'G7 Residence', 'null', 1039, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1040, 'Gacayan Condotel', 'null', 1040, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1041, 'Gading Nias', 'null', 1041, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1042, 'Galactic', 'null', 1042, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1043, 'Galaxi Group', 'null', 1043, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1044, 'Galaxy Entertainment', 'null', 1044, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1045, 'Gama Hotels', 'null', 1045, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1046, 'Gandhi Hospitality Management', 'null', 1046, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1047, 'Gangnam Best View', 'null', 1047, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1048, 'Garden Palace Hotels', 'null', 1048, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1049, 'Garden Studio', 'null', 1049, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1050, 'Gardena Agency', 'null', 1050, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1051, 'Gargallo', 'null', 1051, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1052, 'Garnet', 'null', 1052, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1053, 'Gaudi Group', 'null', 1053, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1054, 'Gaylord Hotels', 'null', 1054, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1055, 'Gaynorch Property', 'null', 1055, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1056, 'GCH Hotel Group', 'null', 1056, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1057, 'Gcloud', 'null', 1057, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1058, 'Gemini Hospitality', 'null', 1058, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1059, 'Gemtrad', 'null', 1059, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1060, 'Generator Hotel and Hostel', 'null', 1060, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1061, 'Genesis', 'null', 1061, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1062, 'Gentong Kost', 'null', 1062, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1063, 'GerberaHome', 'null', 1063, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1064, 'Getaway Merimbula', 'null', 1064, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1065, 'Getaways SA', 'null', 1065, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1066, 'GetLavanda', 'null', 1066, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1067, 'Giang Tran', 'null', 1067, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1068, 'Giannoulis Hotels and Resorts', 'null', 1068, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1069, 'Gilles Mangin', 'null', 1069, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1070, 'Ginger Hotels', 'null', 1070, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1071, 'Gita Ayu Villa', 'null', 1071, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1072, 'Glacier Park Company', 'null', 1072, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1073, 'GLI (Global Live Investment Inc.)', 'null', 1073, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1074, 'Global Coms Japan', 'null', 1074, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1075, 'Global International Hotel', 'null', 1075, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1076, 'Global Top Group', 'null', 1076, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1077, 'Global Villas', 'null', 1077, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1078, 'Gloria Hotels & Resorts', 'null', 1078, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1079, 'GO Hotels', 'null', 1079, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1080, 'GODOGAISYA JESSICA', 'null', 1080, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1081, 'Gojo Paradiso', 'null', 1081, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1082, 'Goki', 'null', 1082, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1083, 'Gold Coast Holiday Houses', 'null', 1083, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1084, 'Gold Coast Holiday Rentals', 'null', 1084, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1085, 'Gold Coast Luxury Resorts', 'null', 1085, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1086, 'Gold Group Hotels', 'null', 1086, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1087, 'Golden Chain', 'null', 1087, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1088, 'Golden Leaf Hotels & Residences', 'null', 1088, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1089, 'Golden Roof Group', 'null', 1089, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1090, 'Golden Stay Dubai', 'null', 1090, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1091, 'Good Choi', 'null', 1091, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1092, 'Good Night Inn', 'null', 1092, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1093, 'Good Rest Property', 'null', 1093, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1094, 'Good Smile Nico', 'null', 1094, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1095, 'Good Stay', 'null', 1095, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1096, 'Goodday Kyoto', 'null', 1096, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1097, 'Gooderson Leisure', 'null', 1097, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1098, 'GoodHope', 'null', 1098, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1099, 'Goodstay Hotel', 'null', 1099, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1100, 'Gorgeou Group Accommodation', 'null', 1100, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1101, 'Grace Cup by Compass', 'null', 1101, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1102, 'Graduate Hotels', 'null', 1102, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1103, 'Graha Pande Residence', 'null', 1103, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1104, 'Graha Pastika', 'null', 1104, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1105, 'Gran Prix Hotels', 'null', 1105, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1106, 'Grand Hotels International (GHI)', 'null', 1106, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1107, 'Grand Isabella Residences', 'null', 1107, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1108, 'Grand Khalifah Guesthouse', 'null', 1108, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1109, 'Grand Seaview Realty & Dev\'t Corp', 'null', 1109, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1110, 'Grand Skylight Hotels', 'null', 1110, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1111, 'Grandboutique Inn Pro', 'null', 1111, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1112, 'Grandouce_JP', 'null', 1112, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1113, 'Grandroomservices', 'null', 1113, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1114, 'Grange Hotels', 'null', 1114, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1115, 'Granvista Hotels & Resorts', 'null', 1115, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1116, 'Grapp', 'null', 1116, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1117, 'Great Hotels of the World', 'null', 1117, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1118, 'Great Southern Hotels', 'null', 1118, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1119, 'Great Stay', 'null', 1119, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1120, 'Great Wolf Resorts', 'null', 1120, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1121, 'GreatVillas Asia', 'null', 1121, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1122, 'Green Future', 'null', 1122, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1123, 'Green Homestay', 'null', 1123, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1124, 'Green Lake View Apartments', 'null', 1124, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1125, 'Green Pramuka City', 'null', 1125, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1126, 'Green Pramuka City by Novi', 'null', 1126, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1127, 'Green Rich Hotels', 'null', 1127, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1128, 'Green Star', 'null', 1128, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1129, 'Green Tree Inns', 'null', 1129, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1130, 'Greenland International Hotels Group', 'null', 1130, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1131, 'GreenLine Hotels', 'null', 1131, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1132, 'Greens Hotels', 'null', 1132, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1133, 'Griya Gribig', 'null', 1133, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1134, 'Griya Lidya', 'null', 1134, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1135, 'Griya Malioboro', 'null', 1135, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1136, 'Griya Syariah', 'null', 1136, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1137, 'Group -Liberty', 'null', 1137, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1138, 'Groupe Frontenac', 'null', 1138, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1139, 'Groupe Sogepar', 'null', 1139, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1140, 'GROUPO PINERO', 'null', 1140, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1141, 'GRT Hotels & Resorts', 'null', 1141, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1142, 'GRUPO HOTELERO SANTA FE', 'null', 1142, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1143, 'Grupo Roisa', 'null', 1143, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1144, 'Grupotel', 'null', 1144, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1145, 'Gruppo Trevi', 'null', 1145, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1146, 'Guangzhou Merci bnb', 'null', 1146, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1147, 'Guest Easy', 'null', 1147, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1148, 'Guest House Hata Group JP', 'null', 1148, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1149, 'Guest House Miss Anis', 'null', 1149, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1150, 'Guest Houser_C', 'null', 1150, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1151, 'Guest Ready_C', 'null', 1151, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1152, 'GuestHouse KOTO Fushimi Inari', 'null', 1152, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1153, 'Gulf Hotels Group', 'null', 1153, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1154, 'Gusde House', 'null', 1154, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1155, 'Gusman', 'null', 1155, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1156, 'Guvon Hotels', 'null', 1156, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1157, 'Guzman', 'null', 1157, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1158, 'GV Hotels', 'null', 1158, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1159, 'Gyza Pro', 'null', 1159, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1160, 'H Boutique', 'null', 1160, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1161, 'H hotel', 'null', 1161, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1162, 'H Residence', 'null', 1162, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1163, 'H10 Hotels', 'null', 1165, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1164, 'Ha Thao', 'null', 1166, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1165, 'Habitat Apartments', 'null', 1167, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1166, 'Habitat Italy_C', 'null', 1168, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1167, 'Hacienda', 'null', 1169, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1168, 'Haka Tourism Group', 'null', 1170, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1169, 'Hakone Ichinoyu Group', 'null', 1171, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1170, 'Halldis_C', 'null', 1172, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1171, 'Hallmark Hotels', 'null', 1173, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1172, 'Hamdan Jayadi', 'null', 1174, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1173, 'Hamilton Island Enterprises', 'null', 1175, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1174, 'Hanafubuki', 'null', 1176, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1175, 'Handgrowing', 'null', 1177, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1176, 'Handys', 'null', 1178, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1177, 'Hanging Kite Apartments', 'null', 1179, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1178, 'Hankyu-Hanshin-Daiichi Hotel Group', 'null', 1180, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1179, 'Hanmadan', 'null', 1181, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1180, 'Hans Group', 'null', 1182, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1181, 'Hansen Gateway', 'null', 1183, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1182, 'Hanting Inns & Hotels', 'null', 1184, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1183, 'Happy 8 Retreat Group', 'null', 1185, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1184, 'Happy Hoildays', 'null', 1186, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1185, 'Happy People', 'null', 1187, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1186, 'Happy Place Condo', 'null', 1188, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1187, 'Happy Rooms_JP', 'null', 1189, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1188, 'Happy Tokyo Office', 'null', 1190, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1189, 'Happy Zleepy', 'null', 1191, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1190, 'Harbour Plaza Hotels & Resorts', 'null', 1192, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1191, 'Hardage Group', 'null', 1193, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1192, 'Harjinder Property', 'null', 1194, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1193, 'Harlequin Hotels & Resorts', 'null', 1195, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1194, 'HAS', 'null', 1196, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1195, 'Hase', 'null', 1197, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1196, 'Hatena Solutions', 'null', 1198, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1197, 'Hayatudin', 'null', 1199, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1198, 'H-Bridge_JP', 'null', 1163, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1199, 'HCC Hotels', 'null', 1200, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1200, 'Heartland Inn', 'null', 1201, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1201, 'Hearton Hotel', 'null', 1202, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1202, 'Heide Emigre Thailand', 'null', 1203, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1203, 'Heiwa Fukushi Yukokan', 'null', 1204, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1204, 'Hello Aparments', 'null', 1205, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1205, 'Hello Apartments New York', 'null', 1206, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1206, 'Hello Guest_C', 'null', 1207, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1207, 'Helmsley & Harley Hotels', 'null', 1208, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1208, 'Help2Rent', 'null', 1209, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1209, 'Henann Group of Resorts', 'null', 1210, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1210, 'Hendra Management', 'null', 1211, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1211, 'Hendry Pro', 'null', 1212, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1212, 'Hengky Cendana', 'null', 1213, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1213, 'Henn na Hotel', 'null', 1214, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1214, 'Henry\'s Apartment', 'null', 1215, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1215, 'Hercules Property', 'null', 1216, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1216, 'Here House', 'null', 1217, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1217, 'Heritage Collection', 'null', 1218, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1218, 'Heritage Group', 'null', 1219, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1219, 'Heritage Hotels (New Zealand)', 'null', 1220, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1220, 'Herla', 'null', 1221, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1221, 'Hesperia Hotels & Resorts', 'null', 1222, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1222, 'HeyMi', 'null', 1223, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1223, 'Hh GUEST HOUSE', 'null', 1224, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1224, 'HIG Group', 'null', 1229, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1225, 'HIM Hospitality', 'null', 1235, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1226, 'Hi5 Apartments', 'null', 1225, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1227, 'Hide Out Okinawa', 'null', 1226, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1228, 'Hien Thao TA', 'null', 1227, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1229, 'Hifumi', 'null', 1228, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1230, 'High Tech Hoteles', 'null', 1230, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1231, 'Highgate Hotels', 'null', 1231, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1232, 'HiGuests', 'null', 1232, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1233, 'hiii-Homtel', 'null', 1233, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1234, 'Hilton Worldwide', 'null', 1234, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1235, 'Hintown_C', 'null', 1236, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1236, 'Hiro and Saki JP', 'null', 1237, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1237, 'Historic Hotels of Europe', 'null', 1238, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1238, 'HK CTS Hotels', 'null', 1239, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1239, 'HK Hotels', 'null', 1240, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1240, 'HKG-Connectivity-test Chain', 'null', 1241, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1241, 'HM Hotels', 'null', 1242, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1242, 'HMH Hotel Group', 'null', 1243, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1243, 'HMI Hotel Group', 'null', 1244, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1244, 'Hoa Tran', 'null', 1245, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1245, 'Hoang kim Group', 'null', 1246, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1246, 'Hoang Son', 'null', 1247, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1247, 'Hoasun', 'null', 1248, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1248, 'HOC Apartment Thailand', 'null', 1249, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1249, 'Hokkaido Jutaku Shukuhaku', 'null', 1250, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1250, 'Hokkaido Style', 'null', 1251, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1251, 'Holiday Accommodation Pty Ltd', 'null', 1253, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1252, 'Holiday Great Ocean Road', 'null', 1254, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1253, 'Holiday Homes QLD', 'null', 1255, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1254, 'Holiday Hotels & Resorts', 'null', 1256, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1255, 'Holiday Nelson', 'null', 1257, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1256, 'Holiday Rentals', 'null', 1258, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1257, 'Holiday Rentals Pattaya', 'null', 1259, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1258, 'Holiday Velvet', 'null', 1260, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1259, 'Holiday Villa', 'null', 1261, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1260, 'Holiday Villa Hotels & Resorts', 'null', 1262, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1261, 'Holiday Villa Network', 'null', 1263, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1262, 'Holiday Villa Thailand Co., Ltd', 'null', 1264, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1263, 'Holidays2Malaga', 'null', 1265, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1264, 'HoliHouse_C', 'null', 1266, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1265, 'Holi-Rent', 'null', 1252, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1266, 'Hollyear Hotels', 'null', 1267, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1267, 'Holy Cow Phuket_C', 'null', 1268, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1268, 'Holyguest - Luxury rentals_C', 'null', 1269, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1269, 'Holyguest_C', 'null', 1270, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1270, 'Homayoon Villa', 'null', 1271, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1271, 'Home Away From Home', 'null', 1272, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1272, 'Home Connect_C', 'null', 1273, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1273, 'Home From Home', 'null', 1274, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1274, 'Home from Home_C', 'null', 1275, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1275, 'Home Inn', 'null', 1276, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1276, 'Home n Fun', 'null', 1277, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1277, 'Home Peace Home', 'null', 1278, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1278, 'Home Select', 'null', 1279, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1279, 'Home Sweet Home Samui', 'null', 1280, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1280, 'Homearound', 'null', 1281, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1281, 'HomeHost Accommodation Group', 'null', 1282, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1282, 'Homes In Hua Hin', 'null', 1283, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1283, 'Homes in India', 'null', 1284, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1284, 'Homes Livemax', 'null', 1285, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1285, 'Homes Local Agencies', 'null', 1286, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1286, 'Homestay Baguio', 'null', 1287, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1287, 'Homestay Nagoya Hill', 'null', 1288, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1288, 'Homestay Seaview Vung Tau', 'null', 1289, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1289, 'Homestay Tembi', 'null', 1290, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1290, 'Hometel', 'null', 1291, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1291, 'Hometel Hanoi', 'null', 1292, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1292, 'Homie', 'null', 1293, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1293, 'Homie Homestay&Villa', 'null', 1294, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1294, 'Homing Place', 'null', 1295, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1295, 'Homy Group', 'null', 1296, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1296, 'HON MAN T.', 'null', 1297, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1297, 'Hong Lan TA', 'null', 1298, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1298, 'Hong Minh', 'null', 1299, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1299, 'Hoostia', 'null', 1300, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1300, 'HOP INN Hotels', 'null', 1301, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1301, 'Hori Takeo', 'null', 1302, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1302, 'Horison Hotels Group', 'null', 1303, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1303, 'Horizon Homes Samui', 'null', 1304, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1304, 'Hoshino Resort', 'null', 1305, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1305, 'Hospes', 'null', 1306, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1306, 'Hospitality Innovators Inc', 'null', 1307, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1307, 'Hospitality Operations', 'null', 1308, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1308, 'Hospo Alliance', 'null', 1309, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1309, 'Host and Lodger', 'null', 1310, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1310, 'Host Helper', 'null', 1311, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1311, 'Host Kick_C', 'null', 1312, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1312, 'Host Maker_C', 'null', 1313, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1313, 'Hostal Live', 'null', 1314, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1314, 'Hostals Castilla', 'null', 1315, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1315, 'HostAStay', 'null', 1316, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1316, 'Hostel Furoya', 'null', 1317, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1317, 'Hostel One', 'null', 1318, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1318, 'Hostemplo', 'null', 1319, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1319, 'Hostmaker_C', 'null', 1320, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1320, 'Hotel 1-2-3', 'null', 1321, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1321, 'Hotel 81', 'null', 1322, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1322, 'Hotel 88', 'null', 1323, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1323, 'Hotel 99', 'null', 1324, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1324, 'Hotel Areaone', 'null', 1325, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1325, 'Hotel Aryaduta', 'null', 1326, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1326, 'Hotel Clover', 'null', 1327, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1327, 'Hotel De La Paix', 'null', 1328, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1328, 'Hotel du Vin', 'null', 1329, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1329, 'Hotel Equatorial Group', 'null', 1330, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1330, 'Hotel Fine Group', 'null', 1331, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1331, 'Hotel Goonline Management', 'null', 1332, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1332, 'Hotel Help', 'null', 1333, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1333, 'Hotel Hokke Club Group', 'null', 1334, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1334, 'Hotel Keihan', 'null', 1335, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1335, 'Hotel Livemax', 'null', 1336, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1336, 'Hotel Monterey Group', 'null', 1337, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1337, 'Hotel Revenue', 'null', 1338, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1338, 'Hotel Royal Group', 'null', 1339, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1339, 'Hotel San Francisco', 'null', 1340, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1340, 'Hotel San Marco', 'null', 1341, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1341, 'Hotel Sentral', 'null', 1342, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1342, 'Hotel Sentral Group', 'null', 1343, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1343, 'Hotel Seri Malaysia', 'null', 1344, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1344, 'Hotel Skypark', 'null', 1345, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1345, 'Hotel Sogo', 'null', 1346, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1346, 'Hotel Tetora Group', 'null', 1347, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1347, 'Hotel Trend', 'null', 1348, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1348, 'Hotel Trusty', 'null', 1349, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1349, 'Hotel WBF', 'null', 1350, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1350, 'Hotel Wing International', 'null', 1351, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1351, 'Hotel Α-1 Group', 'null', 1352, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1352, 'Hotelarius', 'null', 1353, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1353, 'Hoteles Catalonia', 'null', 1354, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1354, 'Hoteles Mision', 'null', 1355, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1355, 'Hoteles R-H', 'null', 1356, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1356, 'Hoteles Santos', 'null', 1357, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1357, 'Hoteles Silken', 'null', 1358, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1358, 'Hotello', 'null', 1359, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1359, 'Hotels & Preference', 'null', 1360, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1360, 'Hotels by Fassbind', 'null', 1361, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1361, 'Hotels de Paris Rive Gauche', 'null', 1362, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1362, 'Hotels du Roy', 'null', 1363, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1363, 'Hotels Group', 'null', 1364, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1364, 'Hotels Mision', 'null', 1365, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1365, 'Hotels Solutions Direct', 'null', 1366, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1366, 'Hotelz Group', 'null', 1367, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1367, 'Hotusa Hotels', 'null', 1368, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1368, 'House in Bandung', 'null', 1369, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1369, 'House in Danang', 'null', 1370, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1370, 'House of Asia', 'null', 1371, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1371, 'House of Chandra', 'null', 1372, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1372, 'House of Memory', 'null', 1373, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1373, 'House Sarah', 'null', 1374, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1374, 'HPL', 'null', 1375, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1375, 'HPW Group', 'null', 1376, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1376, 'HQ Anest', 'null', 1377, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1377, 'HQ Japan ParkHome', 'null', 1378, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1378, 'HQ Kokusai Kikaku', 'null', 1379, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1379, 'HQ Riverestate', 'null', 1380, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1380, 'H-Top Hotels Group', 'null', 1164, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1381, 'Hua Hin Fever', 'null', 1381, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1382, 'Hua Hin Property Online', 'null', 1382, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1383, 'Hua Shan Art Inn', 'null', 1383, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1384, 'HuahinCondo4Rent', 'null', 1384, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1385, 'Huazhu Hotels Group', 'null', 1385, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1386, 'Human Company', 'null', 1386, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1387, 'Humus Hospitality', 'null', 1387, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1388, 'Hunguest Hotels', 'null', 1388, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1389, 'Huri Saryan', 'null', 1389, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1390, 'Husa Hoteles', 'null', 1390, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1391, 'HW House', 'null', 1391, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1392, 'Hyatt Hotels', 'null', 1392, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1393, 'Hyatt Place Hotels', 'null', 1393, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1394, 'I Fukawa', 'null', 1394, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1395, 'I Jackson Aberia', 'null', 1395, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1396, 'I Ogaki', 'null', 1396, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1397, 'I Putu Gede Suriyantana', 'null', 1397, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1398, 'I SU Sang Un', 'null', 1398, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1399, 'I Sunsun house', 'null', 1399, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1400, 'I Wayan Yudiarta', 'null', 1400, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1401, 'Iabsakul Property', 'null', 1402, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1402, 'Ibeng Group', 'null', 1403, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1403, 'Iberostar Hotels & Resorts', 'null', 1404, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1404, 'Ibrahim', 'null', 1405, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1405, 'Ichigo Ichie', 'null', 1407, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1406, 'Iconic Hotels', 'null', 1408, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1407, 'Ida Octaviani Property', 'null', 1409, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1408, 'Idea Hotels', 'null', 1410, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1409, 'IGB', 'null', 1411, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1410, 'IHQ 414929278@qq.com', 'null', 1413, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1411, 'IHQ Fukuoka Yoshino968', 'null', 1414, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1412, 'IHQ Kato-11', 'null', 1415, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1413, 'IHQ Kyonokatadomari', 'null', 1416, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1414, 'IHQ Kyoto Eikosha Otomari', 'null', 1417, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1415, 'IHQ Mintkingen', 'null', 1418, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1416, 'IHQ Ohori House', 'null', 1419, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1417, 'IHQ Osaka', 'null', 1420, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1418, 'IHQ Osaka Chunyingchi', 'null', 1421, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1419, 'IHQ Osaka Fun World', 'null', 1422, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1420, 'IHQ Osaka Iwamoto', 'null', 1423, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1421, 'IHQ Osaka Kazuki Masai', 'null', 1424, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1422, 'IHQ Osaka Nami', 'null', 1425, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1423, 'IHQ Osaka Song', 'null', 1426, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1424, 'IHQ Osaka Toshihiro Boku (Earth Group)', 'null', 1427, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1425, 'IHQ Osaka Yoko.chameleo', 'null', 1428, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1426, 'IHQ Ryota Nakanishi', 'null', 1429, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1427, 'IHQ Sapporo', 'null', 1430, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1428, 'IHQ TM', 'null', 1431, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1429, 'IHQ TMIH', 'null', 1432, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1430, 'IHQ Tokyo', 'null', 1433, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1431, 'IHQ Tokyo Happy Train Shinjuku', 'null', 1434, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1432, 'IHQ Tokyo Yunting3542', 'null', 1435, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1433, 'Ihwan Roosyanto', 'null', 1436, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1434, 'Ilunion Hotels', 'null', 1437, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1435, 'Imagine Bali Villa', 'null', 1438, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1436, 'Immogroom', 'null', 1439, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1437, 'Imperial College', 'null', 1440, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1438, 'Imperial Group of Hotels', 'null', 1441, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1439, 'Imperial Hotels Group', 'null', 1442, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1440, 'Impiana', 'null', 1443, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1441, 'Impressco', 'null', 1444, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1442, 'In The Hood Hospitality', 'null', 1445, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1443, 'Indar Jo', 'null', 1446, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1444, 'Indi Phuket', 'null', 1447, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1445, 'Indigo Suites', 'null', 1448, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1446, 'Individual Bali Villas', 'null', 1449, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1447, 'Infinity Property', 'null', 1450, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1448, 'Ingenia', 'null', 1451, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1449, 'Ini Vie Hospitality', 'null', 1452, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1450, 'Iniciativas Guscar', 'null', 1453, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1451, 'Ink Accommodation_C', 'null', 1454, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1452, 'Inna Hotel Group', 'null', 1456, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1453, 'Inna Maulina', 'null', 1457, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1454, 'InnApartment', 'null', 1458, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1455, 'Innotality', 'null', 1459, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1456, 'Innovation Style', 'null', 1460, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1457, 'Insail Hotels Group', 'null', 1461, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1458, 'Inside', 'null', 1462, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1459, 'IntercityHotel', 'null', 1463, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1460, 'InterContinental Hotels Group', 'null', 1464, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1461, 'Interhome', 'null', 1465, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1462, 'Interindo Group', 'null', 1466, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1463, 'IntiWhiz Hotels', 'null', 1467, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1464, 'Intour Group', 'null', 1468, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1465, 'IPR', 'null', 1469, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1466, 'Ira Prisma Group', 'null', 1471, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1467, 'Irfan Hasbi Basma', 'null', 1472, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1468, 'Irma Aprita', 'null', 1473, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1469, 'Irong Group', 'null', 1474, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1470, 'Irooms Apartment', 'null', 1475, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1471, 'IRS Royal Apartments', 'null', 1476, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1472, 'Isak Mongan', 'null', 1477, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1473, 'Ishin Hotels', 'null', 1478, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1474, 'ISJ', 'null', 1479, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1475, 'Islands Stay Hotels', 'null', 1480, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1476, 'Isrentals_C', 'null', 1481, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1477, 'Isrotel', 'null', 1482, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1478, 'Ista', 'null', 1483, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1479, 'Isvara', 'null', 1484, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1480, 'ITC Welcomgroup Hotels Palaces and Resorts', 'null', 1485, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1481, 'ITI Hotels', 'null', 1486, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1482, 'Itoen Hotels', 'null', 1487, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1483, 'ITX', 'null', 1488, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1484, 'IVL Property', 'null', 1489, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1485, 'Ivy Villa', 'null', 1490, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1486, 'Iwasaki Maki', 'null', 1491, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1487, 'Izumi Hotels', 'null', 1492, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1488, 'iCheck Inn Gropus', 'null', 1406, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1489, 'iHome Homestay', 'null', 1412, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1490, 'i-Hotel', 'null', 1401, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1491, 'inn-tellingence Hotels', 'null', 1455, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1492, 'iproperti', 'null', 1470, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1493, 'J&I home', 'null', 1493, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1494, 'JA Hotels & Resort', 'null', 1494, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1495, 'Jackson Homestay', 'null', 1495, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1496, 'Jacky', 'null', 1496, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1497, 'Jaelani Qadir', 'null', 1497, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1498, 'Jakarta Property', 'null', 1498, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1499, 'JAL Hotels', 'null', 1499, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1500, 'James Kok', 'null', 1500, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1501, 'Jang Paza', 'null', 1501, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1502, 'Janjao Property', 'null', 1502, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1503, 'Jannah Group', 'null', 1503, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1504, 'Japan Association of Secluded Hot Spring Inns', 'null', 1504, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1505, 'Japan International Solutions', 'null', 1505, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1506, 'Japan La Casa', 'null', 1506, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1507, 'Japan Style West', 'null', 1507, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1508, 'Japan Tourism Corporation', 'null', 1508, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1509, 'Japan World Wide Planning Rebirth', 'null', 1509, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1510, 'Japan@home', 'null', 1510, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1511, 'Japango_JP', 'null', 1511, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1512, 'Japanian', 'null', 1512, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1513, 'Japaning hotel Tenjin', 'null', 1513, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1514, 'Jasmine Residence', 'null', 1514, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1515, 'Jasmine Suite', 'null', 1515, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1516, 'Jason Properties', 'null', 1516, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1517, 'Jayakarta Hotels & Resorts', 'null', 1517, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1518, 'Jayarahayu Group', 'null', 1518, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1519, 'Jazz Apt', 'null', 1519, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1520, 'JB Condo Rentals', 'null', 1520, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1521, 'Jebel Ali International Hotels', 'null', 1521, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1522, 'JENDELA360', 'null', 1522, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1523, 'Jenny Properties', 'null', 1523, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1524, 'Jenny\'s Retreats', 'null', 1524, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1525, 'Jessy Guest House', 'null', 1525, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1526, 'Jet Set Let Ltd_C', 'null', 1526, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1527, 'Jethro Property', 'null', 1527, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1528, 'Jetta Enterprise', 'null', 1528, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1529, 'Jetwing Hotels', 'null', 1529, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1530, 'Jimmy Homestay', 'null', 1530, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1531, 'Jinjiang International', 'null', 1531, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1532, 'Jinling Hotels & Resorts', 'null', 1532, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1533, 'JJ Hospitality', 'null', 1533, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1534, 'JL RICH RESOURCES ENTERPRISE', 'null', 1534, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1535, 'JM Hoteles', 'null', 1535, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1536, 'Jo Condo Unit', 'null', 1536, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1537, 'Joany Villa', 'null', 1537, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1538, 'Joe Yohanes Kartika', 'null', 1538, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1539, 'Joglo Villa Bali', 'null', 1539, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1540, 'John Boutique Villa', 'null', 1540, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1541, 'John D. Condotel & Staycation ', 'null', 1541, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1542, 'John NgChengSwee', 'null', 1542, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1543, 'Jolly Budiharti', 'null', 1543, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1544, 'Jopi Rooms', 'null', 1544, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1545, 'Joy', 'null', 1545, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1546, 'Joy Supanat Property', 'null', 1546, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1547, 'JP airbbbbb(DNU)', 'null', 1547, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1548, 'JP Airdream.com', 'null', 1548, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1549, 'JP angel-r', 'null', 1549, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1550, 'JP Bigsunli', 'null', 1550, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1551, 'JP Broworks2016', 'null', 1551, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1552, 'JP Casa Viento Stay', 'null', 1552, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1553, 'JP Chunhedesign', 'null', 1553, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1554, 'JP cityhotel.osaka', 'null', 1554, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1555, 'JP fuku5034', 'null', 1555, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1556, 'JP Hospo Agoda(DNU)', 'null', 1556, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1557, 'JP IHQ Chenglei19820419', 'null', 1557, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1558, 'JP IHQ Osaka rddbk1688', 'null', 1558, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1559, 'JP Shirakabanoyado', 'null', 1559, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1560, 'JP Tokyosharehouse.com', 'null', 1560, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1561, 'jp xiangxiang.zhang324', 'null', 1561, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1562, 'JP Yokosokansai', 'null', 1562, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1563, 'JP_Acardia_AH', 'null', 1563, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1564, 'JP_Aikansha', 'null', 1564, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1565, 'JP_AOCA', 'null', 1565, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1566, 'JP_BNBCARES', 'null', 1566, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1567, 'JP_FukuokaNow', 'null', 1567, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1568, 'JP_Japango', 'null', 1568, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1569, 'JP_Kelly_House', 'null', 1569, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1570, 'JP_LBL', 'null', 1570, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1571, 'JP_Mdex', 'null', 1571, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1572, 'JP_MrKinjo', 'null', 1572, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1573, 'JP_PJP', 'null', 1573, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1574, 'JP_Sai Industries (Ideal Resort)', 'null', 1574, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1575, 'JP_SHI(s-hotel)', 'null', 1575, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1576, 'JP_Sumuka_Life', 'null', 1576, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1577, 'JP_Tomarunen', 'null', 1577, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1578, 'JPT', 'null', 1578, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1579, 'JQ Innovation', 'null', 1579, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1580, 'JR Hotel Group', 'null', 1580, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1581, 'JSB Property', 'null', 1581, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1582, 'JSM', 'null', 1582, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1583, 'JUCY', 'null', 1583, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1584, 'Julfan Basma Group', 'null', 1584, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1585, 'Julia Real', 'null', 1585, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1586, 'July Pattaya', 'null', 1586, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1587, 'Jumeirah', 'null', 1587, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1588, 'Jung Soo Lee', 'null', 1588, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1589, 'Jupiter Hotels', 'null', 1589, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1590, 'Juragan Property', 'null', 1590, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1591, 'Jurys Inn', 'null', 1591, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1592, 'Justa Hotels & Resorts', 'null', 1592, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1593, 'Justin Vinhomes', 'null', 1593, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1594, 'Juvy\'s Place', 'null', 1594, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1595, 'K Squared_C', 'null', 1595, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1596, 'K&K', 'null', 1599, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1597, 'Kaani Hotels', 'null', 1600, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1598, 'Kafuna.A', 'null', 1601, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1599, 'Kagum Group', 'null', 1602, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1600, 'Kai Chen Properties', 'null', 1603, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1601, 'Kaikon', 'null', 1604, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1602, 'Kaikoura Holiday Homes', 'null', 1605, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1603, 'Kaimoo Resorts & Hotels', 'null', 1606, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1604, 'Kamenoi Hotel', 'null', 1607, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1605, 'Kampung Wisata Kali Code', 'null', 1608, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1606, 'Kana\'s Room', 'null', 1609, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1607, 'Kanematsu', 'null', 1610, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1608, 'Kanpo no Yado', 'null', 1611, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1609, 'Kaohsiung Siziwan', 'null', 1612, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1610, 'Karabao', 'null', 1613, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1611, 'Karaksa Hotel', 'null', 1614, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1612, 'Karang Kedemple', 'null', 1615, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1613, 'KAREBA GROUP', 'null', 1616, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1614, 'KARISMA HOTELS', 'null', 1617, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1615, 'Kariyushi Hotels', 'null', 1618, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1616, 'Kase Group', 'null', 1619, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1617, 'Kauai Real Estate_C', 'null', 1620, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1618, 'Kaya Hotels & Resorts', 'null', 1621, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1619, 'Kayana Tour', 'null', 1622, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1620, 'Kayu Putih Bali', 'null', 1623, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1621, 'Kazuhiko Isozaki', 'null', 1624, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1622, 'KC Hotels & Resorts', 'null', 1625, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1623, 'K-carve life', 'null', 1596, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1624, 'Keahotels', 'null', 1626, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1625, 'Keetapat Property', 'null', 1627, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1626, 'Kei Villas', 'null', 1628, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1627, 'Keikyu EX Inn', 'null', 1629, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1628, 'Keio Presso Inn', 'null', 1630, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1629, 'Keita Homestay', 'null', 1631, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1630, 'Kejayaan 65 Residence', 'null', 1632, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1631, 'Kelly Inns', 'null', 1633, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1632, 'Kempinski', 'null', 1634, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1633, 'Kending Hotels', 'null', 1635, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1634, 'Kerpooh Property', 'null', 1636, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1635, 'KervanSaray Hotels', 'null', 1637, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1636, 'Kerzner International', 'null', 1638, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1637, 'Key One', 'null', 1639, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1638, 'Keypro', 'null', 1640, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1639, 'Keys Hotels', 'null', 1641, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1640, 'Keys Technology_JP', 'null', 1642, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1641, 'Keywii_C', 'null', 1643, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1642, 'Khaosan Tokyo Guest House', 'null', 1644, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1643, 'KHC (Kibutzim)', 'null', 1645, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1644, 'Kibbutz Hotels', 'null', 1646, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1645, 'Kieu Trang', 'null', 1647, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1646, 'Kiev Apartment Now', 'null', 1648, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1647, 'Kiev Apartments', 'null', 1649, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1648, 'Kiki', 'null', 1650, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1649, 'Kim Hyeonmi', 'null', 1651, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1650, 'Kim Properties', 'null', 1652, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1651, 'Kimpton Hotels & Restaurant Group', 'null', 1653, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1652, 'Kingdom Villas', 'null', 1654, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1653, 'Kingsland Studios', 'null', 1655, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1654, 'Kinifrog Property', 'null', 1656, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1655, 'Kiwi Holiday Parks', 'null', 1657, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1656, 'KL Shortstay', 'null', 1658, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1657, 'KL101', 'null', 1659, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1658, 'KLIH', 'null', 1660, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1659, 'KLS Resorts', 'null', 1661, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1660, 'KNP Management (Stay Samui)', 'null', 1662, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1661, 'Koalabeds Group', 'null', 1663, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1662, 'Koentari Home', 'null', 1664, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1663, 'Kohabi Home JP', 'null', 1665, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1664, 'Kokyonoyado', 'null', 1666, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1665, 'Komang Arjawa', 'null', 1667, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1666, 'Kona Coast Vacations_C', 'null', 1668, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1667, 'KOS', 'null', 1669, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1668, 'Kos Elsa', 'null', 1670, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1669, 'Kos Muwardi 34', 'null', 1671, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1670, 'Kos U9A', 'null', 1672, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1671, 'Kosciusko First National_C', 'null', 1673, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1672, 'Kosmopolito Hotels International', 'null', 1674, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1673, 'KOST AYU', 'null', 1675, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1674, 'KOST URIP', 'null', 1676, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1675, 'Kost Wily', 'null', 1677, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1676, 'Kowa-estate', 'null', 1678, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1677, 'KP Wong', 'null', 1679, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1678, 'Krabi Villa Management by Krabi Riviera Company Ltd.', 'null', 1680, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1679, 'Krabirents', 'null', 1681, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1680, 'K\'s House', 'null', 1598, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1681, 'KSK Japan', 'null', 1682, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1682, 'KT9house', 'null', 1683, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1683, 'K-Togashi Value build JP', 'null', 1597, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1684, 'Kubu Carik', 'null', 1684, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1685, 'Kufu', 'null', 1685, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1686, 'Kukuh Januardi', 'null', 1686, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1687, 'Kuretakeso', 'null', 1687, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1688, 'Kusuma Estate', 'null', 1688, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1689, 'Kuyakitoda_AsapOne_JP', 'null', 1689, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1690, 'Kyoritsu Resort', 'null', 1690, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1691, 'Kyoto machiya', 'null', 1691, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1692, 'Kyoto Vacation Rental Wonderland', 'null', 1692, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1693, 'Kyukamura Hotels', 'null', 1693, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1694, 'La Bella Casa Bali', 'null', 1697, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1695, 'La Cabane', 'null', 1698, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1696, 'La Comunity_C', 'null', 1699, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1697, 'La Joya & La Joya II Biu Biu', 'null', 1700, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1698, 'La Mer Homes_C', 'null', 1701, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1699, 'La Quinta Inns & Suites', 'null', 1702, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1700, 'La Villa Bali', 'null', 1703, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1701, 'L\'Abode Accommodation', 'null', 1694, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1702, 'Labor Land', 'null', 1704, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1703, 'Labranda Hotels & Resorts', 'null', 1705, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1704, 'Laddawan Property', 'null', 1706, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1705, 'LAE', 'null', 1707, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1706, 'Lafontaine Group', 'null', 1708, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1707, 'Laguna Phuket', 'null', 1709, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1708, 'Lakbayan Hotels', 'null', 1710, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1709, 'Lakeshores Holiday & Short Stay Accommodation', 'null', 1711, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1710, 'LaLiT Hotels Palaces and Resorts', 'null', 1712, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1711, 'Lalu Arjuna', 'null', 1713, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1712, 'Lam Ha', 'null', 1714, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1713, 'Lampin Yasuda', 'null', 1715, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1714, 'Land Japan', 'null', 1716, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1715, 'LANDEE', 'null', 1717, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1716, 'Landison', 'null', 1718, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1717, 'Landlord', 'null', 1719, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1718, 'Landmark Hotels & Suites', 'null', 1720, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1719, 'Langebaan Holiday Homes', 'null', 1721, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1720, 'Langham Hotels International', 'null', 1722, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1721, 'Lanson Place', 'null', 1723, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1722, 'LanzaroteLanzarote_C', 'null', 1724, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1723, 'Larkspur', 'null', 1725, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1724, 'Lavana', 'null', 1726, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1725, 'Lavanda', 'null', 1727, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1726, 'Lavender Apartment', 'null', 1728, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1727, 'Lavender Villa Spa', 'null', 1729, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1728, 'Lavie En Rose', 'null', 1730, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1729, 'LCB groups', 'null', 1731, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1730, 'LDG Serviced Apartments', 'null', 1732, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1731, 'LDK', 'null', 1733, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1732, 'Le Apple', 'null', 1734, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1733, 'Le Bleu - Nha Trong Xom', 'null', 1735, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1734, 'Le Green Hotel & Suite', 'null', 1736, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1735, 'LE Hotels Group', 'null', 1737, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1736, 'Le Sabot Bali', 'null', 1738, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1737, 'Le Soleil De Van', 'null', 1739, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1738, 'Leading', 'null', 1740, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1739, 'Leading Hotels of the World', 'null', 1741, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1740, 'LED', 'null', 1742, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1741, 'Lee', 'null', 1743, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1742, 'Leeu Collection', 'null', 1744, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1743, 'Legacy Hotels and Resorts', 'null', 1745, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1744, 'Legend Hotels International Corporation', 'null', 1746, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1745, 'Legend Japan', 'null', 1747, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1746, 'Legian Sunset Residence', 'null', 1748, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1747, 'Lemon Tree Hotels', 'null', 1749, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1748, 'Lenny Syam', 'null', 1750, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1749, 'Leo Group', 'null', 1751, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1750, 'Leogrand', 'null', 1752, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1751, 'Leon Gfeel', 'null', 1753, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1752, 'Leonardi Hotels', 'null', 1754, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1753, 'Leonardo Hotels', 'null', 1755, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1754, 'Les Hotels de Paris', 'null', 1756, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1755, 'Les Relais de Paris - Jardins de Paris', 'null', 1757, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1756, 'Let Me Inn', 'null', 1758, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1757, 'L\'Heritage Hotel', 'null', 1695, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1758, 'L\'Hotel', 'null', 1696, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1759, 'LIA KOST', 'null', 1760, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1760, 'Li Qin', 'null', 1759, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1761, 'Lianglinman Property', 'null', 1761, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1762, 'Lianjia Corporation', 'null', 1762, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1763, 'Libertel', 'null', 1763, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1764, 'Library Hotel Collection', 'null', 1764, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1765, 'Lidan rentals', 'null', 1765, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1766, 'Life Planning', 'null', 1766, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1767, 'Lifelulu_JP', 'null', 1767, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1768, 'Lifestyle Retreats', 'null', 1768, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1769, 'Likehome Apartment', 'null', 1769, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1770, 'Lilian Home', 'null', 1770, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1771, 'Lillie', 'null', 1771, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1772, 'Lily', 'null', 1772, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1773, 'LiLy Homestay', 'null', 1773, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1774, 'Lily\'s Condo', 'null', 1774, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1775, 'Lin Pro', 'null', 1775, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1776, 'Lineup', 'null', 1776, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1777, 'Ling Nan Hotel Group', 'null', 1777, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1778, 'Ling Properties', 'null', 1778, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1779, 'Linh Tran Group', 'null', 1779, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1780, 'Linzi', 'null', 1780, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1781, 'Lion Roars Hotels and Lodges', 'null', 1781, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1782, 'Lisbon Serviced Apartments', 'null', 1782, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1783, 'Little America Hotels', 'null', 1783, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1784, 'Little Hoi An Group', 'null', 1784, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1785, 'Liv Living', 'null', 1785, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1786, 'Live at home Bangna', 'null', 1786, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1787, 'Livin Africa', 'null', 1787, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1788, 'Living Hotels', 'null', 1788, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1789, 'Lizaplan/Kushitsu.com', 'null', 1789, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1790, 'LJ Hooker Real Estate', 'null', 1790, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1791, 'LK Group', 'null', 1791, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1792, 'lloguercerdanya_C', 'null', 1792, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1793, 'LO.AN Hotels', 'null', 1793, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1794, 'Loan Group', 'null', 1794, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1795, 'Locationwise', 'null', 1795, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1796, 'Lock Forward', 'null', 1796, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1797, 'Lodgable_C', 'null', 1797, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1798, 'Lodtunduh Sari Villa', 'null', 1798, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1799, 'Loews Hotels', 'null', 1799, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1800, 'Lofty Phuket', 'null', 1800, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1801, 'Logi -Service_C', 'null', 1801, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1802, 'Logis de France', 'null', 1802, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1803, 'Londo Bungalow', 'null', 1803, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1804, 'London Base_C', 'null', 1804, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1805, 'Long Beach Hotel Group', 'null', 1805, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1806, 'Long Stay', 'null', 1806, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1807, 'Looting Café Property', 'null', 1807, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1808, 'Lope De Vega Tower Condominium', 'null', 1808, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1809, 'Lords Hotels & Resorts', 'null', 1809, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1810, 'Lost in the Magic Vacation Homes_C', 'null', 1810, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1811, 'Lotte Hotel', 'null', 1811, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1812, 'Lotus House Hanoi', 'null', 1812, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1813, 'Louvre Hôtels', 'null', 1813, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1814, 'Lovaito Villa', 'null', 1814, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1815, 'Love I Feng Chia Night Market', 'null', 1815, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1816, 'Love Taipei', 'null', 1816, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1817, 'Lovina Beach House Villa', 'null', 1817, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1818, 'Lovina Homes', 'null', 1818, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1819, 'Lovina Krui Surf', 'null', 1819, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1820, 'Lovina Residences', 'null', 1820, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1821, 'Low Yat', 'null', 1821, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1822, 'Loyal Unicorn', 'null', 1822, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1823, 'Loyalty USA_C', 'null', 1823, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1824, 'LSE', 'null', 1824, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1825, 'Lugaris', 'null', 1825, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1826, 'Luo Properties', 'null', 1826, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1827, 'Luvill', 'null', 1827, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1828, 'Lux Rooms Night Bazaar', 'null', 1828, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1829, 'LUX* Resorts', 'null', 1829, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1830, 'Luxe in Venice', 'null', 1830, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1831, 'Luxe Worldwide Hotels', 'null', 1831, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1832, 'Luxemon Hotels Group', 'null', 1832, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1833, 'Luxstay', 'null', 1833, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1834, 'Luxury Hua Hin Property Co., Ltd', 'null', 1834, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1835, 'Luxury Lakeside Accommodation Group', 'null', 1835, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1836, 'Luxury Perth Stays', 'null', 1836, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1837, 'Luxury Rental Group_C', 'null', 1837, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1838, 'Luxury Samui Villa', 'null', 1838, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1839, 'Luxury Staycation', 'null', 1839, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1840, 'Luxury Travels', 'null', 1840, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1841, 'Luxury Villas and Homes', 'null', 1841, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1842, 'LuYue', 'null', 1842, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1843, 'Lvyue Hotels & Resorts', 'null', 1843, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1844, 'Lys Property Management', 'null', 1844, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1845, 'Lz myroad JP', 'null', 1845, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1846, 'M Boutique', 'null', 1846, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1847, 'M Design', 'null', 1847, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1848, 'M Stay', 'null', 1848, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1849, 'M Support', 'null', 1849, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1850, 'M&R Hospitality', 'null', 1852, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1851, 'M&T', 'null', 1853, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1852, 'MAADS', 'null', 1854, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1853, 'Macau CTS Hotel', 'null', 1855, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1854, 'Maccarat', 'null', 1856, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1855, 'Macdonald Hotels Group', 'null', 1857, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1856, 'Mad Monkey', 'null', 1858, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1857, 'Made Comfy', 'null', 1859, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1858, 'Madmee Property', 'null', 1860, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1859, 'Mae Rampung Beach House', 'null', 1861, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1860, 'Magic of Bali Villas', 'null', 1862, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1861, 'Magnetic Island_C', 'null', 1863, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1862, 'Magnuson Hotels', 'null', 1864, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1863, 'Mahkota Property', 'null', 1865, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1864, 'Mai Villa Group', 'null', 1866, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1865, 'Maison Prive', 'null', 1867, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1866, 'MaisonNets', 'null', 1868, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1867, 'Majestic Hotel Group', 'null', 1869, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1868, 'Majestic Hotels', 'null', 1870, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1869, 'Majordomo', 'null', 1871, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1870, 'Makarem Group', 'null', 1872, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1871, 'Makassar Kost Exclusive Group', 'null', 1873, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1872, 'Makati - Tomo\'s Condotel', 'null', 1874, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1873, 'Makluxuryliving', 'null', 1875, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1874, 'Maleo Moyo Diving', 'null', 1876, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1875, 'Mallorca Holiday Villas', 'null', 1877, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1876, 'Mallorcanorth Villa Services', 'null', 1878, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1877, 'Malmaison Hotels', 'null', 1879, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1878, 'Maman Sumarna', 'null', 1880, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1879, 'Man', 'null', 1881, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1880, 'Manara Management', 'null', 1882, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1881, 'Mandarin Oriental Hotel Group', 'null', 1883, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1882, 'Manggala Bali', 'null', 1884, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1883, 'Manhattan', 'null', 1885, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1884, 'Manila Condotel', 'null', 1886, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1885, 'Manlilu', 'null', 1887, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1886, 'Manly Stay', 'null', 1888, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1887, 'Manotel Hotel Group', 'null', 1889, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1888, 'Manseikaku Hotels', 'null', 1890, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1889, 'Mansley', 'null', 1891, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1890, 'Mantra Group', 'null', 1892, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1891, 'Marc Hotels & Resorts', 'null', 1893, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1892, 'Marcus Hotels and Resorts', 'null', 1894, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1893, 'Marenostrum and Curious', 'null', 1895, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1894, 'Margareta Nola', 'null', 1896, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1895, 'Margonda Residence', 'null', 1897, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1896, 'Marhba Holiday Homes', 'null', 1898, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1897, 'Marigold Aonang Villa', 'null', 1899, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1898, 'Maritim Hotels', 'null', 1900, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1899, 'Mark and Christine', 'null', 1901, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1900, 'Mark it', 'null', 1902, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1901, 'Marquee Residence', 'null', 1903, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1902, 'Marriott', 'null', 1904, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1903, 'Marroad Hotels', 'null', 1905, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1904, 'Martin\'s Hotels', 'null', 1906, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1905, 'Maruhide', 'null', 1907, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1906, 'Maruyama', 'null', 1908, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1907, 'Maryan Moyo Bungalows', 'null', 1909, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1908, 'Massimo Two', 'null', 1910, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1909, 'Massive Sapporo', 'null', 1911, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1910, 'Master Inn', 'null', 1912, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1911, 'Master Japan Minpaku', 'null', 1913, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1912, 'Matsue Kousan Inc', 'null', 1914, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1913, 'Matsuri Technology_JP', 'null', 1915, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1914, 'Matt Birkey Vacation Rentals_C', 'null', 1916, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1915, 'Maurice Hurand Hotels', 'null', 1917, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1916, 'Maviba Villas and Resorts', 'null', 1918, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1917, 'Max House', 'null', 1919, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1918, 'MaXhit_C', 'null', 1920, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1919, 'Maxhome', 'null', 1921, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1920, 'Maxima julianne Lindy M. Arce', 'null', 1922, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1921, 'MaxOneHotels', 'null', 1923, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1922, 'Maxstays', 'null', 1924, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1923, 'Maybourne Hotel Group', 'null', 1925, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1924, 'Mayfair Hotels & Resort', 'null', 1926, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1925, 'Mayfair Hotels&Resorts', 'null', 1927, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1926, 'Maykenbel Group', 'null', 1928, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1927, 'Mayland', 'null', 1929, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1928, 'McGrath Byron Bay', 'null', 1930, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1929, 'MCM Hotels', 'null', 1931, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1930, 'MDI', 'null', 1932, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1931, 'Mebuki', 'null', 1933, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1932, 'Mediapura', 'null', 1934, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1933, 'Mediatorat', 'null', 1935, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1934, 'Meininger Hotels', 'null', 1936, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1935, 'Meitetsu Inn', 'null', 1937, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1936, 'Melbourne Short Stay Apartments', 'null', 1938, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1937, 'Melco Resorts & Entertainment', 'null', 1939, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1938, 'Melhome_C', 'null', 1940, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1939, 'Melia Hotels International', 'null', 1941, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1940, 'Melinda group', 'null', 1942, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1941, 'Mella House Uluwatu', 'null', 1943, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1942, 'Meme Properties', 'null', 1944, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1943, 'Meninas Opera', 'null', 1945, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1944, 'Menteng Group', 'null', 1946, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1945, 'Menzies Hotels', 'null', 1947, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1946, 'Meow Homestay', 'null', 1948, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1947, 'Mercer Hotels', 'null', 1949, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1948, 'Merin City Suites Apartment', 'null', 1950, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1949, 'Merin Suites Tower', 'null', 1951, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1950, 'Meriton Suites', 'null', 1952, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1951, 'Meritus Group', 'null', 1953, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1952, 'Meritus Hotels & Resorts', 'null', 1954, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1953, 'Merivale Apartments', 'null', 1955, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1954, 'Merry Property', 'null', 1956, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1955, 'Metro Hotels', 'null', 1957, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1956, 'Metro Rent', 'null', 1958, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1957, 'Metropolitan Golden Management (MGM)', 'null', 1959, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1958, 'Mets', 'null', 1960, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1959, 'Meyer Real Estate_C', 'null', 1961, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1960, 'MGM Resorts International', 'null', 1962, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1961, 'MH Apartments', 'null', 1963, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1962, 'MH Group', 'null', 1964, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1963, 'Mi Casa Su Casa', 'null', 1965, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1964, 'Mia Macarena', 'null', 1966, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1965, 'Mickey TH', 'null', 1967, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1966, 'Middlewood Hotel & Resort', 'null', 1968, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1967, 'Midtown Rentals', 'null', 1969, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1968, 'Mielparque', 'null', 1970, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1969, 'Mikoto Far East Phil. Inc', 'null', 1971, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1970, 'Millennium & Copthorne Hotels', 'null', 1972, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1971, 'Minggu Villas', 'null', 1973, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1972, 'Mingren', 'null', 1974, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1973, 'Minh\'s Apt in Danang', 'null', 1975, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1974, 'Minor International', 'null', 1976, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1975, 'Minpaku Honpo', 'null', 1977, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1976, 'Mint Din House', 'null', 1978, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1977, 'Mint Hotels', 'null', 1979, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1978, 'Mint Resorts & Apartments', 'null', 1980, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1979, 'Miosba Homestay', 'null', 1981, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1980, 'Mirai Factory', 'null', 1982, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1981, 'Miramar Hotel and Investment', 'null', 1983, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1982, 'Miri Sato', 'null', 1984, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1983, 'Mirvac Hotel & Resort', 'null', 1985, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1984, 'Mitchell Corp', 'null', 1986, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1985, 'Mitsis Hotels', 'null', 1987, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1986, 'Mitsui Garden Hotel_DO NOT USE', 'null', 1988, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1987, 'Mitsui Garden Hotels', 'null', 1989, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1988, 'Miyako Hotels & Resorts', 'null', 1990, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1989, 'MJ', 'null', 1991, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1990, 'MK Hotel & Resort', 'null', 1992, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1991, 'Mode Duo', 'null', 1994, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1992, 'Modern Sun Estate', 'null', 1995, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1993, 'Moderno Urquinaona', 'null', 1996, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1994, 'Modo Apartment', 'null', 1997, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1995, 'Momo_JP', 'null', 1998, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1996, 'Mona Lisa Hotels and Residences', 'null', 1999, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1997, 'Mondo Hospitality', 'null', 2000, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1998, 'Mondo Living', 'null', 2001, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (1999, 'Mono Apartments', 'null', 2002, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2000, 'Montenegro-Booking_C', 'null', 2003, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2001, 'MonthStayz', 'null', 2004, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2002, 'Moon House', 'null', 2005, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2003, 'Moopun', 'null', 2006, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2004, 'Morae Travel & Tour Inc.', 'null', 2007, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2005, 'More Than a Room', 'null', 2008, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2006, 'Mo-Rentals', 'null', 1993, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2007, 'Morgans Hotel Group', 'null', 2009, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2008, 'Mornington Hotel Group', 'null', 2010, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2009, 'Moroccan Suite-Mr Liang', 'null', 2011, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2010, 'Morwing Hotels Group', 'null', 2012, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2011, 'Moshamanla Hotel Group', 'null', 2013, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2012, 'Motel 6', 'null', 2014, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2013, 'Mountain Plus_C', 'null', 2015, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2014, 'Movenpick Hotels & Resorts', 'null', 2016, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2015, 'Movenpick Residence Ekkamai', 'null', 2017, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2016, 'Mowu', 'null', 2018, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2017, 'Mr.KINJO_JP', 'null', 2019, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2018, 'M\'s Four', 'null', 1850, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2019, 'M\'s Hotel Group', 'null', 1851, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2020, 'Ms. Hsu Properties', 'null', 2020, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2021, 'Ms. Liao Properties', 'null', 2021, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2022, 'Mt.Baker Lodging_C', 'null', 2022, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2023, 'MTT Korea', 'null', 2023, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2024, 'Muar Warni Villa', 'null', 2024, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2025, 'Muh Zaenuddin Khair', 'null', 2025, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2026, 'Muhammad Gazali', 'null', 2026, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2027, 'Mulia Homestay', 'null', 2027, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2028, 'Musliadi Nasution', 'null', 2028, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2029, 'MXC Condotel', 'null', 2029, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2030, 'My Apatel', 'null', 2030, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2031, 'My Cannes_C', 'null', 2031, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2032, 'My Choice of Stay', 'null', 2032, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2033, 'My City Apartments', 'null', 2033, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2034, 'My Get Away Asia', 'null', 2034, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2035, 'My Gia', 'null', 2035, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2036, 'My Holiday WA', 'null', 2036, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2037, 'MY Home', 'null', 2037, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2038, 'My Hotel', 'null', 2038, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2039, 'My Place', 'null', 2039, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2040, 'My Rooms', 'null', 2040, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2041, 'My Story Hotels', 'null', 2041, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2042, 'My Villa Group', 'null', 2042, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2043, 'Myconian Collection', 'null', 2043, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2044, 'myNext', 'null', 2044, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2045, 'Mystays Hotel Management', 'null', 2045, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2046, 'Nadezhda', 'null', 2046, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2047, 'Nadler Hotels', 'null', 2047, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2048, 'Nadya Properties', 'null', 2048, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2049, 'Nagisa Bali', 'null', 2049, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2050, 'Naiade', 'null', 2050, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2051, 'Nakula Management', 'null', 2051, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2052, 'Nam Phuong Home', 'null', 2052, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2053, 'Namba Jisho', 'null', 2053, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2054, 'Namto House', 'null', 2054, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2055, 'Nancy Properties', 'null', 2055, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2056, 'Nandu Hospitality', 'null', 2056, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2057, 'Nanturuj Tower', 'null', 2057, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2058, 'Narai Hotel Group', 'null', 2058, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2059, 'Nasma Luxury Stays', 'null', 2059, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2060, 'NASYKEV', 'null', 2060, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2061, 'Natan Villa', 'null', 2061, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2062, 'National Company for Tourism Group', 'null', 2062, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2063, 'Native Apartments', 'null', 2063, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2064, 'Natsusan(Summer)_JP', 'null', 2064, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2065, 'Naumi', 'null', 2065, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2066, 'Nazeki Villa', 'null', 2066, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2067, 'Nazwa Room', 'null', 2067, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2068, 'NB Holidays AU', 'null', 2068, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2069, 'NB Villas', 'null', 2069, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2070, 'Ndalem Maharani Guesthouse', 'null', 2070, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2071, 'Ndalem Mantrigawen', 'null', 2071, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2072, 'Ndalem Natan Royal Heritage', 'null', 2072, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2073, 'Ndalem Sarengat', 'null', 2073, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2074, 'Nejico', 'null', 2074, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2075, 'Nest', 'null', 2075, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2076, 'Nest Hotel', 'null', 2076, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2077, 'Nesting Nomad', 'null', 2077, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2078, 'Nevsky Hotel Group', 'null', 2078, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2079, 'New Arabian Homes', 'null', 2079, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2080, 'New Century Tourism Group', 'null', 2080, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2081, 'New Gaea Hotels', 'null', 2081, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2082, 'New Gloria', 'null', 2082, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2083, 'New Life Villas', 'null', 2083, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2084, 'New Otani Hotels', 'null', 2084, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2085, 'New Town', 'null', 2085, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2086, 'New Wave Hotel', 'null', 2086, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2087, 'New World Hotels', 'null', 2087, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2088, 'NewLink', 'null', 2088, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2089, 'Newmark Hotels', 'null', 2089, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2090, 'Newton Residence', 'null', 2090, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2091, 'Next Story Group', 'null', 2091, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2092, 'Nextage', 'null', 2092, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2093, 'Nexus Regency', 'null', 2093, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2094, 'NH Hotels', 'null', 2094, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2095, 'NHA Master - Do Not Use', 'null', 2095, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2096, 'Nha Trang Harbor', 'null', 2096, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2097, 'Nha Trang Wonderland', 'null', 2097, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2098, 'NHM', 'null', 2098, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2099, 'Nicely Decorated', 'null', 2099, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2100, 'NicoJapan', 'null', 2100, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2101, 'Nimit Manatpon', 'null', 2101, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2102, 'Nimman Expat', 'null', 2102, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2103, 'Nine Hours', 'null', 2103, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2104, 'Ninety Six Hotel', 'null', 2104, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2105, 'Nirvana Holiday Homes', 'null', 2105, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2106, 'Nirwana Guest House', 'null', 2106, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2107, 'Nisade', 'null', 2107, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2108, 'Nishitetsu Hotel Group', 'null', 2108, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2109, 'Nishitetsu Inn', 'null', 2109, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2110, 'Nittakarn Property', 'null', 2110, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2111, 'No chain', 'null', 2111, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2112, 'NOAHCorporation', 'null', 2112, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2113, 'Nobel House Hotels & Resorts', 'null', 2113, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2114, 'Noguchi Kanko Group Hotels', 'null', 2114, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2115, 'Nomads World Hotel', 'null', 2115, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2116, 'Nomura Hiroyuki JP', 'null', 2116, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2117, 'Nordic Hotels', 'null', 2117, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2118, 'NOSTOI', 'null', 2118, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2119, 'Novascotia Boutique Homes', 'null', 2119, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2120, 'Novia', 'null', 2120, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2121, 'Novum Hospitality', 'null', 2121, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2122, 'Nox Rentals_C', 'null', 2122, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2123, 'NRMA', 'null', 2123, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2124, 'NTA Tower', 'null', 2124, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2125, 'Nueh GH', 'null', 2125, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2126, 'Nugroho Puji', 'null', 2126, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2127, 'Nuibay Sunset', 'null', 2127, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2128, 'Nunez i Navarro', 'null', 2128, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2129, 'Nurma Warianti', 'null', 2129, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2130, 'Nusa Dua Beach', 'null', 2130, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2131, 'NvUps Villa', 'null', 2131, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2132, 'NXimending Guesthouse', 'null', 2132, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2133, 'Nyanse Homestay', 'null', 2133, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2134, 'Nyoman Conto', 'null', 2134, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2135, 'Nyoman Dana', 'null', 2135, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2136, 'Oak Grove Inn', 'null', 2136, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2137, 'Oaks Hotels & Resorts', 'null', 2137, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2138, 'Oakwood Worldwide', 'null', 2138, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2139, 'OASIS HOTELS AND RESORTS', 'null', 2141, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2140, 'Oasis Apartments', 'null', 2139, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2141, 'Oasis Collections_C', 'null', 2140, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2142, 'Oberoi Hotels & Resorts', 'null', 2142, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2143, 'Occidental Hotels & Resorts', 'null', 2143, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2144, 'Ocean Link', 'null', 2144, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2145, 'Oceania Hotels', 'null', 2145, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2146, 'Octo Property Management', 'null', 2146, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2147, 'OD Group', 'null', 2147, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2148, 'Odalys Vacances', 'null', 2148, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2149, 'Oeoe', 'null', 2149, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2150, 'OeP', 'null', 2150, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2151, 'Office Fortune', 'null', 2151, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2152, 'Ohla', 'null', 2152, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2153, 'Ohruri Group', 'null', 2153, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2154, 'Oikos', 'null', 2154, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2155, 'OK Hotels', 'null', 2155, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2156, 'Okura Hotels and Resorts', 'null', 2156, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2157, 'Okura Nikko Hotels', 'null', 2157, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2158, 'Old Town Hotels', 'null', 2158, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2159, 'Olimpic Golden Tulip', 'null', 2159, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2160, 'Olivia Hotels', 'null', 2160, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2161, 'Olleh Private House', 'null', 2161, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2162, 'Omenahotelli', 'null', 2162, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2163, 'Omni Hotels & Resorts', 'null', 2163, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2164, 'Omran Hospitality', 'null', 2164, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2165, 'Onasol Hotels', 'null', 2165, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2166, 'ONDA (Zari)', 'null', 2166, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2167, 'ONDA (Zari) Homes', 'null', 2167, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2168, 'Onda YCS', 'null', 2168, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2169, 'One Avenue', 'null', 2169, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2170, 'One Day Guesthouse', 'null', 2170, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2171, 'One Host', 'null', 2171, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2172, 'One Perfect Stay', 'null', 2172, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2173, 'One Property', 'null', 2173, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2174, 'One&Only', 'null', 2174, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2175, 'Oneday More', 'null', 2175, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2176, 'Onk propeties', 'null', 2176, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2177, 'ONOMO Hotel Group', 'null', 2177, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2178, 'Onyx Hospitality', 'null', 2178, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2179, 'Ooedo Onsen Monogatari Hotels & Resorts', 'null', 2179, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2180, 'Oops', 'null', 2180, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2181, 'Operaramblas Sans', 'null', 2181, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2182, 'Orange Hotels', 'null', 2182, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2183, 'Orange Premier', 'null', 2183, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2184, 'Orchardz Hotels', 'null', 2184, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2185, 'Orenz Pro', 'null', 2185, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2186, 'Orient-Express Hotels', 'null', 2186, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2187, 'Origami Start_C', 'null', 2187, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2188, 'Orion Hotel Group', 'null', 2188, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2189, 'Orion Hotels and Resorts', 'null', 2189, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2190, 'Orix Real Estate', 'null', 2190, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2191, 'Orkid Inn', 'null', 2191, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2192, 'Orlando Holiday Rental Homes_C', 'null', 2192, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2193, 'Ormond Group', 'null', 2193, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2194, 'Oro Beach Houses', 'null', 2194, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2195, 'Oro oro ombo group', 'null', 2195, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2196, 'ORR Real Estate', 'null', 2196, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2197, 'OrtigasRealEstate.COM,CO', 'null', 2197, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2198, 'Osaka GLI(DNU)', 'null', 2198, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2199, 'Osaki BNB JP', 'null', 2199, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2200, 'Otomari', 'null', 2200, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2201, 'Oukaen_JP', 'null', 2201, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2202, 'Outrigger Hotels & Resorts', 'null', 2202, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2203, 'Ovolo Group', 'null', 2203, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2204, 'OX Consulting', 'null', 2204, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2205, 'Oxford Hotel Group', 'null', 2205, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2206, 'Oxford Hotels & Inns', 'null', 2206, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2207, 'OYO Rooms', 'null', 2207, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2208, 'P. Trower Co., Ltd', 'null', 2208, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2209, 'Pacific Investment', 'null', 2209, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2210, 'Pacific Palms Signature Properties', 'null', 2210, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2211, 'Pacific Regency', 'null', 2211, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2212, 'Paires', 'null', 2212, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2213, 'Pajaree Property', 'null', 2213, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2214, 'PALACE RESORTS', 'null', 2214, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2215, 'Palladium Hotels Group', 'null', 2215, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2216, 'Palm Beach Holiday Rentals', 'null', 2216, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2217, 'Palm Living', 'null', 2217, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2218, 'Pam K Property', 'null', 2218, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2219, 'Pammy Property', 'null', 2219, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2220, 'Pan Pacific Hotels and Resorts', 'null', 2220, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2221, 'Panda Villa', 'null', 2221, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2222, 'Panita', 'null', 2222, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2223, 'Pansion Glory Aleluja_C', 'null', 2223, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2224, 'PaQwell Property', 'null', 2224, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2225, 'Paradise Properties Hua Hin', 'null', 2225, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2226, 'Parador Hotels & Resorts', 'null', 2226, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2227, 'Paradores Hotels', 'null', 2227, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2228, 'Paragon Village Indonesia', 'null', 2228, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2229, 'Paragon Villas', 'null', 2229, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2230, 'Parinayokp Properties', 'null', 2230, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2231, 'Paris Inn', 'null', 2231, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2232, 'Parisian Home_C', 'null', 2233, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2233, 'Paris-Nice Vacations', 'null', 2232, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2234, 'Park & Suites Apart - Hotels', 'null', 2234, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2235, 'Park Avenue Hotels & Suites', 'null', 2235, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2236, 'Park Hotels', 'null', 2236, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2237, 'Parkcity Everly Group', 'null', 2237, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2238, 'Parkes Estate', 'null', 2238, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2239, 'Parkland Group', 'null', 2239, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2240, 'Pass The Keys_C', 'null', 2240, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2241, 'Patria Hospitalities Pvt Ltd', 'null', 2241, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2242, 'Pattamaporn Property', 'null', 2242, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2243, 'Patton Hospitality', 'null', 2243, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2244, 'Paul', 'null', 2244, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2245, 'Peace Land Group', 'null', 2245, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2246, 'Pearl Hotel Management', 'null', 2246, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2247, 'Pearl-Continental Hotels & Resorts', 'null', 2247, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2248, 'Peeradech TH', 'null', 2248, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2249, 'Peermont Hotels, Casinos & Resorts', 'null', 2249, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2250, 'Pegasus', 'null', 2250, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2251, 'Pelangi Rooms', 'null', 2251, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2252, 'Pelican Stay', 'null', 2252, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2253, 'Pelita Property', 'null', 2253, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2254, 'Pendowo Huis Guesthouse', 'null', 2254, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2255, 'Penguin Homes', 'null', 2255, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2256, 'Peninsula Hotels', 'null', 2256, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2257, 'Penta Hotels', 'null', 2257, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2258, 'Per AQUUM Retreats, Resorts and Residence', 'null', 2258, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2259, 'Perfect Host Malaysia', 'null', 2259, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2260, 'Perfectly Paris', 'null', 2260, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2261, 'Perkasa Hotel', 'null', 2261, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2262, 'Pesonna Hotels', 'null', 2262, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2263, 'Pestana Hotels and Resorts', 'null', 2263, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2264, 'Pet Friendly Holiday Homes', 'null', 2264, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2265, 'Petit Grande Homes', 'null', 2265, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2266, 'Petogogan Residence', 'null', 2266, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2267, 'Petr Tomanek', 'null', 2267, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2268, 'Petra Zidar', 'null', 2268, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2269, 'Peymans', 'null', 2269, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2270, 'Ph Condohub', 'null', 2270, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2271, 'Phasute', 'null', 2271, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2272, 'Phatthraporn Property', 'null', 2272, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2273, 'PHC', 'null', 2273, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2274, 'Phi Yen', 'null', 2274, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2275, 'Phil Property Expert, Inc', 'null', 2275, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2276, 'Phillip Island Holiday Homes', 'null', 2276, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2277, 'PHM Hospitality', 'null', 2277, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2278, 'Phoenix Apartment Hanoi', 'null', 2278, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2279, 'Phoenix Inn Suites', 'null', 2279, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2280, 'Phuket Direct', 'null', 2280, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2281, 'Phuket Island Property Services Co., Ltd', 'null', 2281, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2282, 'Phuket Marbella', 'null', 2282, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2283, 'Phuket Property Expert Co., Ltd', 'null', 2283, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2284, 'Phuket Real Estate Focus', 'null', 2284, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2285, 'Phuket Real Living', 'null', 2285, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2286, 'Phuket Rent Mix', 'null', 2286, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2287, 'Phuket Vacation Homes', 'null', 2287, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2288, 'PhuketAREA-com', 'null', 2288, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2289, 'Phuketas', 'null', 2289, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2290, 'Piao Home Inn', 'null', 2290, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2291, 'Pick A Flat', 'null', 2291, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2292, 'Pico De Loro Cove Condotel', 'null', 2292, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2293, 'Piks Keys', 'null', 2293, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2294, 'Pimprajan Property', 'null', 2294, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2295, 'Pinnacle Tourism Marketing', 'null', 2295, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2296, 'Pinoy Properties', 'null', 2296, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2297, 'Pintula V', 'null', 2297, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2298, 'Pipi', 'null', 2298, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2299, 'Pitaria', 'null', 2299, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2300, 'Pittinun Property', 'null', 2300, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2301, 'PK Holiday Homes', 'null', 2301, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2302, 'PK Park', 'null', 2302, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2303, 'Place2Stay Hotels', 'null', 2303, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2304, 'Placeholder', 'null', 2304, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2305, 'Plateno', 'null', 2305, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2306, 'Platinum Management', 'null', 2306, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2307, 'Platinum Stay', 'null', 2307, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2308, 'Play Residence', 'null', 2308, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2309, 'Playasol', 'null', 2309, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2310, 'Plays_JP', 'null', 2310, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2311, 'Plaza Premium Lounge', 'null', 2311, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2312, 'Plus One', 'null', 2312, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2313, 'Plus Property', 'null', 2313, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2314, 'Plush NHA', 'null', 2314, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2315, 'PM Malang', 'null', 2315, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2316, 'PML Apartments', 'null', 2316, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2317, 'Point A Hotels', 'null', 2317, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2318, 'Pondok Adi Mangement', 'null', 2318, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2319, 'PONDOK BRILLIANT', 'null', 2319, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2320, 'Pondok Nyaman 15', 'null', 2320, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2321, 'PONDOK PUJI', 'null', 2321, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2322, 'PONDOK SERUNI', 'null', 2322, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2323, 'Pondok Simpang Tiga / Amri', 'null', 2323, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2324, 'Port Fairy Holiday Rentals', 'null', 2324, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2325, 'Port Stephens Accommodation_C (Accom Nelson Bay)', 'null', 2325, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2326, 'Portfolio Niseko', 'null', 2326, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2327, 'Posadas', 'null', 2327, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2328, 'Position Perfect Accommodation Group', 'null', 2328, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2329, 'Prague for you_C', 'null', 2329, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2330, 'Prague Residences', 'null', 2330, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2331, 'Prague-hotel UK', 'null', 2331, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2332, 'Prajas Homestay', 'null', 2332, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2333, 'Pramana Hotels & Resorts', 'null', 2333, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2334, 'Pramana Villa Management', 'null', 2334, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2335, 'Prapassorn', 'null', 2335, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2336, 'Prasi Hospitality', 'null', 2336, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2337, 'Pratiwi Villas', 'null', 2337, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2338, 'Precious Suites', 'null', 2338, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2339, 'Preferred Hotel Group', 'null', 2339, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2340, 'Premier Hotels', 'null', 2340, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2341, 'Premier Inn International', 'null', 2341, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2342, 'Premiere Group', 'null', 2342, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2343, 'Premium Beach VT', 'null', 2343, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2344, 'Premium Holidays', 'null', 2344, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2345, 'Prestige Phuket', 'null', 2345, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2346, 'Prevera Homes', 'null', 2346, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2347, 'PRINCESS HOTELS AND RESORTS', 'null', 2351, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2348, 'Pricise Hotels', 'null', 2347, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2349, 'Prima', 'null', 2348, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2350, 'PrimeUCD_JP', 'null', 2349, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2351, 'Prince Hotels', 'null', 2350, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2352, 'Principal Hayley Hotels and Conference Venues', 'null', 2352, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2353, 'Prisa', 'null', 2353, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2354, 'Prisma Utama Group', 'null', 2354, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2355, 'Private Hotels', 'null', 2355, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2356, 'Private Ubud Villas', 'null', 2356, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2357, 'Pro Phuket', 'null', 2357, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2358, 'Promenade Hotels & Resort', 'null', 2358, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2359, 'Property Management Duncan', 'null', 2359, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2360, 'Property Management Queenstown', 'null', 2360, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2361, 'Property Providers', 'null', 2361, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2362, 'Protea Hotels', 'null', 2362, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2363, 'Provenance Hotels', 'null', 2363, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2364, 'Proviewland', 'null', 2364, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2365, 'PRS @ One Palm Tree Villas', 'null', 2365, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2366, 'PT Sixteen Event', 'null', 2366, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2367, 'PTOP Rent_C', 'null', 2367, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2368, 'PTT Group', 'null', 2368, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2369, 'Pub Rooms', 'null', 2369, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2370, 'PubLove', 'null', 2370, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2371, 'Pueblo Bonito Hotels and Resorts', 'null', 2371, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2372, 'Puerta del Sol', 'null', 2372, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2373, 'Pulitzer and Regina', 'null', 2373, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2374, 'Puncak Holiday', 'null', 2374, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2375, 'Punthill Apartment Hotels', 'null', 2375, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2376, 'Puri Landu', 'null', 2376, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2377, 'Puri Phunix Babarsari', 'null', 2377, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2378, 'Puri Sabina', 'null', 2378, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2379, 'Puri Senayan', 'null', 2379, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2380, 'Puri Vilas Indonesia', 'null', 2380, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2381, 'Purimas Group', 'null', 2381, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2382, 'PUTH', 'null', 2382, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2383, 'Puti Sari banilai Homestay', 'null', 2383, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2384, 'Q Hotels Group', 'null', 2384, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2385, 'Q properties', 'null', 2385, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2386, 'Q Square Garden Apartment', 'null', 2386, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2387, 'QB House', 'null', 2388, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2388, 'Qhome', 'null', 2389, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2389, 'Q-Home Apartments Group', 'null', 2387, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2390, 'Qiansu', 'null', 2390, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2391, 'Qifa Group', 'null', 2391, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2392, 'QT Hotels & Resorts', 'null', 2392, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2393, 'Quality Rentals Pattaya', 'null', 2393, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2394, 'Quay Holidays_C', 'null', 2394, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2395, 'Quentin Hotels', 'null', 2395, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2396, 'Quest Serviced Apartments', 'null', 2396, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2397, 'QUOC TRAVEL', 'null', 2397, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2398, 'R Guesthouse', 'null', 2398, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2399, 'R.Resort', 'null', 2399, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2400, 'R2 Residence', 'null', 2400, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2401, 'RAC Parks and Resorts', 'null', 2401, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2402, 'Raconteur Matsumoto', 'null', 2402, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2403, 'RACV Resorts', 'null', 2403, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2404, 'Radiance Hospitality Group', 'null', 2404, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2405, 'Radisson Hotel Group', 'null', 2405, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2406, 'Raditya Villa', 'null', 2406, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2407, 'Rafael Zulueta', 'null', 2407, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2408, 'Rafaelhoteles', 'null', 2408, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2409, 'Rafat Abuaqel Properties', 'null', 2409, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2410, 'Rafleys Costa del Sol_C', 'null', 2410, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2411, 'RAISYA KOST', 'null', 2415, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2412, 'Raimon Warmasen', 'null', 2411, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2413, 'Raine & Horne (Central Coast Holidays)', 'null', 2412, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2414, 'Raine & Horne Snowy Mountains', 'null', 2413, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2415, 'Rainstay', 'null', 2414, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2416, 'Raja Apartemen', 'null', 2416, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2417, 'Rajawali Property', 'null', 2417, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2418, 'Raka Group', 'null', 2418, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2419, 'Rakuna', 'null', 2419, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2420, 'Ramayana Hotels Group', 'null', 2420, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2421, 'Ramee Group of Hotels, Resorts and Apartments', 'null', 2421, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2422, 'Raoum Inn', 'null', 2422, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2423, 'RAPPOCINI', 'null', 2423, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2424, 'Rastasya Irawan', 'null', 2424, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2425, 'Rava Home', 'null', 2425, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2426, 'Raw Management', 'null', 2426, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2427, 'Ray White Cairns Beaches Holiday Collection', 'null', 2427, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2428, 'RDG Properties', 'null', 2428, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2429, 'Real Hospitality Group', 'null', 2429, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2430, 'Realizer', 'null', 2430, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2431, 'Recommended', 'null', 2431, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2432, 'Red Carnation Hotel Collection', 'null', 2432, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2433, 'Red Lion Hotels', 'null', 2433, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2434, 'Red Planet', 'null', 2434, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2435, 'Red Roof Inn', 'null', 2435, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2436, 'RedDoorz', 'null', 2436, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2437, 'Reez', 'null', 2437, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2438, 'Reffan Property', 'null', 2438, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2439, 'Reflect Property', 'null', 2439, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2440, 'Refre Forum', 'null', 2440, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2441, 'Regal Hotels International', 'null', 2441, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2442, 'Regalia', 'null', 2442, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2443, 'Regent International Hotels', 'null', 2443, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2444, 'Rejuvenate Stays', 'null', 2444, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2445, 'Relais & Chateaux', 'null', 2445, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2446, 'Relax Street', 'null', 2446, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2447, 'RelaxAway', 'null', 2447, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2448, 'Release Wanaka', 'null', 2448, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2449, 'Remar Hotels', 'null', 2449, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2450, 'Remember Trip', 'null', 2450, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2451, 'Rena', 'null', 2451, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2452, 'Rendi', 'null', 2452, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2453, 'Rent A Villa Phuket', 'null', 2453, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2454, 'Rent House Pattaya', 'null', 2454, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2455, 'Rent In Rome', 'null', 2455, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2456, 'Rent Suites', 'null', 2456, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2457, 'Rental Management', 'null', 2458, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2458, 'Rental Villa Bali', 'null', 2459, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2459, 'Rentaloka', 'null', 2460, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2460, 'Rentals Short Term', 'null', 2461, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2461, 'rent-apartment.com', 'null', 2457, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2462, 'RentClass', 'null', 2462, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2463, 'Rentmystay', 'null', 2463, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2464, 'Rentopolis', 'null', 2464, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2465, 'Rents In Phuket', 'null', 2465, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2466, 'Reqrea', 'null', 2466, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2467, 'Residence Tokyo', 'null', 2467, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2468, 'Residhome', 'null', 2468, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2469, 'Resol Hotel and Resort', 'null', 2469, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2470, 'Resol_JP', 'null', 2470, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2471, 'Resort Homes of Florida_C', 'null', 2471, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2472, 'Resort Izumigo', 'null', 2472, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2473, 'Resort Trust', 'null', 2473, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2474, 'Resorts Suites', 'null', 2474, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2475, 'Resorts World', 'null', 2475, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2476, 'Resorts World Genting', 'null', 2476, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2477, 'Rest Night Group', 'null', 2477, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2478, 'Retaj Hotels', 'null', 2478, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2479, 'Retreats Victoria', 'null', 2479, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2480, 'Revan Ray', 'null', 2480, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2481, 'Revanaya Bacpacker Room', 'null', 2481, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2482, 'RevFox', 'null', 2482, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2483, 'Revina Purnama Apartment', 'null', 2483, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2484, 'Rex Properties', 'null', 2484, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2485, 'Rey-Alexandra Suites', 'null', 2485, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2486, 'RHR', 'null', 2486, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2487, 'RIMBA DESA Jepara', 'null', 2494, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2488, 'Richard Cordero', 'null', 2488, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2489, 'Richmond Hotel', 'null', 2489, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2490, 'Richmonde Hotels & Resorts', 'null', 2490, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2491, 'Ridwan Property', 'null', 2491, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2492, 'Rihga Royal Hotels', 'null', 2492, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2493, 'Riki Metro Suite Apartment', 'null', 2493, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2494, 'Rimonim', 'null', 2495, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2495, 'Ring Bali Property', 'null', 2496, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2496, 'Ringhotels', 'null', 2497, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2497, 'Rinn Group', 'null', 2498, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2498, 'Risa Phuket Property', 'null', 2499, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2499, 'Risshisha_JP', 'null', 2500, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2500, 'Ritz Garden', 'null', 2501, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2501, 'Riu Hotels and Resorts', 'null', 2502, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2502, 'River Hotels', 'null', 2503, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2503, 'Riverview Hotel Group', 'null', 2504, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2504, 'Riviera House', 'null', 2505, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2505, 'Riviera VIP Real Estate_C', 'null', 2506, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2506, 'Rixos World Wide', 'null', 2507, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2507, 'Ri-Yaz Hotels & Resorts', 'null', 2487, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2508, 'RnR Serviced Apartments', 'null', 2508, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2509, 'Robert Property', 'null', 2509, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2510, 'Robinsons Land Corporation', 'null', 2510, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2511, 'Rocco Forte Collection', 'null', 2511, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2512, 'Rock Stay', 'null', 2512, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2513, 'Roda Group', 'null', 2513, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2514, 'Rodd Hotels & Resorts', 'null', 2514, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2515, 'Rodeway Inn', 'null', 2515, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2516, 'Roemah Abdoe Lembah Harau', 'null', 2516, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2517, 'Roemah Djogja Guest House', 'null', 2517, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2518, 'Rofusesignature Management', 'null', 2518, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2519, 'Roheda Group', 'null', 2519, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2520, 'Roi Putra', 'null', 2520, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2521, 'Roisa Apartments', 'null', 2521, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2522, 'Rojen Holiday Homes', 'null', 2522, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2523, 'Rokon Group', 'null', 2523, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2524, 'Roland Konrad Properties', 'null', 2524, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2525, 'Rome-unique_C', 'null', 2525, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2526, 'Ronda BCN House', 'null', 2526, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2527, 'Rongshu Gongguan', 'null', 2527, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2528, 'RoniaVilla', 'null', 2528, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2529, 'Room & Revenue', 'null', 2529, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2530, 'Room Mate Hotels', 'null', 2530, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2531, 'Room Panda', 'null', 2531, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2532, 'Room Rentals Cebu', 'null', 2532, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2533, 'Room Service Spain_C', 'null', 2533, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2534, 'room.rental.japan', 'null', 2534, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2535, 'Room007', 'null', 2535, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2536, 'Room22Phuket', 'null', 2536, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2537, 'RoomInger_C', 'null', 2537, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2538, 'Roomku @ Bassura City', 'null', 2538, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2539, 'Roomme', 'null', 2539, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2540, 'Roomromo', 'null', 2540, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2541, 'Ros Harries Marketing', 'null', 2541, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2542, 'Rosadi Rachman', 'null', 2542, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2543, 'Rose Hotels & Apartments', 'null', 2543, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2544, 'Rosedale', 'null', 2544, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2545, 'Roseland Hotels & Spa Group', 'null', 2545, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2546, 'Rosetta Homestay', 'null', 2546, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2547, 'Rosewood Hotels & Resorts', 'null', 2547, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2548, 'Rotana', 'null', 2548, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2549, 'Route Inn Hotels', 'null', 2549, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2550, 'Rove Hotels', 'null', 2550, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2551, 'Royal Orchid Hotels', 'null', 2551, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2552, 'Royal Park Hotels', 'null', 2552, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2553, 'ROYAL RESORTS', 'null', 2553, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2554, 'Royal Total Internasional', 'null', 2554, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2555, 'Royal Twin Group', 'null', 2555, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2556, 'Royale Chulan Hotels & Resorts', 'null', 2556, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2557, 'Rozd Holiday Homes', 'null', 2557, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2558, 'RPGC', 'null', 2558, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2559, 'RTSJ Real Estate Brokerage', 'null', 2559, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2560, 'RU Master_C', 'null', 2560, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2561, 'Ruby Group', 'null', 2561, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2562, 'Rudy Gunawan', 'null', 2562, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2563, 'Rujia Condotel Corp', 'null', 2563, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2564, 'Rully Property', 'null', 2564, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2565, 'RUMAH BUNDA', 'null', 2565, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2566, 'Rumah Desa', 'null', 2566, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2567, 'Rumah Kost Kualanamu', 'null', 2567, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2568, 'Rumah Kost Mahmud', 'null', 2568, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2569, 'Rumah Nenek', 'null', 2569, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2570, 'Rumah Rahman', 'null', 2570, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2571, 'Ruoyu Asset', 'null', 2571, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2572, 'Ryan Eka Putra', 'null', 2572, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2573, 'Rydges Hotels & Resorts', 'null', 2573, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2574, 'S&N', 'null', 2574, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2575, 'S&W Investment', 'null', 2575, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2576, 'SA Agency Services_C', 'null', 2576, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2577, 'Saba Suites', 'null', 2577, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2578, 'Sabai Group', 'null', 2578, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2579, 'SACO Apartments', 'null', 2579, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2580, 'Safeer Hotels', 'null', 2580, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2581, 'Safeer Hotels and Tourism Company', 'null', 2581, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2582, 'Safestay group', 'null', 2582, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2583, 'Safestay Hostels', 'null', 2583, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2584, 'Safir Hotels & Resorts', 'null', 2584, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2585, 'Safitour', 'null', 2585, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2586, 'Sahara', 'null', 2586, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2587, 'Sahid Hotels', 'null', 2587, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2588, 'Saigon Corner', 'null', 2588, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2589, 'Saigon Home Party', 'null', 2589, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2590, 'Saigon Lotus', 'null', 2590, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2591, 'Saigon Rooms', 'null', 2591, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2592, 'Saigon Sweethome', 'null', 2592, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2593, 'Saigonhost', 'null', 2593, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2594, 'Sain Property', 'null', 2594, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2595, 'Saitarn Samui', 'null', 2595, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2596, 'Sala Hospitality Group', 'null', 2596, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2597, 'Salam Group', 'null', 2597, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2598, 'Salles Hotels', 'null', 2598, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2599, 'Sam Xu', 'null', 2599, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2600, 'Sama Sama Holiday Homes', 'null', 2600, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2601, 'Samastha Indonesia', 'null', 2601, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2602, 'Samed Resorts Group', 'null', 2602, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2603, 'Sami Firdavs', 'null', 2603, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2604, 'Samui Dream Villas', 'null', 2604, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2605, 'Samui Holiday Villa Rental', 'null', 2605, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2606, 'Sana Hotels', 'null', 2606, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2607, 'Sanco Inn Hotels', 'null', 2607, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2608, 'Sandals & Beaches Resorts', 'null', 2608, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2609, 'Sandman Group', 'null', 2609, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2610, 'Sandra', 'null', 2610, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2611, 'Sandra Property', 'null', 2611, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2612, 'Sands China', 'null', 2612, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2613, 'Sanremo Oasis Condominium', 'null', 2613, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2614, 'Sant Jordi', 'null', 2614, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2615, 'Santa Grand Hotels', 'null', 2615, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2616, 'Santika Indonesia Hotels & Resorts', 'null', 2616, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2617, 'Santoni\'s Place', 'null', 2617, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2618, 'SARASA Hotels', 'null', 2618, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2619, 'Sari Pacifica Hotel & Resorts', 'null', 2619, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2620, 'Sarovar Hotels & Resorts', 'null', 2620, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2621, 'Sasmito Group', 'null', 2621, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2622, 'Sateraito Office', 'null', 2622, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2623, 'Savi Rooms', 'null', 2623, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2624, 'Sawa Muli Resort', 'null', 2624, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2625, 'Sawasdee Hotels Group', 'null', 2625, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2626, 'SB Hotels', 'null', 2626, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2627, 'Scandic Hotels', 'null', 2627, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2628, 'Scenic Hotel Group', 'null', 2628, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2629, 'Schick Hotels', 'null', 2629, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2630, 'Scuba Tribe Bali', 'null', 2630, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2631, 'Sea Lion House', 'null', 2631, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2632, 'Sea N\' Rent', 'null', 2632, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2633, 'Seaclub', 'null', 2633, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2634, 'Seashells Hospitality Group', 'null', 2634, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2635, 'Seaside Holiday Home Accommodation', 'null', 2635, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2636, 'Seasons Apartment Hotel Group', 'null', 2636, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2637, 'SeaStay Vung Tau', 'null', 2637, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2638, 'Secluded Bali Villas', 'null', 2638, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2639, 'Second Homes', 'null', 2639, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2640, 'Seda Hotels', 'null', 2640, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2641, 'Sederhana Homestay', 'null', 2641, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2642, 'Sejahtera Apartments', 'null', 2642, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2643, 'Sekai Hotel', 'null', 2643, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2644, 'Select Hotels Group', 'null', 2644, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2645, 'Selog Villa', 'null', 2645, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2646, 'Selvy', 'null', 2646, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2647, 'Sensation Apartments', 'null', 2647, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2648, 'Sentana Management', 'null', 2648, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2649, 'Sentoria Group', 'null', 2649, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2650, 'Sentra Timur Residence by Angelica', 'null', 2650, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2651, 'Sentra Timur Residence by Tulus', 'null', 2651, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2652, 'Seoul Apartment', 'null', 2652, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2653, 'Sercotel Hotels', 'null', 2653, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2654, 'Serena Hotels', 'null', 2654, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2655, 'Serena\'s House', 'null', 2655, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2656, 'Serenata Hotels & Resorts', 'null', 2656, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2657, 'Serenity Pattaya', 'null', 2657, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2658, 'Serenity Twin Villa', 'null', 2658, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2659, 'Serviced Houses', 'null', 2659, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2660, 'Servigroup Hotels', 'null', 2660, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2661, 'Seven Peaks Property', 'null', 2661, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2662, 'Seven Trumpets', 'null', 2662, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2663, 'Sewa in Villa', 'null', 2663, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2664, 'SGP', 'null', 2664, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2665, 'Shaftesbury Hotels', 'null', 2665, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2666, 'Shamrocks Rooms', 'null', 2666, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2667, 'Shangri-La Hotels and Resorts', 'null', 2667, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2668, 'Shangrila Mountain View Baguio', 'null', 2668, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2669, 'Shanika Properties @ F1 BGC', 'null', 2669, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2670, 'Shanshui Trends Hotel', 'null', 2670, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2671, 'Shanti Collection', 'null', 2671, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2672, 'Share Japan', 'null', 2672, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2673, 'SHCR', 'null', 2673, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2674, 'Shen Yu Lin', 'null', 2674, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2675, 'SHI Inc.', 'null', 2675, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2676, 'Shiadu', 'null', 2676, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2677, 'Shiki Group', 'null', 2677, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2678, 'Shilla Hotel', 'null', 2678, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2679, 'Shilo Inns', 'null', 2679, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2680, 'Shindom Inn', 'null', 2680, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2681, 'Shinju Apartment', 'null', 2681, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2682, 'SHKP Hotels', 'null', 2682, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2683, 'Shoney\'s Inn', 'null', 2683, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2684, 'Short Booking Holiday Homes', 'null', 2684, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2685, 'Short Letting_C', 'null', 2685, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2686, 'Short Rental Perth', 'null', 2686, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2687, 'Short Stay Group apartments', 'null', 2687, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2688, 'Short Stay Plus', 'null', 2688, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2689, 'Short Stay Plus AU', 'null', 2689, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2690, 'ShortOZ Stay', 'null', 2690, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2691, 'ShortstayPh Inc.', 'null', 2691, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2692, 'ShortStayPoland', 'null', 2692, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2693, 'ShuGuang Hotel Group', 'null', 2693, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2694, 'SILK Experience Excellence', 'null', 2700, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2695, 'Siam Hotel Group', 'null', 2694, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2696, 'Sichapak Property', 'null', 2695, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2697, 'Signature Group', 'null', 2696, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2698, 'Signature Holiday Homes', 'null', 2697, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2699, 'Siho Villa', 'null', 2698, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2700, 'Sila Dharma Hospitality Management', 'null', 2699, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2701, 'Silver Cloud Inns & Hotels', 'null', 2701, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2702, 'Silver Oaks Group', 'null', 2702, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2703, 'Silver Star (All Japan Ryokan Hotel Association)', 'null', 2703, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2704, 'Silverland Hotels & Spa Group', 'null', 2704, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2705, 'Simms Group', 'null', 2705, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2706, 'Simply Heaven', 'null', 2706, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2707, 'Simply Homy', 'null', 2707, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2708, 'Sina Hotels', 'null', 2708, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2709, 'Sinar Batu', 'null', 2709, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2710, 'Singapore Attractions', 'null', 2710, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2711, 'Singer Group', 'null', 2711, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2712, 'Sino Group', 'null', 2712, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2713, 'Sinta Putri', 'null', 2713, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2714, 'Sipadan Inn', 'null', 2714, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2715, 'Sirenis Hotels & Resorts', 'null', 2715, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2716, 'Sirinda Property', 'null', 2716, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2717, 'Siriwan Property', 'null', 2717, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2718, 'Sirkeci Group Hotels', 'null', 2718, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2719, 'Sitipong Property', 'null', 2719, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2720, 'Six Senses', 'null', 2720, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2721, 'SJM', 'null', 2721, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2722, 'Skalon Limited', 'null', 2722, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2723, 'Skandinavia by TC Property', 'null', 2723, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2724, 'Ski Japan', 'null', 2724, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2725, 'SkiJapan', 'null', 2725, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2726, 'Sky Dragon Hai Phong', 'null', 2726, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2727, 'Sky Hotel', 'null', 2727, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2728, 'Skycity', 'null', 2728, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2729, 'Skytary', 'null', 2729, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2730, 'Slaviero Hotels', 'null', 2730, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2731, 'Slavyanka Hotel Chain', 'null', 2731, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2732, 'Sleepover in NMMBA', 'null', 2732, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2733, 'SleepRest', 'null', 2733, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2734, 'SlifeAus_C', 'null', 2734, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2735, 'Slow Enjoy Living', 'null', 2735, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2736, 'Small Luxury Hotel of the World', 'null', 2736, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2737, 'Smart Hotel', 'null', 2737, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2738, 'Smiley Group', 'null', 2738, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2739, 'SMU Trading', 'null', 2739, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2740, 'SNC Management', 'null', 2740, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2741, 'SoftInn', 'null', 2741, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2742, 'Soho Suites KLCC by Aloha', 'null', 2742, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2743, 'SoHome Australia', 'null', 2743, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2744, 'Sokha Hotels & Resorts', 'null', 2744, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2745, 'Solare Hotels', 'null', 2745, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2746, 'SOLMAR HOTELS & RESORTS', 'null', 2746, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2747, 'Soluxe Hotel Group', 'null', 2747, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2748, 'Som', 'null', 2748, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2749, 'Somnuk', 'null', 2749, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2750, 'Sonders Property Management Corp', 'null', 2750, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2751, 'Sonesta', 'null', 2751, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2752, 'Sonya Stoyanova', 'null', 2752, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2753, 'SooBali', 'null', 2753, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2754, 'Sorell Hotels', 'null', 2754, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2755, 'Sotetsu Fresa Inn', 'null', 2755, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2756, 'Southouse Residence', 'null', 2756, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2757, 'Sozonext', 'null', 2757, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2758, 'Space Management_JP', 'null', 2758, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2759, 'Spain Rentals', 'null', 2759, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2760, 'SPB Citystar', 'null', 2760, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2761, 'Spicers Retreats, Hotels and Lodges', 'null', 2761, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2762, 'Spring Garden Villa', 'null', 2762, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2763, 'Squeeze', 'null', 2763, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2764, 'SR Vacation Rental', 'null', 2764, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2765, 'Sriya Homestay', 'null', 2765, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2766, 'SSAW Boutique Group', 'null', 2766, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2767, 'ST Vung Tau Apartment', 'null', 2767, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2768, 'Sta. Maria Homes', 'null', 2768, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2769, 'Stamford Hotels & Resorts', 'null', 2769, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2770, 'Stanford', 'null', 2770, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2771, 'Stanley', 'null', 2771, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2772, 'Starfish Properties', 'null', 2772, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2773, 'Starhotels', 'null', 2773, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2774, 'Starlight Suites Hotels', 'null', 2774, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2775, 'Starwood Hotels & Resorts Worldwide', 'null', 2775, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2776, 'Station Casino', 'null', 2776, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2777, 'Stay Barcelona Apartments_C', 'null', 2777, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2778, 'Stay Gold', 'null', 2778, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2779, 'Stay Humble', 'null', 2779, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2780, 'Stay in Cape Town', 'null', 2780, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2781, 'Stay in Paternoster', 'null', 2781, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2782, 'Stay in Villa Bandung', 'null', 2782, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2783, 'Stay Japan', 'null', 2783, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2784, 'Stay Kyoto', 'null', 2784, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2785, 'Stay Waiheke Holiday Homes', 'null', 2785, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2786, 'StayBeyond', 'null', 2786, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2787, 'Staybeyond_C', 'null', 2787, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2788, 'Staycation', 'null', 2788, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2789, 'Staycation Vacation Rentals_C', 'null', 2789, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2790, 'StayHome Asia', 'null', 2790, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2791, 'Staykeeper', 'null', 2791, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2792, 'Staynest_C', 'null', 2792, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2793, 'Staypineapple', 'null', 2793, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2794, 'StayWell Hospitality Group', 'null', 2794, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2795, 'Staywest Apartments', 'null', 2795, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2796, 'Stefanie Halim', 'null', 2796, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2797, 'Stella', 'null', 2797, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2798, 'Stellawood_JP', 'null', 2798, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2799, 'Sterling Hotels and Resorts', 'null', 2799, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2800, 'Stevanus Group', 'null', 2800, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2801, 'Stoneman Vacation Villa_C', 'null', 2801, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2802, 'StoneTree', 'null', 2802, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2803, 'Studio Apartment Korea', 'null', 2803, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2804, 'Stylers', 'null', 2804, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2805, 'Suba Group of Hotels', 'null', 2805, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2806, 'Subhome', 'null', 2806, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2807, 'Sublet4U HQ Ltd_C', 'null', 2807, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2808, 'Sudima', 'null', 2808, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2809, 'SuerteFortun', 'null', 2809, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2810, 'Suflindo Group', 'null', 2810, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2811, 'Suhelmiadi Adi', 'null', 2811, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2812, 'SuiwaGroup', 'null', 2812, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2813, 'Sukuragawa(Phoenix.lyx89)_JP', 'null', 2813, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2814, 'Sumberkima Hill Private Villa Retreat', 'null', 2814, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2815, 'Sumifuku_JP', 'null', 2815, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2816, 'SummerHouse Bali', 'null', 2816, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2817, 'Summit Group', 'null', 2817, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2818, 'Sumuka', 'null', 2818, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2819, 'Sun Inn Group', 'null', 2819, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2820, 'Sun International', 'null', 2820, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2821, 'Sun Resorts', 'null', 2821, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2822, 'Sun Siyam Resorts', 'null', 2822, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2823, 'Sunburst Holidays', 'null', 2823, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2824, 'Sunex Luxury Apartment', 'null', 2824, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2825, 'SunMei', 'null', 2825, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2826, 'Sunny Group', 'null', 2826, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2827, 'Sunny House', 'null', 2827, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2828, 'Sunny Thailand', 'null', 2828, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2829, 'Sunotel Grupo', 'null', 2829, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2830, 'SUNRISE HOUSE', 'null', 2832, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2831, 'SunRich_JP', 'null', 2830, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2832, 'Sunrise (xiangxiang.zhang)_JP', 'null', 2831, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2833, 'Sunroute Hotel', 'null', 2833, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2834, 'Sunshine Hotels & Resort', 'null', 2834, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2835, 'Sunshine Hotels & Resorts, Pattaya', 'null', 2835, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2836, 'Sunshine Samui Villas', 'null', 2836, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2837, 'Sunway Group', 'null', 2837, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2838, 'Sunway Hotels & Resorts', 'null', 2838, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2839, 'Sunworld Dynasty Hotel', 'null', 2839, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2840, 'Supaporn Property', 'null', 2840, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2841, 'Super 8', 'null', 2841, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2842, 'Super 8 Hotels', 'null', 2842, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2843, 'Super Hotel', 'null', 2843, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2844, 'Superlab', 'null', 2844, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2845, 'Supranational Hotels', 'null', 2845, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2846, 'Surapong Property', 'null', 2846, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2847, 'Sure Property', 'null', 2847, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2848, 'Suria', 'null', 2848, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2849, 'Surmeli Hotels & Resorts', 'null', 2849, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2850, 'Surya Hotels', 'null', 2850, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2851, 'Susan Group', 'null', 2851, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2852, 'Susan\'s Bali Villas', 'null', 2852, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2853, 'Sutera Harbour Resort', 'null', 2853, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2854, 'Sutton Place Hotel', 'null', 2854, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2855, 'Suzaku', 'null', 2855, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2856, 'Suzuka', 'null', 2856, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2857, 'Sweet Inn Apartments', 'null', 2857, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2858, 'Sweet Inn_C', 'null', 2858, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2859, 'Swell Stays', 'null', 2859, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2860, 'Swisbell Hotel International', 'null', 2860, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2861, 'Swiss Garden International', 'null', 2861, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2862, 'Swiss International Hotels & Resorts', 'null', 2862, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2863, 'Swiss Quality Hotels International', 'null', 2863, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2864, 'Swiss Youth Hostels', 'null', 2864, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2865, 'Swiss-Belhotel International', 'null', 2865, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2866, 'Switch entertaiment', 'null', 2866, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2867, 'Syaeful', 'null', 2867, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2868, 'Syafic Homestay', 'null', 2868, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2869, 'Sydney Lodges', 'null', 2869, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2870, 'Sylvie Asa', 'null', 2870, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2871, 'T Stay', 'null', 2871, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2872, 'T+Hotel', 'null', 2872, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2873, 'Taga Home Vietnam', 'null', 2873, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2874, 'Tagaytay A-Staycation by Naya and Darla', 'null', 2874, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2875, 'Tagaytay Staycation', 'null', 2875, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2876, 'Tagaytay Vacation House', 'null', 2876, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2877, 'TAI PHAT Hold Family Business', 'null', 2877, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2878, 'Tai Tai House', 'null', 2878, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2879, 'Tainan Gulf Castle', 'null', 2879, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2880, 'Taipei Meets', 'null', 2880, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2881, 'Taj Hotels Resorts and Palaces', 'null', 2881, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2882, 'TAKE Consulting_JP', 'null', 2882, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2883, 'Takumi', 'null', 2883, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2884, 'Tam House Villa', 'null', 2884, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2885, 'Tamalate Residence Group', 'null', 2885, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2886, 'Taman Paradise', 'null', 2886, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2887, 'Taman Sari Bali Villas Kerobokan', 'null', 2887, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2888, 'Taman Tirta Lovina', 'null', 2888, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2889, 'Tamora', 'null', 2889, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2890, 'Tamu Seseh', 'null', 2890, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2891, 'Tan Long', 'null', 2891, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2892, 'Tang Dynasty Group of Hotels', 'null', 2893, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2893, 'Tang’s Living Group', 'null', 2894, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2894, 'Tanglin Pakuwon', 'null', 2895, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2895, 'Tan\'s Apartment', 'null', 2892, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2896, 'Taruruhto JP', 'null', 2896, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2897, 'Taurus Bali', 'null', 2897, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2898, 'Tauzia Hotel Management', 'null', 2898, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2899, 'Tavers Pension House', 'null', 2899, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2900, 'Taylor Korea', 'null', 2900, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2901, 'TD Hotels Group', 'null', 2901, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2902, 'Teddy Yudi', 'null', 2902, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2903, 'Tedi', 'null', 2903, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2904, 'Tembi Rumah Budaya', 'null', 2904, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2905, 'Terrace Hill Resort', 'null', 2905, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2906, 'test', 'null', 2906, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2907, 'Test Chain', 'null', 2907, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2908, 'Test Hotel', 'null', 2908, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2909, 'TFE Hotels', 'null', 2909, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2910, 'Thai Homeaway', 'null', 2910, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2911, 'Thai Nice @ 15 Sukhumvit Residence', 'null', 2911, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2912, 'Thai Property Group', 'null', 2912, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2913, 'Thai Smile Property', 'null', 2913, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2914, 'Thailand Holiday Homes', 'null', 2914, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2915, 'Thaittaya', 'null', 2915, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2916, 'Tham Yeo', 'null', 2916, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2917, 'Thanh Nga', 'null', 2917, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2918, 'Thansasit', 'null', 2918, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2919, 'Thao Lieu', 'null', 2919, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2920, 'THC Hostels', 'null', 2920, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2921, 'The Ark Retreat', 'null', 2921, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2922, 'The Backpacker Group', 'null', 2922, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2923, 'The Baile Apartment', 'null', 2923, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2924, 'The Bali Agent', 'null', 2924, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2925, 'The Batu Villa', 'null', 2925, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2926, 'The Berry Luxury Apartments', 'null', 2926, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2927, 'THE BnB Bandung Metro Indah', 'null', 2927, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2928, 'The Boutique Collection', 'null', 2928, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2929, 'The Cabin', 'null', 2929, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2930, 'The Cabin Property', 'null', 2930, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2931, 'The Cairn Collection', 'null', 2931, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2932, 'The Capital Hotels & Apartments', 'null', 2932, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2933, 'The Como Serviced Apartment', 'null', 2933, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2934, 'The Concierge Guru_C', 'null', 2934, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2935, 'The Damai Master Pool Villa', 'null', 2935, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2936, 'The Doors', 'null', 2936, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2937, 'The Fern Hotels and Resorts', 'null', 2937, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2938, 'THE FIVE', 'null', 2938, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2939, 'The Green Park', 'null', 2939, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2940, 'The Heritage Hotels Group', 'null', 2940, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2941, 'THE HOMEE', 'null', 2941, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2942, 'The Jerai Hotels & Resorts', 'null', 2942, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2943, 'The Jones', 'null', 2943, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2944, 'The Klagan', 'null', 2944, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2945, 'The Kraton Homestay', 'null', 2945, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2946, 'The Kunci', 'null', 2946, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2947, 'The Lane Bay Villa', 'null', 2947, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2948, 'The Leela Palaces, Hotels and Resorts', 'null', 2948, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2949, 'The Leverage Hotel', 'null', 2949, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2950, 'The Local Stay_C', 'null', 2950, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2951, 'The London Agent', 'null', 2951, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2952, 'The Lowy Group', 'null', 2952, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2953, 'The Luxe Nomad', 'null', 2953, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2954, 'The Luxe Residences', 'null', 2954, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2955, 'The Luxury Signature', 'null', 2955, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2956, 'The Luxury Topview Phuket', 'null', 2956, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2957, 'The Maharajo Guest House Jakarta', 'null', 2957, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2958, 'The Mantis Collection', 'null', 2958, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2959, 'The Marmara Collection', 'null', 2959, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2960, 'The Maruca Group_C', 'null', 2960, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2961, 'The Memories Cottage', 'null', 2961, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2962, 'The Nox Group', 'null', 2962, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2963, 'The Palacio de Laoag', 'null', 2963, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2964, 'The Patra', 'null', 2964, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2965, 'The Pride Hotels', 'null', 2965, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2966, 'The Red House Company', 'null', 2966, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2967, 'The Regency Group', 'null', 2967, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2968, 'The Scout Group', 'null', 2968, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2969, 'The Star Entertainment Group', 'null', 2969, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2970, 'The Streets Apartments', 'null', 2970, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2971, 'The Student Hotel', 'null', 2971, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2972, 'The Sunset Hotel Group', 'null', 2972, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2973, 'The Three Corners', 'null', 2973, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2974, 'The Trump Hotel Collection', 'null', 2974, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2975, 'The Unique Collection of Hotels and Resorts', 'null', 2975, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2976, 'The Venues Collection', 'null', 2976, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2977, 'The Zonvil Condominium', 'null', 2977, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2978, 'THHR', 'null', 2978, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2979, 'Thi Hoang Homes', 'null', 2979, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2980, 'Thien Kim Real', 'null', 2980, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2981, 'Think Hotels', 'null', 2981, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2982, 'Thippawan Property', 'null', 2982, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2983, 'Thistle & Guoman', 'null', 2983, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2984, 'Thon Hotels', 'null', 2984, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2985, 'Three A Corporation', 'null', 2985, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2986, 'Three Oaks Group', 'null', 2986, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2987, 'Thunder Storm Property', 'null', 2987, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2988, 'TIHG', 'null', 2990, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2989, 'TIME Hotels', 'null', 2991, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2990, 'Tianlun International Hotels', 'null', 2988, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2991, 'Tiara Court', 'null', 2989, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2992, 'Times Japan', 'null', 2992, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2993, 'Times Square NHA', 'null', 2993, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2994, 'Timhotels', 'null', 2994, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2995, 'Tirto 27', 'null', 2995, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2996, 'Titanic', 'null', 2996, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2997, 'Tivoli Hotels & Resorts', 'null', 2997, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2998, 'TOBU Group', 'null', 2998, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (2999, 'TOC Hostel & Suites', 'null', 2999, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3000, 'Toho Resort Hotels', 'null', 3000, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3001, 'Tokyo Furnished', 'null', 3001, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3002, 'Tokyu Hotels', 'null', 3002, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3003, 'Tokyu Stay', 'null', 3003, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3004, 'TOP 10 Holiday Parks', 'null', 3004, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3005, 'Topotels International', 'null', 3005, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3006, 'Toronto Motel Group', 'null', 3006, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3007, 'Total Bali', 'null', 3007, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3008, 'Touch of Spice', 'null', 3008, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3009, 'Tourism Adventure Group', 'null', 3009, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3010, 'Tourism By G', 'null', 3010, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3011, 'Toushin', 'null', 3011, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3012, 'Towers Real Estate', 'null', 3012, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3013, 'Towny', 'null', 3013, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3014, 'Toyoko Inn', 'null', 3014, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3015, 'Toyotomi', 'null', 3015, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3016, 'Traditional Hanok', 'null', 3016, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3017, 'Tran Duy Villa', 'null', 3017, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3018, 'Tran Suites Hanoi', 'null', 3018, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3019, 'Trans Vita d.o.o_C', 'null', 3019, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3020, 'Travel Estate', 'null', 3020, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3021, 'Travel Gate Croatia_C', 'null', 3021, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3022, 'Travel Guidal', 'null', 3022, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3023, 'Travel Ouensha Kyoto', 'null', 3023, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3024, 'Travelbee Management Corporation', 'null', 3024, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3025, 'Traveler Genius', 'null', 3025, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3026, 'Travelessence K.K', 'null', 3026, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3027, 'Traveletc Apartments', 'null', 3027, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3028, 'Traveling Family Villa', 'null', 3028, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3029, 'Travelio', 'null', 3029, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3030, 'Traveller\'s Inn', 'null', 3030, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3031, 'Travelodge', 'null', 3031, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3032, 'Travelodge Europe', 'null', 3032, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3033, 'Treebo Hotels', 'null', 3033, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3034, 'Tribal Xperience Port Barton Town', 'null', 3034, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3035, 'Trim Off JP', 'null', 3035, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3036, 'Trip Inn', 'null', 3036, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3037, 'Trip Mall', 'null', 3037, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3038, 'Trip Pod', 'null', 3038, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3039, 'Trip11', 'null', 3039, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3040, 'Triple Apartment', 'null', 3040, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3041, 'Tripster Hub Travel Solutions', 'null', 3041, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3042, 'TripVillas', 'null', 3042, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3043, 'Tripvillas_C', 'null', 3043, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3044, 'Tritic Management', 'null', 3044, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3045, 'Triumph Hotels', 'null', 3045, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3046, 'Trivelles group', 'null', 3046, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3047, 'TRM Hospitality', 'null', 3047, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3048, 'TropicLook_C', 'null', 3048, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3049, 'Truc Phan', 'null', 3049, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3050, 'Trust In_C', 'null', 3050, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3051, 'TrustLight_JP', 'null', 3051, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3052, 'Trustrive', 'null', 3052, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3053, 'Tsokkos', 'null', 3053, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3054, 'Tsukigime Club', 'null', 3054, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3055, 'Tsuruga Group Hotels', 'null', 3055, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3056, 'Tujia Group', 'null', 3056, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3057, 'Tuli Hotels& Resorts', 'null', 3057, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3058, 'Tulip Hotel Group', 'null', 3058, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3059, 'TUMON VACATION RENTAL', 'null', 3059, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3060, 'Tune Hotels', 'null', 3060, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3061, 'Turim Hotels', 'null', 3061, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3062, 'Tuti Ha Long', 'null', 3062, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3063, 'Twin sea', 'null', 3063, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3064, 'Twist', 'null', 3064, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3065, 'Twizel Holiday Homes', 'null', 3065, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3066, 'Two Roads Hospitality', 'null', 3066, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3067, 'Two Villas Holiday', 'null', 3067, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3068, 'Ty House Danang', 'null', 3068, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3069, 'Tyson Properties', 'null', 3069, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3070, 'U Hotel Group', 'null', 3070, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3071, 'UBIQS', 'null', 3072, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3072, 'Ubud Batan Nyuh Bed Breakfast & Spa', 'null', 3073, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3073, 'Ubud Prime Villas', 'null', 3074, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3074, 'Ubud Property', 'null', 3075, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3075, 'Ubud Stay', 'null', 3076, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3076, 'UHG', 'null', 3077, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3077, 'Uhi Property', 'null', 3078, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3078, 'Uhome', 'null', 3079, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3079, 'Ulysses Getaways', 'null', 3080, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3080, 'Umah Tantra Tantri', 'null', 3081, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3081, 'Umdloti Letting & Sales', 'null', 3082, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3082, 'Umi hotels', 'null', 3083, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3083, 'UNA Hotels', 'null', 3084, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3084, 'Unico Hotels', 'null', 3085, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3085, 'UniQue Koh Samui', 'null', 3086, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3086, 'UniRez', 'null', 3087, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3087, 'U-Nit Rental Group', 'null', 3071, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3088, 'Unitune', 'null', 3088, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3089, 'Universal Resorts', 'null', 3089, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3090, 'Universal Studios', 'null', 3090, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3091, 'Unizo Hotels', 'null', 3091, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3092, 'Unlisted Collection', 'null', 3092, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3093, 'Unwind Holidays', 'null', 3093, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3094, 'Uptown', 'null', 3094, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3095, 'Urban Hotel Group', 'null', 3095, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3096, 'Urban House', 'null', 3096, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3097, 'Urban Spaces', 'null', 3097, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3098, 'Urban Suites', 'null', 3098, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3099, 'Urbanauts', 'null', 3099, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3100, 'UrbanMinder', 'null', 3100, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3101, 'Urbany Hostels', 'null', 3101, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3102, 'USP Property Management', 'null', 3102, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3103, 'Utama Mas Propertindo', 'null', 3103, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3104, 'V Guest House', 'null', 3104, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3105, 'Vacance', 'null', 3105, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3106, 'Vacances Bleues', 'null', 3106, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3107, 'Vacanze Italiane MED', 'null', 3107, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3108, 'Vacanzes', 'null', 3108, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3109, 'Vacasa SA', 'null', 3109, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3110, 'Vacation Bay Holiday Homes_C', 'null', 3110, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3111, 'Vacation Marbella', 'null', 3111, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3112, 'Vacation Rental Pros_C', 'null', 3112, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3113, 'Vacay Villa', 'null', 3113, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3114, 'Vagabond Inn', 'null', 3114, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3115, 'Vail Resorts', 'null', 3115, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3116, 'Valamar Hotels & Resorts', 'null', 3116, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3117, 'Valcambre_C', 'null', 3117, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3118, 'Vals Next_JP', 'null', 3118, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3119, 'Vantage Hospitality', 'null', 3119, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3120, 'Variety Hotels', 'null', 3120, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3121, 'Vaway_C', 'null', 3121, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3122, 'VBA Hospitality Group', 'null', 3122, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3123, 'Vebriani', 'null', 3123, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3124, 'Veeve_C', 'null', 3124, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3125, 'Vegan Organizer', 'null', 3125, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3126, 'Veloche home', 'null', 3126, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3127, 'Venice Rent Apartments', 'null', 3127, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3128, 'Vera Villas Management', 'null', 3128, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3129, 'Veranda Resorts', 'null', 3129, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3130, 'Veriu group', 'null', 3130, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3131, 'Verve Travel Management', 'null', 3131, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3132, 'Very Jaya', 'null', 3132, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3133, 'Vessel Hotel', 'null', 3133, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3134, 'VHM Hotels', 'null', 3134, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3135, 'VIP Hotels', 'null', 3186, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3136, 'VIP Stays Concierge PH', 'null', 3187, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3137, 'Via Inn', 'null', 3135, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3138, 'Viceroy Hotel Group', 'null', 3136, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3139, 'Victor Plotnikov', 'null', 3137, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3140, 'Victor Properties', 'null', 3138, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3141, 'Victoria Court', 'null', 3139, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3142, 'Victoria Home NHA', 'null', 3140, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3143, 'Victoria Properties', 'null', 3141, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3144, 'Victoria Room', 'null', 3142, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3145, 'Vienna Hotel Group', 'null', 3143, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3146, 'Vienna Hotels', 'null', 3144, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3147, 'Vienna House', 'null', 3145, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3148, 'Vietnam 1989', 'null', 3146, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3149, 'Vietnam House', 'null', 3147, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3150, 'Vietstork TA', 'null', 3148, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3151, 'Vika Meredian', 'null', 3149, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3152, 'Vila Galé', 'null', 3150, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3153, 'Villa Anastacia Inn', 'null', 3151, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3154, 'Villa Bali Management', 'null', 3152, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3155, 'Villa Bening', 'null', 3153, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3156, 'Villa BoBos', 'null', 3154, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3157, 'Villa Bugis Management', 'null', 3155, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3158, 'Villa Finder', 'null', 3156, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3159, 'Villa Fontaine Hotels', 'null', 3157, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3160, 'Villa Griya Wira Karya', 'null', 3158, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3161, 'Villa Hotels', 'null', 3159, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3162, 'Villa Istana Bunga', 'null', 3160, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3163, 'Villa Kampung Artis Bali', 'null', 3161, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3164, 'Villa Kampung Ayem', 'null', 3162, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3165, 'Villa Kubu Management', 'null', 3163, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3166, 'Villa Lombok Pahawang', 'null', 3164, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3167, 'Villa Lucio Selviana', 'null', 3165, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3168, 'Villa Marizella_C', 'null', 3166, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3169, 'Villa Mulyono', 'null', 3167, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3170, 'Villa Nadira', 'null', 3168, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3171, 'Villa Paerdoe', 'null', 3169, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3172, 'Villa Paolija', 'null', 3170, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3173, 'Villa Pulau Cinta', 'null', 3171, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3174, 'Villa Santibis', 'null', 3172, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3175, 'Villa Short Stay', 'null', 3173, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3176, 'Villa Tentram', 'null', 3174, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3177, 'Villa Trixie', 'null', 3175, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3178, 'Villa True Colors', 'null', 3176, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3179, 'VillaIstanaBunga', 'null', 3177, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3180, 'Villas Bali', 'null', 3178, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3181, 'VillaVania', 'null', 3179, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3182, 'Villaz_C', 'null', 3180, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3183, 'Vilorium', 'null', 3181, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3184, 'Vincci Hoteles', 'null', 3182, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3185, 'Vince Chan', 'null', 3183, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3186, 'Vinomofo', 'null', 3184, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3187, 'Vinpearl Hotels and Resorts', 'null', 3185, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3188, 'Visit Japan', 'null', 3188, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3189, 'Visit the Entrance', 'null', 3189, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3190, 'Visith Property', 'null', 3190, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3191, 'Vista Hotel Management', 'null', 3191, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3192, 'Vista Residences Inc 1', 'null', 3192, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3193, 'Vista Rooms', 'null', 3193, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3194, 'Vistarooms', 'null', 3194, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3195, 'Vistay', 'null', 3195, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3196, 'Vita Emerald', 'null', 3196, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3197, 'Viva Hotels and Resorts', 'null', 3197, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3198, 'VMC Vacation Home Rental', 'null', 3198, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3199, 'VMG Resorts_C', 'null', 3199, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3200, 'Vodaless', 'null', 3200, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3201, 'Voluntad', 'null', 3201, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3202, 'Von Essen Hotels', 'null', 3202, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3203, 'Vondel Hotels', 'null', 3203, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3204, 'Vortex Managers_C', 'null', 3204, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3205, 'Voyages Ayers Rock Resort', 'null', 3205, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3206, 'Voyages Hotels and Resorts', 'null', 3206, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3207, 'VP Hotels', 'null', 3207, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3208, 'VR Hotels', 'null', 3208, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3209, 'VRI (Vacation Resorts International)', 'null', 3209, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3210, 'Vsbias', 'null', 3210, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3211, 'Vuaban Pattaya', 'null', 3211, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3212, 'Vuaban Phuket', 'null', 3212, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3213, 'WA Stay Group', 'null', 3213, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3214, 'Wabisaby', 'null', 3214, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3215, 'Wafaby Guesthouse', 'null', 3215, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3216, 'Waiheke Unlimited', 'null', 3216, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3217, 'Wako', 'null', 3217, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3218, 'Waldorf Apartment Group', 'null', 3218, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3219, 'Waldorf New Zealand', 'null', 3219, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3220, 'Walt Disney World Resort', 'null', 3220, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3221, 'Wana Prasta', 'null', 3221, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3222, 'Wanda Hotels and Resorts', 'null', 3222, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3223, 'Wang', 'null', 3223, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3224, 'Wangtianxing_JP', 'null', 3224, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3225, 'Wardana Group', 'null', 3225, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3226, 'Warner Leisure Hotels', 'null', 3226, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3227, 'Warwick International Hotels', 'null', 3227, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3228, 'Washington Hotel Corporation', 'null', 3228, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3229, 'Waterfront Hotels & Casinos', 'null', 3229, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3230, 'Waterplace Group', 'null', 3230, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3231, 'Wayne Group', 'null', 3231, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3232, 'Weflating', 'null', 3232, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3233, 'WEI MING CHANG_C', 'null', 3233, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3234, 'Wei Tiao', 'null', 3234, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3235, 'Wejoin', 'null', 3235, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3236, 'Welcom Heritage', 'null', 3236, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3237, 'Welcome Break', 'null', 3237, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3238, 'Welcomer Group_C', 'null', 3238, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3239, 'Wellington Management Group', 'null', 3239, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3240, 'Wenxing Hotel Group', 'null', 3240, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3241, 'Westay', 'null', 3241, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3242, 'Westcord Hotels', 'null', 3242, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3243, 'Westgate', 'null', 3243, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3244, 'White Beard', 'null', 3244, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3245, 'Widi', 'null', 3245, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3246, 'Wiggo Yttergard', 'null', 3246, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3247, 'Wigi Hidayat', 'null', 3247, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3248, 'Wild Bush Luxury', 'null', 3248, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3249, 'Williams Group', 'null', 3249, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3250, 'Wilson Hispanos', 'null', 3250, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3251, 'Win Rooms', 'null', 3251, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3252, 'Win Win Property_C', 'null', 3252, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3253, 'Wintc Property', 'null', 3253, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3254, 'Winterfell Hotels', 'null', 3254, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3255, 'Wise Factory', 'null', 3255, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3256, 'Wisma Karmel', 'null', 3256, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3257, 'Wisma Kopari', 'null', 3257, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3258, 'Wisma Pondok Pelangi', 'null', 3258, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3259, 'Wisma Sederhana', 'null', 3259, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3260, 'Withus Condotel', 'null', 3260, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3261, 'Wizzela Media', 'null', 3261, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3262, 'WMC GROUP', 'null', 3262, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3263, 'Wofox Apartments', 'null', 3263, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3264, 'Wombat\'s City Hostels', 'null', 3264, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3265, 'Wonderland Japan', 'null', 3265, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3266, 'Woodside Bay Estate', 'null', 3266, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3267, 'Woodstock', 'null', 3267, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3268, 'World Apartments', 'null', 3268, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3269, 'World Hotels - Do not use', 'null', 3269, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3270, 'World Resort Operation', 'null', 3270, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3271, 'World Wide Japan', 'null', 3271, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3272, 'Worldwide Apartments_C', 'null', 3272, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3273, 'Wotopia', 'null', 3273, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3274, 'WoZhai', 'null', 3274, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3275, 'Wuxiaoning', 'null', 3275, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3276, 'Wyndham Hotels & Resorts', 'null', 3276, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3277, 'Wyndham Vacation Rentals', 'null', 3277, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3278, 'Wynn', 'null', 3278, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3279, 'Xflat Services FZ LLC', 'null', 3279, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3280, 'Xiamen Yangxue Flower House', 'null', 3280, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3281, 'Xotel', 'null', 3281, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3282, 'XS', 'null', 3282, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3283, 'Yamashita', 'null', 3283, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3284, 'Yanapat Property', 'null', 3284, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3285, 'Yanjoon Holiday Homes Rental L.L.C', 'null', 3285, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3286, 'Yanthi Property', 'null', 3286, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3287, 'Yanti Yanti', 'null', 3287, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3288, 'YayanKurniawan', 'null', 3288, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3289, 'Yedawon', 'null', 3289, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3290, 'Yellow Hotels', 'null', 3290, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3291, 'Yendebabo Homestay', 'null', 3291, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3292, 'YHA Australia Hostels', 'null', 3292, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3293, 'YHA England & Wales', 'null', 3293, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3294, 'YHA Israel', 'null', 3294, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3295, 'YHA New Zealand', 'null', 3295, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3296, 'Yield Management', 'null', 3296, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3297, 'Ying Stay', 'null', 3297, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3298, 'YMCA', 'null', 3298, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3299, 'Yobel', 'null', 3299, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3300, 'Yoga', 'null', 3300, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3301, 'Yoho', 'null', 3301, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3302, 'Yoho_AC', 'null', 3302, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3303, 'Yorkeys Knob accommodation', 'null', 3303, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3304, 'Yoshihiro Kimura', 'null', 3304, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3305, 'You Hometel', 'null', 3305, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3306, 'You Stylish Apartments', 'null', 3306, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3307, 'Your Host Helper', 'null', 3307, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3308, 'Your Prague Hotels', 'null', 3308, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3309, 'Your Vica Stay_C', 'null', 3309, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3310, 'Your.Rentals A/S_C', 'null', 3310, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3311, 'YTL', 'null', 3311, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3312, 'YTL Hotels', 'null', 3312, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3313, 'Yudi Eko', 'null', 3313, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3314, 'Yudis Nur Riyadi', 'null', 3314, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3315, 'Yueyou Hotels', 'null', 3315, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3316, 'Yukai Resort', 'null', 3316, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3317, 'Yuly Anjiani', 'null', 3317, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3318, 'Yummy Plus', 'null', 3318, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3319, 'Yuni Kajane', 'null', 3319, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3320, 'Yupihome_C', 'null', 3320, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3321, 'YUSTAY Saigon', 'null', 3321, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3322, 'Yuyuan', 'null', 3322, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3323, 'YY38', 'null', 3323, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3324, 'Z Hotels', 'null', 3324, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3325, 'Zahra Al Jazeerah', 'null', 3325, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3326, 'Zara Property', 'null', 3326, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3327, 'Zarems', 'null', 3327, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3328, 'Zedekiah\'s Apartment Transient House', 'null', 3328, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3329, 'ZEN Rooms', 'null', 3329, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3330, 'Zencious Dormitory', 'null', 3330, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3331, 'Zenit Hotels', 'null', 3331, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3332, 'Zenith Holiday Homes', 'null', 3332, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3333, 'Zens', 'null', 3333, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3334, 'Zensan Bed And Bath', 'null', 3334, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3335, 'Zhensu Information Technology', 'null', 3335, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3336, 'Zhiqin', 'null', 3336, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3337, 'Zleepy', 'null', 3337, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3338, 'ZO Rooms', 'null', 3338, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3339, 'ZOSTEL', 'null', 3339, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3340, 'Zuri Hotel Management (ZHM)', 'null', 3340, 1, 1, 1, 1, 1)"); + DB::connection()->statement("INSERT INTO `property_chain` VALUES (3341, 'Zuzu Hospitality', 'null', 3341, 1, 1, 1, 1, 1)"); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_chain', function (Blueprint $table) { + $table->dropColumn('priority'); + }); + } +} diff --git a/database/migrations/2020_07_08_141717_change_column_language_base_and_language_translate_clear_foreingkeys.php b/database/migrations/2020_07_08_141717_change_column_language_base_and_language_translate_clear_foreingkeys.php new file mode 100644 index 0000000..a3079a0 --- /dev/null +++ b/database/migrations/2020_07_08_141717_change_column_language_base_and_language_translate_clear_foreingkeys.php @@ -0,0 +1,37 @@ +dropForeign(['created_by']); + $table->dropForeign(['updated_by']); + }); + + Schema::table('language_translate', function (Blueprint $table) { + $table->dropForeign(['created_by']); + $table->dropForeign(['updated_by']); + }); + + } + + public function down() + { + Schema::table('language_base', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + + Schema::table('language_translate', function (Blueprint $table) { + $table->foreign('created_by')->references('id')->on('user'); + $table->foreign('updated_by')->references('id')->on('user'); + }); + } + +} diff --git a/database/migrations/2020_07_13_104422_add_column_and_create_data_property_room_view_type_table.php b/database/migrations/2020_07_13_104422_add_column_and_create_data_property_room_view_type_table.php new file mode 100644 index 0000000..1eb86a3 --- /dev/null +++ b/database/migrations/2020_07_13_104422_add_column_and_create_data_property_room_view_type_table.php @@ -0,0 +1,104 @@ +string('language_key',100)->after('name')->nullable(); + }); + + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_room_view_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::table('property_room_view_type')->insert( + [ + [ + 'name' => 'Park', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Pool ', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'River', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Sea ', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Street', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Valley', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ], + [ + 'name' => 'Monument', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ] + ] + + ); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_room_view_type', function (Blueprint $table) { + $table->dropColumn('language_key'); + }); + + DB::statement('SET FOREIGN_KEY_CHECKS=0;'); + DB::table('property_room_view_type')->truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + } +} diff --git a/database/migrations/2020_07_14_181858_add_title_language_key_to_property_fact.php b/database/migrations/2020_07_14_181858_add_title_language_key_to_property_fact.php new file mode 100644 index 0000000..4e7f69d --- /dev/null +++ b/database/migrations/2020_07_14_181858_add_title_language_key_to_property_fact.php @@ -0,0 +1,33 @@ +string('title_language_key',250)->after('language_key')->nullable(); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_fact', function (Blueprint $table) { + $table->dropColumn('title_language_key'); + }); + } +} diff --git a/database/migrations/2020_07_22_095749_truncate_related_property_tables.php b/database/migrations/2020_07_22_095749_truncate_related_property_tables.php new file mode 100644 index 0000000..1ce924c --- /dev/null +++ b/database/migrations/2020_07_22_095749_truncate_related_property_tables.php @@ -0,0 +1,68 @@ +truncate(); + DB::table('jobs')->truncate(); + DB::table('failed_jobs')->truncate(); + + DB::table('offer')->truncate(); + DB::table('offer_accommodation_mapping')->truncate(); + DB::table('offer_cancellation_policy')->truncate(); + DB::table('offer_contact_mapping')->truncate(); + DB::table('offer_fact_mapping')->truncate(); + DB::table('offer_important_notes')->truncate(); + DB::table('offer_photo_mapping')->truncate(); + DB::table('offer_price')->truncate(); + DB::table('offer_room_mapping')->truncate(); + + DB::table('property')->truncate(); + DB::table('property_additional_info')->truncate(); + DB::table('property_brand')->truncate(); + DB::table('property_channel_mapping')->truncate(); + DB::table('property_config')->truncate(); + DB::table('property_contact')->truncate(); + DB::table('property_content')->truncate(); + DB::table('property_executive')->truncate(); + DB::table('property_fact_attribute_mapping')->truncate(); + DB::table('property_fact_mapping')->truncate(); + DB::table('property_module_mapping')->truncate(); + DB::table('property_photo')->truncate(); + DB::table('property_room')->truncate(); + DB::table('property_room_availability')->truncate(); + DB::table('property_room_bed')->truncate(); + DB::table('property_room_fact_mapping')->truncate(); + DB::table('property_room_photo_mapping')->truncate(); + DB::table('property_room_rate')->truncate(); + DB::table('property_room_rate_channel_mapping')->truncate(); + DB::table('property_room_rate_inclusion_mapping')->truncate(); + DB::table('property_room_rate_mapping')->truncate(); + DB::table('property_room_rate_mapping_setup')->truncate(); + DB::table('property_room_rate_price')->truncate(); + DB::table('property_room_view_mapping')->truncate(); + DB::table('property_web')->truncate(); + + DB::table('user')->truncate(); + DB::table('user_property_mapping')->truncate(); + + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + */ + } + + + public function down() + { + // + } +} diff --git a/database/migrations/2020_07_22_135248_add_icon_to_property_executive_type.php b/database/migrations/2020_07_22_135248_add_icon_to_property_executive_type.php new file mode 100644 index 0000000..1109f18 --- /dev/null +++ b/database/migrations/2020_07_22_135248_add_icon_to_property_executive_type.php @@ -0,0 +1,34 @@ +string('icon',32)->after('language_key')->nullable(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('property_executive_type', function (Blueprint $table) { + $table->dropColumn('icon'); + + }); + } +} diff --git a/database/migrations/2020_07_24_143309_add_language_key_to_tables.php b/database/migrations/2020_07_24_143309_add_language_key_to_tables.php new file mode 100644 index 0000000..cc68d7e --- /dev/null +++ b/database/migrations/2020_07_24_143309_add_language_key_to_tables.php @@ -0,0 +1,30 @@ +string('language_key',128)->after('name')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('country', function (Blueprint $table) { $table->dropColumn('language_key'); }); + } +} diff --git a/database/migrations/2020_08_10_112926_add_accommodation_type_to_property_room_rate.php b/database/migrations/2020_08_10_112926_add_accommodation_type_to_property_room_rate.php new file mode 100644 index 0000000..a324ee3 --- /dev/null +++ b/database/migrations/2020_08_10_112926_add_accommodation_type_to_property_room_rate.php @@ -0,0 +1,35 @@ +unsignedInteger('accommodation_type')->after('description'); + }); + \DB::table('property_room_rate')->update(['accommodation_type' => 13]); + Schema::table('property_room_rate', function (Blueprint $table) { + $table->foreign('accommodation_type', 'accommodation_type_foreign')->references('id')->on('property_fact'); + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + } +} diff --git a/database/migrations/2020_08_12_111815_add_room_size_to_property_room.php b/database/migrations/2020_08_12_111815_add_room_size_to_property_room.php new file mode 100644 index 0000000..86b02aa --- /dev/null +++ b/database/migrations/2020_08_12_111815_add_room_size_to_property_room.php @@ -0,0 +1,25 @@ +statement("UPDATE property_chain SET name = 'property_chain-independent' WHERE id = 1"); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_08_26_174248_update_siteconfig_20200826.php b/database/migrations/2020_08_26_174248_update_siteconfig_20200826.php new file mode 100644 index 0000000..4b85a90 --- /dev/null +++ b/database/migrations/2020_08_26_174248_update_siteconfig_20200826.php @@ -0,0 +1,32 @@ +where('config_key' , 'profile_rate_mapping')->update(['config_value_json' => $profileRateMapping]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_08_27_173249_update_site_config_20200827.php b/database/migrations/2020_08_27_173249_update_site_config_20200827.php new file mode 100644 index 0000000..a4a373c --- /dev/null +++ b/database/migrations/2020_08_27_173249_update_site_config_20200827.php @@ -0,0 +1,32 @@ +where('config_key' , 'profile_rate_mapping')->update(['config_value_json' => $profileRateMapping]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_08_28_144129_edit_property_channel_mapping_setup_20200828.php b/database/migrations/2020_08_28_144129_edit_property_channel_mapping_setup_20200828.php new file mode 100644 index 0000000..b34cf46 --- /dev/null +++ b/database/migrations/2020_08_28_144129_edit_property_channel_mapping_setup_20200828.php @@ -0,0 +1,38 @@ + Error; 1 =>Success; 2=> Start, 3=> Pending, 4 => Cancel/Refund', + `created_at` int(11) DEFAULT NULL, + `updated_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +); + "); + + DB::statement(" + CREATE TABLE `payment_type` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `pos_code` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `bank_code` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `threed_model` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `params` mediumtext COLLATE utf8mb4_unicode_ci, + `installment` tinyint(1) DEFAULT NULL COMMENT '0:Active, 1:Passive', + `status` tinyint(1) DEFAULT NULL COMMENT '0: Passive, 1: ActiveProd, 2: Test', + `created_by` int(11) DEFAULT NULL, + `updated_by` int(11) DEFAULT NULL, + `created_at` int(11) DEFAULT NULL, + `updated_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +); + "); + + DB::statement(" + CREATE TABLE `property_payment_installment` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `property_id` int(11) NOT NULL, + `property_payment_mapping_id` int(11) NOT NULL, + `installment` tinyint(3) DEFAULT NULL, + `commission` double(10,2) NOT NULL, + `status` tinyint(1) DEFAULT NULL, + `created_by` int(11) DEFAULT NULL, + `updated_by` int(11) DEFAULT NULL, + `created_at` int(11) DEFAULT NULL, + `updated_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +); + "); + + DB::statement(" + CREATE TABLE `property_payment_mapping` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `property_id` int(11) NOT NULL, + `payment_type_id` int(11) NOT NULL, + `params` mediumtext COLLATE utf8mb4_unicode_ci, + `installment` tinyint(1) DEFAULT NULL COMMENT '0:Active, 1:Passive', + `currency_code` varchar(3) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `is_default` tinyint(1) DEFAULT NULL, + `status` tinyint(1) DEFAULT NULL COMMENT '0: Passive, 1: ActiveProd, 2: Test', + `created_by` int(11) DEFAULT NULL, + `updated_by` int(11) DEFAULT NULL, + `created_at` int(11) DEFAULT NULL, + `updated_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +); + "); + + DB::statement(" + CREATE TABLE `currency_rates` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `date` date DEFAULT NULL, + `currency_code` varchar(3) CHARACTER SET utf8 DEFAULT NULL, + `exc_currency_code` varchar(3) CHARACTER SET utf8 DEFAULT NULL, + `rate` double(10,2) DEFAULT NULL, + `custom_rate` double(10,2) DEFAULT NULL, + `created_at` int(11) DEFAULT NULL, + `updated_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +); + "); + + + } + + + public function down() + { + // + } +} diff --git a/database/migrations/2020_11_02_133050_update_property_fact_table.php b/database/migrations/2020_11_02_133050_update_property_fact_table.php new file mode 100644 index 0000000..22769e6 --- /dev/null +++ b/database/migrations/2020_11_02_133050_update_property_fact_table.php @@ -0,0 +1,27 @@ +statement("INSERT INTO `property_web_menu` VALUES (1, null, 'Home', 'myweb-menu-home', '/', 1, 1, 1, 1, 1, 1, 1);"); + DB::connection()->statement("INSERT INTO `property_web_menu` VALUES (2, null, 'About', 'myweb-menu-about', '/about', 1, 2, 1, 1, 1, 1, 1);"); + DB::connection()->statement("INSERT INTO `property_web_menu` VALUES (3, null, 'Gallery', 'myweb-menu-gallery', '/gallery', 1, 3, 1, 1, 1, 1, 1);"); + DB::connection()->statement("INSERT INTO `property_web_menu` VALUES (4, null, 'Rooms', 'myweb-menu-rooms', '/rooms', 1, 4, 1, 1, 1, 1, 1);"); + DB::connection()->statement("INSERT INTO `property_web_menu` VALUES (5, null, 'Reservation', 'myweb-menu-reservation', '/booking', 2, 5, 1, 1, 1, 1, 1);"); + DB::connection()->statement("INSERT INTO `property_web_menu` VALUES (6, null, 'Contact Us', 'myweb-menu-contact_us', '/contact', 1, 6, 1, 1, 1, 1, 1);"); + } + + + public function down() + { + // + } +} diff --git a/database/migrations/2020_11_12_131542_create_table_property_web_setup.php b/database/migrations/2020_11_12_131542_create_table_property_web_setup.php new file mode 100644 index 0000000..7816de8 --- /dev/null +++ b/database/migrations/2020_11_12_131542_create_table_property_web_setup.php @@ -0,0 +1,41 @@ +where('config_key' , 'profile_rate_mapping')->update(['config_value_json' => $profileRateMapping]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2020_12_22_175505_payment_type_change_name_data.php b/database/migrations/2020_12_22_175505_payment_type_change_name_data.php new file mode 100644 index 0000000..efb997a --- /dev/null +++ b/database/migrations/2020_12_22_175505_payment_type_change_name_data.php @@ -0,0 +1,58 @@ +truncate(); + DB::statement('SET FOREIGN_KEY_CHECKS=1;'); + + DB::statement(' + INSERT INTO `property_place_fact_title_fact_mapping` VALUES (1,36,1,1,1,1,1,1,1),(2,36,1,2,1,1,1,1,1),(3,36,1,3,1,1,1,1,1),(4,36,1,4,1,1,1,1,1),(5,36,1,5,1,1,1,1,1),(6,37,1,1,1,1,1,1,1),(7,37,1,2,1,1,1,1,1),(8,37,1,3,1,1,1,1,1),(9,37,1,4,1,1,1,1,1),(10,37,1,5,1,1,1,1,1),(11,38,1,1,1,1,1,1,1),(12,38,1,2,1,1,1,1,1),(13,38,1,3,1,1,1,1,1),(14,38,1,4,1,1,1,1,1),(15,38,1,5,1,1,1,1,1),(16,39,1,1,1,1,1,1,1),(17,39,1,2,1,1,1,1,1),(18,39,1,3,1,1,1,1,1),(19,39,1,4,1,1,1,1,1),(20,39,1,5,1,1,1,1,1),(21,36,2,7,1,1,1,1,1),(22,36,2,8,1,1,1,1,1),(23,36,2,9,1,1,1,1,1),(24,36,2,10,1,1,1,1,1),(25,36,2,11,1,1,1,1,1),(26,36,2,12,1,1,1,1,1),(27,36,2,13,1,1,1,1,1),(28,36,2,14,1,1,1,1,1),(29,36,2,15,1,1,1,1,1),(30,36,2,16,1,1,1,1,1),(31,36,2,17,1,1,1,1,1),(32,36,2,18,1,1,1,1,1),(33,36,2,19,1,1,1,1,1),(34,36,2,20,1,1,1,1,1),(35,36,2,21,1,1,1,1,1),(36,36,2,22,1,1,1,1,1),(37,36,2,23,1,1,1,1,1),(38,36,2,24,1,1,1,1,1),(39,36,2,25,1,1,1,1,1),(40,37,2,7,1,1,1,1,1),(41,37,2,8,1,1,1,1,1),(42,37,2,9,1,1,1,1,1),(43,37,2,10,1,1,1,1,1),(44,37,2,11,1,1,1,1,1),(45,37,2,12,1,1,1,1,1),(46,37,2,13,1,1,1,1,1),(47,37,2,14,1,1,1,1,1),(48,37,2,15,1,1,1,1,1),(49,37,2,16,1,1,1,1,1),(50,37,2,17,1,1,1,1,1),(51,37,2,18,1,1,1,1,1),(52,37,2,19,1,1,1,1,1),(53,37,2,20,1,1,1,1,1),(54,37,2,21,1,1,1,1,1),(55,37,2,22,1,1,1,1,1),(56,37,2,23,1,1,1,1,1),(57,37,2,24,1,1,1,1,1),(58,37,2,25,1,1,1,1,1),(59,38,2,7,1,1,1,1,1),(60,38,2,8,1,1,1,1,1),(61,38,2,9,1,1,1,1,1),(62,38,2,10,1,1,1,1,1),(63,38,2,11,1,1,1,1,1),(64,38,2,12,1,1,1,1,1),(65,38,2,13,1,1,1,1,1),(66,38,2,14,1,1,1,1,1),(67,38,2,15,1,1,1,1,1),(68,38,2,16,1,1,1,1,1),(69,38,2,17,1,1,1,1,1),(70,38,2,18,1,1,1,1,1),(71,38,2,19,1,1,1,1,1),(72,38,2,20,1,1,1,1,1),(73,38,2,21,1,1,1,1,1),(74,38,2,22,1,1,1,1,1),(75,38,2,23,1,1,1,1,1),(76,38,2,24,1,1,1,1,1),(77,38,2,25,1,1,1,1,1),(78,39,2,7,1,1,1,1,1),(79,39,2,8,1,1,1,1,1),(80,39,2,9,1,1,1,1,1),(81,39,2,10,1,1,1,1,1),(82,39,2,11,1,1,1,1,1),(83,39,2,12,1,1,1,1,1),(84,39,2,13,1,1,1,1,1),(85,39,2,14,1,1,1,1,1),(86,39,2,15,1,1,1,1,1),(87,39,2,16,1,1,1,1,1),(88,39,2,17,1,1,1,1,1),(89,39,2,18,1,1,1,1,1),(90,39,2,19,1,1,1,1,1),(91,39,2,20,1,1,1,1,1),(92,39,2,21,1,1,1,1,1),(93,39,2,22,1,1,1,1,1),(94,39,2,23,1,1,1,1,1),(95,39,2,24,1,1,1,1,1),(96,39,2,25,1,1,1,1,1),(97,36,3,26,1,1,1,1,1),(98,36,3,27,1,1,1,1,1),(99,36,3,28,1,1,1,1,1),(100,36,3,29,1,1,1,1,1),(101,36,3,30,1,1,1,1,1),(102,36,3,31,1,1,1,1,1),(103,36,3,32,1,1,1,1,1),(104,36,3,33,1,1,1,1,1),(105,36,3,34,1,1,1,1,1),(106,36,3,35,1,1,1,1,1),(107,37,3,26,1,1,1,1,1),(108,37,3,27,1,1,1,1,1),(109,37,3,28,1,1,1,1,1),(110,37,3,29,1,1,1,1,1),(111,37,3,30,1,1,1,1,1),(112,37,3,31,1,1,1,1,1),(113,37,3,32,1,1,1,1,1),(114,37,3,33,1,1,1,1,1),(115,37,3,34,1,1,1,1,1),(116,37,3,35,1,1,1,1,1),(117,38,3,26,1,1,1,1,1),(118,38,3,27,1,1,1,1,1),(119,38,3,28,1,1,1,1,1),(120,38,3,29,1,1,1,1,1),(121,38,3,30,1,1,1,1,1),(122,38,3,31,1,1,1,1,1),(123,38,3,32,1,1,1,1,1),(124,38,3,33,1,1,1,1,1),(125,38,3,34,1,1,1,1,1),(126,38,3,35,1,1,1,1,1),(127,39,3,26,1,1,1,1,1),(128,39,3,27,1,1,1,1,1),(129,39,3,28,1,1,1,1,1),(130,39,3,29,1,1,1,1,1),(131,39,3,30,1,1,1,1,1),(132,39,3,31,1,1,1,1,1),(133,39,3,32,1,1,1,1,1),(134,39,3,33,1,1,1,1,1),(135,39,3,34,1,1,1,1,1),(136,39,3,35,1,1,1,1,1),(137,36,4,42,1,1,1,1,1),(138,36,4,43,1,1,1,1,1),(139,36,4,44,1,1,1,1,1),(140,36,4,45,1,1,1,1,1),(141,36,4,46,1,1,1,1,1),(142,36,4,47,1,1,1,1,1),(143,36,4,48,1,1,1,1,1),(144,36,4,49,1,1,1,1,1),(145,36,4,50,1,1,1,1,1),(146,36,4,51,1,1,1,1,1),(147,36,4,52,1,1,1,1,1),(148,36,4,53,1,1,1,1,1),(149,36,4,54,1,1,1,1,1),(150,36,4,55,1,1,1,1,1),(151,36,4,56,1,1,1,1,1),(152,37,4,42,1,1,1,1,1),(153,37,4,43,1,1,1,1,1),(154,37,4,44,1,1,1,1,1),(155,37,4,45,1,1,1,1,1),(156,37,4,46,1,1,1,1,1),(157,37,4,47,1,1,1,1,1),(158,37,4,48,1,1,1,1,1),(159,37,4,49,1,1,1,1,1),(160,37,4,50,1,1,1,1,1),(161,37,4,51,1,1,1,1,1),(162,37,4,52,1,1,1,1,1),(163,37,4,53,1,1,1,1,1),(164,37,4,54,1,1,1,1,1),(165,37,4,55,1,1,1,1,1),(166,37,4,56,1,1,1,1,1),(167,38,4,42,1,1,1,1,1),(168,38,4,43,1,1,1,1,1),(169,38,4,44,1,1,1,1,1),(170,38,4,45,1,1,1,1,1),(171,38,4,46,1,1,1,1,1),(172,38,4,47,1,1,1,1,1),(173,38,4,48,1,1,1,1,1),(174,38,4,49,1,1,1,1,1),(175,38,4,50,1,1,1,1,1),(176,38,4,51,1,1,1,1,1),(177,38,4,52,1,1,1,1,1),(178,38,4,53,1,1,1,1,1),(179,38,4,54,1,1,1,1,1),(180,38,4,55,1,1,1,1,1),(181,38,4,56,1,1,1,1,1),(182,39,4,42,1,1,1,1,1),(183,39,4,43,1,1,1,1,1),(184,39,4,44,1,1,1,1,1),(185,39,4,45,1,1,1,1,1),(186,39,4,46,1,1,1,1,1),(187,39,4,47,1,1,1,1,1),(188,39,4,48,1,1,1,1,1),(189,39,4,49,1,1,1,1,1),(190,39,4,50,1,1,1,1,1),(191,39,4,51,1,1,1,1,1),(192,39,4,52,1,1,1,1,1),(193,39,4,53,1,1,1,1,1),(194,39,4,54,1,1,1,1,1),(195,39,4,55,1,1,1,1,1),(196,39,4,56,1,1,1,1,1),(197,36,5,66,1,1,1,1,1),(198,36,5,67,1,1,1,1,1),(199,36,5,68,1,1,1,1,1),(200,36,5,69,1,1,1,1,1),(201,36,5,70,1,1,1,1,1),(202,36,5,71,1,1,1,1,1),(203,36,5,72,1,1,1,1,1),(204,36,5,73,1,1,1,1,1),(205,36,5,74,1,1,1,1,1),(206,36,5,75,1,1,1,1,1),(207,36,5,76,1,1,1,1,1),(208,36,5,77,1,1,1,1,1),(209,36,5,78,1,1,1,1,1),(210,36,5,79,1,1,1,1,1),(211,36,5,80,1,1,1,1,1),(212,36,5,81,1,1,1,1,1),(213,36,5,82,1,1,1,1,1),(214,36,5,83,1,1,1,1,1),(215,36,5,84,1,1,1,1,1),(216,36,5,85,1,1,1,1,1),(217,36,5,86,1,1,1,1,1),(218,36,5,87,1,1,1,1,1),(219,36,5,88,1,1,1,1,1),(220,36,5,89,1,1,1,1,1),(221,36,5,90,1,1,1,1,1),(222,36,5,91,1,1,1,1,1),(223,36,5,92,1,1,1,1,1),(224,36,5,93,1,1,1,1,1),(225,36,5,94,1,1,1,1,1),(226,36,5,95,1,1,1,1,1),(227,36,5,96,1,1,1,1,1),(228,36,5,97,1,1,1,1,1),(229,36,5,98,1,1,1,1,1),(230,37,5,66,1,1,1,1,1),(231,37,5,67,1,1,1,1,1),(232,37,5,68,1,1,1,1,1),(233,37,5,69,1,1,1,1,1),(234,37,5,70,1,1,1,1,1),(235,37,5,71,1,1,1,1,1),(236,37,5,72,1,1,1,1,1),(237,37,5,73,1,1,1,1,1),(238,37,5,74,1,1,1,1,1),(239,37,5,75,1,1,1,1,1),(240,37,5,76,1,1,1,1,1),(241,37,5,77,1,1,1,1,1),(242,37,5,78,1,1,1,1,1),(243,37,5,79,1,1,1,1,1),(244,37,5,80,1,1,1,1,1),(245,37,5,81,1,1,1,1,1),(246,37,5,82,1,1,1,1,1),(247,37,5,83,1,1,1,1,1),(248,37,5,84,1,1,1,1,1),(249,37,5,85,1,1,1,1,1),(250,37,5,86,1,1,1,1,1),(251,37,5,87,1,1,1,1,1),(252,37,5,88,1,1,1,1,1),(253,37,5,89,1,1,1,1,1),(254,37,5,90,1,1,1,1,1),(255,37,5,91,1,1,1,1,1),(256,37,5,92,1,1,1,1,1),(257,37,5,93,1,1,1,1,1),(258,37,5,94,1,1,1,1,1),(259,37,5,95,1,1,1,1,1),(260,37,5,96,1,1,1,1,1),(261,37,5,97,1,1,1,1,1),(262,37,5,98,1,1,1,1,1),(263,38,5,66,1,1,1,1,1),(264,38,5,67,1,1,1,1,1),(265,38,5,68,1,1,1,1,1),(266,38,5,69,1,1,1,1,1),(267,38,5,70,1,1,1,1,1),(268,38,5,71,1,1,1,1,1),(269,38,5,72,1,1,1,1,1),(270,38,5,73,1,1,1,1,1),(271,38,5,74,1,1,1,1,1),(272,38,5,75,1,1,1,1,1),(273,38,5,76,1,1,1,1,1),(274,38,5,77,1,1,1,1,1),(275,38,5,78,1,1,1,1,1),(276,38,5,79,1,1,1,1,1),(277,38,5,80,1,1,1,1,1),(278,38,5,81,1,1,1,1,1),(279,38,5,82,1,1,1,1,1),(280,38,5,83,1,1,1,1,1),(281,38,5,84,1,1,1,1,1),(282,38,5,85,1,1,1,1,1),(283,38,5,86,1,1,1,1,1),(284,38,5,87,1,1,1,1,1),(285,38,5,88,1,1,1,1,1),(286,38,5,89,1,1,1,1,1),(287,38,5,90,1,1,1,1,1),(288,38,5,91,1,1,1,1,1),(289,38,5,92,1,1,1,1,1),(290,38,5,93,1,1,1,1,1),(291,38,5,94,1,1,1,1,1),(292,38,5,95,1,1,1,1,1),(293,38,5,96,1,1,1,1,1),(294,38,5,97,1,1,1,1,1),(295,38,5,98,1,1,1,1,1),(296,39,5,66,1,1,1,1,1),(297,39,5,67,1,1,1,1,1),(298,39,5,68,1,1,1,1,1),(299,39,5,69,1,1,1,1,1),(300,39,5,70,1,1,1,1,1),(301,39,5,71,1,1,1,1,1),(302,39,5,72,1,1,1,1,1),(303,39,5,73,1,1,1,1,1),(304,39,5,74,1,1,1,1,1),(305,39,5,75,1,1,1,1,1),(306,39,5,76,1,1,1,1,1),(307,39,5,77,1,1,1,1,1),(308,39,5,78,1,1,1,1,1),(309,39,5,79,1,1,1,1,1),(310,39,5,80,1,1,1,1,1),(311,39,5,81,1,1,1,1,1),(312,39,5,82,1,1,1,1,1),(313,39,5,83,1,1,1,1,1),(314,39,5,84,1,1,1,1,1),(315,39,5,85,1,1,1,1,1),(316,39,5,86,1,1,1,1,1),(317,39,5,87,1,1,1,1,1),(318,39,5,88,1,1,1,1,1),(319,39,5,89,1,1,1,1,1),(320,39,5,90,1,1,1,1,1),(321,39,5,91,1,1,1,1,1),(322,39,5,92,1,1,1,1,1),(323,39,5,93,1,1,1,1,1),(324,39,5,94,1,1,1,1,1),(325,39,5,95,1,1,1,1,1),(326,39,5,96,1,1,1,1,1),(327,39,5,97,1,1,1,1,1),(328,39,5,98,1,1,1,1,1),(329,40,1,5,1,1,1,1,1),(330,40,1,6,1,1,1,1,1),(331,41,1,5,1,1,1,1,1),(332,41,1,6,1,1,1,1,1),(333,42,1,5,1,1,1,1,1),(334,42,1,6,1,1,1,1,1),(335,43,1,5,1,1,1,1,1),(336,43,1,6,1,1,1,1,1),(337,44,1,5,1,1,1,1,1),(338,44,1,6,1,1,1,1,1),(339,45,1,5,1,1,1,1,1),(340,45,1,6,1,1,1,1,1),(341,46,1,5,1,1,1,1,1),(342,46,1,6,1,1,1,1,1),(343,47,1,5,1,1,1,1,1),(344,47,1,6,1,1,1,1,1),(345,48,1,5,1,1,1,1,1),(346,48,1,6,1,1,1,1,1),(347,49,1,5,1,1,1,1,1),(348,49,1,6,1,1,1,1,1),(349,50,1,5,1,1,1,1,1),(350,50,1,6,1,1,1,1,1),(351,51,1,5,1,1,1,1,1),(352,51,1,6,1,1,1,1,1),(353,52,1,5,1,1,1,1,1),(354,52,1,6,1,1,1,1,1),(355,53,1,5,1,1,1,1,1),(356,53,1,6,1,1,1,1,1),(357,54,1,5,1,1,1,1,1),(358,54,1,6,1,1,1,1,1),(359,55,1,5,1,1,1,1,1),(360,55,1,6,1,1,1,1,1),(361,56,1,5,1,1,1,1,1),(362,56,1,6,1,1,1,1,1),(363,41,3,36,1,1,1,1,1),(364,41,3,37,1,1,1,1,1),(365,41,3,38,1,1,1,1,1),(366,41,3,39,1,1,1,1,1),(367,41,3,40,1,1,1,1,1),(368,41,3,41,1,1,1,1,1),(369,42,3,36,1,1,1,1,1),(370,42,3,37,1,1,1,1,1),(371,42,3,38,1,1,1,1,1),(372,42,3,39,1,1,1,1,1),(373,42,3,40,1,1,1,1,1),(374,42,3,41,1,1,1,1,1),(375,43,3,37,1,1,1,1,1),(376,43,3,38,1,1,1,1,1),(377,43,3,39,1,1,1,1,1),(378,43,3,40,1,1,1,1,1),(379,43,3,41,1,1,1,1,1),(380,44,3,37,1,1,1,1,1),(381,44,3,38,1,1,1,1,1),(382,44,3,39,1,1,1,1,1),(383,44,3,40,1,1,1,1,1),(384,44,3,41,1,1,1,1,1),(385,45,3,37,1,1,1,1,1),(386,45,3,38,1,1,1,1,1),(387,45,3,39,1,1,1,1,1),(388,45,3,40,1,1,1,1,1),(389,45,3,41,1,1,1,1,1),(390,46,3,37,1,1,1,1,1),(391,46,3,38,1,1,1,1,1),(392,46,3,39,1,1,1,1,1),(393,46,3,40,1,1,1,1,1),(394,46,3,41,1,1,1,1,1),(395,47,3,37,1,1,1,1,1),(396,47,3,38,1,1,1,1,1),(397,47,3,39,1,1,1,1,1),(398,47,3,40,1,1,1,1,1),(399,47,3,41,1,1,1,1,1),(400,48,3,37,1,1,1,1,1),(401,48,3,38,1,1,1,1,1),(402,48,3,39,1,1,1,1,1),(403,48,3,40,1,1,1,1,1),(404,48,3,41,1,1,1,1,1),(405,49,3,37,1,1,1,1,1),(406,49,3,38,1,1,1,1,1),(407,49,3,39,1,1,1,1,1),(408,49,3,40,1,1,1,1,1),(409,49,3,41,1,1,1,1,1),(410,50,3,37,1,1,1,1,1),(411,50,3,38,1,1,1,1,1),(412,50,3,39,1,1,1,1,1),(413,50,3,40,1,1,1,1,1),(414,50,3,41,1,1,1,1,1),(415,51,3,37,1,1,1,1,1),(416,51,3,38,1,1,1,1,1),(417,51,3,39,1,1,1,1,1),(418,51,3,40,1,1,1,1,1),(419,51,3,41,1,1,1,1,1),(420,52,3,37,1,1,1,1,1),(421,52,3,38,1,1,1,1,1),(422,52,3,39,1,1,1,1,1),(423,52,3,40,1,1,1,1,1),(424,52,3,41,1,1,1,1,1),(425,53,3,37,1,1,1,1,1),(426,53,3,38,1,1,1,1,1),(427,53,3,39,1,1,1,1,1),(428,53,3,40,1,1,1,1,1),(429,53,3,41,1,1,1,1,1),(430,54,3,37,1,1,1,1,1),(431,54,3,38,1,1,1,1,1),(432,54,3,39,1,1,1,1,1),(433,54,3,40,1,1,1,1,1),(434,54,3,41,1,1,1,1,1),(435,55,3,37,1,1,1,1,1),(436,55,3,38,1,1,1,1,1),(437,55,3,39,1,1,1,1,1),(438,55,3,40,1,1,1,1,1),(439,55,3,41,1,1,1,1,1),(440,56,3,37,1,1,1,1,1),(441,56,3,38,1,1,1,1,1),(442,56,3,39,1,1,1,1,1),(443,56,3,40,1,1,1,1,1),(444,56,3,41,1,1,1,1,1),(445,41,4,42,1,1,1,1,1),(446,41,4,43,1,1,1,1,1),(447,41,4,44,1,1,1,1,1),(448,41,4,45,1,1,1,1,1),(449,41,4,46,1,1,1,1,1),(450,41,4,47,1,1,1,1,1),(451,41,4,48,1,1,1,1,1),(452,41,4,49,1,1,1,1,1),(453,41,4,50,1,1,1,1,1),(454,41,4,51,1,1,1,1,1),(455,41,4,52,1,1,1,1,1),(456,41,4,53,1,1,1,1,1),(457,41,4,54,1,1,1,1,1),(458,41,4,55,1,1,1,1,1),(459,41,4,56,1,1,1,1,1),(460,42,4,42,1,1,1,1,1),(461,42,4,43,1,1,1,1,1),(462,42,4,44,1,1,1,1,1),(463,42,4,45,1,1,1,1,1),(464,42,4,46,1,1,1,1,1),(465,42,4,47,1,1,1,1,1),(466,42,4,48,1,1,1,1,1),(467,42,4,49,1,1,1,1,1),(468,42,4,50,1,1,1,1,1),(469,42,4,51,1,1,1,1,1),(470,42,4,52,1,1,1,1,1),(471,42,4,53,1,1,1,1,1),(472,42,4,54,1,1,1,1,1),(473,42,4,55,1,1,1,1,1),(474,42,4,56,1,1,1,1,1),(475,43,4,42,1,1,1,1,1),(476,43,4,43,1,1,1,1,1),(477,43,4,44,1,1,1,1,1),(478,43,4,45,1,1,1,1,1),(479,43,4,46,1,1,1,1,1),(480,43,4,47,1,1,1,1,1),(481,43,4,48,1,1,1,1,1),(482,43,4,49,1,1,1,1,1),(483,43,4,50,1,1,1,1,1),(484,43,4,51,1,1,1,1,1),(485,43,4,52,1,1,1,1,1),(486,43,4,53,1,1,1,1,1),(487,43,4,54,1,1,1,1,1),(488,43,4,55,1,1,1,1,1),(489,43,4,56,1,1,1,1,1),(490,44,4,42,1,1,1,1,1),(491,44,4,43,1,1,1,1,1),(492,44,4,44,1,1,1,1,1),(493,44,4,45,1,1,1,1,1),(494,44,4,46,1,1,1,1,1),(495,44,4,47,1,1,1,1,1),(496,44,4,48,1,1,1,1,1),(497,44,4,49,1,1,1,1,1),(498,44,4,50,1,1,1,1,1),(499,44,4,51,1,1,1,1,1),(500,44,4,52,1,1,1,1,1),(501,44,4,53,1,1,1,1,1),(502,44,4,54,1,1,1,1,1),(503,44,4,55,1,1,1,1,1),(504,44,4,56,1,1,1,1,1),(505,45,4,42,1,1,1,1,1),(506,45,4,43,1,1,1,1,1),(507,45,4,44,1,1,1,1,1),(508,45,4,45,1,1,1,1,1),(509,45,4,46,1,1,1,1,1),(510,45,4,47,1,1,1,1,1),(511,45,4,48,1,1,1,1,1),(512,45,4,49,1,1,1,1,1),(513,45,4,50,1,1,1,1,1),(514,45,4,51,1,1,1,1,1),(515,45,4,52,1,1,1,1,1),(516,45,4,53,1,1,1,1,1),(517,45,4,54,1,1,1,1,1),(518,45,4,55,1,1,1,1,1),(519,45,4,56,1,1,1,1,1),(520,46,4,42,1,1,1,1,1),(521,46,4,43,1,1,1,1,1),(522,46,4,44,1,1,1,1,1),(523,46,4,45,1,1,1,1,1),(524,46,4,46,1,1,1,1,1),(525,46,4,47,1,1,1,1,1),(526,46,4,48,1,1,1,1,1),(527,46,4,49,1,1,1,1,1),(528,46,4,50,1,1,1,1,1),(529,46,4,51,1,1,1,1,1),(530,46,4,52,1,1,1,1,1),(531,46,4,53,1,1,1,1,1),(532,46,4,54,1,1,1,1,1),(533,46,4,55,1,1,1,1,1),(534,46,4,56,1,1,1,1,1),(535,47,4,42,1,1,1,1,1),(536,47,4,43,1,1,1,1,1),(537,47,4,44,1,1,1,1,1),(538,47,4,45,1,1,1,1,1),(539,47,4,46,1,1,1,1,1),(540,47,4,47,1,1,1,1,1),(541,47,4,48,1,1,1,1,1),(542,47,4,49,1,1,1,1,1),(543,47,4,50,1,1,1,1,1),(544,47,4,51,1,1,1,1,1),(545,47,4,52,1,1,1,1,1),(546,47,4,53,1,1,1,1,1),(547,47,4,54,1,1,1,1,1),(548,47,4,55,1,1,1,1,1),(549,47,4,56,1,1,1,1,1),(550,48,4,42,1,1,1,1,1),(551,48,4,43,1,1,1,1,1),(552,48,4,44,1,1,1,1,1),(553,48,4,45,1,1,1,1,1),(554,48,4,46,1,1,1,1,1),(555,48,4,47,1,1,1,1,1),(556,48,4,48,1,1,1,1,1),(557,48,4,49,1,1,1,1,1),(558,48,4,50,1,1,1,1,1),(559,48,4,51,1,1,1,1,1),(560,48,4,52,1,1,1,1,1),(561,48,4,53,1,1,1,1,1),(562,48,4,54,1,1,1,1,1),(563,48,4,55,1,1,1,1,1),(564,48,4,56,1,1,1,1,1),(565,49,4,42,1,1,1,1,1),(566,49,4,43,1,1,1,1,1),(567,49,4,44,1,1,1,1,1),(568,49,4,45,1,1,1,1,1),(569,49,4,46,1,1,1,1,1),(570,49,4,47,1,1,1,1,1),(571,49,4,48,1,1,1,1,1),(572,49,4,49,1,1,1,1,1),(573,49,4,50,1,1,1,1,1),(574,49,4,51,1,1,1,1,1),(575,49,4,52,1,1,1,1,1),(576,49,4,53,1,1,1,1,1),(577,49,4,54,1,1,1,1,1),(578,49,4,55,1,1,1,1,1),(579,49,4,56,1,1,1,1,1),(580,50,4,42,1,1,1,1,1),(581,50,4,43,1,1,1,1,1),(582,50,4,44,1,1,1,1,1),(583,50,4,45,1,1,1,1,1),(584,50,4,46,1,1,1,1,1),(585,50,4,47,1,1,1,1,1),(586,50,4,48,1,1,1,1,1),(587,50,4,49,1,1,1,1,1),(588,50,4,50,1,1,1,1,1),(589,50,4,51,1,1,1,1,1),(590,50,4,52,1,1,1,1,1),(591,50,4,53,1,1,1,1,1),(592,50,4,54,1,1,1,1,1),(593,50,4,55,1,1,1,1,1),(594,50,4,56,1,1,1,1,1),(595,51,4,42,1,1,1,1,1),(596,51,4,43,1,1,1,1,1),(597,51,4,44,1,1,1,1,1),(598,51,4,45,1,1,1,1,1),(599,51,4,46,1,1,1,1,1),(600,51,4,47,1,1,1,1,1),(601,51,4,48,1,1,1,1,1),(602,51,4,49,1,1,1,1,1),(603,51,4,50,1,1,1,1,1),(604,51,4,51,1,1,1,1,1),(605,51,4,52,1,1,1,1,1),(606,51,4,53,1,1,1,1,1),(607,51,4,54,1,1,1,1,1),(608,51,4,55,1,1,1,1,1),(609,51,4,56,1,1,1,1,1),(610,52,4,42,1,1,1,1,1),(611,52,4,43,1,1,1,1,1),(612,52,4,44,1,1,1,1,1),(613,52,4,45,1,1,1,1,1),(614,52,4,46,1,1,1,1,1),(615,52,4,47,1,1,1,1,1),(616,52,4,48,1,1,1,1,1),(617,52,4,49,1,1,1,1,1),(618,52,4,50,1,1,1,1,1),(619,52,4,51,1,1,1,1,1),(620,52,4,52,1,1,1,1,1),(621,52,4,53,1,1,1,1,1),(622,52,4,54,1,1,1,1,1),(623,52,4,55,1,1,1,1,1),(624,52,4,56,1,1,1,1,1),(625,53,4,42,1,1,1,1,1),(626,53,4,43,1,1,1,1,1),(627,53,4,44,1,1,1,1,1),(628,53,4,45,1,1,1,1,1),(629,53,4,46,1,1,1,1,1),(630,53,4,47,1,1,1,1,1),(631,53,4,48,1,1,1,1,1),(632,53,4,49,1,1,1,1,1),(633,53,4,50,1,1,1,1,1),(634,53,4,51,1,1,1,1,1),(635,53,4,52,1,1,1,1,1),(636,53,4,53,1,1,1,1,1),(637,53,4,54,1,1,1,1,1),(638,53,4,55,1,1,1,1,1),(639,53,4,56,1,1,1,1,1),(640,54,4,42,1,1,1,1,1),(641,54,4,43,1,1,1,1,1),(642,54,4,44,1,1,1,1,1),(643,54,4,45,1,1,1,1,1),(644,54,4,46,1,1,1,1,1),(645,54,4,47,1,1,1,1,1),(646,54,4,48,1,1,1,1,1),(647,54,4,49,1,1,1,1,1),(648,54,4,50,1,1,1,1,1),(649,54,4,51,1,1,1,1,1),(650,54,4,52,1,1,1,1,1),(651,54,4,53,1,1,1,1,1),(652,54,4,54,1,1,1,1,1),(653,54,4,55,1,1,1,1,1),(654,54,4,56,1,1,1,1,1),(655,55,4,42,1,1,1,1,1),(656,55,4,43,1,1,1,1,1),(657,55,4,44,1,1,1,1,1),(658,55,4,45,1,1,1,1,1),(659,55,4,46,1,1,1,1,1),(660,55,4,47,1,1,1,1,1),(661,55,4,48,1,1,1,1,1),(662,55,4,49,1,1,1,1,1),(663,55,4,50,1,1,1,1,1),(664,55,4,51,1,1,1,1,1),(665,55,4,52,1,1,1,1,1),(666,55,4,53,1,1,1,1,1),(667,55,4,54,1,1,1,1,1),(668,55,4,55,1,1,1,1,1),(669,55,4,56,1,1,1,1,1),(670,56,4,42,1,1,1,1,1),(671,56,4,43,1,1,1,1,1),(672,56,4,44,1,1,1,1,1),(673,56,4,45,1,1,1,1,1),(674,56,4,46,1,1,1,1,1),(675,56,4,47,1,1,1,1,1),(676,56,4,48,1,1,1,1,1),(677,56,4,49,1,1,1,1,1),(678,56,4,50,1,1,1,1,1),(679,56,4,51,1,1,1,1,1),(680,56,4,52,1,1,1,1,1),(681,56,4,53,1,1,1,1,1),(682,56,4,54,1,1,1,1,1),(683,56,4,55,1,1,1,1,1),(684,56,4,56,1,1,1,1,1),(685,41,5,66,1,1,1,1,1),(686,41,5,67,1,1,1,1,1),(687,41,5,68,1,1,1,1,1),(688,41,5,69,1,1,1,1,1),(689,41,5,70,1,1,1,1,1),(690,41,5,71,1,1,1,1,1),(691,41,5,72,1,1,1,1,1),(692,41,5,73,1,1,1,1,1),(693,41,5,74,1,1,1,1,1),(694,41,5,75,1,1,1,1,1),(695,41,5,76,1,1,1,1,1),(696,41,5,77,1,1,1,1,1),(697,41,5,78,1,1,1,1,1),(698,41,5,79,1,1,1,1,1),(699,41,5,80,1,1,1,1,1),(700,41,5,81,1,1,1,1,1),(701,41,5,82,1,1,1,1,1),(702,41,5,83,1,1,1,1,1),(703,41,5,84,1,1,1,1,1),(704,41,5,85,1,1,1,1,1),(705,41,5,86,1,1,1,1,1),(706,41,5,87,1,1,1,1,1),(707,41,5,88,1,1,1,1,1),(708,41,5,89,1,1,1,1,1),(709,41,5,90,1,1,1,1,1),(710,41,5,91,1,1,1,1,1),(711,41,5,92,1,1,1,1,1),(712,41,5,93,1,1,1,1,1),(713,41,5,94,1,1,1,1,1),(714,41,5,95,1,1,1,1,1),(715,41,5,96,1,1,1,1,1),(716,41,5,97,1,1,1,1,1),(717,41,5,98,1,1,1,1,1),(718,42,5,66,1,1,1,1,1),(719,42,5,67,1,1,1,1,1),(720,42,5,68,1,1,1,1,1),(721,42,5,69,1,1,1,1,1),(722,42,5,70,1,1,1,1,1),(723,42,5,71,1,1,1,1,1),(724,42,5,72,1,1,1,1,1),(725,42,5,73,1,1,1,1,1),(726,42,5,74,1,1,1,1,1),(727,42,5,75,1,1,1,1,1),(728,42,5,76,1,1,1,1,1),(729,42,5,77,1,1,1,1,1),(730,42,5,78,1,1,1,1,1),(731,42,5,79,1,1,1,1,1),(732,42,5,80,1,1,1,1,1),(733,42,5,81,1,1,1,1,1),(734,42,5,82,1,1,1,1,1),(735,42,5,83,1,1,1,1,1),(736,42,5,84,1,1,1,1,1),(737,42,5,85,1,1,1,1,1),(738,42,5,86,1,1,1,1,1),(739,42,5,87,1,1,1,1,1),(740,42,5,88,1,1,1,1,1),(741,42,5,89,1,1,1,1,1),(742,42,5,90,1,1,1,1,1),(743,42,5,91,1,1,1,1,1),(744,42,5,92,1,1,1,1,1),(745,42,5,93,1,1,1,1,1),(746,42,5,94,1,1,1,1,1),(747,42,5,95,1,1,1,1,1),(748,42,5,96,1,1,1,1,1),(749,42,5,97,1,1,1,1,1),(750,42,5,98,1,1,1,1,1),(751,43,5,66,1,1,1,1,1),(752,43,5,67,1,1,1,1,1),(753,43,5,68,1,1,1,1,1),(754,43,5,69,1,1,1,1,1),(755,43,5,70,1,1,1,1,1),(756,43,5,71,1,1,1,1,1),(757,43,5,72,1,1,1,1,1),(758,43,5,73,1,1,1,1,1),(759,43,5,74,1,1,1,1,1),(760,43,5,75,1,1,1,1,1),(761,43,5,76,1,1,1,1,1),(762,43,5,77,1,1,1,1,1),(763,43,5,78,1,1,1,1,1),(764,43,5,79,1,1,1,1,1),(765,43,5,80,1,1,1,1,1),(766,43,5,81,1,1,1,1,1),(767,43,5,82,1,1,1,1,1),(768,43,5,83,1,1,1,1,1),(769,43,5,84,1,1,1,1,1),(770,43,5,85,1,1,1,1,1),(771,43,5,86,1,1,1,1,1),(772,43,5,87,1,1,1,1,1),(773,43,5,88,1,1,1,1,1),(774,43,5,89,1,1,1,1,1),(775,43,5,90,1,1,1,1,1),(776,43,5,91,1,1,1,1,1),(777,43,5,92,1,1,1,1,1),(778,43,5,93,1,1,1,1,1),(779,43,5,94,1,1,1,1,1),(780,43,5,95,1,1,1,1,1),(781,43,5,96,1,1,1,1,1),(782,43,5,97,1,1,1,1,1),(783,43,5,98,1,1,1,1,1),(784,44,5,66,1,1,1,1,1),(785,44,5,67,1,1,1,1,1),(786,44,5,68,1,1,1,1,1),(787,44,5,69,1,1,1,1,1),(788,44,5,70,1,1,1,1,1),(789,44,5,71,1,1,1,1,1),(790,44,5,72,1,1,1,1,1),(791,44,5,73,1,1,1,1,1),(792,44,5,74,1,1,1,1,1),(793,44,5,75,1,1,1,1,1),(794,44,5,76,1,1,1,1,1),(795,44,5,77,1,1,1,1,1),(796,44,5,78,1,1,1,1,1),(797,44,5,79,1,1,1,1,1),(798,44,5,80,1,1,1,1,1),(799,44,5,81,1,1,1,1,1),(800,44,5,82,1,1,1,1,1),(801,44,5,83,1,1,1,1,1),(802,44,5,84,1,1,1,1,1),(803,44,5,85,1,1,1,1,1),(804,44,5,86,1,1,1,1,1),(805,44,5,87,1,1,1,1,1),(806,44,5,88,1,1,1,1,1),(807,44,5,89,1,1,1,1,1),(808,44,5,90,1,1,1,1,1),(809,44,5,91,1,1,1,1,1),(810,44,5,92,1,1,1,1,1),(811,44,5,93,1,1,1,1,1),(812,44,5,94,1,1,1,1,1),(813,44,5,95,1,1,1,1,1),(814,44,5,96,1,1,1,1,1),(815,44,5,97,1,1,1,1,1),(816,44,5,98,1,1,1,1,1),(817,45,5,66,1,1,1,1,1),(818,45,5,67,1,1,1,1,1),(819,45,5,68,1,1,1,1,1),(820,45,5,69,1,1,1,1,1),(821,45,5,70,1,1,1,1,1),(822,45,5,71,1,1,1,1,1),(823,45,5,72,1,1,1,1,1),(824,45,5,73,1,1,1,1,1),(825,45,5,74,1,1,1,1,1),(826,45,5,75,1,1,1,1,1),(827,45,5,76,1,1,1,1,1),(828,45,5,77,1,1,1,1,1),(829,45,5,78,1,1,1,1,1),(830,45,5,79,1,1,1,1,1),(831,45,5,80,1,1,1,1,1),(832,45,5,81,1,1,1,1,1),(833,45,5,82,1,1,1,1,1),(834,45,5,83,1,1,1,1,1),(835,45,5,84,1,1,1,1,1),(836,45,5,85,1,1,1,1,1),(837,45,5,86,1,1,1,1,1),(838,45,5,87,1,1,1,1,1),(839,45,5,88,1,1,1,1,1),(840,45,5,89,1,1,1,1,1),(841,45,5,90,1,1,1,1,1),(842,45,5,91,1,1,1,1,1),(843,45,5,92,1,1,1,1,1),(844,45,5,93,1,1,1,1,1),(845,45,5,94,1,1,1,1,1),(846,45,5,95,1,1,1,1,1),(847,45,5,96,1,1,1,1,1),(848,45,5,97,1,1,1,1,1),(849,45,5,98,1,1,1,1,1),(850,46,5,66,1,1,1,1,1),(851,46,5,67,1,1,1,1,1),(852,46,5,68,1,1,1,1,1),(853,46,5,69,1,1,1,1,1),(854,46,5,70,1,1,1,1,1),(855,46,5,71,1,1,1,1,1),(856,46,5,72,1,1,1,1,1),(857,46,5,73,1,1,1,1,1),(858,46,5,74,1,1,1,1,1),(859,46,5,75,1,1,1,1,1),(860,46,5,76,1,1,1,1,1),(861,46,5,77,1,1,1,1,1),(862,46,5,78,1,1,1,1,1),(863,46,5,79,1,1,1,1,1),(864,46,5,80,1,1,1,1,1),(865,46,5,81,1,1,1,1,1),(866,46,5,82,1,1,1,1,1),(867,46,5,83,1,1,1,1,1),(868,46,5,84,1,1,1,1,1),(869,46,5,85,1,1,1,1,1),(870,46,5,86,1,1,1,1,1),(871,46,5,87,1,1,1,1,1),(872,46,5,88,1,1,1,1,1),(873,46,5,89,1,1,1,1,1),(874,46,5,90,1,1,1,1,1),(875,46,5,91,1,1,1,1,1),(876,46,5,92,1,1,1,1,1),(877,46,5,93,1,1,1,1,1),(878,46,5,94,1,1,1,1,1),(879,46,5,95,1,1,1,1,1),(880,46,5,96,1,1,1,1,1),(881,46,5,97,1,1,1,1,1),(882,46,5,98,1,1,1,1,1),(883,47,5,66,1,1,1,1,1),(884,47,5,67,1,1,1,1,1),(885,47,5,68,1,1,1,1,1),(886,47,5,69,1,1,1,1,1),(887,47,5,70,1,1,1,1,1),(888,47,5,71,1,1,1,1,1),(889,47,5,72,1,1,1,1,1),(890,47,5,73,1,1,1,1,1),(891,47,5,74,1,1,1,1,1),(892,47,5,75,1,1,1,1,1),(893,47,5,76,1,1,1,1,1),(894,47,5,77,1,1,1,1,1),(895,47,5,78,1,1,1,1,1),(896,47,5,79,1,1,1,1,1),(897,47,5,80,1,1,1,1,1),(898,47,5,81,1,1,1,1,1),(899,47,5,82,1,1,1,1,1),(900,47,5,83,1,1,1,1,1),(901,47,5,84,1,1,1,1,1),(902,47,5,85,1,1,1,1,1),(903,47,5,86,1,1,1,1,1),(904,47,5,87,1,1,1,1,1),(905,47,5,88,1,1,1,1,1),(906,47,5,89,1,1,1,1,1),(907,47,5,90,1,1,1,1,1),(908,47,5,91,1,1,1,1,1),(909,47,5,92,1,1,1,1,1),(910,47,5,93,1,1,1,1,1),(911,47,5,94,1,1,1,1,1),(912,47,5,95,1,1,1,1,1),(913,47,5,96,1,1,1,1,1),(914,47,5,97,1,1,1,1,1),(915,47,5,98,1,1,1,1,1),(916,48,5,66,1,1,1,1,1),(917,48,5,67,1,1,1,1,1),(918,48,5,68,1,1,1,1,1),(919,48,5,69,1,1,1,1,1),(920,48,5,70,1,1,1,1,1),(921,48,5,71,1,1,1,1,1),(922,48,5,72,1,1,1,1,1),(923,48,5,73,1,1,1,1,1),(924,48,5,74,1,1,1,1,1),(925,48,5,75,1,1,1,1,1),(926,48,5,76,1,1,1,1,1),(927,48,5,77,1,1,1,1,1),(928,48,5,78,1,1,1,1,1),(929,48,5,79,1,1,1,1,1),(930,48,5,80,1,1,1,1,1),(931,48,5,81,1,1,1,1,1),(932,48,5,82,1,1,1,1,1),(933,48,5,83,1,1,1,1,1),(934,48,5,84,1,1,1,1,1),(935,48,5,85,1,1,1,1,1),(936,48,5,86,1,1,1,1,1),(937,48,5,87,1,1,1,1,1),(938,48,5,88,1,1,1,1,1),(939,48,5,89,1,1,1,1,1),(940,48,5,90,1,1,1,1,1),(941,48,5,91,1,1,1,1,1),(942,48,5,92,1,1,1,1,1),(943,48,5,93,1,1,1,1,1),(944,48,5,94,1,1,1,1,1),(945,48,5,95,1,1,1,1,1),(946,48,5,96,1,1,1,1,1),(947,48,5,97,1,1,1,1,1),(948,48,5,98,1,1,1,1,1),(949,49,5,66,1,1,1,1,1),(950,49,5,67,1,1,1,1,1),(951,49,5,68,1,1,1,1,1),(952,49,5,69,1,1,1,1,1),(953,49,5,70,1,1,1,1,1),(954,49,5,71,1,1,1,1,1),(955,49,5,72,1,1,1,1,1),(956,49,5,73,1,1,1,1,1),(957,49,5,74,1,1,1,1,1),(958,49,5,75,1,1,1,1,1),(959,49,5,76,1,1,1,1,1),(960,49,5,77,1,1,1,1,1),(961,49,5,78,1,1,1,1,1),(962,49,5,79,1,1,1,1,1),(963,49,5,80,1,1,1,1,1),(964,49,5,81,1,1,1,1,1),(965,49,5,82,1,1,1,1,1),(966,49,5,83,1,1,1,1,1),(967,49,5,84,1,1,1,1,1),(968,49,5,85,1,1,1,1,1),(969,49,5,86,1,1,1,1,1),(970,49,5,87,1,1,1,1,1),(971,49,5,88,1,1,1,1,1),(972,49,5,89,1,1,1,1,1),(973,49,5,90,1,1,1,1,1),(974,49,5,91,1,1,1,1,1),(975,49,5,92,1,1,1,1,1),(976,49,5,93,1,1,1,1,1),(977,49,5,94,1,1,1,1,1),(978,49,5,95,1,1,1,1,1),(979,49,5,96,1,1,1,1,1),(980,49,5,97,1,1,1,1,1),(981,49,5,98,1,1,1,1,1),(982,50,5,66,1,1,1,1,1),(983,50,5,67,1,1,1,1,1),(984,50,5,68,1,1,1,1,1),(985,50,5,69,1,1,1,1,1),(986,50,5,70,1,1,1,1,1),(987,50,5,71,1,1,1,1,1),(988,50,5,72,1,1,1,1,1),(989,50,5,73,1,1,1,1,1),(990,50,5,74,1,1,1,1,1),(991,50,5,75,1,1,1,1,1),(992,50,5,76,1,1,1,1,1),(993,50,5,77,1,1,1,1,1),(994,50,5,78,1,1,1,1,1),(995,50,5,79,1,1,1,1,1),(996,50,5,80,1,1,1,1,1),(997,50,5,81,1,1,1,1,1),(998,50,5,82,1,1,1,1,1),(999,50,5,83,1,1,1,1,1),(1000,50,5,84,1,1,1,1,1),(1001,50,5,85,1,1,1,1,1),(1002,50,5,86,1,1,1,1,1),(1003,50,5,87,1,1,1,1,1),(1004,50,5,88,1,1,1,1,1),(1005,50,5,89,1,1,1,1,1),(1006,50,5,90,1,1,1,1,1),(1007,50,5,91,1,1,1,1,1),(1008,50,5,92,1,1,1,1,1),(1009,50,5,93,1,1,1,1,1),(1010,50,5,94,1,1,1,1,1),(1011,50,5,95,1,1,1,1,1),(1012,50,5,96,1,1,1,1,1),(1013,50,5,97,1,1,1,1,1),(1014,50,5,98,1,1,1,1,1),(1015,51,5,66,1,1,1,1,1),(1016,51,5,67,1,1,1,1,1),(1017,51,5,68,1,1,1,1,1),(1018,51,5,69,1,1,1,1,1),(1019,51,5,70,1,1,1,1,1),(1020,51,5,71,1,1,1,1,1),(1021,51,5,72,1,1,1,1,1),(1022,51,5,73,1,1,1,1,1),(1023,51,5,74,1,1,1,1,1),(1024,51,5,75,1,1,1,1,1),(1025,51,5,76,1,1,1,1,1),(1026,51,5,77,1,1,1,1,1),(1027,51,5,78,1,1,1,1,1),(1028,51,5,79,1,1,1,1,1),(1029,51,5,80,1,1,1,1,1),(1030,51,5,81,1,1,1,1,1),(1031,51,5,82,1,1,1,1,1),(1032,51,5,83,1,1,1,1,1),(1033,51,5,84,1,1,1,1,1),(1034,51,5,85,1,1,1,1,1),(1035,51,5,86,1,1,1,1,1),(1036,51,5,87,1,1,1,1,1),(1037,51,5,88,1,1,1,1,1),(1038,51,5,89,1,1,1,1,1),(1039,51,5,90,1,1,1,1,1),(1040,51,5,91,1,1,1,1,1),(1041,51,5,92,1,1,1,1,1),(1042,51,5,93,1,1,1,1,1),(1043,51,5,94,1,1,1,1,1),(1044,51,5,95,1,1,1,1,1),(1045,51,5,96,1,1,1,1,1),(1046,51,5,97,1,1,1,1,1),(1047,51,5,98,1,1,1,1,1),(1048,52,5,66,1,1,1,1,1),(1049,52,5,67,1,1,1,1,1),(1050,52,5,68,1,1,1,1,1),(1051,52,5,69,1,1,1,1,1),(1052,52,5,70,1,1,1,1,1),(1053,52,5,71,1,1,1,1,1),(1054,52,5,72,1,1,1,1,1),(1055,52,5,73,1,1,1,1,1),(1056,52,5,74,1,1,1,1,1),(1057,52,5,75,1,1,1,1,1),(1058,52,5,76,1,1,1,1,1),(1059,52,5,77,1,1,1,1,1),(1060,52,5,78,1,1,1,1,1),(1061,52,5,79,1,1,1,1,1),(1062,52,5,80,1,1,1,1,1),(1063,52,5,81,1,1,1,1,1),(1064,52,5,82,1,1,1,1,1),(1065,52,5,83,1,1,1,1,1),(1066,52,5,84,1,1,1,1,1),(1067,52,5,85,1,1,1,1,1),(1068,52,5,86,1,1,1,1,1),(1069,52,5,87,1,1,1,1,1),(1070,52,5,88,1,1,1,1,1),(1071,52,5,89,1,1,1,1,1),(1072,52,5,90,1,1,1,1,1),(1073,52,5,91,1,1,1,1,1),(1074,52,5,92,1,1,1,1,1),(1075,52,5,93,1,1,1,1,1),(1076,52,5,94,1,1,1,1,1),(1077,52,5,95,1,1,1,1,1),(1078,52,5,96,1,1,1,1,1),(1079,52,5,97,1,1,1,1,1),(1080,52,5,98,1,1,1,1,1),(1081,53,5,66,1,1,1,1,1),(1082,53,5,67,1,1,1,1,1),(1083,53,5,68,1,1,1,1,1),(1084,53,5,69,1,1,1,1,1),(1085,53,5,70,1,1,1,1,1),(1086,53,5,71,1,1,1,1,1),(1087,53,5,72,1,1,1,1,1),(1088,53,5,73,1,1,1,1,1),(1089,53,5,74,1,1,1,1,1),(1090,53,5,75,1,1,1,1,1),(1091,53,5,76,1,1,1,1,1),(1092,53,5,77,1,1,1,1,1),(1093,53,5,78,1,1,1,1,1),(1094,53,5,79,1,1,1,1,1),(1095,53,5,80,1,1,1,1,1),(1096,53,5,81,1,1,1,1,1),(1097,53,5,82,1,1,1,1,1),(1098,53,5,83,1,1,1,1,1),(1099,53,5,84,1,1,1,1,1),(1100,53,5,85,1,1,1,1,1),(1101,53,5,86,1,1,1,1,1),(1102,53,5,87,1,1,1,1,1),(1103,53,5,88,1,1,1,1,1),(1104,53,5,89,1,1,1,1,1),(1105,53,5,90,1,1,1,1,1),(1106,53,5,91,1,1,1,1,1),(1107,53,5,92,1,1,1,1,1),(1108,53,5,93,1,1,1,1,1),(1109,53,5,94,1,1,1,1,1),(1110,53,5,95,1,1,1,1,1),(1111,53,5,96,1,1,1,1,1),(1112,53,5,97,1,1,1,1,1),(1113,53,5,98,1,1,1,1,1),(1114,54,5,66,1,1,1,1,1),(1115,54,5,67,1,1,1,1,1),(1116,54,5,68,1,1,1,1,1),(1117,54,5,69,1,1,1,1,1),(1118,54,5,70,1,1,1,1,1),(1119,54,5,71,1,1,1,1,1),(1120,54,5,72,1,1,1,1,1),(1121,54,5,73,1,1,1,1,1),(1122,54,5,74,1,1,1,1,1),(1123,54,5,75,1,1,1,1,1),(1124,54,5,76,1,1,1,1,1),(1125,54,5,77,1,1,1,1,1),(1126,54,5,78,1,1,1,1,1),(1127,54,5,79,1,1,1,1,1),(1128,54,5,80,1,1,1,1,1),(1129,54,5,81,1,1,1,1,1),(1130,54,5,82,1,1,1,1,1),(1131,54,5,83,1,1,1,1,1),(1132,54,5,84,1,1,1,1,1),(1133,54,5,85,1,1,1,1,1),(1134,54,5,86,1,1,1,1,1),(1135,54,5,87,1,1,1,1,1),(1136,54,5,88,1,1,1,1,1),(1137,54,5,89,1,1,1,1,1),(1138,54,5,90,1,1,1,1,1),(1139,54,5,91,1,1,1,1,1),(1140,54,5,92,1,1,1,1,1),(1141,54,5,93,1,1,1,1,1),(1142,54,5,94,1,1,1,1,1),(1143,54,5,95,1,1,1,1,1),(1144,54,5,96,1,1,1,1,1),(1145,54,5,97,1,1,1,1,1),(1146,54,5,98,1,1,1,1,1),(1147,55,5,66,1,1,1,1,1),(1148,55,5,67,1,1,1,1,1),(1149,55,5,68,1,1,1,1,1),(1150,55,5,69,1,1,1,1,1),(1151,55,5,70,1,1,1,1,1),(1152,55,5,71,1,1,1,1,1),(1153,55,5,72,1,1,1,1,1),(1154,55,5,73,1,1,1,1,1),(1155,55,5,74,1,1,1,1,1),(1156,55,5,75,1,1,1,1,1),(1157,55,5,76,1,1,1,1,1),(1158,55,5,77,1,1,1,1,1),(1159,55,5,78,1,1,1,1,1),(1160,55,5,79,1,1,1,1,1),(1161,55,5,80,1,1,1,1,1),(1162,55,5,81,1,1,1,1,1),(1163,55,5,82,1,1,1,1,1),(1164,55,5,83,1,1,1,1,1),(1165,55,5,84,1,1,1,1,1),(1166,55,5,85,1,1,1,1,1),(1167,55,5,86,1,1,1,1,1),(1168,55,5,87,1,1,1,1,1),(1169,55,5,88,1,1,1,1,1),(1170,55,5,89,1,1,1,1,1),(1171,55,5,90,1,1,1,1,1),(1172,55,5,91,1,1,1,1,1),(1173,55,5,92,1,1,1,1,1),(1174,55,5,93,1,1,1,1,1),(1175,55,5,94,1,1,1,1,1),(1176,55,5,95,1,1,1,1,1),(1177,55,5,96,1,1,1,1,1),(1178,55,5,97,1,1,1,1,1),(1179,55,5,98,1,1,1,1,1),(1180,56,5,66,1,1,1,1,1),(1181,56,5,67,1,1,1,1,1),(1182,56,5,68,1,1,1,1,1),(1183,56,5,69,1,1,1,1,1),(1184,56,5,70,1,1,1,1,1),(1185,56,5,71,1,1,1,1,1),(1186,56,5,72,1,1,1,1,1),(1187,56,5,73,1,1,1,1,1),(1188,56,5,74,1,1,1,1,1),(1189,56,5,75,1,1,1,1,1),(1190,56,5,76,1,1,1,1,1),(1191,56,5,77,1,1,1,1,1),(1192,56,5,78,1,1,1,1,1),(1193,56,5,79,1,1,1,1,1),(1194,56,5,80,1,1,1,1,1),(1195,56,5,81,1,1,1,1,1),(1196,56,5,82,1,1,1,1,1),(1197,56,5,83,1,1,1,1,1),(1198,56,5,84,1,1,1,1,1),(1199,56,5,85,1,1,1,1,1),(1200,56,5,86,1,1,1,1,1),(1201,56,5,87,1,1,1,1,1),(1202,56,5,88,1,1,1,1,1),(1203,56,5,89,1,1,1,1,1),(1204,56,5,90,1,1,1,1,1),(1205,56,5,91,1,1,1,1,1),(1206,56,5,92,1,1,1,1,1),(1207,56,5,93,1,1,1,1,1),(1208,56,5,94,1,1,1,1,1),(1209,56,5,95,1,1,1,1,1),(1210,56,5,96,1,1,1,1,1),(1211,56,5,97,1,1,1,1,1),(1212,56,5,98,1,1,1,1,1),(1213,57,1,5,1,1,1,1,1),(1214,57,1,6,1,1,1,1,1),(1215,58,1,5,1,1,1,1,1),(1216,58,1,6,1,1,1,1,1),(1217,59,1,5,1,1,1,1,1),(1218,59,1,6,1,1,1,1,1),(1219,57,3,36,1,1,1,1,1),(1220,57,3,37,1,1,1,1,1),(1221,57,3,38,1,1,1,1,1),(1222,57,3,39,1,1,1,1,1),(1223,57,3,40,1,1,1,1,1),(1224,57,3,41,1,1,1,1,1),(1225,58,3,36,1,1,1,1,1),(1226,58,3,37,1,1,1,1,1),(1227,58,3,38,1,1,1,1,1),(1228,58,3,39,1,1,1,1,1),(1229,58,3,40,1,1,1,1,1),(1230,58,3,41,1,1,1,1,1),(1231,59,3,36,1,1,1,1,1),(1232,59,3,37,1,1,1,1,1),(1233,59,3,38,1,1,1,1,1),(1234,59,3,39,1,1,1,1,1),(1235,59,3,40,1,1,1,1,1),(1236,59,3,41,1,1,1,1,1),(1237,57,4,42,1,1,1,1,1),(1238,57,4,43,1,1,1,1,1),(1239,57,4,44,1,1,1,1,1),(1240,57,4,45,1,1,1,1,1),(1241,57,4,46,1,1,1,1,1),(1242,57,4,47,1,1,1,1,1),(1243,57,4,48,1,1,1,1,1),(1244,57,4,49,1,1,1,1,1),(1245,57,4,50,1,1,1,1,1),(1246,57,4,51,1,1,1,1,1),(1247,57,4,52,1,1,1,1,1),(1248,57,4,53,1,1,1,1,1),(1249,57,4,54,1,1,1,1,1),(1250,57,4,55,1,1,1,1,1),(1251,57,4,56,1,1,1,1,1),(1252,58,4,42,1,1,1,1,1),(1253,58,4,43,1,1,1,1,1),(1254,58,4,44,1,1,1,1,1),(1255,58,4,45,1,1,1,1,1),(1256,58,4,46,1,1,1,1,1),(1257,58,4,47,1,1,1,1,1),(1258,58,4,48,1,1,1,1,1),(1259,58,4,49,1,1,1,1,1),(1260,58,4,50,1,1,1,1,1),(1261,58,4,51,1,1,1,1,1),(1262,58,4,52,1,1,1,1,1),(1263,58,4,53,1,1,1,1,1),(1264,58,4,54,1,1,1,1,1),(1265,58,4,55,1,1,1,1,1),(1266,58,4,56,1,1,1,1,1),(1267,59,4,42,1,1,1,1,1),(1268,59,4,43,1,1,1,1,1),(1269,59,4,44,1,1,1,1,1),(1270,59,4,45,1,1,1,1,1),(1271,59,4,46,1,1,1,1,1),(1272,59,4,47,1,1,1,1,1),(1273,59,4,48,1,1,1,1,1),(1274,59,4,49,1,1,1,1,1),(1275,59,4,50,1,1,1,1,1),(1276,59,4,51,1,1,1,1,1),(1277,59,4,52,1,1,1,1,1),(1278,59,4,53,1,1,1,1,1),(1279,59,4,54,1,1,1,1,1),(1280,59,4,55,1,1,1,1,1),(1281,59,4,56,1,1,1,1,1),(1282,57,5,66,1,1,1,1,1),(1283,57,5,67,1,1,1,1,1),(1284,57,5,68,1,1,1,1,1),(1285,57,5,69,1,1,1,1,1),(1286,57,5,70,1,1,1,1,1),(1287,57,5,71,1,1,1,1,1),(1288,57,5,72,1,1,1,1,1),(1289,57,5,73,1,1,1,1,1),(1290,57,5,74,1,1,1,1,1),(1291,57,5,75,1,1,1,1,1),(1292,57,5,76,1,1,1,1,1),(1293,57,5,77,1,1,1,1,1),(1294,57,5,78,1,1,1,1,1),(1295,57,5,79,1,1,1,1,1),(1296,57,5,80,1,1,1,1,1),(1297,57,5,81,1,1,1,1,1),(1298,57,5,82,1,1,1,1,1),(1299,57,5,83,1,1,1,1,1),(1300,57,5,84,1,1,1,1,1),(1301,57,5,85,1,1,1,1,1),(1302,57,5,86,1,1,1,1,1),(1303,57,5,87,1,1,1,1,1),(1304,57,5,88,1,1,1,1,1),(1305,57,5,89,1,1,1,1,1),(1306,57,5,90,1,1,1,1,1),(1307,57,5,91,1,1,1,1,1),(1308,57,5,92,1,1,1,1,1),(1309,57,5,93,1,1,1,1,1),(1310,57,5,94,1,1,1,1,1),(1311,57,5,95,1,1,1,1,1),(1312,57,5,96,1,1,1,1,1),(1313,57,5,97,1,1,1,1,1),(1314,57,5,98,1,1,1,1,1),(1315,58,5,66,1,1,1,1,1),(1316,58,5,67,1,1,1,1,1),(1317,58,5,68,1,1,1,1,1),(1318,58,5,69,1,1,1,1,1),(1319,58,5,70,1,1,1,1,1),(1320,58,5,71,1,1,1,1,1),(1321,58,5,72,1,1,1,1,1),(1322,58,5,73,1,1,1,1,1),(1323,58,5,74,1,1,1,1,1),(1324,58,5,75,1,1,1,1,1),(1325,58,5,76,1,1,1,1,1),(1326,58,5,77,1,1,1,1,1),(1327,58,5,78,1,1,1,1,1),(1328,58,5,79,1,1,1,1,1),(1329,58,5,80,1,1,1,1,1),(1330,58,5,81,1,1,1,1,1),(1331,58,5,82,1,1,1,1,1),(1332,58,5,83,1,1,1,1,1),(1333,58,5,84,1,1,1,1,1),(1334,58,5,85,1,1,1,1,1),(1335,58,5,86,1,1,1,1,1),(1336,58,5,87,1,1,1,1,1),(1337,58,5,88,1,1,1,1,1),(1338,58,5,89,1,1,1,1,1),(1339,58,5,90,1,1,1,1,1),(1340,58,5,91,1,1,1,1,1),(1341,58,5,92,1,1,1,1,1),(1342,58,5,93,1,1,1,1,1),(1343,58,5,94,1,1,1,1,1),(1344,58,5,95,1,1,1,1,1),(1345,58,5,96,1,1,1,1,1),(1346,58,5,97,1,1,1,1,1),(1347,58,5,98,1,1,1,1,1),(1348,59,5,66,1,1,1,1,1),(1349,59,5,67,1,1,1,1,1),(1350,59,5,68,1,1,1,1,1),(1351,59,5,69,1,1,1,1,1),(1352,59,5,70,1,1,1,1,1),(1353,59,5,71,1,1,1,1,1),(1354,59,5,72,1,1,1,1,1),(1355,59,5,73,1,1,1,1,1),(1356,59,5,74,1,1,1,1,1),(1357,59,5,75,1,1,1,1,1),(1358,59,5,76,1,1,1,1,1),(1359,59,5,77,1,1,1,1,1),(1360,59,5,78,1,1,1,1,1),(1361,59,5,79,1,1,1,1,1),(1362,59,5,80,1,1,1,1,1),(1363,59,5,81,1,1,1,1,1),(1364,59,5,82,1,1,1,1,1),(1365,59,5,83,1,1,1,1,1),(1366,59,5,84,1,1,1,1,1),(1367,59,5,85,1,1,1,1,1),(1368,59,5,86,1,1,1,1,1),(1369,59,5,87,1,1,1,1,1),(1370,59,5,88,1,1,1,1,1),(1371,59,5,89,1,1,1,1,1),(1372,59,5,90,1,1,1,1,1),(1373,59,5,91,1,1,1,1,1),(1374,59,5,92,1,1,1,1,1),(1375,59,5,93,1,1,1,1,1),(1376,59,5,94,1,1,1,1,1),(1377,59,5,95,1,1,1,1,1),(1378,59,5,96,1,1,1,1,1),(1379,59,5,97,1,1,1,1,1),(1380,59,5,98,1,1,1,1,1),(1381,10,1,5,1,1,1,1,1),(1382,10,1,6,1,1,1,1,1),(1383,10,2,7,1,1,1,1,1),(1384,10,2,8,1,1,1,1,1),(1385,10,2,9,1,1,1,1,1),(1386,10,2,10,1,1,1,1,1),(1387,10,2,11,1,1,1,1,1),(1388,10,2,12,1,1,1,1,1),(1389,10,2,13,1,1,1,1,1),(1390,10,2,14,1,1,1,1,1),(1391,10,2,15,1,1,1,1,1),(1392,10,2,16,1,1,1,1,1),(1393,10,2,17,1,1,1,1,1),(1394,10,2,18,1,1,1,1,1),(1395,10,2,19,1,1,1,1,1),(1396,10,2,20,1,1,1,1,1),(1397,10,2,21,1,1,1,1,1),(1398,10,2,22,1,1,1,1,1),(1399,10,2,23,1,1,1,1,1),(1400,10,2,24,1,1,1,1,1),(1401,10,2,25,1,1,1,1,1),(1402,10,3,26,1,1,1,1,1),(1403,10,3,27,1,1,1,1,1),(1404,10,3,28,1,1,1,1,1),(1405,10,3,29,1,1,1,1,1),(1406,10,3,30,1,1,1,1,1),(1407,10,3,31,1,1,1,1,1),(1408,10,3,32,1,1,1,1,1),(1409,10,3,33,1,1,1,1,1),(1410,10,3,34,1,1,1,1,1),(1411,10,3,35,1,1,1,1,1),(1412,10,4,42,1,1,1,1,1),(1413,10,4,43,1,1,1,1,1),(1414,10,4,44,1,1,1,1,1),(1415,10,4,45,1,1,1,1,1),(1416,10,4,46,1,1,1,1,1),(1417,10,4,47,1,1,1,1,1),(1418,10,4,48,1,1,1,1,1),(1419,10,4,49,1,1,1,1,1),(1420,10,4,57,1,1,1,1,1),(1421,10,4,58,1,1,1,1,1),(1422,10,4,59,1,1,1,1,1),(1423,10,4,60,1,1,1,1,1),(1424,10,4,61,1,1,1,1,1),(1425,10,4,62,1,1,1,1,1),(1426,10,4,63,1,1,1,1,1),(1427,10,4,64,1,1,1,1,1),(1428,10,4,65,1,1,1,1,1),(1429,10,5,66,1,1,1,1,1),(1430,10,5,67,1,1,1,1,1),(1431,10,5,68,1,1,1,1,1),(1432,10,5,69,1,1,1,1,1),(1433,10,5,70,1,1,1,1,1),(1434,10,5,71,1,1,1,1,1),(1435,10,5,72,1,1,1,1,1),(1436,10,5,73,1,1,1,1,1),(1437,10,5,74,1,1,1,1,1),(1438,10,5,75,1,1,1,1,1),(1439,10,5,76,1,1,1,1,1),(1440,10,5,77,1,1,1,1,1),(1441,10,5,78,1,1,1,1,1),(1442,10,5,79,1,1,1,1,1),(1443,10,5,80,1,1,1,1,1),(1444,10,5,81,1,1,1,1,1),(1445,10,5,82,1,1,1,1,1),(1446,10,5,83,1,1,1,1,1),(1447,10,5,84,1,1,1,1,1),(1448,10,5,85,1,1,1,1,1),(1449,10,5,86,1,1,1,1,1),(1450,10,5,87,1,1,1,1,1),(1451,10,5,88,1,1,1,1,1),(1452,10,5,89,1,1,1,1,1),(1453,10,5,90,1,1,1,1,1),(1454,10,5,91,1,1,1,1,1),(1455,10,5,92,1,1,1,1,1),(1456,10,5,93,1,1,1,1,1),(1457,10,5,94,1,1,1,1,1),(1458,10,5,95,1,1,1,1,1),(1459,10,5,96,1,1,1,1,1),(1460,10,5,97,1,1,1,1,1),(1461,10,5,98,1,1,1,1,1),(1462,60,6,99,1,1,1,1,1),(1463,60,6,100,1,1,1,1,1),(1464,60,6,101,1,1,1,1,1),(1465,60,6,102,1,1,1,1,1),(1466,60,6,103,1,1,1,1,1),(1467,60,6,104,1,1,1,1,1),(1468,61,6,99,1,1,1,1,1),(1469,61,6,100,1,1,1,1,1),(1470,61,6,101,1,1,1,1,1),(1471,61,6,102,1,1,1,1,1),(1472,61,6,103,1,1,1,1,1),(1473,61,6,104,1,1,1,1,1),(1474,62,6,99,1,1,1,1,1),(1475,62,6,100,1,1,1,1,1),(1476,62,6,101,1,1,1,1,1),(1477,62,6,102,1,1,1,1,1),(1478,62,6,103,1,1,1,1,1),(1479,62,6,104,1,1,1,1,1),(1480,63,6,99,1,1,1,1,1),(1481,63,6,100,1,1,1,1,1),(1482,63,6,101,1,1,1,1,1),(1483,63,6,102,1,1,1,1,1),(1484,63,6,103,1,1,1,1,1),(1485,63,6,104,1,1,1,1,1),(1486,64,6,99,1,1,1,1,1),(1487,64,6,100,1,1,1,1,1),(1488,64,6,101,1,1,1,1,1),(1489,64,6,102,1,1,1,1,1),(1490,64,6,103,1,1,1,1,1),(1491,64,6,104,1,1,1,1,1),(1492,65,6,99,1,1,1,1,1),(1493,65,6,100,1,1,1,1,1),(1494,65,6,101,1,1,1,1,1),(1495,65,6,102,1,1,1,1,1),(1496,65,6,103,1,1,1,1,1),(1497,65,6,104,1,1,1,1,1),(1498,66,6,99,1,1,1,1,1),(1499,66,6,100,1,1,1,1,1),(1500,66,6,101,1,1,1,1,1),(1501,66,6,102,1,1,1,1,1),(1502,66,6,103,1,1,1,1,1),(1503,66,6,104,1,1,1,1,1),(1504,67,6,99,1,1,1,1,1),(1505,67,6,100,1,1,1,1,1),(1506,67,6,101,1,1,1,1,1),(1507,67,6,102,1,1,1,1,1),(1508,67,6,103,1,1,1,1,1),(1509,67,6,104,1,1,1,1,1),(1510,68,6,99,1,1,1,1,1),(1511,68,6,100,1,1,1,1,1),(1512,68,6,101,1,1,1,1,1),(1513,68,6,102,1,1,1,1,1),(1514,68,6,103,1,1,1,1,1),(1515,68,6,104,1,1,1,1,1),(1516,69,6,99,1,1,1,1,1),(1517,69,6,100,1,1,1,1,1),(1518,69,6,101,1,1,1,1,1),(1519,69,6,102,1,1,1,1,1),(1520,69,6,103,1,1,1,1,1),(1521,69,6,104,1,1,1,1,1),(1522,70,6,99,1,1,1,1,1),(1523,70,6,100,1,1,1,1,1),(1524,70,6,101,1,1,1,1,1),(1525,70,6,102,1,1,1,1,1),(1526,70,6,103,1,1,1,1,1),(1527,70,6,104,1,1,1,1,1),(1528,71,6,99,1,1,1,1,1),(1529,71,6,100,1,1,1,1,1),(1530,71,6,101,1,1,1,1,1),(1531,71,6,102,1,1,1,1,1),(1532,71,6,103,1,1,1,1,1),(1533,71,6,104,1,1,1,1,1),(1534,72,6,99,1,1,1,1,1),(1535,72,6,100,1,1,1,1,1),(1536,72,6,101,1,1,1,1,1),(1537,72,6,102,1,1,1,1,1),(1538,72,6,103,1,1,1,1,1),(1539,72,6,104,1,1,1,1,1),(1540,60,7,108,1,1,1,1,1),(1541,60,7,109,1,1,1,1,1),(1542,60,7,110,1,1,1,1,1),(1543,60,7,111,1,1,1,1,1),(1544,60,7,112,1,1,1,1,1),(1545,60,7,113,1,1,1,1,1),(1546,60,7,114,1,1,1,1,1),(1547,60,7,115,1,1,1,1,1),(1548,60,7,116,1,1,1,1,1),(1549,60,7,117,1,1,1,1,1),(1550,60,7,118,1,1,1,1,1),(1551,60,7,119,1,1,1,1,1),(1552,60,7,120,1,1,1,1,1),(1553,60,7,121,1,1,1,1,1),(1554,61,7,108,1,1,1,1,1),(1555,61,7,109,1,1,1,1,1),(1556,61,7,110,1,1,1,1,1),(1557,61,7,111,1,1,1,1,1),(1558,61,7,112,1,1,1,1,1),(1559,61,7,113,1,1,1,1,1),(1560,61,7,114,1,1,1,1,1),(1561,61,7,115,1,1,1,1,1),(1562,61,7,116,1,1,1,1,1),(1563,61,7,117,1,1,1,1,1),(1564,61,7,118,1,1,1,1,1),(1565,61,7,119,1,1,1,1,1),(1566,61,7,120,1,1,1,1,1),(1567,61,7,121,1,1,1,1,1),(1568,62,7,108,1,1,1,1,1),(1569,62,7,109,1,1,1,1,1),(1570,62,7,110,1,1,1,1,1),(1571,62,7,111,1,1,1,1,1),(1572,62,7,112,1,1,1,1,1),(1573,62,7,113,1,1,1,1,1),(1574,62,7,114,1,1,1,1,1),(1575,62,7,115,1,1,1,1,1),(1576,62,7,116,1,1,1,1,1),(1577,62,7,117,1,1,1,1,1),(1578,62,7,118,1,1,1,1,1),(1579,62,7,119,1,1,1,1,1),(1580,62,7,120,1,1,1,1,1),(1581,62,7,121,1,1,1,1,1),(1582,63,7,108,1,1,1,1,1),(1583,63,7,109,1,1,1,1,1),(1584,63,7,110,1,1,1,1,1),(1585,63,7,111,1,1,1,1,1),(1586,63,7,112,1,1,1,1,1),(1587,63,7,113,1,1,1,1,1),(1588,63,7,114,1,1,1,1,1),(1589,63,7,115,1,1,1,1,1),(1590,63,7,116,1,1,1,1,1),(1591,63,7,117,1,1,1,1,1),(1592,63,7,118,1,1,1,1,1),(1593,63,7,119,1,1,1,1,1),(1594,63,7,120,1,1,1,1,1),(1595,63,7,121,1,1,1,1,1),(1596,64,7,108,1,1,1,1,1),(1597,64,7,109,1,1,1,1,1),(1598,64,7,110,1,1,1,1,1),(1599,64,7,111,1,1,1,1,1),(1600,64,7,112,1,1,1,1,1),(1601,64,7,113,1,1,1,1,1),(1602,64,7,114,1,1,1,1,1),(1603,64,7,115,1,1,1,1,1),(1604,64,7,116,1,1,1,1,1),(1605,64,7,117,1,1,1,1,1),(1606,64,7,118,1,1,1,1,1),(1607,64,7,119,1,1,1,1,1),(1608,64,7,120,1,1,1,1,1),(1609,64,7,121,1,1,1,1,1),(1610,65,7,108,1,1,1,1,1),(1611,65,7,109,1,1,1,1,1),(1612,65,7,110,1,1,1,1,1),(1613,65,7,111,1,1,1,1,1),(1614,65,7,112,1,1,1,1,1),(1615,65,7,113,1,1,1,1,1),(1616,65,7,114,1,1,1,1,1),(1617,65,7,115,1,1,1,1,1),(1618,65,7,116,1,1,1,1,1),(1619,65,7,117,1,1,1,1,1),(1620,65,7,118,1,1,1,1,1),(1621,65,7,119,1,1,1,1,1),(1622,65,7,120,1,1,1,1,1),(1623,65,7,121,1,1,1,1,1),(1624,66,7,108,1,1,1,1,1),(1625,66,7,109,1,1,1,1,1),(1626,66,7,110,1,1,1,1,1),(1627,66,7,111,1,1,1,1,1),(1628,66,7,112,1,1,1,1,1),(1629,66,7,113,1,1,1,1,1),(1630,66,7,114,1,1,1,1,1),(1631,66,7,115,1,1,1,1,1),(1632,66,7,116,1,1,1,1,1),(1633,66,7,117,1,1,1,1,1),(1634,66,7,118,1,1,1,1,1),(1635,66,7,119,1,1,1,1,1),(1636,66,7,120,1,1,1,1,1),(1637,66,7,121,1,1,1,1,1),(1638,67,7,108,1,1,1,1,1),(1639,67,7,109,1,1,1,1,1),(1640,67,7,110,1,1,1,1,1),(1641,67,7,111,1,1,1,1,1),(1642,67,7,112,1,1,1,1,1),(1643,67,7,113,1,1,1,1,1),(1644,67,7,114,1,1,1,1,1),(1645,67,7,115,1,1,1,1,1),(1646,67,7,116,1,1,1,1,1),(1647,67,7,117,1,1,1,1,1),(1648,67,7,118,1,1,1,1,1),(1649,67,7,119,1,1,1,1,1),(1650,67,7,120,1,1,1,1,1),(1651,67,7,121,1,1,1,1,1),(1652,68,7,108,1,1,1,1,1),(1653,68,7,109,1,1,1,1,1),(1654,68,7,110,1,1,1,1,1),(1655,68,7,111,1,1,1,1,1),(1656,68,7,112,1,1,1,1,1),(1657,68,7,113,1,1,1,1,1),(1658,68,7,114,1,1,1,1,1),(1659,68,7,115,1,1,1,1,1),(1660,68,7,116,1,1,1,1,1),(1661,68,7,117,1,1,1,1,1),(1662,68,7,118,1,1,1,1,1),(1663,68,7,119,1,1,1,1,1),(1664,68,7,120,1,1,1,1,1),(1665,68,7,121,1,1,1,1,1),(1666,69,7,108,1,1,1,1,1),(1667,69,7,109,1,1,1,1,1),(1668,69,7,110,1,1,1,1,1),(1669,69,7,111,1,1,1,1,1),(1670,69,7,112,1,1,1,1,1),(1671,69,7,113,1,1,1,1,1),(1672,69,7,114,1,1,1,1,1),(1673,69,7,115,1,1,1,1,1),(1674,69,7,116,1,1,1,1,1),(1675,69,7,117,1,1,1,1,1),(1676,69,7,118,1,1,1,1,1),(1677,69,7,119,1,1,1,1,1),(1678,69,7,120,1,1,1,1,1),(1679,69,7,121,1,1,1,1,1),(1680,70,7,108,1,1,1,1,1),(1681,70,7,109,1,1,1,1,1),(1682,70,7,110,1,1,1,1,1),(1683,70,7,111,1,1,1,1,1),(1684,70,7,112,1,1,1,1,1),(1685,70,7,113,1,1,1,1,1),(1686,70,7,114,1,1,1,1,1),(1687,70,7,115,1,1,1,1,1),(1688,70,7,116,1,1,1,1,1),(1689,70,7,117,1,1,1,1,1),(1690,70,7,118,1,1,1,1,1),(1691,70,7,119,1,1,1,1,1),(1692,70,7,120,1,1,1,1,1),(1693,70,7,121,1,1,1,1,1),(1694,71,7,108,1,1,1,1,1),(1695,71,7,109,1,1,1,1,1),(1696,71,7,110,1,1,1,1,1),(1697,71,7,111,1,1,1,1,1),(1698,71,7,112,1,1,1,1,1),(1699,71,7,113,1,1,1,1,1),(1700,71,7,114,1,1,1,1,1),(1701,71,7,115,1,1,1,1,1),(1702,71,7,116,1,1,1,1,1),(1703,71,7,117,1,1,1,1,1),(1704,71,7,118,1,1,1,1,1),(1705,71,7,119,1,1,1,1,1),(1706,71,7,120,1,1,1,1,1),(1707,71,7,121,1,1,1,1,1),(1708,72,7,108,1,1,1,1,1),(1709,72,7,109,1,1,1,1,1),(1710,72,7,110,1,1,1,1,1),(1711,72,7,111,1,1,1,1,1),(1712,72,7,112,1,1,1,1,1),(1713,72,7,113,1,1,1,1,1),(1714,72,7,114,1,1,1,1,1),(1715,72,7,115,1,1,1,1,1),(1716,72,7,116,1,1,1,1,1),(1717,72,7,117,1,1,1,1,1),(1718,72,7,118,1,1,1,1,1),(1719,72,7,119,1,1,1,1,1),(1720,72,7,120,1,1,1,1,1),(1721,72,7,121,1,1,1,1,1),(1722,70,8,124,1,1,1,1,1),(1723,70,8,125,1,1,1,1,1),(1724,70,8,126,1,1,1,1,1),(1725,70,8,127,1,1,1,1,1),(1726,70,8,128,1,1,1,1,1),(1727,70,8,129,1,1,1,1,1),(1728,70,8,130,1,1,1,1,1),(1729,70,9,131,1,1,1,1,1),(1730,70,9,132,1,1,1,1,1),(1731,70,9,133,1,1,1,1,1),(1732,70,9,134,1,1,1,1,1),(1733,70,9,135,1,1,1,1,1),(1734,70,9,136,1,1,1,1,1),(1735,70,9,137,1,1,1,1,1),(1736,70,9,138,1,1,1,1,1),(1737,70,9,139,1,1,1,1,1),(1738,70,9,140,1,1,1,1,1),(1739,70,9,141,1,1,1,1,1),(1740,73,6,105,1,1,1,1,1),(1741,73,6,106,1,1,1,1,1),(1742,73,6,107,1,1,1,1,1),(1743,74,6,105,1,1,1,1,1),(1744,74,6,106,1,1,1,1,1),(1745,74,6,107,1,1,1,1,1),(1746,75,6,105,1,1,1,1,1),(1747,75,6,106,1,1,1,1,1),(1748,75,6,107,1,1,1,1,1),(1749,76,6,105,1,1,1,1,1),(1750,76,6,106,1,1,1,1,1),(1751,76,6,107,1,1,1,1,1),(1752,77,6,106,1,1,1,1,1),(1753,77,6,107,1,1,1,1,1),(1754,77,6,105,1,1,1,1,1),(1755,73,7,108,1,1,1,1,1),(1756,73,7,109,1,1,1,1,1),(1757,73,7,122,1,1,1,1,1),(1758,73,7,123,1,1,1,1,1),(1759,73,7,117,1,1,1,1,1),(1760,73,7,118,1,1,1,1,1),(1761,73,7,119,1,1,1,1,1),(1762,73,7,120,1,1,1,1,1),(1763,73,7,121,1,1,1,1,1),(1764,74,7,108,1,1,1,1,1),(1765,74,7,109,1,1,1,1,1),(1766,74,7,122,1,1,1,1,1),(1767,74,7,123,1,1,1,1,1),(1768,74,7,117,1,1,1,1,1),(1769,74,7,118,1,1,1,1,1),(1770,74,7,119,1,1,1,1,1),(1771,74,7,120,1,1,1,1,1),(1772,74,7,121,1,1,1,1,1),(1773,75,7,108,1,1,1,1,1),(1774,75,7,109,1,1,1,1,1),(1775,75,7,122,1,1,1,1,1),(1776,75,7,123,1,1,1,1,1),(1777,75,7,117,1,1,1,1,1),(1778,75,7,118,1,1,1,1,1),(1779,75,7,119,1,1,1,1,1),(1780,75,7,120,1,1,1,1,1),(1781,75,7,121,1,1,1,1,1),(1782,76,7,108,1,1,1,1,1),(1783,76,7,109,1,1,1,1,1),(1784,76,7,122,1,1,1,1,1),(1785,76,7,123,1,1,1,1,1),(1786,76,7,117,1,1,1,1,1),(1787,76,7,118,1,1,1,1,1),(1788,76,7,119,1,1,1,1,1),(1789,76,7,120,1,1,1,1,1),(1790,76,7,121,1,1,1,1,1),(1791,77,7,108,1,1,1,1,1),(1792,77,7,109,1,1,1,1,1),(1793,77,7,122,1,1,1,1,1),(1794,77,7,123,1,1,1,1,1),(1795,77,7,117,1,1,1,1,1),(1796,77,7,118,1,1,1,1,1),(1797,77,7,119,1,1,1,1,1),(1798,77,7,120,1,1,1,1,1),(1799,77,7,121,1,1,1,1,1),(1800,13,6,103,1,1,1,1,1),(1801,13,6,104,1,1,1,1,1),(1802,13,7,108,1,1,1,1,1),(1803,13,7,109,1,1,1,1,1),(1804,13,7,110,1,1,1,1,1),(1805,13,7,111,1,1,1,1,1),(1806,13,7,112,1,1,1,1,1),(1807,13,7,113,1,1,1,1,1),(1808,13,7,114,1,1,1,1,1),(1809,13,7,115,1,1,1,1,1),(1810,13,7,116,1,1,1,1,1),(1811,13,7,117,1,1,1,1,1),(1812,13,7,118,1,1,1,1,1),(1813,13,7,119,1,1,1,1,1),(1814,13,7,120,1,1,1,1,1),(1815,13,7,121,1,1,1,1,1),(1816,13,10,142,1,1,1,1,1),(1817,13,10,143,1,1,1,1,1),(1818,13,10,144,1,1,1,1,1),(1819,13,10,145,1,1,1,1,1),(1820,13,10,146,1,1,1,1,1),(1821,13,10,147,1,1,1,1,1),(1822,13,10,148,1,1,1,1,1),(1823,13,10,149,1,1,1,1,1),(1824,13,10,150,1,1,1,1,1),(1825,13,10,151,1,1,1,1,1),(1826,13,10,152,1,1,1,1,1),(1827,13,10,153,1,1,1,1,1),(1828,77,11,154,1,1,1,1,1),(1829,77,11,155,1,1,1,1,1),(1830,77,11,156,1,1,1,1,1),(1831,77,11,157,1,1,1,1,1),(1832,78,11,154,1,1,1,1,1),(1833,78,11,155,1,1,1,1,1),(1834,78,11,156,1,1,1,1,1),(1835,78,11,157,1,1,1,1,1),(1836,79,11,154,1,1,1,1,1),(1837,79,11,155,1,1,1,1,1),(1838,79,11,156,1,1,1,1,1),(1839,79,11,157,1,1,1,1,1),(1840,80,11,154,1,1,1,1,1),(1841,80,11,155,1,1,1,1,1),(1842,80,11,156,1,1,1,1,1),(1843,80,11,157,1,1,1,1,1),(1844,81,11,154,1,1,1,1,1),(1845,81,11,155,1,1,1,1,1),(1846,81,11,156,1,1,1,1,1),(1847,81,11,157,1,1,1,1,1),(1848,82,11,154,1,1,1,1,1),(1849,82,11,155,1,1,1,1,1),(1850,82,11,156,1,1,1,1,1),(1851,82,11,157,1,1,1,1,1),(1852,83,11,154,1,1,1,1,1),(1853,83,11,155,1,1,1,1,1),(1854,83,11,156,1,1,1,1,1),(1855,83,11,157,1,1,1,1,1),(1856,84,11,154,1,1,1,1,1),(1857,84,11,155,1,1,1,1,1),(1858,84,11,156,1,1,1,1,1),(1859,84,11,157,1,1,1,1,1),(1860,85,11,154,1,1,1,1,1),(1861,85,11,155,1,1,1,1,1),(1862,85,11,156,1,1,1,1,1),(1863,85,11,157,1,1,1,1,1),(1864,86,11,154,1,1,1,1,1),(1865,86,11,155,1,1,1,1,1),(1866,86,11,156,1,1,1,1,1),(1867,86,11,157,1,1,1,1,1),(1868,87,11,154,1,1,1,1,1),(1869,87,11,155,1,1,1,1,1),(1870,87,11,156,1,1,1,1,1),(1871,87,11,157,1,1,1,1,1),(1872,88,11,154,1,1,1,1,1),(1873,88,11,155,1,1,1,1,1),(1874,88,11,156,1,1,1,1,1),(1875,88,11,157,1,1,1,1,1),(1876,89,11,154,1,1,1,1,1),(1877,89,11,155,1,1,1,1,1),(1878,89,11,156,1,1,1,1,1),(1879,89,11,157,1,1,1,1,1),(1880,90,11,154,1,1,1,1,1),(1881,90,11,155,1,1,1,1,1),(1882,90,11,156,1,1,1,1,1),(1883,90,11,157,1,1,1,1,1),(1884,91,11,154,1,1,1,1,1),(1885,91,11,155,1,1,1,1,1),(1886,91,11,156,1,1,1,1,1),(1887,91,11,157,1,1,1,1,1),(1888,92,11,154,1,1,1,1,1),(1889,92,11,155,1,1,1,1,1),(1890,92,11,156,1,1,1,1,1),(1891,92,11,157,1,1,1,1,1),(1892,93,11,154,1,1,1,1,1),(1893,93,11,155,1,1,1,1,1),(1894,93,11,156,1,1,1,1,1),(1895,93,11,157,1,1,1,1,1),(1896,94,11,154,1,1,1,1,1),(1897,94,11,155,1,1,1,1,1),(1898,94,11,156,1,1,1,1,1),(1899,94,11,157,1,1,1,1,1),(1900,95,11,154,1,1,1,1,1),(1901,95,11,155,1,1,1,1,1),(1902,95,11,156,1,1,1,1,1),(1903,95,11,157,1,1,1,1,1),(1904,16,11,154,1,1,1,1,1),(1905,16,11,155,1,1,1,1,1),(1906,16,11,156,1,1,1,1,1),(1907,16,11,157,1,1,1,1,1),(1908,77,7,158,1,1,1,1,1),(1909,77,7,159,1,1,1,1,1),(1910,77,7,160,1,1,1,1,1),(1911,77,7,161,1,1,1,1,1),(1912,77,7,162,1,1,1,1,1),(1913,77,7,163,1,1,1,1,1),(1914,78,7,158,1,1,1,1,1),(1915,78,7,159,1,1,1,1,1),(1916,78,7,160,1,1,1,1,1),(1917,78,7,164,1,1,1,1,1),(1918,78,7,165,1,1,1,1,1),(1919,78,7,166,1,1,1,1,1),(1920,78,7,167,1,1,1,1,1),(1921,78,7,168,1,1,1,1,1),(1922,78,7,169,1,1,1,1,1),(1923,78,7,170,1,1,1,1,1),(1924,78,7,171,1,1,1,1,1),(1925,78,7,172,1,1,1,1,1),(1926,78,7,173,1,1,1,1,1),(1927,78,7,174,1,1,1,1,1),(1928,78,7,175,1,1,1,1,1),(1929,78,7,176,1,1,1,1,1),(1930,78,7,177,1,1,1,1,1),(1931,78,7,178,1,1,1,1,1),(1932,78,7,179,1,1,1,1,1),(1933,78,7,180,1,1,1,1,1),(1934,78,7,181,1,1,1,1,1),(1935,78,7,182,1,1,1,1,1),(1936,78,7,183,1,1,1,1,1),(1937,78,7,184,1,1,1,1,1),(1938,78,7,185,1,1,1,1,1),(1939,78,7,186,1,1,1,1,1),(1940,78,7,187,1,1,1,1,1),(1941,78,7,188,1,1,1,1,1),(1942,78,7,189,1,1,1,1,1),(1943,78,7,190,1,1,1,1,1),(1944,78,7,191,1,1,1,1,1),(1945,78,7,192,1,1,1,1,1),(1946,78,7,193,1,1,1,1,1),(1947,78,7,194,1,1,1,1,1),(1948,78,7,195,1,1,1,1,1),(1949,78,7,196,1,1,1,1,1),(1950,78,7,161,1,1,1,1,1),(1951,78,7,197,1,1,1,1,1),(1952,78,7,198,1,1,1,1,1),(1953,78,7,162,1,1,1,1,1),(1954,78,7,163,1,1,1,1,1),(1955,79,7,158,1,1,1,1,1),(1956,79,7,199,1,1,1,1,1),(1957,79,7,163,1,1,1,1,1),(1958,79,7,200,1,1,1,1,1),(1959,80,7,158,1,1,1,1,1),(1960,80,7,159,1,1,1,1,1),(1961,80,7,160,1,1,1,1,1),(1962,80,7,164,1,1,1,1,1),(1963,80,7,165,1,1,1,1,1),(1964,80,7,166,1,1,1,1,1),(1965,80,7,167,1,1,1,1,1),(1966,80,7,168,1,1,1,1,1),(1967,80,7,169,1,1,1,1,1),(1968,80,7,170,1,1,1,1,1),(1969,80,7,171,1,1,1,1,1),(1970,80,7,172,1,1,1,1,1),(1971,80,7,173,1,1,1,1,1),(1972,80,7,174,1,1,1,1,1),(1973,80,7,175,1,1,1,1,1),(1974,80,7,176,1,1,1,1,1),(1975,80,7,177,1,1,1,1,1),(1976,80,7,178,1,1,1,1,1),(1977,80,7,179,1,1,1,1,1),(1978,80,7,180,1,1,1,1,1),(1979,80,7,181,1,1,1,1,1),(1980,80,7,182,1,1,1,1,1),(1981,80,7,183,1,1,1,1,1),(1982,80,7,184,1,1,1,1,1),(1983,80,7,185,1,1,1,1,1),(1984,80,7,186,1,1,1,1,1),(1985,80,7,187,1,1,1,1,1),(1986,80,7,188,1,1,1,1,1),(1987,80,7,189,1,1,1,1,1),(1988,80,7,190,1,1,1,1,1),(1989,80,7,191,1,1,1,1,1),(1990,80,7,192,1,1,1,1,1),(1991,80,7,193,1,1,1,1,1),(1992,80,7,194,1,1,1,1,1),(1993,80,7,195,1,1,1,1,1),(1994,80,7,196,1,1,1,1,1),(1995,80,7,161,1,1,1,1,1),(1996,80,7,197,1,1,1,1,1),(1997,80,7,198,1,1,1,1,1),(1998,80,7,162,1,1,1,1,1),(1999,80,7,163,1,1,1,1,1),(2000,81,7,158,1,1,1,1,1),(2001,81,7,201,1,1,1,1,1),(2002,81,7,202,1,1,1,1,1),(2003,81,7,203,1,1,1,1,1),(2004,81,7,204,1,1,1,1,1),(2005,81,7,205,1,1,1,1,1),(2006,81,7,206,1,1,1,1,1),(2007,81,7,207,1,1,1,1,1),(2008,81,7,208,1,1,1,1,1),(2009,81,7,163,1,1,1,1,1),(2010,82,7,158,1,1,1,1,1),(2011,82,7,209,1,1,1,1,1),(2012,82,7,210,1,1,1,1,1),(2013,82,7,211,1,1,1,1,1),(2014,82,7,212,1,1,1,1,1),(2015,82,7,213,1,1,1,1,1),(2016,82,7,214,1,1,1,1,1),(2017,82,7,215,1,1,1,1,1),(2018,82,7,216,1,1,1,1,1),(2019,82,7,217,1,1,1,1,1),(2020,83,12,218,1,1,1,1,1),(2021,83,12,219,1,1,1,1,1),(2022,83,12,220,1,1,1,1,1),(2023,83,12,221,1,1,1,1,1),(2024,83,12,222,1,1,1,1,1),(2025,83,12,223,1,1,1,1,1),(2026,83,12,224,1,1,1,1,1),(2027,83,12,225,1,1,1,1,1),(2028,83,12,226,1,1,1,1,1),(2029,83,12,227,1,1,1,1,1),(2030,83,12,228,1,1,1,1,1),(2031,83,12,229,1,1,1,1,1),(2032,83,12,230,1,1,1,1,1),(2033,83,12,231,1,1,1,1,1),(2034,16,13,232,1,1,1,1,1),(2035,16,13,233,1,1,1,1,1),(2036,16,13,234,1,1,1,1,1),(2037,16,13,235,1,1,1,1,1),(2038,16,13,236,1,1,1,1,1),(2039,16,13,237,1,1,1,1,1),(2040,16,13,238,1,1,1,1,1),(2041,16,13,239,1,1,1,1,1),(2042,16,13,240,1,1,1,1,1),(2043,16,13,241,1,1,1,1,1),(2044,16,13,242,1,1,1,1,1),(2045,16,13,243,1,1,1,1,1),(2046,16,13,244,1,1,1,1,1),(2047,16,13,245,1,1,1,1,1),(2048,16,13,246,1,1,1,1,1),(2049,16,13,247,1,1,1,1,1),(2050,16,13,248,1,1,1,1,1),(2051,16,13,249,1,1,1,1,1),(2052,16,14,250,1,1,1,1,1),(2053,16,14,251,1,1,1,1,1),(2054,16,14,252,1,1,1,1,1),(2055,16,14,253,1,1,1,1,1),(2056,17,15,254,1,1,1,1,1),(2057,17,15,255,1,1,1,1,1),(2058,17,15,256,1,1,1,1,1),(2059,17,15,257,1,1,1,1,1),(2060,17,15,258,1,1,1,1,1),(2061,17,15,259,1,1,1,1,1),(2062,17,15,260,1,1,1,1,1),(2063,17,15,261,1,1,1,1,1),(2064,17,15,262,1,1,1,1,1),(2065,17,15,263,1,1,1,1,1),(2066,17,15,264,1,1,1,1,1),(2067,17,15,265,1,1,1,1,1),(2068,17,15,266,1,1,1,1,1),(2069,17,15,267,1,1,1,1,1),(2070,17,15,268,1,1,1,1,1),(2071,17,15,269,1,1,1,1,1),(2072,18,15,254,1,1,1,1,1),(2073,18,15,255,1,1,1,1,1),(2074,18,15,256,1,1,1,1,1),(2075,18,15,257,1,1,1,1,1),(2076,18,15,258,1,1,1,1,1),(2077,18,15,259,1,1,1,1,1),(2078,18,15,260,1,1,1,1,1),(2079,18,15,261,1,1,1,1,1),(2080,18,15,262,1,1,1,1,1),(2081,18,15,263,1,1,1,1,1),(2082,18,15,264,1,1,1,1,1),(2083,18,15,265,1,1,1,1,1),(2084,18,15,266,1,1,1,1,1),(2085,18,15,267,1,1,1,1,1),(2086,18,15,268,1,1,1,1,1),(2087,18,15,269,1,1,1,1,1),(2088,19,15,254,1,1,1,1,1),(2089,19,15,255,1,1,1,1,1),(2090,19,15,256,1,1,1,1,1),(2091,19,15,257,1,1,1,1,1),(2092,19,15,258,1,1,1,1,1),(2093,19,15,259,1,1,1,1,1),(2094,19,15,260,1,1,1,1,1),(2095,19,15,261,1,1,1,1,1),(2096,19,15,262,1,1,1,1,1),(2097,19,15,263,1,1,1,1,1),(2098,19,15,264,1,1,1,1,1),(2099,19,15,265,1,1,1,1,1),(2100,19,15,266,1,1,1,1,1),(2101,19,15,267,1,1,1,1,1),(2102,19,15,268,1,1,1,1,1),(2103,19,15,269,1,1,1,1,1),(2104,20,15,254,1,1,1,1,1),(2105,20,15,255,1,1,1,1,1),(2106,20,15,256,1,1,1,1,1),(2107,20,15,257,1,1,1,1,1),(2108,20,15,258,1,1,1,1,1),(2109,20,15,259,1,1,1,1,1),(2110,20,15,260,1,1,1,1,1),(2111,20,15,261,1,1,1,1,1),(2112,20,15,262,1,1,1,1,1),(2113,20,15,263,1,1,1,1,1),(2114,20,15,264,1,1,1,1,1),(2115,20,15,265,1,1,1,1,1),(2116,20,15,266,1,1,1,1,1),(2117,20,15,267,1,1,1,1,1),(2118,20,15,268,1,1,1,1,1),(2119,20,15,269,1,1,1,1,1),(2120,21,15,254,1,1,1,1,1),(2121,21,15,255,1,1,1,1,1),(2122,21,15,256,1,1,1,1,1),(2123,21,15,257,1,1,1,1,1),(2124,21,15,258,1,1,1,1,1),(2125,21,15,259,1,1,1,1,1),(2126,21,15,260,1,1,1,1,1),(2127,21,15,261,1,1,1,1,1),(2128,21,15,262,1,1,1,1,1),(2129,21,15,263,1,1,1,1,1),(2130,21,15,264,1,1,1,1,1),(2131,21,15,265,1,1,1,1,1),(2132,21,15,266,1,1,1,1,1),(2133,21,15,267,1,1,1,1,1),(2134,21,15,268,1,1,1,1,1),(2135,21,15,269,1,1,1,1,1),(2136,22,15,254,1,1,1,1,1),(2137,22,15,255,1,1,1,1,1),(2138,22,15,256,1,1,1,1,1),(2139,22,15,257,1,1,1,1,1),(2140,22,15,258,1,1,1,1,1),(2141,22,15,259,1,1,1,1,1),(2142,22,15,260,1,1,1,1,1),(2143,22,15,261,1,1,1,1,1),(2144,22,15,262,1,1,1,1,1),(2145,22,15,263,1,1,1,1,1),(2146,22,15,264,1,1,1,1,1),(2147,22,15,265,1,1,1,1,1),(2148,22,15,266,1,1,1,1,1),(2149,22,15,267,1,1,1,1,1),(2150,22,15,268,1,1,1,1,1),(2151,22,15,269,1,1,1,1,1),(2152,23,15,254,1,1,1,1,1),(2153,23,15,255,1,1,1,1,1),(2154,23,15,256,1,1,1,1,1),(2155,23,15,257,1,1,1,1,1),(2156,23,15,258,1,1,1,1,1),(2157,23,15,259,1,1,1,1,1),(2158,23,15,260,1,1,1,1,1),(2159,23,15,261,1,1,1,1,1),(2160,23,15,262,1,1,1,1,1),(2161,23,15,263,1,1,1,1,1),(2162,23,15,264,1,1,1,1,1),(2163,23,15,265,1,1,1,1,1),(2164,23,15,266,1,1,1,1,1),(2165,23,15,267,1,1,1,1,1),(2166,23,15,268,1,1,1,1,1),(2167,23,15,269,1,1,1,1,1),(2168,24,15,254,1,1,1,1,1),(2169,24,15,255,1,1,1,1,1),(2170,24,15,256,1,1,1,1,1),(2171,24,15,257,1,1,1,1,1),(2172,24,15,258,1,1,1,1,1),(2173,24,15,259,1,1,1,1,1),(2174,24,15,260,1,1,1,1,1),(2175,24,15,261,1,1,1,1,1),(2176,24,15,262,1,1,1,1,1),(2177,24,15,263,1,1,1,1,1),(2178,24,15,264,1,1,1,1,1),(2179,24,15,265,1,1,1,1,1),(2180,24,15,266,1,1,1,1,1),(2181,24,15,267,1,1,1,1,1),(2182,24,15,268,1,1,1,1,1),(2183,24,15,269,1,1,1,1,1),(2184,25,15,254,1,1,1,1,1),(2185,25,15,255,1,1,1,1,1),(2186,25,15,256,1,1,1,1,1),(2187,25,15,257,1,1,1,1,1),(2188,25,15,258,1,1,1,1,1),(2189,25,15,259,1,1,1,1,1),(2190,25,15,260,1,1,1,1,1),(2191,25,15,261,1,1,1,1,1),(2192,25,15,262,1,1,1,1,1),(2193,25,15,263,1,1,1,1,1),(2194,25,15,264,1,1,1,1,1),(2195,25,15,265,1,1,1,1,1),(2196,25,15,266,1,1,1,1,1),(2197,25,15,267,1,1,1,1,1),(2198,25,15,268,1,1,1,1,1),(2199,25,15,269,1,1,1,1,1),(2200,26,15,254,1,1,1,1,1),(2201,26,15,255,1,1,1,1,1),(2202,26,15,256,1,1,1,1,1),(2203,26,15,257,1,1,1,1,1),(2204,26,15,258,1,1,1,1,1),(2205,26,15,259,1,1,1,1,1),(2206,26,15,260,1,1,1,1,1),(2207,26,15,261,1,1,1,1,1),(2208,26,15,262,1,1,1,1,1),(2209,26,15,263,1,1,1,1,1),(2210,26,15,264,1,1,1,1,1),(2211,26,15,265,1,1,1,1,1),(2212,26,15,266,1,1,1,1,1),(2213,26,15,267,1,1,1,1,1),(2214,26,15,268,1,1,1,1,1),(2215,26,15,269,1,1,1,1,1),(2216,17,16,270,1,1,1,1,1),(2217,17,16,271,1,1,1,1,1),(2218,17,16,272,1,1,1,1,1),(2219,17,16,273,1,1,1,1,1),(2220,17,16,274,1,1,1,1,1),(2221,17,16,275,1,1,1,1,1),(2222,17,16,276,1,1,1,1,1),(2223,17,16,277,1,1,1,1,1),(2224,17,16,278,1,1,1,1,1),(2225,17,16,279,1,1,1,1,1),(2226,17,16,280,1,1,1,1,1),(2227,17,16,281,1,1,1,1,1),(2228,17,16,282,1,1,1,1,1),(2229,18,16,270,1,1,1,1,1),(2230,18,16,271,1,1,1,1,1),(2231,18,16,272,1,1,1,1,1),(2232,18,16,273,1,1,1,1,1),(2233,18,16,274,1,1,1,1,1),(2234,18,16,275,1,1,1,1,1),(2235,18,16,276,1,1,1,1,1),(2236,18,16,277,1,1,1,1,1),(2237,18,16,278,1,1,1,1,1),(2238,18,16,279,1,1,1,1,1),(2239,18,16,280,1,1,1,1,1),(2240,18,16,281,1,1,1,1,1),(2241,18,16,282,1,1,1,1,1),(2242,19,16,270,1,1,1,1,1),(2243,19,16,271,1,1,1,1,1),(2244,19,16,272,1,1,1,1,1),(2245,19,16,273,1,1,1,1,1),(2246,19,16,274,1,1,1,1,1),(2247,19,16,275,1,1,1,1,1),(2248,19,16,276,1,1,1,1,1),(2249,19,16,277,1,1,1,1,1),(2250,19,16,278,1,1,1,1,1),(2251,19,16,279,1,1,1,1,1),(2252,19,16,280,1,1,1,1,1),(2253,19,16,281,1,1,1,1,1),(2254,19,16,282,1,1,1,1,1),(2255,20,16,270,1,1,1,1,1),(2256,20,16,271,1,1,1,1,1),(2257,20,16,272,1,1,1,1,1),(2258,20,16,273,1,1,1,1,1),(2259,20,16,274,1,1,1,1,1),(2260,20,16,275,1,1,1,1,1),(2261,20,16,276,1,1,1,1,1),(2262,20,16,277,1,1,1,1,1),(2263,20,16,278,1,1,1,1,1),(2264,20,16,279,1,1,1,1,1),(2265,20,16,280,1,1,1,1,1),(2266,20,16,281,1,1,1,1,1),(2267,20,16,282,1,1,1,1,1),(2268,21,16,270,1,1,1,1,1),(2269,21,16,271,1,1,1,1,1),(2270,21,16,272,1,1,1,1,1),(2271,21,16,273,1,1,1,1,1),(2272,21,16,274,1,1,1,1,1),(2273,21,16,275,1,1,1,1,1),(2274,21,16,276,1,1,1,1,1),(2275,21,16,277,1,1,1,1,1),(2276,21,16,278,1,1,1,1,1),(2277,21,16,279,1,1,1,1,1),(2278,21,16,280,1,1,1,1,1),(2279,21,16,281,1,1,1,1,1),(2280,21,16,282,1,1,1,1,1),(2281,22,16,270,1,1,1,1,1),(2282,22,16,271,1,1,1,1,1),(2283,22,16,272,1,1,1,1,1),(2284,22,16,273,1,1,1,1,1),(2285,22,16,274,1,1,1,1,1),(2286,22,16,275,1,1,1,1,1),(2287,22,16,276,1,1,1,1,1),(2288,22,16,277,1,1,1,1,1),(2289,22,16,278,1,1,1,1,1),(2290,22,16,279,1,1,1,1,1),(2291,22,16,280,1,1,1,1,1),(2292,22,16,281,1,1,1,1,1),(2293,22,16,282,1,1,1,1,1),(2294,23,16,270,1,1,1,1,1),(2295,23,16,271,1,1,1,1,1),(2296,23,16,272,1,1,1,1,1),(2297,23,16,273,1,1,1,1,1),(2298,23,16,274,1,1,1,1,1),(2299,23,16,275,1,1,1,1,1),(2300,23,16,276,1,1,1,1,1),(2301,23,16,277,1,1,1,1,1),(2302,23,16,278,1,1,1,1,1),(2303,23,16,279,1,1,1,1,1),(2304,23,16,280,1,1,1,1,1),(2305,23,16,281,1,1,1,1,1),(2306,23,16,282,1,1,1,1,1),(2307,24,16,270,1,1,1,1,1),(2308,24,16,271,1,1,1,1,1),(2309,24,16,272,1,1,1,1,1),(2310,24,16,273,1,1,1,1,1),(2311,24,16,274,1,1,1,1,1),(2312,24,16,275,1,1,1,1,1),(2313,24,16,276,1,1,1,1,1),(2314,24,16,277,1,1,1,1,1),(2315,24,16,278,1,1,1,1,1),(2316,24,16,279,1,1,1,1,1),(2317,24,16,280,1,1,1,1,1),(2318,24,16,281,1,1,1,1,1),(2319,24,16,282,1,1,1,1,1),(2320,25,16,270,1,1,1,1,1),(2321,25,16,271,1,1,1,1,1),(2322,25,16,272,1,1,1,1,1),(2323,25,16,273,1,1,1,1,1),(2324,25,16,274,1,1,1,1,1),(2325,25,16,275,1,1,1,1,1),(2326,25,16,276,1,1,1,1,1),(2327,25,16,277,1,1,1,1,1),(2328,25,16,278,1,1,1,1,1),(2329,25,16,279,1,1,1,1,1),(2330,25,16,280,1,1,1,1,1),(2331,25,16,281,1,1,1,1,1),(2332,25,16,282,1,1,1,1,1),(2333,26,16,270,1,1,1,1,1),(2334,26,16,271,1,1,1,1,1),(2335,26,16,272,1,1,1,1,1),(2336,26,16,273,1,1,1,1,1),(2337,26,16,274,1,1,1,1,1),(2338,26,16,275,1,1,1,1,1),(2339,26,16,276,1,1,1,1,1),(2340,26,16,277,1,1,1,1,1),(2341,26,16,278,1,1,1,1,1),(2342,26,16,279,1,1,1,1,1),(2343,26,16,280,1,1,1,1,1),(2344,26,16,281,1,1,1,1,1),(2345,26,16,282,1,1,1,1,1),(2346,18,17,283,1,1,1,1,1),(2347,18,17,284,1,1,1,1,1),(2348,18,17,285,1,1,1,1,1),(2349,18,17,286,1,1,1,1,1),(2350,18,17,287,1,1,1,1,1),(2351,18,17,288,1,1,1,1,1),(2352,18,17,289,1,1,1,1,1),(2353,18,17,290,1,1,1,1,1),(2354,18,17,291,1,1,1,1,1),(2355,18,17,67,1,1,1,1,1),(2356,18,17,292,1,1,1,1,1),(2357,18,17,71,1,1,1,1,1),(2358,18,17,82,1,1,1,1,1),(2359,18,17,293,1,1,1,1,1),(2360,17,7,294,1,1,1,1,1),(2361,17,7,295,1,1,1,1,1),(2362,17,7,296,1,1,1,1,1),(2363,17,7,297,1,1,1,1,1),(2364,17,7,298,1,1,1,1,1),(2365,17,7,299,1,1,1,1,1),(2366,17,7,300,1,1,1,1,1),(2367,17,7,301,1,1,1,1,1),(2368,17,7,302,1,1,1,1,1),(2369,17,7,303,1,1,1,1,1),(2370,17,7,304,1,1,1,1,1),(2371,17,7,305,1,1,1,1,1),(2372,17,7,306,1,1,1,1,1),(2373,17,7,307,1,1,1,1,1),(2374,17,7,308,1,1,1,1,1),(2375,17,7,309,1,1,1,1,1),(2376,17,7,310,1,1,1,1,1),(2377,17,7,311,1,1,1,1,1),(2378,17,7,312,1,1,1,1,1),(2379,17,7,313,1,1,1,1,1),(2380,18,7,294,1,1,1,1,1),(2381,18,7,295,1,1,1,1,1),(2382,18,7,296,1,1,1,1,1),(2383,18,7,297,1,1,1,1,1),(2384,18,7,298,1,1,1,1,1),(2385,18,7,299,1,1,1,1,1),(2386,18,7,300,1,1,1,1,1),(2387,18,7,301,1,1,1,1,1),(2388,18,7,302,1,1,1,1,1),(2389,18,7,303,1,1,1,1,1),(2390,18,7,304,1,1,1,1,1),(2391,18,7,305,1,1,1,1,1),(2392,18,7,306,1,1,1,1,1),(2393,18,7,307,1,1,1,1,1),(2394,18,7,308,1,1,1,1,1),(2395,18,7,309,1,1,1,1,1),(2396,18,7,310,1,1,1,1,1),(2397,18,7,311,1,1,1,1,1),(2398,18,7,312,1,1,1,1,1),(2399,18,7,313,1,1,1,1,1),(2400,19,7,294,1,1,1,1,1),(2401,19,7,295,1,1,1,1,1),(2402,19,7,296,1,1,1,1,1),(2403,19,7,297,1,1,1,1,1),(2404,19,7,298,1,1,1,1,1),(2405,19,7,299,1,1,1,1,1),(2406,19,7,300,1,1,1,1,1),(2407,19,7,301,1,1,1,1,1),(2408,19,7,302,1,1,1,1,1),(2409,19,7,303,1,1,1,1,1),(2410,19,7,304,1,1,1,1,1),(2411,19,7,305,1,1,1,1,1),(2412,19,7,306,1,1,1,1,1),(2413,19,7,307,1,1,1,1,1),(2414,19,7,308,1,1,1,1,1),(2415,19,7,309,1,1,1,1,1),(2416,19,7,310,1,1,1,1,1),(2417,19,7,311,1,1,1,1,1),(2418,19,7,312,1,1,1,1,1),(2419,19,7,313,1,1,1,1,1),(2420,20,7,294,1,1,1,1,1),(2421,20,7,295,1,1,1,1,1),(2422,20,7,296,1,1,1,1,1),(2423,20,7,297,1,1,1,1,1),(2424,20,7,298,1,1,1,1,1),(2425,20,7,299,1,1,1,1,1),(2426,20,7,300,1,1,1,1,1),(2427,20,7,301,1,1,1,1,1),(2428,20,7,302,1,1,1,1,1),(2429,20,7,303,1,1,1,1,1),(2430,20,7,304,1,1,1,1,1),(2431,20,7,305,1,1,1,1,1),(2432,20,7,306,1,1,1,1,1),(2433,20,7,307,1,1,1,1,1),(2434,20,7,308,1,1,1,1,1),(2435,20,7,309,1,1,1,1,1),(2436,20,7,310,1,1,1,1,1),(2437,20,7,311,1,1,1,1,1),(2438,20,7,312,1,1,1,1,1),(2439,20,7,313,1,1,1,1,1),(2440,21,7,294,1,1,1,1,1),(2441,21,7,295,1,1,1,1,1),(2442,21,7,296,1,1,1,1,1),(2443,21,7,297,1,1,1,1,1),(2444,21,7,298,1,1,1,1,1),(2445,21,7,299,1,1,1,1,1),(2446,21,7,300,1,1,1,1,1),(2447,21,7,301,1,1,1,1,1),(2448,21,7,302,1,1,1,1,1),(2449,21,7,303,1,1,1,1,1),(2450,21,7,304,1,1,1,1,1),(2451,21,7,305,1,1,1,1,1),(2452,21,7,306,1,1,1,1,1),(2453,21,7,307,1,1,1,1,1),(2454,21,7,308,1,1,1,1,1),(2455,21,7,309,1,1,1,1,1),(2456,21,7,310,1,1,1,1,1),(2457,21,7,311,1,1,1,1,1),(2458,21,7,312,1,1,1,1,1),(2459,21,7,313,1,1,1,1,1),(2460,22,7,294,1,1,1,1,1),(2461,22,7,295,1,1,1,1,1),(2462,22,7,296,1,1,1,1,1),(2463,22,7,297,1,1,1,1,1),(2464,22,7,298,1,1,1,1,1),(2465,22,7,299,1,1,1,1,1),(2466,22,7,300,1,1,1,1,1),(2467,22,7,301,1,1,1,1,1),(2468,22,7,302,1,1,1,1,1),(2469,22,7,303,1,1,1,1,1),(2470,22,7,304,1,1,1,1,1),(2471,22,7,305,1,1,1,1,1),(2472,22,7,306,1,1,1,1,1),(2473,22,7,307,1,1,1,1,1),(2474,22,7,308,1,1,1,1,1),(2475,22,7,309,1,1,1,1,1),(2476,22,7,310,1,1,1,1,1),(2477,22,7,311,1,1,1,1,1),(2478,22,7,312,1,1,1,1,1),(2479,22,7,313,1,1,1,1,1),(2480,23,7,294,1,1,1,1,1),(2481,23,7,295,1,1,1,1,1),(2482,23,7,296,1,1,1,1,1),(2483,23,7,297,1,1,1,1,1),(2484,23,7,298,1,1,1,1,1),(2485,23,7,299,1,1,1,1,1),(2486,23,7,300,1,1,1,1,1),(2487,23,7,301,1,1,1,1,1),(2488,23,7,302,1,1,1,1,1),(2489,23,7,303,1,1,1,1,1),(2490,23,7,304,1,1,1,1,1),(2491,23,7,305,1,1,1,1,1),(2492,23,7,306,1,1,1,1,1),(2493,23,7,307,1,1,1,1,1),(2494,23,7,308,1,1,1,1,1),(2495,23,7,309,1,1,1,1,1),(2496,23,7,310,1,1,1,1,1),(2497,23,7,311,1,1,1,1,1),(2498,23,7,312,1,1,1,1,1),(2499,23,7,313,1,1,1,1,1),(2500,24,7,294,1,1,1,1,1),(2501,24,7,295,1,1,1,1,1),(2502,24,7,296,1,1,1,1,1),(2503,24,7,297,1,1,1,1,1),(2504,24,7,298,1,1,1,1,1),(2505,24,7,299,1,1,1,1,1),(2506,24,7,300,1,1,1,1,1),(2507,24,7,301,1,1,1,1,1),(2508,24,7,302,1,1,1,1,1),(2509,24,7,303,1,1,1,1,1),(2510,24,7,304,1,1,1,1,1),(2511,24,7,305,1,1,1,1,1),(2512,24,7,306,1,1,1,1,1),(2513,24,7,307,1,1,1,1,1),(2514,24,7,308,1,1,1,1,1),(2515,24,7,309,1,1,1,1,1),(2516,24,7,310,1,1,1,1,1),(2517,24,7,311,1,1,1,1,1),(2518,24,7,312,1,1,1,1,1),(2519,24,7,313,1,1,1,1,1),(2520,25,7,294,1,1,1,1,1),(2521,25,7,295,1,1,1,1,1),(2522,25,7,296,1,1,1,1,1),(2523,25,7,297,1,1,1,1,1),(2524,25,7,298,1,1,1,1,1),(2525,25,7,299,1,1,1,1,1),(2526,25,7,300,1,1,1,1,1),(2527,25,7,301,1,1,1,1,1),(2528,25,7,302,1,1,1,1,1),(2529,25,7,303,1,1,1,1,1),(2530,25,7,304,1,1,1,1,1),(2531,25,7,305,1,1,1,1,1),(2532,25,7,306,1,1,1,1,1),(2533,25,7,307,1,1,1,1,1),(2534,25,7,308,1,1,1,1,1),(2535,25,7,309,1,1,1,1,1),(2536,25,7,310,1,1,1,1,1),(2537,25,7,311,1,1,1,1,1),(2538,25,7,312,1,1,1,1,1),(2539,25,7,313,1,1,1,1,1),(2540,26,7,294,1,1,1,1,1),(2541,26,7,295,1,1,1,1,1),(2542,26,7,296,1,1,1,1,1),(2543,26,7,297,1,1,1,1,1),(2544,26,7,298,1,1,1,1,1),(2545,26,7,299,1,1,1,1,1),(2546,26,7,300,1,1,1,1,1),(2547,26,7,301,1,1,1,1,1),(2548,26,7,302,1,1,1,1,1),(2549,26,7,303,1,1,1,1,1),(2550,26,7,304,1,1,1,1,1),(2551,26,7,305,1,1,1,1,1),(2552,26,7,306,1,1,1,1,1),(2553,26,7,307,1,1,1,1,1),(2554,26,7,308,1,1,1,1,1),(2555,26,7,309,1,1,1,1,1),(2556,26,7,310,1,1,1,1,1),(2557,26,7,311,1,1,1,1,1),(2558,26,7,312,1,1,1,1,1),(2559,26,7,313,1,1,1,1,1),(2560,96,18,314,1,1,1,1,1),(2561,96,18,315,1,1,1,1,1),(2562,96,18,316,1,1,1,1,1),(2563,96,18,317,1,1,1,1,1),(2564,96,18,318,1,1,1,1,1),(2565,96,18,319,1,1,1,1,1),(2566,96,18,320,1,1,1,1,1),(2567,96,18,321,1,1,1,1,1),(2568,96,18,322,1,1,1,1,1),(2569,97,18,323,1,1,1,1,1),(2570,97,18,324,1,1,1,1,1),(2571,97,18,325,1,1,1,1,1),(2572,97,18,326,1,1,1,1,1),(2573,97,18,327,1,1,1,1,1),(2574,97,18,328,1,1,1,1,1),(2575,98,18,314,1,1,1,1,1),(2576,98,18,316,1,1,1,1,1),(2577,98,18,330,1,1,1,1,1),(2578,99,18,323,1,1,1,1,1),(2579,99,18,324,1,1,1,1,1),(2580,99,18,325,1,1,1,1,1),(2581,99,18,326,1,1,1,1,1),(2582,99,18,327,1,1,1,1,1),(2583,99,18,328,1,1,1,1,1),(2584,96,7,336,1,1,1,1,1),(2585,96,7,337,1,1,1,1,1),(2586,96,7,338,1,1,1,1,1),(2587,96,7,339,1,1,1,1,1),(2588,96,7,340,1,1,1,1,1),(2589,96,7,341,1,1,1,1,1),(2590,96,7,342,1,1,1,1,1),(2591,96,7,343,1,1,1,1,1),(2592,96,7,344,1,1,1,1,1),(2593,96,7,345,1,1,1,1,1),(2594,96,7,346,1,1,1,1,1),(2595,96,7,347,1,1,1,1,1),(2596,96,7,348,1,1,1,1,1),(2597,96,7,349,1,1,1,1,1),(2598,96,7,350,1,1,1,1,1),(2599,96,7,351,1,1,1,1,1),(2600,96,7,352,1,1,1,1,1),(2601,96,7,353,1,1,1,1,1),(2602,96,7,354,1,1,1,1,1),(2603,96,7,355,1,1,1,1,1),(2604,97,7,336,1,1,1,1,1),(2605,97,7,337,1,1,1,1,1),(2606,97,7,338,1,1,1,1,1),(2607,97,7,339,1,1,1,1,1),(2608,97,7,340,1,1,1,1,1),(2609,97,7,341,1,1,1,1,1),(2610,97,7,342,1,1,1,1,1),(2611,97,7,343,1,1,1,1,1),(2612,97,7,344,1,1,1,1,1),(2613,97,7,345,1,1,1,1,1),(2614,97,7,346,1,1,1,1,1),(2615,97,7,347,1,1,1,1,1),(2616,97,7,348,1,1,1,1,1),(2617,97,7,349,1,1,1,1,1),(2618,97,7,350,1,1,1,1,1),(2619,97,7,351,1,1,1,1,1),(2620,97,7,352,1,1,1,1,1),(2621,97,7,353,1,1,1,1,1),(2622,97,7,354,1,1,1,1,1),(2623,97,7,355,1,1,1,1,1),(2624,98,7,336,1,1,1,1,1),(2625,98,7,337,1,1,1,1,1),(2626,98,7,338,1,1,1,1,1),(2627,98,7,339,1,1,1,1,1),(2628,98,7,340,1,1,1,1,1),(2629,98,7,341,1,1,1,1,1),(2630,98,7,342,1,1,1,1,1),(2631,98,7,343,1,1,1,1,1),(2632,98,7,344,1,1,1,1,1),(2633,98,7,345,1,1,1,1,1),(2634,98,7,346,1,1,1,1,1),(2635,98,7,347,1,1,1,1,1),(2636,98,7,348,1,1,1,1,1),(2637,98,7,349,1,1,1,1,1),(2638,98,7,350,1,1,1,1,1),(2639,98,7,351,1,1,1,1,1),(2640,98,7,352,1,1,1,1,1),(2641,98,7,353,1,1,1,1,1),(2642,98,7,354,1,1,1,1,1),(2643,98,7,355,1,1,1,1,1),(2644,99,7,336,1,1,1,1,1),(2645,99,7,337,1,1,1,1,1),(2646,99,7,338,1,1,1,1,1),(2647,99,7,339,1,1,1,1,1),(2648,99,7,340,1,1,1,1,1),(2649,99,7,341,1,1,1,1,1),(2650,99,7,342,1,1,1,1,1),(2651,99,7,343,1,1,1,1,1),(2652,99,7,344,1,1,1,1,1),(2653,99,7,345,1,1,1,1,1),(2654,99,7,346,1,1,1,1,1),(2655,99,7,347,1,1,1,1,1),(2656,99,7,348,1,1,1,1,1),(2657,99,7,349,1,1,1,1,1),(2658,99,7,350,1,1,1,1,1),(2659,99,7,351,1,1,1,1,1),(2660,99,7,352,1,1,1,1,1),(2661,99,7,353,1,1,1,1,1),(2662,99,7,354,1,1,1,1,1),(2663,99,7,355,1,1,1,1,1),(2664,28,7,356,1,1,1,1,1),(2665,28,7,357,1,1,1,1,1),(2666,28,7,358,1,1,1,1,1),(2667,28,7,359,1,1,1,1,1),(2668,28,7,360,1,1,1,1,1),(2669,28,7,361,1,1,1,1,1),(2670,33,7,362,1,1,1,1,1),(2671,33,7,363,1,1,1,1,1),(2672,33,7,364,1,1,1,1,1),(2673,33,7,365,1,1,1,1,1),(2674,33,7,366,1,1,1,1,1),(2675,33,7,367,1,1,1,1,1),(2676,33,7,368,1,1,1,1,1),(2677,33,7,369,1,1,1,1,1),(2678,33,7,370,1,1,1,1,1),(2679,33,7,371,1,1,1,1,1),(2680,33,7,372,1,1,1,1,1),(2681,33,7,373,1,1,1,1,1),(2682,33,7,374,1,1,1,1,1),(2683,33,7,375,1,1,1,1,1),(2684,33,7,376,1,1,1,1,1),(2685,33,7,377,1,1,1,1,1),(2686,28,19,378,1,1,1,1,1),(2687,28,19,379,1,1,1,1,1),(2688,28,19,380,1,1,1,1,1),(2689,28,19,381,1,1,1,1,1),(2690,28,19,382,1,1,1,1,1),(2691,29,19,383,1,1,1,1,1),(2692,29,19,384,1,1,1,1,1),(2693,29,19,385,1,1,1,1,1),(2694,29,19,386,1,1,1,1,1),(2695,29,19,387,1,1,1,1,1),(2696,30,19,388,1,1,1,1,1),(2697,30,19,389,1,1,1,1,1),(2698,30,19,390,1,1,1,1,1),(2699,30,19,391,1,1,1,1,1),(2700,31,19,384,1,1,1,1,1),(2701,31,19,385,1,1,1,1,1),(2702,31,19,386,1,1,1,1,1),(2703,31,19,387,1,1,1,1,1),(2704,31,19,392,1,1,1,1,1),(2705,32,19,393,1,1,1,1,1),(2706,32,19,394,1,1,1,1,1),(2707,32,19,385,1,1,1,1,1),(2708,32,19,395,1,1,1,1,1); + '); + } + + + public function down() + { + // + } +} diff --git a/database/migrations/2021_01_06_113020_update_data_place_fact_icon_field.php b/database/migrations/2021_01_06_113020_update_data_place_fact_icon_field.php new file mode 100644 index 0000000..2c731df --- /dev/null +++ b/database/migrations/2021_01_06_113020_update_data_place_fact_icon_field.php @@ -0,0 +1,28 @@ + Error; 1 =>Success; 2=> Start, 3=> Pending, 4 => Cancel/Refund, 5 => LNK' ; + ") ; + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + } +} diff --git a/database/migrations/2021_02_01_144004_update_data_general_timezone.php b/database/migrations/2021_02_01_144004_update_data_general_timezone.php new file mode 100644 index 0000000..806fee0 --- /dev/null +++ b/database/migrations/2021_02_01_144004_update_data_general_timezone.php @@ -0,0 +1,24 @@ +where('config_key' , 'profile_rate_mapping')->update(['config_value_json' => $profileRateMapping]); + + } + + + public function down() + { + // + } +} diff --git a/database/migrations/2021_02_10_133328_property_payment_transaction_status.php b/database/migrations/2021_02_10_133328_property_payment_transaction_status.php new file mode 100644 index 0000000..d74c497 --- /dev/null +++ b/database/migrations/2021_02_10_133328_property_payment_transaction_status.php @@ -0,0 +1,57 @@ +call(FirstRunSeeder::class); + $this->call(PropertyFactSeeder::class); + $this->call(PropertyAdditionalInfoKeySeeder::class); + $this->call(PropertyAdditionalInfoKeyLocaleSeeder::class); + $this->call(PropertyExecuteTypeSeeder::class); + $this->call(PropertyExecuteTypeLocaleSeeder::class); + $this->call(PropertyExecuteSeeder::class); +// $this->call(PropertyPhotoSeeder::class); + $this->call(PropertyTypeSeeder::class); + $this->call(PropertyGoogleLabelSeeder::class); + $this->call(PropertyChainSeeder::class); + } +} diff --git a/database/seeds/DestinationTableSeeder.php b/database/seeds/DestinationTableSeeder.php new file mode 100644 index 0000000..bed94b4 --- /dev/null +++ b/database/seeds/DestinationTableSeeder.php @@ -0,0 +1,34 @@ +truncate(); +/* + $unixTimestamp = time(); + $destinationId = DB::table('destination')->insertGetId([ + 'name'=> 'Turkey', 'parent_id' => 0, 'country_code' => 'TR', 'created_at'=> $unixTimestamp, 'updated_at' => $unixTimestamp + ]); + $destinationId = DB::table('destination')->insertGetId([ + 'name'=> 'Istanbul', 'parent_id' => $destinationId, 'country_code' => 'TR', 'created_at'=> $unixTimestamp, 'updated_at' => $unixTimestamp + ]); + $destinationId = DB::table('destination')->insertGetId([ + 'name'=> 'Fatih', 'parent_id' => $destinationId, 'country_code' => 'TR','created_at'=> $unixTimestamp, 'updated_at' => $unixTimestamp + ]); + + DB::table('destination')->insertGetId([ + 'name'=> 'Sultanahmet', 'parent_id' => $destinationId, 'country_code' => 'TR', 'created_at'=> $unixTimestamp, 'updated_at' => $unixTimestamp + ]); +*/ + + } +} diff --git a/database/seeds/FirstRunSeeder.php b/database/seeds/FirstRunSeeder.php new file mode 100644 index 0000000..540e6d2 --- /dev/null +++ b/database/seeds/FirstRunSeeder.php @@ -0,0 +1,775 @@ +insertGetId( + [ + 'id' => 1, + 'gender' => 'M', + 'name' => 'Test', + 'surname' => 'User -1-', + 'email' => 'test1@rezervasyon.com', + 'password' => Hash::make('123456'), + "hash_key" => hash('sha512', Str::random(32) ), + 'phone' => '02123668989', + 'user_type' => 1, + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + + + ] + ); + DB::table('user')->insertGetId( + [ + 'id' => 2, + 'gender' => 'M', + 'name' => 'Test', + 'surname' => 'User -2-', + 'email' => 'test2@rezervasyon.com', + 'password' => Hash::make('1234567'), + "hash_key" => hash('sha512', Str::random(32) ), + 'phone' => '02123668989', + 'user_type' => 0, + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + + ); + DB::table('user')->insertGetId( + + [ + 'id' => 3, + 'gender' => 'M', + 'name' => 'Test', + 'surname' => 'User -3-', + 'email' => 'test3@rezervasyon.com', + 'password' => Hash::make('123456'), + "hash_key" => hash('sha512', Str::random(32) ), + 'phone' => '02123668989', + 'user_type' => 0, + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + // LANGUAGE DATA + DB::table('language')->insertGetId( + [ + 'id' => 7, + 'code' => 'en', + 'name' => 'English', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('language')->insertGetId( + [ + 'id' => 10, + 'code' => 'de', + 'name' => 'German', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('language')->insertGetId( + [ + 'id' => 22, + 'code' => 'tr', + 'name' => 'Turkish', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + + // CURRENCY DATA + DB::table('currency')->insertGetId( + [ + 'id' => 1, + 'code' => 'TRY', + 'name' => 'Turkish Lira', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('currency')->insertGetId( + [ + 'id' => 2, + 'code' => 'USD', + 'name' => 'US Dollar', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('currency')->insertGetId( + [ + 'id' => 3, + 'code' => 'EUR', + 'name' => 'Euro', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + // CURRENCY LOCALE DATA + DB::table('currency_locale')->insertGetId( + [ + 'id' => 1, + 'currency_code' => 'TRY', + 'name' => 'Turkish Lira', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('currency_locale')->insertGetId( + [ + 'id' => 2, + 'currency_code' => 'USD', + 'name' => 'US Dollar', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('currency_locale')->insertGetId( + [ + 'id' => 3, + 'currency_code' => 'EUR', + 'name' => 'Euro', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + // PROPERTY DATA + DB::table('property')->insertGetId( + [ + 'id' => 1, + 'name' => 'Test Hotel -1-', + 'destination_id' => 1, + 'rating' => 1, + 'currency_type' => 'EUR', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + // PROPERTY MAPPING DATA + DB::table('user_property_mapping')->insertGetId( + [ + 'id' => 1, + 'user_id' => 1, + 'property_id' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + // PROPERTY CONTENT CATEGORY + DB::table('property_content_category')->insertGetId( + [ + 'id' => 1, + 'name' => 'Location', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category')->insertGetId( + [ + 'id' => 2, + 'name' => 'Facilities', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category')->insertGetId( + [ + 'id' => 3, + 'name' => 'Rooms', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category')->insertGetId( + [ + 'id' => 4, + 'name' => 'Sports/Entertainment', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category')->insertGetId( + [ + 'id' => 5, + 'name' => 'Meals', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category')->insertGetId( + [ + 'id' => 6, + 'name' => 'Payment', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + + // PROPERTY CONTENT CATEGORY LOCALE + DB::table('property_content_category_locale')->insertGetId( + [ + 'id' => 1, + 'content_category_id' => 1, + 'name' => 'Location', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category_locale')->insertGetId( + [ + 'id' => 2, + 'content_category_id' => 2, + 'name' => 'Facilities', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category_locale')->insertGetId( + [ + 'id' => 3, + 'content_category_id' => 3, + 'name' => 'Rooms', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category_locale')->insertGetId( + [ + 'id' => 4, + 'content_category_id' => 4, + 'name' => 'Sports/Entertainment', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_content_category_locale')->insertGetId( + [ + 'id' => 5, + 'content_category_id' => 5, + 'name' => 'Meals', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 1, + 'category_name' => "General", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 2, + 'category_name' => "View of exterior", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 3, + 'category_name' => "Bar", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 4, + 'category_name' => "Sport/ leisure", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 5, + 'category_name' => "Conference facilities", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 6, + 'category_name' => "Lobby", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 7, + 'category_name' => "Pool", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 8, + 'category_name' => "Restaurant", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 9, + 'category_name' => "Beach", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 10, + 'category_name' => "Terrace", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category')->insertGetId( + [ + 'id' => 11, + 'category_name' => "Accommodation", + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 1, + 'property_photo_category_id' => 1, + 'category_name' => 'Genel', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 2, + 'property_photo_category_id' => 2, + 'category_name' => 'dış görünüm', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 3, + 'property_photo_category_id' => 3, + 'category_name' => 'bar', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 4, + 'property_photo_category_id' => 4, + 'category_name' => 'Spor/eğlence', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 5, + 'property_photo_category_id' => 5, + 'category_name' => 'Konferans salonu', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 6, + 'property_photo_category_id' => 6, + 'category_name' => 'Lobi', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 7, + 'property_photo_category_id' => 7, + 'category_name' => 'Havuz', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 8, + 'property_photo_category_id' => 8, + 'category_name' => 'Restoran', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 9, + 'property_photo_category_id' => 9, + 'category_name' => 'Kumsal', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 10, + 'property_photo_category_id' => 10, + 'category_name' => 'Teras', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 11, + 'property_photo_category_id' => 11, + 'category_name' => 'Konaklama', + 'locale' => 'tr', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 12, + 'property_photo_category_id' => 1, + 'category_name' => 'General', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 13, + 'property_photo_category_id' => 2, + 'category_name' => 'View of exterior', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 14, + 'property_photo_category_id' => 3, + 'category_name' => 'Bar', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 15, + 'property_photo_category_id' => 4, + 'category_name' => 'Sport/leisure', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 16, + 'property_photo_category_id' => 5, + 'category_name' => 'Conference facilities', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 17, + 'property_photo_category_id' => 6, + 'category_name' => 'Lobby', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 18, + 'property_photo_category_id' => 7, + 'category_name' => 'Pool', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 19, + 'property_photo_category_id' => 8, + 'category_name' => 'Restaurant', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 20, + 'property_photo_category_id' => 9, + 'category_name' => 'Beach', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 21, + 'property_photo_category_id' => 10, + 'category_name' => 'Terrace', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + DB::table('property_photo_category_locale')->insertGetId( + [ + 'id' => 22, + 'property_photo_category_id' => 11, + 'category_name' => 'Accommodation', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + ); + + } +} diff --git a/database/seeds/PropertyAdditionalInfoKeyLocaleSeeder.php b/database/seeds/PropertyAdditionalInfoKeyLocaleSeeder.php new file mode 100644 index 0000000..e314b0f --- /dev/null +++ b/database/seeds/PropertyAdditionalInfoKeyLocaleSeeder.php @@ -0,0 +1,60 @@ +delete(); + + \DB::table('property_additional_info_key_locale')->insert(array ( + 0 => + array ( + 'id' => 1, + 'additional_info_key_id' => 1, + 'additional_info_key' => 'Building Year', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 1 => + array ( + 'id' => 2, + 'additional_info_key_id' => 2, + 'additional_info_key' => 'Restoration Year', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 2 => + array ( + 'id' => 3, + 'additional_info_key_id' => 3, + 'additional_info_key' => 'Room Count', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + )); + + + } +} diff --git a/database/seeds/PropertyAdditionalInfoKeySeeder.php b/database/seeds/PropertyAdditionalInfoKeySeeder.php new file mode 100644 index 0000000..731e5a7 --- /dev/null +++ b/database/seeds/PropertyAdditionalInfoKeySeeder.php @@ -0,0 +1,53 @@ +delete(); + + \DB::table('property_additional_info_key')->insert(array ( + 0 => + array ( + 'id' => 1, + 'additional_info_key' => 'Building Year', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 1 => + array ( + 'id' => 2, + 'additional_info_key' => 'Restoration Year', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 2 => + array ( + 'id' => 3, + 'additional_info_key' => 'Room Count', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + )); + + + } +} diff --git a/database/seeds/PropertyChainSeeder.php b/database/seeds/PropertyChainSeeder.php new file mode 100644 index 0000000..1ba6951 --- /dev/null +++ b/database/seeds/PropertyChainSeeder.php @@ -0,0 +1,133 @@ +delete(); + + \DB::table('property_chain')->insert(array ( + 0 => + array ( + 'id' => 1, + 'name' => 'Independent', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 1 => + array ( + 'id' => 2, + 'name' => 'Adam\'s Mark', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 2 => + array ( + 'id' => 3, + 'name' => 'Shilo Inn', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 3 => + array ( + 'id' => 4, + 'name' => 'Renaissance', + 'loyalty' => 'Marriott', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 4 => + array ( + 'id' => 5, + 'name' => 'Best Western', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 5 => + array ( + 'id' => 6, + 'name' => 'Clarion', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 6 => + array ( + 'id' => 7, + 'name' => 'Comfort Inn', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 7 => + array ( + 'id' => 8, + 'name' => 'Courtyard', + 'loyalty' => 'Marriott', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 8 => + array ( + 'id' => 9, + 'name' => 'Doral', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 9 => + array ( + 'id' => 10, + 'name' => 'Days Inn', + 'loyalty' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + )); + + + } +} diff --git a/database/seeds/PropertyExecuteSeeder.php b/database/seeds/PropertyExecuteSeeder.php new file mode 100644 index 0000000..8d12c5f --- /dev/null +++ b/database/seeds/PropertyExecuteSeeder.php @@ -0,0 +1,42 @@ +delete(); + + \DB::table('property_executive')->insert(array ( + 0 => + array ( + 'id' => 1, + 'property_id' => 1, + 'executive_type_id' => 1, + 'name_surname' => 'Burhan Çetin', + 'email' => 'mail@burhancetin.com', + 'phone_code' => NULL, + 'phone' => NULL, + 'mobile_code' => NULL, + 'mobile' => NULL, + 'fax_code' => NULL, + 'fax' => NULL, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1571573358, + 'updated_at' => 1571573358, + ), + )); + + + } +} diff --git a/database/seeds/PropertyExecuteTypeLocaleSeeder.php b/database/seeds/PropertyExecuteTypeLocaleSeeder.php new file mode 100644 index 0000000..0bde96e --- /dev/null +++ b/database/seeds/PropertyExecuteTypeLocaleSeeder.php @@ -0,0 +1,83 @@ +delete(); + + \DB::table('property_executive_type_locale')->insert(array ( + 0 => + array ( + 'id' => 1, + 'executive_id' => 1, + 'name' => 'Finance', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 1 => + array ( + 'id' => 2, + 'executive_id' => 2, + 'name' => 'Reservation', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 2 => + array ( + 'id' => 3, + 'executive_id' => 3, + 'name' => 'Sales', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 3 => + array ( + 'id' => 4, + 'executive_id' => 4, + 'name' => 'Activity', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 4 => + array ( + 'id' => 5, + 'executive_id' => 5, + 'name' => 'Group', + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + )); + + + } +} diff --git a/database/seeds/PropertyExecuteTypeSeeder.php b/database/seeds/PropertyExecuteTypeSeeder.php new file mode 100644 index 0000000..66656d7 --- /dev/null +++ b/database/seeds/PropertyExecuteTypeSeeder.php @@ -0,0 +1,73 @@ +delete(); + + \DB::table('property_executive_type')->insert(array ( + 0 => + array ( + 'id' => 1, + 'name' => 'Finance', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 1 => + array ( + 'id' => 2, + 'name' => 'Reservation', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 2 => + array ( + 'id' => 3, + 'name' => 'Sales', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 3 => + array ( + 'id' => 4, + 'name' => 'Activity', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 4 => + array ( + 'id' => 5, + 'name' => 'Group', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + )); + + + } +} diff --git a/database/seeds/PropertyFactSeeder.php b/database/seeds/PropertyFactSeeder.php new file mode 100644 index 0000000..05b6d53 --- /dev/null +++ b/database/seeds/PropertyFactSeeder.php @@ -0,0 +1,5623 @@ +delete(); + + \DB::table('property_fact')->insert(array ( + 0 => + array ( + 'id' => 1, + 'name' => 'Amenities', + 'parent_id' => NULL, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 1 => + array ( + 'id' => 2, + 'name' => 'Payment', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 2 => + array ( + 'id' => 3, + 'name' => 'American Express', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fa fa-cc-amex', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 3 => + array ( + 'id' => 4, + 'name' => 'VISA', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fab fa-cc-visa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 4 => + array ( + 'id' => 5, + 'name' => 'MasterCard', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fab fa-cc-mastercard', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 5 => + array ( + 'id' => 6, + 'name' => 'Diner\'s Club', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fab fa-cc-diners-club', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 6 => + array ( + 'id' => 7, + 'name' => 'JCB', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fab fa-cc-jcb', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 7 => + array ( + 'id' => 8, + 'name' => 'EC-Card', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-credit-card', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 8 => + array ( + 'id' => 9, + 'name' => 'Cash', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-money-bill-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 9 => + array ( + 'id' => 10, + 'name' => 'Cheque', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-money-check-edit-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 10 => + array ( + 'id' => 11, + 'name' => 'Traveller Cheuque', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-money-check-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 11 => + array ( + 'id' => 12, + 'name' => 'Company Invoice', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-file-invoice-dollar', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 12 => + array ( + 'id' => 13, + 'name' => 'SZÉP Card', + 'parent_id' => 2, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-credit-card', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 13 => + array ( + 'id' => 14, + 'name' => 'Accommodation', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 14 => + array ( + 'id' => 15, + 'name' => 'All inclusive', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 15 => + array ( + 'id' => 16, + 'name' => 'Bed and Breakfast', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bread-slice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 16 => + array ( + 'id' => 17, + 'name' => 'Lunch', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 17 => + array ( + 'id' => 18, + 'name' => 'Only Room', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 18 => + array ( + 'id' => 19, + 'name' => 'Full Board', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-check-double', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 19 => + array ( + 'id' => 20, + 'name' => 'Half Board', + 'parent_id' => 14, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-check', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 20 => + array ( + 'id' => 21, + 'name' => 'Services', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 21 => + array ( + 'id' => 22, + 'name' => 'Reception', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-concierge-bell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 22 => + array ( + 'id' => 23, + 'name' => '24 Hour Room Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-clock', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 23 => + array ( + 'id' => 24, + 'name' => '24 Hour Check-in Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-door-open', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 24 => + array ( + 'id' => 25, + 'name' => 'Room Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-phone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 25 => + array ( + 'id' => 26, + 'name' => 'Dry Clean Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 26 => + array ( + 'id' => 27, + 'name' => 'Cleaning Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-broom', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 27 => + array ( + 'id' => 28, + 'name' => 'Shoeshine', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shoe-prints', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 28 => + array ( + 'id' => 29, + 'name' => 'Housekeeping', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-broom', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 29 => + array ( + 'id' => 30, + 'name' => 'Ironing Service', + 'parent_id' => 21, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 30 => + array ( + 'id' => 31, + 'name' => 'Internet', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 31 => + array ( + 'id' => 32, + 'name' => 'WiFi', + 'parent_id' => 31, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wifi', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 32 => + array ( + 'id' => 33, + 'name' => 'Cable Internet', + 'parent_id' => 31, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ethernet', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 33 => + array ( + 'id' => 34, + 'name' => 'Business Center', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 34 => + array ( + 'id' => 35, + 'name' => 'Fax', + 'parent_id' => 34, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fax', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 35 => + array ( + 'id' => 36, + 'name' => 'Photocopy', + 'parent_id' => 34, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-copy', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 36 => + array ( + 'id' => 37, + 'name' => 'Computer', + 'parent_id' => 34, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-laptop', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 37 => + array ( + 'id' => 38, + 'name' => 'Printer', + 'parent_id' => 34, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-print', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 38 => + array ( + 'id' => 39, + 'name' => 'Scanner', + 'parent_id' => 34, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-file-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 39 => + array ( + 'id' => 40, + 'name' => 'Transportation', + 'parent_id' => 1, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 40 => + array ( + 'id' => 41, + 'name' => 'Rent a car', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-car', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 41 => + array ( + 'id' => 42, + 'name' => 'Bicycle Rental', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bicycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 42 => + array ( + 'id' => 43, + 'name' => 'Airport Transfer', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shuttle-van', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 43 => + array ( + 'id' => 44, + 'name' => 'Motorcycle Rental', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-motorcycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 44 => + array ( + 'id' => 45, + 'name' => 'Scooter Rental', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-motorcycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 45 => + array ( + 'id' => 46, + 'name' => 'Taxi', + 'parent_id' => 40, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-taxi', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 46 => + array ( + 'id' => 47, + 'name' => 'Disabled', + 'parent_id' => 1, + 'type' => 1, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 47 => + array ( + 'id' => 48, + 'name' => 'Disable Entrance', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 48 => + array ( + 'id' => 49, + 'name' => 'Disabled Lift', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 49 => + array ( + 'id' => 50, + 'name' => 'Disabled Bath', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shower', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 50 => + array ( + 'id' => 51, + 'name' => 'Toilet for Disabled Use', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-toilet', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 51 => + array ( + 'id' => 52, + 'name' => 'Disabled Room', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 52 => + array ( + 'id' => 53, + 'name' => 'Disabled Parking', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-parking', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 53 => + array ( + 'id' => 54, + 'name' => 'Disabled Ramp', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 54 => + array ( + 'id' => 55, + 'name' => 'Disabled Service', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 55 => + array ( + 'id' => 56, + 'name' => 'Terrace for the Disabled', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 56 => + array ( + 'id' => 57, + 'name' => 'Mobile Patient Bed', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 57 => + array ( + 'id' => 58, + 'name' => 'Companion Bed', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 58 => + array ( + 'id' => 59, + 'name' => 'Wheelchair', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 59 => + array ( + 'id' => 60, + 'name' => 'Wheelchair Ramps', + 'parent_id' => 47, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wheelchair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 60 => + array ( + 'id' => 61, + 'name' => 'Facility', + 'parent_id' => NULL, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 61 => + array ( + 'id' => 62, + 'name' => 'Public', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 62 => + array ( + 'id' => 63, + 'name' => 'Elevator', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-arrows-alt-v', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 63 => + array ( + 'id' => 64, + 'name' => 'Ballroom', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 64 => + array ( + 'id' => 65, + 'name' => 'Refrigerator', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 65 => + array ( + 'id' => 66, + 'name' => 'Coffee Tea Maker', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 66 => + array ( + 'id' => 67, + 'name' => 'Dance Studio', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 67 => + array ( + 'id' => 68, + 'name' => 'Lounge', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-couch', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 68 => + array ( + 'id' => 69, + 'name' => 'Electrical Car Charging Station', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-charging-station', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 69 => + array ( + 'id' => 70, + 'name' => 'Football Field', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-futbol', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 70 => + array ( + 'id' => 71, + 'name' => 'Sun Terrace', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-sun', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 71 => + array ( + 'id' => 72, + 'name' => 'Gym', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dumbbell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 72 => + array ( + 'id' => 73, + 'name' => 'Auditorium', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-microphone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 73 => + array ( + 'id' => 74, + 'name' => 'Library', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-book', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 74 => + array ( + 'id' => 75, + 'name' => 'Mosque', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-star-and-crescent', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 75 => + array ( + 'id' => 76, + 'name' => 'Microwave', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 76 => + array ( + 'id' => 77, + 'name' => 'Music Library', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 77 => + array ( + 'id' => 78, + 'name' => 'Public Kitchen', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 78 => + array ( + 'id' => 79, + 'name' => 'Playground', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 79 => + array ( + 'id' => 80, + 'name' => 'Game Room', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-chess-queen', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 80 => + array ( + 'id' => 81, + 'name' => 'Designated Smoking Area', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-smoking', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 81 => + array ( + 'id' => 82, + 'name' => 'Panoramic Terrace', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-star', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 82 => + array ( + 'id' => 83, + 'name' => 'Lobby', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-concierge-bell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 83 => + array ( + 'id' => 84, + 'name' => 'Chapel / Shrine', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-church', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 84 => + array ( + 'id' => 85, + 'name' => 'Tennis court', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-table-tennis', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 85 => + array ( + 'id' => 86, + 'name' => 'Terrace', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-star', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 86 => + array ( + 'id' => 87, + 'name' => 'Meeting room', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-user-friends', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 87 => + array ( + 'id' => 88, + 'name' => 'Tv Room', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 88 => + array ( + 'id' => 89, + 'name' => 'Video Library', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-video', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 89 => + array ( + 'id' => 90, + 'name' => 'Theater Hall', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 90 => + array ( + 'id' => 91, + 'name' => 'Safe Box', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 91 => + array ( + 'id' => 92, + 'name' => 'Cafeteria', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 92 => + array ( + 'id' => 93, + 'name' => 'Shops', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-store', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 93 => + array ( + 'id' => 94, + 'name' => 'Newspaper Buffet', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-newspaper', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 94 => + array ( + 'id' => 95, + 'name' => 'Minimarket', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-store-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 95 => + array ( + 'id' => 96, + 'name' => 'Bar (s)', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-beer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 96 => + array ( + 'id' => 97, + 'name' => 'Roofbar', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-beer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 97 => + array ( + 'id' => 98, + 'name' => 'Bicycle Room', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bicycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 98 => + array ( + 'id' => 99, + 'name' => 'Car park', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-parking', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 99 => + array ( + 'id' => 100, + 'name' => 'Children\'s Club', + 'parent_id' => 62, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-child', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 100 => + array ( + 'id' => 101, + 'name' => 'Food & Drink', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 101 => + array ( + 'id' => 102, + 'name' => 'Garden Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cocktail', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 102 => + array ( + 'id' => 103, + 'name' => 'Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-beer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 103 => + array ( + 'id' => 104, + 'name' => 'BBQ Facilities', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hamburger', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 104 => + array ( + 'id' => 105, + 'name' => 'Beach Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-beer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 105 => + array ( + 'id' => 106, + 'name' => 'Cafe', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 106 => + array ( + 'id' => 107, + 'name' => 'Disco Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cocktail', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 107 => + array ( + 'id' => 108, + 'name' => 'Icecream', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ice-cream', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 108 => + array ( + 'id' => 109, + 'name' => 'Pancake Corner', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cookie', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 109 => + array ( + 'id' => 110, + 'name' => 'Pool Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wine-bottle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 110 => + array ( + 'id' => 111, + 'name' => 'Beverage Vending Machine', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 111 => + array ( + 'id' => 112, + 'name' => 'Cafeteria', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 112 => + array ( + 'id' => 113, + 'name' => 'Breakfast room', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bread-slice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 113 => + array ( + 'id' => 114, + 'name' => 'Indoor Restaurant', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-door-closed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 114 => + array ( + 'id' => 115, + 'name' => 'Lobby Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wine-bottle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 115 => + array ( + 'id' => 116, + 'name' => 'Hookah cafe', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-joint', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 116 => + array ( + 'id' => 117, + 'name' => 'Food Service In Room', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 117 => + array ( + 'id' => 118, + 'name' => 'Take Away', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-box', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 118 => + array ( + 'id' => 119, + 'name' => 'Pastry Shop', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cookie', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 119 => + array ( + 'id' => 120, + 'name' => 'Restaurant', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 120 => + array ( + 'id' => 121, + 'name' => 'Open Buffet Restaurant', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 121 => + array ( + 'id' => 122, + 'name' => 'A La Carte Restaurant', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 122 => + array ( + 'id' => 123, + 'name' => 'Snack bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-candy-cane', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 123 => + array ( + 'id' => 124, + 'name' => 'Terrace Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cocktail', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 124 => + array ( + 'id' => 125, + 'name' => 'Vitamin Bar', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-apple-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 125 => + array ( + 'id' => 126, + 'name' => 'Special Diet', + 'parent_id' => 101, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-carrot', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 126 => + array ( + 'id' => 127, + 'name' => 'Pool', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 127 => + array ( + 'id' => 128, + 'name' => 'Aqua Park', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 128 => + array ( + 'id' => 129, + 'name' => 'Male / Female Separate Swimming Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimmer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 129 => + array ( + 'id' => 130, + 'name' => 'Pool with Water Slide', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 130 => + array ( + 'id' => 131, + 'name' => 'Hot Water Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 131 => + array ( + 'id' => 132, + 'name' => 'Locker Cabinet', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-restroom', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 132 => + array ( + 'id' => 133, + 'name' => 'Sunbed', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 133 => + array ( + 'id' => 134, + 'name' => 'Freshwater Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 134 => + array ( + 'id' => 135, + 'name' => 'Themed Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 135 => + array ( + 'id' => 136, + 'name' => 'Thermal Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 136 => + array ( + 'id' => 137, + 'name' => 'Saltwater Pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 137 => + array ( + 'id' => 138, + 'name' => 'Swimming pool', + 'parent_id' => 127, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimmer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 138 => + array ( + 'id' => 139, + 'name' => 'Spa, Wellness & Care', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 139 => + array ( + 'id' => 140, + 'name' => 'Acupuncture', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-slash', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 140 => + array ( + 'id' => 141, + 'name' => 'Aromatic Balneo Therapy', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 141 => + array ( + 'id' => 142, + 'name' => 'Asthma Cave', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 142 => + array ( + 'id' => 143, + 'name' => 'Bio Sauna', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 143 => + array ( + 'id' => 144, + 'name' => 'Steam Bath', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 144 => + array ( + 'id' => 145, + 'name' => 'Steam Bathhouse', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 145 => + array ( + 'id' => 146, + 'name' => 'Steam Room', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 146 => + array ( + 'id' => 147, + 'name' => 'Skin Care', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-allergies', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 147 => + array ( + 'id' => 148, + 'name' => 'Mud Bath', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 148 => + array ( + 'id' => 149, + 'name' => 'Doctor', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-briefcase-medical', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 149 => + array ( + 'id' => 150, + 'name' => 'Finnish Sauna', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 150 => + array ( + 'id' => 151, + 'name' => 'Fitness Center', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dumbbell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 151 => + array ( + 'id' => 152, + 'name' => 'Nurse', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-user-md', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 152 => + array ( + 'id' => 153, + 'name' => 'Hydrocolon Therapy', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 153 => + array ( + 'id' => 154, + 'name' => 'Hydromassage Bathtub', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 154 => + array ( + 'id' => 155, + 'name' => 'Jacuzzi', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 155 => + array ( + 'id' => 156, + 'name' => 'Hot Spring', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 156 => + array ( + 'id' => 157, + 'name' => 'Snow Room', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-snowflake', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 157 => + array ( + 'id' => 158, + 'name' => 'Hairdresser', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cut', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 158 => + array ( + 'id' => 159, + 'name' => 'Laser Therapy', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 159 => + array ( + 'id' => 160, + 'name' => 'Massage Services', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 160 => + array ( + 'id' => 161, + 'name' => 'Ozone Sauna', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 161 => + array ( + 'id' => 162, + 'name' => 'Infirmary', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-clinic-medical', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 162 => + array ( + 'id' => 163, + 'name' => 'Sauna', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 163 => + array ( + 'id' => 164, + 'name' => 'Solarium', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-sun', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 164 => + array ( + 'id' => 165, + 'name' => 'Spa Bar', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 165 => + array ( + 'id' => 166, + 'name' => 'Shock Pool', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 166 => + array ( + 'id' => 167, + 'name' => 'Thalasso Therapy Center', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 167 => + array ( + 'id' => 168, + 'name' => 'Turkish Bath', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 168 => + array ( + 'id' => 169, + 'name' => 'Yoga', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 169 => + array ( + 'id' => 170, + 'name' => 'Seaweed Treatment', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 170 => + array ( + 'id' => 171, + 'name' => 'Effusion Therapy', + 'parent_id' => 139, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 171 => + array ( + 'id' => 172, + 'name' => 'Activities', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 172 => + array ( + 'id' => 173, + 'name' => 'Aerobic', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dumbbell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 173 => + array ( + 'id' => 174, + 'name' => 'Air Hockey', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hockey-puck', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 174 => + array ( + 'id' => 175, + 'name' => 'Aquaroic', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimmer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 175 => + array ( + 'id' => 176, + 'name' => 'Horse Riding', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-horse', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 176 => + array ( + 'id' => 177, + 'name' => 'Shooting', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bullseye', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 177 => + array ( + 'id' => 178, + 'name' => 'Atv Safari', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-truck-monster', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 178 => + array ( + 'id' => 179, + 'name' => 'Badminton', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-table-tennis', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 179 => + array ( + 'id' => 180, + 'name' => 'Fishing', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fish', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 180 => + array ( + 'id' => 181, + 'name' => 'Balloon', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 181 => + array ( + 'id' => 182, + 'name' => 'Basketball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-basketball-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 182 => + array ( + 'id' => 183, + 'name' => 'Beach Football', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-futbol', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 183 => + array ( + 'id' => 184, + 'name' => 'Beach Volleyball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-volleyball-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 184 => + array ( + 'id' => 185, + 'name' => 'Billiards', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dot-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 185 => + array ( + 'id' => 186, + 'name' => 'Bicycle', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bicycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 186 => + array ( + 'id' => 187, + 'name' => 'Boccia', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'far fa-futbol', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 187 => + array ( + 'id' => 188, + 'name' => 'Bowling', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bowling-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 188 => + array ( + 'id' => 189, + 'name' => 'Ice Skating', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-skating', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 189 => + array ( + 'id' => 190, + 'name' => 'Dance Lessons', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bowling-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 190 => + array ( + 'id' => 191, + 'name' => 'Darts', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bullseye-arrow', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 191 => + array ( + 'id' => 192, + 'name' => 'Pedalo', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bowling-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 192 => + array ( + 'id' => 193, + 'name' => 'Golf', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bicycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 193 => + array ( + 'id' => 194, + 'name' => 'Air Rifle', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bullseye', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 194 => + array ( + 'id' => 195, + 'name' => 'Pool Games', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 195 => + array ( + 'id' => 196, + 'name' => 'Motorboat', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 196 => + array ( + 'id' => 197, + 'name' => 'Jeep Safari', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-truck-monster', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 197 => + array ( + 'id' => 198, + 'name' => 'Jet Ski', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 198 => + array ( + 'id' => 199, + 'name' => 'Gymnastics', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dumbbell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 199 => + array ( + 'id' => 200, + 'name' => 'Jogging', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-running', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 200 => + array ( + 'id' => 201, + 'name' => 'Canoe', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 201 => + array ( + 'id' => 202, + 'name' => 'Karaoke', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-microphone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 202 => + array ( + 'id' => 203, + 'name' => 'Card Games', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-th-large', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 203 => + array ( + 'id' => 204, + 'name' => 'Ski', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-skiing-nordic', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 204 => + array ( + 'id' => 205, + 'name' => 'Kitesurf', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 205 => + array ( + 'id' => 206, + 'name' => 'Pinball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 206 => + array ( + 'id' => 207, + 'name' => 'Ping Pong', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-table-tennis', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 207 => + array ( + 'id' => 208, + 'name' => 'Mini Billiards', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dot-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 208 => + array ( + 'id' => 209, + 'name' => 'Mini Football', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'far fa-futbol', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 209 => + array ( + 'id' => 210, + 'name' => 'Mini Golf', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-golf-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 210 => + array ( + 'id' => 211, + 'name' => 'Motorized Water Sports', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 211 => + array ( + 'id' => 212, + 'name' => 'Banana Boat', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 212 => + array ( + 'id' => 213, + 'name' => 'Archery', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bullseye', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 213 => + array ( + 'id' => 214, + 'name' => 'Okey Team', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 214 => + array ( + 'id' => 215, + 'name' => 'Paintball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ellipsis-h', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 215 => + array ( + 'id' => 216, + 'name' => 'Parasailing', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-parachute-box', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 216 => + array ( + 'id' => 217, + 'name' => 'Parachute', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-parachute-box', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 217 => + array ( + 'id' => 218, + 'name' => 'Pedal Boat', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 218 => + array ( + 'id' => 219, + 'name' => 'Pilates', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 219 => + array ( + 'id' => 220, + 'name' => 'Pinball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 220 => + array ( + 'id' => 221, + 'name' => 'Rafting', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 221 => + array ( + 'id' => 222, + 'name' => 'Ringo', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-life-ring', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 222 => + array ( + 'id' => 223, + 'name' => 'Windsurf', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 223 => + array ( + 'id' => 224, + 'name' => 'Safari', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-compass', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 224 => + array ( + 'id' => 225, + 'name' => 'Chess', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-chess-board', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 225 => + array ( + 'id' => 226, + 'name' => 'Scuba Diving', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimmer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 226 => + array ( + 'id' => 227, + 'name' => 'Surf', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 227 => + array ( + 'id' => 228, + 'name' => 'Squash', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-table-tennis', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 228 => + array ( + 'id' => 229, + 'name' => 'Step', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shoe-prints', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 229 => + array ( + 'id' => 230, + 'name' => 'Water Aerobics', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimmer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 230 => + array ( + 'id' => 231, + 'name' => 'Water Skiing', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 231 => + array ( + 'id' => 232, + 'name' => 'Water Polo', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-volleyball-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 232 => + array ( + 'id' => 233, + 'name' => 'Backgammon', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 233 => + array ( + 'id' => 234, + 'name' => 'Tennis', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-table-tennis', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 234 => + array ( + 'id' => 235, + 'name' => 'Climb', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-mountain', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 235 => + array ( + 'id' => 236, + 'name' => 'Trampolin', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 236 => + array ( + 'id' => 237, + 'name' => 'Trekking', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hiking', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 237 => + array ( + 'id' => 238, + 'name' => 'Volleyball', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-volleyball-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 238 => + array ( + 'id' => 239, + 'name' => 'Paragliding', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-parachute-box', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 239 => + array ( + 'id' => 240, + 'name' => 'Sailing', + 'parent_id' => 172, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 240 => + array ( + 'id' => 241, + 'name' => 'Entertainment', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 241 => + array ( + 'id' => 242, + 'name' => 'Outdoor Activities', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-sun', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 242 => + array ( + 'id' => 243, + 'name' => 'Amphitheatre', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 243 => + array ( + 'id' => 244, + 'name' => 'Animation Team', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-crown', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 244 => + array ( + 'id' => 245, + 'name' => 'Beach Party', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-umbrella-beach', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 245 => + array ( + 'id' => 246, + 'name' => 'Bowling Alley', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bowling-ball', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 246 => + array ( + 'id' => 247, + 'name' => 'Live Entertainment', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 247 => + array ( + 'id' => 248, + 'name' => 'Live music', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 248 => + array ( + 'id' => 249, + 'name' => 'Dance Performances', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 249 => + array ( + 'id' => 250, + 'name' => 'Entertainment Programs', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 250 => + array ( + 'id' => 251, + 'name' => 'Night club', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-glass-cheers', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 251 => + array ( + 'id' => 252, + 'name' => 'Night Shows', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-moon', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 252 => + array ( + 'id' => 253, + 'name' => 'Zoo', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-paw', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 253 => + array ( + 'id' => 254, + 'name' => 'Foam party', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-glass-cheers', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 254 => + array ( + 'id' => 255, + 'name' => 'Casino', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coins', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 255 => + array ( + 'id' => 256, + 'name' => 'Culture Show', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 256 => + array ( + 'id' => 257, + 'name' => 'Fun fair', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dot-circle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 257 => + array ( + 'id' => 258, + 'name' => 'Beach Parties', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-umbrella-beach', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 258 => + array ( + 'id' => 259, + 'name' => 'Pub', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-beer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 259 => + array ( + 'id' => 260, + 'name' => 'Cinema', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-film', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 260 => + array ( + 'id' => 261, + 'name' => 'Circus Acrobatics', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-campground', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 261 => + array ( + 'id' => 262, + 'name' => 'Soft Animation', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-crow', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 262 => + array ( + 'id' => 263, + 'name' => 'Boat Tour', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 263 => + array ( + 'id' => 264, + 'name' => 'Themed Nights', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-mask', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 264 => + array ( + 'id' => 265, + 'name' => 'Yacht tour', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 265 => + array ( + 'id' => 266, + 'name' => 'Sailboat', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-ship', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 266 => + array ( + 'id' => 267, + 'name' => 'Cooking Course', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 267 => + array ( + 'id' => 268, + 'name' => 'Theater Show', + 'parent_id' => 241, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-theater-masks', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 268 => + array ( + 'id' => 269, + 'name' => 'Kids & Baby', + 'parent_id' => 61, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 269 => + array ( + 'id' => 270, + 'name' => 'Sitter', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-baby', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 270 => + array ( + 'id' => 271, + 'name' => 'Children\'s Buffet', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tint', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 271 => + array ( + 'id' => 272, + 'name' => 'Children\'s Disco', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 272 => + array ( + 'id' => 273, + 'name' => 'Kiddy Pool ', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bicycle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 273 => + array ( + 'id' => 274, + 'name' => 'Child Cot', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 274 => + array ( + 'id' => 275, + 'name' => 'Children\'s park', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-child', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 275 => + array ( + 'id' => 276, + 'name' => 'Stroller', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-baby-carriage', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 276 => + array ( + 'id' => 277, + 'name' => 'Baby cot', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 277 => + array ( + 'id' => 278, + 'name' => 'Baby Bathtub', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 278 => + array ( + 'id' => 279, + 'name' => 'Baby Food Sales', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cookie', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 279 => + array ( + 'id' => 280, + 'name' => 'Baby Milk Sales', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tint', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 280 => + array ( + 'id' => 281, + 'name' => 'Cradle', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 281 => + array ( + 'id' => 282, + 'name' => 'Bottle Sterilization', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tint', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 282 => + array ( + 'id' => 283, + 'name' => 'Baby Care Area in Public Toilets', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-baby', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 283 => + array ( + 'id' => 284, + 'name' => 'Water Heater For Baby Formula', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tint', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 284 => + array ( + 'id' => 285, + 'name' => 'Mini Club', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-child', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 285 => + array ( + 'id' => 286, + 'name' => 'Baby Chair', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-chair', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 286 => + array ( + 'id' => 287, + 'name' => 'Children\'s Programs', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-child', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 287 => + array ( + 'id' => 288, + 'name' => 'Children\'s Menu', + 'parent_id' => 269, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-cookie', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 288 => + array ( + 'id' => 289, + 'name' => 'Room', + 'parent_id' => NULL, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 289 => + array ( + 'id' => 290, + 'name' => 'Common Amenities of Rooms', + 'parent_id' => 289, + 'type' => 0, + 'order_number' => 0, + 'icon' => '', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 290 => + array ( + 'id' => 291, + 'name' => '220 Volts', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-plug', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 291 => + array ( + 'id' => 292, + 'name' => 'Outdoor Dining Table', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-sun', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 292 => + array ( + 'id' => 293, + 'name' => 'Wood / Parquet Flooring', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 293 => + array ( + 'id' => 294, + 'name' => 'Alarm', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 294 => + array ( + 'id' => 295, + 'name' => 'Antiallergic', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spray-can', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 295 => + array ( + 'id' => 296, + 'name' => 'Mirror', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 296 => + array ( + 'id' => 297, + 'name' => 'Separate Bedroom', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 297 => + array ( + 'id' => 298, + 'name' => 'Connecting Rooms', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spray-can', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 298 => + array ( + 'id' => 299, + 'name' => 'Garden View', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tree', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 299 => + array ( + 'id' => 300, + 'name' => 'Balcony', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-border-all', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 300 => + array ( + 'id' => 301, + 'name' => 'Bathroom', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 301 => + array ( + 'id' => 302, + 'name' => 'Bathroom Products', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 302 => + array ( + 'id' => 303, + 'name' => 'Telephone in Bathroom', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-phone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 303 => + array ( + 'id' => 304, + 'name' => 'BBQ', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hamburger', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 304 => + array ( + 'id' => 305, + 'name' => 'Baby Table', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-baby', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 305 => + array ( + 'id' => 306, + 'name' => 'Bidet', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-toilet', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 306 => + array ( + 'id' => 307, + 'name' => 'Computer', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-laptop', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 307 => + array ( + 'id' => 308, + 'name' => 'Blu-ray player', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-compact-disc', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 308 => + array ( + 'id' => 309, + 'name' => 'Bosphorus View', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 309 => + array ( + 'id' => 310, + 'name' => 'Bathrobe', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-washer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 310 => + array ( + 'id' => 311, + 'name' => 'Dishwasher', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-washer', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 311 => + array ( + 'id' => 312, + 'name' => 'Refrigerator', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-temperature-low', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 312 => + array ( + 'id' => 313, + 'name' => 'CD Player', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-compact-disc', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 313 => + array ( + 'id' => 314, + 'name' => 'Alarm Clock', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-clock', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 314 => + array ( + 'id' => 315, + 'name' => 'Study Desk', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-pencil-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 315 => + array ( + 'id' => 316, + 'name' => 'Clothes Dryer ', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 316 => + array ( + 'id' => 317, + 'name' => 'Washing machine', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-dryer-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 317 => + array ( + 'id' => 318, + 'name' => 'Drawers', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 318 => + array ( + 'id' => 319, + 'name' => 'Coffee / Tea Maker', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 319 => + array ( + 'id' => 320, + 'name' => 'Mountain View ', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-mountain', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 320 => + array ( + 'id' => 321, + 'name' => 'Sea View', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 321 => + array ( + 'id' => 322, + 'name' => 'Direct Dial Telephone', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-phone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 322 => + array ( + 'id' => 323, + 'name' => 'Laptop', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-laptop', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 323 => + array ( + 'id' => 324, + 'name' => 'Landscape', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tree', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 324 => + array ( + 'id' => 325, + 'name' => 'Smoke Alarm', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bell', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 325 => + array ( + 'id' => 326, + 'name' => 'Shower', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shower', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 326 => + array ( + 'id' => 327, + 'name' => 'Flat Screen Tv', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 327 => + array ( + 'id' => 328, + 'name' => 'DVD Player', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-compact-disc', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 328 => + array ( + 'id' => 329, + 'name' => 'Toaster', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bread-slice', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 329 => + array ( + 'id' => 330, + 'name' => 'Extra Bed', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 330 => + array ( + 'id' => 331, + 'name' => 'Warming Pad', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 331 => + array ( + 'id' => 332, + 'name' => 'Electric Water Heater', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 332 => + array ( + 'id' => 333, + 'name' => 'Extra Long Bed (> 2 mt)', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 333 => + array ( + 'id' => 334, + 'name' => 'Fan', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fan', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 334 => + array ( + 'id' => 335, + 'name' => 'Fax', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fax', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 335 => + array ( + 'id' => 336, + 'name' => 'Owen', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fire', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 336 => + array ( + 'id' => 337, + 'name' => 'Widescreen Tv', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 337 => + array ( + 'id' => 338, + 'name' => 'Lake View ', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 338 => + array ( + 'id' => 339, + 'name' => 'Carpeted Floor', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 339 => + array ( + 'id' => 340, + 'name' => 'Air / Water Filter', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-filter', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 340 => + array ( + 'id' => 341, + 'name' => 'Pool View', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 341 => + array ( + 'id' => 342, + 'name' => 'Heating', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fire', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 342 => + array ( + 'id' => 343, + 'name' => 'Light / Noise / Heat Insulated Curtains', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-lightbulb', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 343 => + array ( + 'id' => 344, + 'name' => 'Second Bathroom', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 344 => + array ( + 'id' => 345, + 'name' => 'Internet Connection', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wifi', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 345 => + array ( + 'id' => 346, + 'name' => 'iPad', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-mobile-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 346 => + array ( + 'id' => 347, + 'name' => 'iPod Docking Station', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-mobile-alt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 347 => + array ( + 'id' => 348, + 'name' => 'Jacuzzi', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hot-tub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 348 => + array ( + 'id' => 349, + 'name' => 'Cable Channels', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 349 => + array ( + 'id' => 350, + 'name' => 'Coffee machine', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 350 => + array ( + 'id' => 351, + 'name' => 'Sofa', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-couch', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 351 => + array ( + 'id' => 352, + 'name' => 'Clothes Cabinet', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 352 => + array ( + 'id' => 353, + 'name' => 'Air Conditioner', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 353 => + array ( + 'id' => 354, + 'name' => 'Dryer', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 354 => + array ( + 'id' => 355, + 'name' => 'Tub', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bath', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 355 => + array ( + 'id' => 356, + 'name' => 'Make up Desk', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fab fa-sketch', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 356 => + array ( + 'id' => 357, + 'name' => 'Massage Service', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-spa', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 357 => + array ( + 'id' => 358, + 'name' => 'Central Heating', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-thermometer-three-quarters', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 358 => + array ( + 'id' => 359, + 'name' => 'Marble Floor', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 359 => + array ( + 'id' => 360, + 'name' => 'Microwave Oven', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fire', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 360 => + array ( + 'id' => 361, + 'name' => 'Mini Bar', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wine-bottle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 361 => + array ( + 'id' => 362, + 'name' => 'Mini Refrigerator', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-temperature-low', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 362 => + array ( + 'id' => 363, + 'name' => 'Kitchenette', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 363 => + array ( + 'id' => 364, + 'name' => 'Kitchen', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 364 => + array ( + 'id' => 365, + 'name' => 'Kitchenware', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 365 => + array ( + 'id' => 366, + 'name' => 'Music Player', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 366 => + array ( + 'id' => 367, + 'name' => 'River View', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-water', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 367 => + array ( + 'id' => 368, + 'name' => 'Furnace', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fire', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 368 => + array ( + 'id' => 369, + 'name' => 'Pool in the Room', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-couch', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 369 => + array ( + 'id' => 370, + 'name' => 'Sitting Group', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-couch', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 370 => + array ( + 'id' => 371, + 'name' => 'Game Console', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-gamepad', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 371 => + array ( + 'id' => 372, + 'name' => 'Paid Movies', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 372 => + array ( + 'id' => 373, + 'name' => 'Private Entrance', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-door-open', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 373 => + array ( + 'id' => 374, + 'name' => 'Private Pool', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-swimming-pool', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 374 => + array ( + 'id' => 375, + 'name' => 'Radio', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-music', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 375 => + array ( + 'id' => 376, + 'name' => 'Clock', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-clock', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 376 => + array ( + 'id' => 377, + 'name' => 'Hair Dryer', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 377 => + array ( + 'id' => 378, + 'name' => 'Safe Box', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 378 => + array ( + 'id' => 379, + 'name' => 'Sound insulation', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 379 => + array ( + 'id' => 380, + 'name' => 'Mosquito Wire', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-hashtag', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 380 => + array ( + 'id' => 381, + 'name' => 'Dressing Room', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-restroom', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 381 => + array ( + 'id' => 382, + 'name' => 'Split Air Conditioner', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wind', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 382 => + array ( + 'id' => 383, + 'name' => 'Local / International Calling', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-phone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 383 => + array ( + 'id' => 384, + 'name' => 'Bottled Water', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-wine-bottle', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 384 => + array ( + 'id' => 385, + 'name' => 'Fireplace', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fire', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 385 => + array ( + 'id' => 386, + 'name' => 'Telephone', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-phone', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 386 => + array ( + 'id' => 387, + 'name' => 'Television', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 387 => + array ( + 'id' => 388, + 'name' => 'Cleaning Products', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-broom', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 388 => + array ( + 'id' => 389, + 'name' => 'Slipper', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-shoe-prints', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 389 => + array ( + 'id' => 390, + 'name' => 'Turkish Coffee Machine', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-coffee', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 390 => + array ( + 'id' => 391, + 'name' => 'Satellite Channels', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tv', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 391 => + array ( + 'id' => 392, + 'name' => 'Iron', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 392 => + array ( + 'id' => 393, + 'name' => 'Ironing Facilities', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-tshirt', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 393 => + array ( + 'id' => 394, + 'name' => 'Fan', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-fan', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 394 => + array ( + 'id' => 395, + 'name' => 'Porch / Courtyard', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-square', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 395 => + array ( + 'id' => 396, + 'name' => 'Video Player', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-compact-disc', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 396 => + array ( + 'id' => 397, + 'name' => 'Pillow Menu', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-bed', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 397 => + array ( + 'id' => 398, + 'name' => 'Dining Areas', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 398 => + array ( + 'id' => 399, + 'name' => 'Dinner Table', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 399 => + array ( + 'id' => 400, + 'name' => 'Dinner Set', + 'parent_id' => 290, + 'type' => 1, + 'order_number' => 0, + 'icon' => 'fas fa-utensils', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + )); + + + } +} diff --git a/database/seeds/PropertyGoogleLabelSeeder.php b/database/seeds/PropertyGoogleLabelSeeder.php new file mode 100644 index 0000000..f1a60b4 --- /dev/null +++ b/database/seeds/PropertyGoogleLabelSeeder.php @@ -0,0 +1,123 @@ +delete(); + + \DB::table('photo_google_label')->insert(array ( + 0 => + array ( + 'id' => 1, + 'label' => 'Resort', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 1 => + array ( + 'id' => 2, + 'label' => 'Building', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 2 => + array ( + 'id' => 3, + 'label' => 'Property', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 3 => + array ( + 'id' => 4, + 'label' => 'Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 4 => + array ( + 'id' => 5, + 'label' => 'Home', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 5 => + array ( + 'id' => 6, + 'label' => 'Bar', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 6 => + array ( + 'id' => 7, + 'label' => 'Pub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 7 => + array ( + 'id' => 8, + 'label' => 'Disco', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 8 => + array ( + 'id' => 9, + 'label' => 'Tavern', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 9 => + array ( + 'id' => 10, + 'label' => 'Nightclub', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + )); + + + } +} diff --git a/database/seeds/PropertyPhotoSeeder.php b/database/seeds/PropertyPhotoSeeder.php new file mode 100644 index 0000000..2158132 --- /dev/null +++ b/database/seeds/PropertyPhotoSeeder.php @@ -0,0 +1,263 @@ +delete(); + + \DB::table('property_photo')->insert(array ( + 0 => + array ( + 'id' => 1, + 'property_id' => 1, + 'property_photo_category_id' => 2, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571403990.jpg', + 'photo_name' => '1571403990.jpg', + 'photo_rank' => NULL, + 'file_size' => '224086', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1161', + 'photo_order' => 1, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 0, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571404371, + ), + 1 => + array ( + 'id' => 2, + 'property_id' => 1, + 'property_photo_category_id' => 2, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571404099.jpg', + 'photo_name' => '1571404099.jpg', + 'photo_rank' => NULL, + 'file_size' => '234013', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1159', + 'photo_order' => 2, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 0, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571404370, + ), + 2 => + array ( + 'id' => 3, + 'property_id' => 1, + 'property_photo_category_id' => 9, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571404388.jpg', + 'photo_name' => '1571404388.jpg', + 'photo_rank' => NULL, + 'file_size' => '195845', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1171', + 'photo_order' => 3, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 3 => + array ( + 'id' => 4, + 'property_id' => 1, + 'property_photo_category_id' => 11, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571404427.jpg', + 'photo_name' => '1571404427.jpg', + 'photo_rank' => NULL, + 'file_size' => '164885', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1160', + 'photo_order' => 4, + 'is_default' => 1, + 'is_temp' => 1, + 'status' => 0, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407419, + ), + 4 => + array ( + 'id' => 5, + 'property_id' => 1, + 'property_photo_category_id' => 6, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571404449.jpg', + 'photo_name' => '1571404449.jpg', + 'photo_rank' => NULL, + 'file_size' => '189233', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1197', + 'photo_order' => 5, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1, + ), + 5 => + array ( + 'id' => 6, + 'property_id' => 1, + 'property_photo_category_id' => 2, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407195.jpg', + 'photo_name' => '1571407195.jpg', + 'photo_rank' => NULL, + 'file_size' => '167280', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1134', + 'photo_order' => 6, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407198, + ), + 6 => + array ( + 'id' => 7, + 'property_id' => 1, + 'property_photo_category_id' => 11, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407199.jpg', + 'photo_name' => '1571407199.jpg', + 'photo_rank' => NULL, + 'file_size' => '195845', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1171', + 'photo_order' => 7, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407201, + ), + 7 => + array ( + 'id' => 8, + 'property_id' => 1, + 'property_photo_category_id' => 2, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407202.jpg', + 'photo_name' => '1571407202.jpg', + 'photo_rank' => NULL, + 'file_size' => '224086', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1161', + 'photo_order' => 8, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407204, + ), + 8 => + array ( + 'id' => 9, + 'property_id' => 1, + 'property_photo_category_id' => 11, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407206.jpg', + 'photo_name' => '1571407206.jpg', + 'photo_rank' => NULL, + 'file_size' => '164885', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1160', + 'photo_order' => 9, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407208, + ), + 9 => + array ( + 'id' => 10, + 'property_id' => 1, + 'property_photo_category_id' => 2, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407209.jpg', + 'photo_name' => '1571407209.jpg', + 'photo_rank' => NULL, + 'file_size' => '234013', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1159', + 'photo_order' => 10, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407211, + ), + 10 => + array ( + 'id' => 11, + 'property_id' => 1, + 'property_photo_category_id' => 9, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407212.jpg', + 'photo_name' => '1571407212.jpg', + 'photo_rank' => NULL, + 'file_size' => '246154', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1324', + 'photo_order' => 11, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407214, + ), + 11 => + array ( + 'id' => 12, + 'property_id' => 1, + 'property_photo_category_id' => 11, + 'photo_path' => '/srv/api.gextranet.com/public/property-photos/1/1571407216.jpg', + 'photo_name' => '1571407216.jpg', + 'photo_rank' => NULL, + 'file_size' => '151624', + 'file_ext' => 'jpg', + 'photo_resolution' => '1740x1160', + 'photo_order' => 12, + 'is_default' => 0, + 'is_temp' => 1, + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 1, + 'updated_at' => 1571407218, + ), + )); + + + } +} diff --git a/database/seeds/PropertyTypeSeeder.php b/database/seeds/PropertyTypeSeeder.php new file mode 100644 index 0000000..2047745 --- /dev/null +++ b/database/seeds/PropertyTypeSeeder.php @@ -0,0 +1,153 @@ +delete(); + + \DB::table('property_type')->insert(array ( + 0 => + array ( + 'id' => 1, + 'name' => '1 Stars Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 1 => + array ( + 'id' => 2, + 'name' => '2 Stars Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 2 => + array ( + 'id' => 3, + 'name' => '3 Stars Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 3 => + array ( + 'id' => 4, + 'name' => '4 Stars Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 4 => + array ( + 'id' => 5, + 'name' => '5 Stars Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 5 => + array ( + 'id' => 6, + 'name' => 'Boutique hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 6 => + array ( + 'id' => 7, + 'name' => 'Apart Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 7 => + array ( + 'id' => 8, + 'name' => 'Residence', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 8 => + array ( + 'id' => 9, + 'name' => 'Hostel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 9 => + array ( + 'id' => 10, + 'name' => 'Resort', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 10 => + array ( + 'id' => 11, + 'name' => 'Thermal Facility', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 11 => + array ( + 'id' => 12, + 'name' => 'Motel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + 12 => + array ( + 'id' => 13, + 'name' => 'Suit Hotel', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => 0, + 'updated_at' => 0, + ), + )); + + + } +} diff --git a/database/seeds/UserTableSeeder.php b/database/seeds/UserTableSeeder.php new file mode 100644 index 0000000..26feb50 --- /dev/null +++ b/database/seeds/UserTableSeeder.php @@ -0,0 +1,54 @@ +insertGetId([ + 'id' => 1, + 'gender' => 'M', + 'name' => 'Test', + 'surname' => 'User -1-', + 'email' => 'test1@rezervasyon.com', + 'password' => Hash::make('123456'), + 'phone' => '02123668989', + 'user_type' => 1, + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + + + ]); + DB::table('user')->insertGetId( + [ + 'id' => 2, + 'gender' => 'M', + 'name' => 'Test', + 'surname' => 'User -2-', + 'email' => 'test2@rezervasyon.com', + 'password' => Hash::make('1234567'), + 'phone' => '02123668989', + 'user_type' => 0, + 'locale' => 'en', + 'status' => 1, + 'created_by' => 1, + 'updated_by' => 1, + 'created_at' => time(), + 'updated_at' => time(), + ] + + ); + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4801ccd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,58 @@ +version: "3.8" + +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: extranetwork_app + restart: unless-stopped + working_dir: /var/www/html + volumes: + - .:/var/www/html + - extranetwork_uploads_data:/home/uploads + ports: + - "8073:80" + depends_on: + - mysql + networks: + - extranetwork_network + + mysql: + image: mysql:8.0 + container_name: extranetwork_mysql + restart: unless-stopped + ports: + - "3307:3306" + environment: + MYSQL_DATABASE: extranetwork_api + MYSQL_ROOT_PASSWORD: "144652qweBk??" + command: --default-authentication-plugin=mysql_native_password + volumes: + - extranetwork_mysql_data:/var/lib/mysql + networks: + - extranetwork_network + + phpmyadmin: + image: phpmyadmin/phpmyadmin + container_name: extranetwork_phpmyadmin + restart: unless-stopped + ports: + - "8081:80" + environment: + PMA_HOST: mysql + PMA_PORT: 3306 + PMA_USER: root + PMA_PASSWORD: "144652qweBk??" + depends_on: + - mysql + networks: + - extranetwork_network + +volumes: + extranetwork_mysql_data: + extranetwork_uploads_data: + +networks: + extranetwork_network: + driver: bridge diff --git a/php b/php new file mode 100644 index 0000000..e69de29 diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..8ef59e8 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,26 @@ + + + + + ./tests + + + + + ./app + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..4be9f04 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Handle Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058432_BU4ZCOX3BL_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058498_KXQFEAR72N_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058692_2PTNCQ6D0Y_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058726_N4JQ1CR3DD_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058727_PC7D0HUQU7_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058728_HPCDZ6OGKO_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_8Z63Y323LE_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058729_U1CXBVYIWS_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27.jpg" new file mode 100644 index 0000000..9243190 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_medium.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_medium.jpg" new file mode 100644 index 0000000..86c3608 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_medium.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_thumbnail.jpg" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_thumbnail.jpg" new file mode 100644 index 0000000..c0cd734 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/1778058964_HVHBI7CM27_thumbnail.jpg" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/awards-certificates/1778057851_IMD365C7C8.pdf" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/awards-certificates/1778057851_IMD365C7C8.pdf" new file mode 100644 index 0000000..ecc5b8c Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/awards-certificates/1778057851_IMD365C7C8.pdf" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_250x250.png" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_250x250.png" new file mode 100644 index 0000000..ba0610a Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_250x250.png" differ diff --git "a/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_750x750.png" "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_750x750.png" new file mode 100644 index 0000000..9f27e06 Binary files /dev/null and "b/public/C:\\www\\api.extranetwork.com\\public\\/property-photos/2026/logo/1778057791_750x750.png" differ diff --git a/public/assets/css/bootstrap.css b/public/assets/css/bootstrap.css new file mode 100644 index 0000000..f918259 --- /dev/null +++ b/public/assets/css/bootstrap.css @@ -0,0 +1,8070 @@ +/*! + * Bootstrap v4.0.0-beta (https://getbootstrap.com) + * Copyright 2011-2017 The Bootstrap Authors + * Copyright 2011-2017 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +@media print { + *, + *::before, + *::after { + text-shadow: none !important; + box-shadow: none !important; + } + a:not(.btn) { + text-decoration: underline; + } + abbr[title]::after { + content: " (" attr(title) ")"; + } + pre { + white-space: pre-wrap !important; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + @page { + size: a3; + } + body { + min-width: 992px !important; + } + .container { + min-width: 992px !important; + } + .navbar { + display: none; + } + .badge { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; +} + +@-ms-viewport { + width: device-width; +} + +article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: 0 !important; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + text-decoration: underline; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -.25em; +} + +sup { + top: -.5em; +} + +a { + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +a:hover { + color: #0056b3; + text-decoration: underline; +} + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):focus { + outline: 0; +} + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +table { + border-collapse: collapse; +} + +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} + +th { + text-align: inherit; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button { + border-radius: 0; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + box-sizing: border-box; + padding: 0; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + outline-offset: -2px; + -webkit-appearance: none; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +summary { + display: list-item; + cursor: pointer; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: 0.5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.2; + color: inherit; +} + +h1, .h1 { + font-size: 2.5rem; +} + +h2, .h2 { + font-size: 2rem; +} + +h3, .h3 { + font-size: 1.75rem; +} + +h4, .h4 { + font-size: 1.5rem; +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2; +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2; +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); +} + +small, +.small { + font-size: 80%; + font-weight: 400; +} + +mark, +.mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} + +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} + +.blockquote-footer { + display: block; + font-size: 80%; + color: #6c757d; +} + +.blockquote-footer::before { + content: "\2014 \00A0"; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 90%; + color: #6c757d; +} + +code, +kbd, +pre, +samp { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +code { + font-size: 87.5%; + color: #e83e8c; + word-break: break-word; +} + +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 87.5%; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} + +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700; +} + +pre { + display: block; + font-size: 87.5%; + color: #212529; +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.row { + display: flex; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; +} + +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, +.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, +.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, +.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, +.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, +.col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; + max-width: none; +} + +.col-1 { + flex: 0 0 8.33333%; + max-width: 8.33333%; +} + +.col-2 { + flex: 0 0 16.66667%; + max-width: 16.66667%; +} + +.col-3 { + flex: 0 0 25%; + max-width: 25%; +} + +.col-4 { + flex: 0 0 33.33333%; + max-width: 33.33333%; +} + +.col-5 { + flex: 0 0 41.66667%; + max-width: 41.66667%; +} + +.col-6 { + flex: 0 0 50%; + max-width: 50%; +} + +.col-7 { + flex: 0 0 58.33333%; + max-width: 58.33333%; +} + +.col-8 { + flex: 0 0 66.66667%; + max-width: 66.66667%; +} + +.col-9 { + flex: 0 0 75%; + max-width: 75%; +} + +.col-10 { + flex: 0 0 83.33333%; + max-width: 83.33333%; +} + +.col-11 { + flex: 0 0 91.66667%; + max-width: 91.66667%; +} + +.col-12 { + flex: 0 0 100%; + max-width: 100%; +} + +.order-first { + order: -1; +} + +.order-last { + order: 13; +} + +.order-0 { + order: 0; +} + +.order-1 { + order: 1; +} + +.order-2 { + order: 2; +} + +.order-3 { + order: 3; +} + +.order-4 { + order: 4; +} + +.order-5 { + order: 5; +} + +.order-6 { + order: 6; +} + +.order-7 { + order: 7; +} + +.order-8 { + order: 8; +} + +.order-9 { + order: 9; +} + +.order-10 { + order: 10; +} + +.order-11 { + order: 11; +} + +.order-12 { + order: 12; +} + +.offset-1 { + margin-left: 8.33333%; +} + +.offset-2 { + margin-left: 16.66667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333%; +} + +.offset-5 { + margin-left: 41.66667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333%; +} + +.offset-8 { + margin-left: 66.66667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333%; +} + +.offset-11 { + margin-left: 91.66667%; +} + +@media (min-width: 576px) { + .col-sm { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-sm-1 { + flex: 0 0 8.33333%; + max-width: 8.33333%; + } + .col-sm-2 { + flex: 0 0 16.66667%; + max-width: 16.66667%; + } + .col-sm-3 { + flex: 0 0 25%; + max-width: 25%; + } + .col-sm-4 { + flex: 0 0 33.33333%; + max-width: 33.33333%; + } + .col-sm-5 { + flex: 0 0 41.66667%; + max-width: 41.66667%; + } + .col-sm-6 { + flex: 0 0 50%; + max-width: 50%; + } + .col-sm-7 { + flex: 0 0 58.33333%; + max-width: 58.33333%; + } + .col-sm-8 { + flex: 0 0 66.66667%; + max-width: 66.66667%; + } + .col-sm-9 { + flex: 0 0 75%; + max-width: 75%; + } + .col-sm-10 { + flex: 0 0 83.33333%; + max-width: 83.33333%; + } + .col-sm-11 { + flex: 0 0 91.66667%; + max-width: 91.66667%; + } + .col-sm-12 { + flex: 0 0 100%; + max-width: 100%; + } + .order-sm-first { + order: -1; + } + .order-sm-last { + order: 13; + } + .order-sm-0 { + order: 0; + } + .order-sm-1 { + order: 1; + } + .order-sm-2 { + order: 2; + } + .order-sm-3 { + order: 3; + } + .order-sm-4 { + order: 4; + } + .order-sm-5 { + order: 5; + } + .order-sm-6 { + order: 6; + } + .order-sm-7 { + order: 7; + } + .order-sm-8 { + order: 8; + } + .order-sm-9 { + order: 9; + } + .order-sm-10 { + order: 10; + } + .order-sm-11 { + order: 11; + } + .order-sm-12 { + order: 12; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.33333%; + } + .offset-sm-2 { + margin-left: 16.66667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.33333%; + } + .offset-sm-5 { + margin-left: 41.66667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.33333%; + } + .offset-sm-8 { + margin-left: 66.66667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.33333%; + } + .offset-sm-11 { + margin-left: 91.66667%; + } +} + +@media (min-width: 768px) { + .col-md { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-md-1 { + flex: 0 0 8.33333%; + max-width: 8.33333%; + } + .col-md-2 { + flex: 0 0 16.66667%; + max-width: 16.66667%; + } + .col-md-3 { + flex: 0 0 25%; + max-width: 25%; + } + .col-md-4 { + flex: 0 0 33.33333%; + max-width: 33.33333%; + } + .col-md-5 { + flex: 0 0 41.66667%; + max-width: 41.66667%; + } + .col-md-6 { + flex: 0 0 50%; + max-width: 50%; + } + .col-md-7 { + flex: 0 0 58.33333%; + max-width: 58.33333%; + } + .col-md-8 { + flex: 0 0 66.66667%; + max-width: 66.66667%; + } + .col-md-9 { + flex: 0 0 75%; + max-width: 75%; + } + .col-md-10 { + flex: 0 0 83.33333%; + max-width: 83.33333%; + } + .col-md-11 { + flex: 0 0 91.66667%; + max-width: 91.66667%; + } + .col-md-12 { + flex: 0 0 100%; + max-width: 100%; + } + .order-md-first { + order: -1; + } + .order-md-last { + order: 13; + } + .order-md-0 { + order: 0; + } + .order-md-1 { + order: 1; + } + .order-md-2 { + order: 2; + } + .order-md-3 { + order: 3; + } + .order-md-4 { + order: 4; + } + .order-md-5 { + order: 5; + } + .order-md-6 { + order: 6; + } + .order-md-7 { + order: 7; + } + .order-md-8 { + order: 8; + } + .order-md-9 { + order: 9; + } + .order-md-10 { + order: 10; + } + .order-md-11 { + order: 11; + } + .order-md-12 { + order: 12; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.33333%; + } + .offset-md-2 { + margin-left: 16.66667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.33333%; + } + .offset-md-5 { + margin-left: 41.66667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.33333%; + } + .offset-md-8 { + margin-left: 66.66667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.33333%; + } + .offset-md-11 { + margin-left: 91.66667%; + } +} + +@media (min-width: 992px) { + .col-lg { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-lg-1 { + flex: 0 0 8.33333%; + max-width: 8.33333%; + } + .col-lg-2 { + flex: 0 0 16.66667%; + max-width: 16.66667%; + } + .col-lg-3 { + flex: 0 0 25%; + max-width: 25%; + } + .col-lg-4 { + flex: 0 0 33.33333%; + max-width: 33.33333%; + } + .col-lg-5 { + flex: 0 0 41.66667%; + max-width: 41.66667%; + } + .col-lg-6 { + flex: 0 0 50%; + max-width: 50%; + } + .col-lg-7 { + flex: 0 0 58.33333%; + max-width: 58.33333%; + } + .col-lg-8 { + flex: 0 0 66.66667%; + max-width: 66.66667%; + } + .col-lg-9 { + flex: 0 0 75%; + max-width: 75%; + } + .col-lg-10 { + flex: 0 0 83.33333%; + max-width: 83.33333%; + } + .col-lg-11 { + flex: 0 0 91.66667%; + max-width: 91.66667%; + } + .col-lg-12 { + flex: 0 0 100%; + max-width: 100%; + } + .order-lg-first { + order: -1; + } + .order-lg-last { + order: 13; + } + .order-lg-0 { + order: 0; + } + .order-lg-1 { + order: 1; + } + .order-lg-2 { + order: 2; + } + .order-lg-3 { + order: 3; + } + .order-lg-4 { + order: 4; + } + .order-lg-5 { + order: 5; + } + .order-lg-6 { + order: 6; + } + .order-lg-7 { + order: 7; + } + .order-lg-8 { + order: 8; + } + .order-lg-9 { + order: 9; + } + .order-lg-10 { + order: 10; + } + .order-lg-11 { + order: 11; + } + .order-lg-12 { + order: 12; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.33333%; + } + .offset-lg-2 { + margin-left: 16.66667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.33333%; + } + .offset-lg-5 { + margin-left: 41.66667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.33333%; + } + .offset-lg-8 { + margin-left: 66.66667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.33333%; + } + .offset-lg-11 { + margin-left: 91.66667%; + } +} + +@media (min-width: 1200px) { + .col-xl { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-xl-1 { + flex: 0 0 8.33333%; + max-width: 8.33333%; + } + .col-xl-2 { + flex: 0 0 16.66667%; + max-width: 16.66667%; + } + .col-xl-3 { + flex: 0 0 25%; + max-width: 25%; + } + .col-xl-4 { + flex: 0 0 33.33333%; + max-width: 33.33333%; + } + .col-xl-5 { + flex: 0 0 41.66667%; + max-width: 41.66667%; + } + .col-xl-6 { + flex: 0 0 50%; + max-width: 50%; + } + .col-xl-7 { + flex: 0 0 58.33333%; + max-width: 58.33333%; + } + .col-xl-8 { + flex: 0 0 66.66667%; + max-width: 66.66667%; + } + .col-xl-9 { + flex: 0 0 75%; + max-width: 75%; + } + .col-xl-10 { + flex: 0 0 83.33333%; + max-width: 83.33333%; + } + .col-xl-11 { + flex: 0 0 91.66667%; + max-width: 91.66667%; + } + .col-xl-12 { + flex: 0 0 100%; + max-width: 100%; + } + .order-xl-first { + order: -1; + } + .order-xl-last { + order: 13; + } + .order-xl-0 { + order: 0; + } + .order-xl-1 { + order: 1; + } + .order-xl-2 { + order: 2; + } + .order-xl-3 { + order: 3; + } + .order-xl-4 { + order: 4; + } + .order-xl-5 { + order: 5; + } + .order-xl-6 { + order: 6; + } + .order-xl-7 { + order: 7; + } + .order-xl-8 { + order: 8; + } + .order-xl-9 { + order: 9; + } + .order-xl-10 { + order: 10; + } + .order-xl-11 { + order: 11; + } + .order-xl-12 { + order: 12; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.33333%; + } + .offset-xl-2 { + margin-left: 16.66667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.33333%; + } + .offset-xl-5 { + margin-left: 41.66667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.33333%; + } + .offset-xl-8 { + margin-left: 66.66667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.33333%; + } + .offset-xl-11 { + margin-left: 91.66667%; + } +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: transparent; +} + +.table th, +.table td { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} + +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} + +.table tbody + tbody { + border-top: 2px solid #dee2e6; +} + +.table .table { + background-color: #fff; +} + +.table-sm th, +.table-sm td { + padding: 0.3rem; +} + +.table-bordered { + border: 1px solid #dee2e6; +} + +.table-bordered th, +.table-bordered td { + border: 1px solid #dee2e6; +} + +.table-bordered thead th, +.table-bordered thead td { + border-bottom-width: 2px; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} + +.table-hover tbody tr:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-primary, +.table-primary > th, +.table-primary > td { + background-color: #b8daff; +} + +.table-hover .table-primary:hover { + background-color: #9fcdff; +} + +.table-hover .table-primary:hover > td, +.table-hover .table-primary:hover > th { + background-color: #9fcdff; +} + +.table-secondary, +.table-secondary > th, +.table-secondary > td { + background-color: #d6d8db; +} + +.table-hover .table-secondary:hover { + background-color: #c8cbcf; +} + +.table-hover .table-secondary:hover > td, +.table-hover .table-secondary:hover > th { + background-color: #c8cbcf; +} + +.table-success, +.table-success > th, +.table-success > td { + background-color: #c3e6cb; +} + +.table-hover .table-success:hover { + background-color: #b1dfbb; +} + +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #b1dfbb; +} + +.table-info, +.table-info > th, +.table-info > td { + background-color: #bee5eb; +} + +.table-hover .table-info:hover { + background-color: #abdde5; +} + +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #abdde5; +} + +.table-warning, +.table-warning > th, +.table-warning > td { + background-color: #ffeeba; +} + +.table-hover .table-warning:hover { + background-color: #ffe8a1; +} + +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #ffe8a1; +} + +.table-danger, +.table-danger > th, +.table-danger > td { + background-color: #f5c6cb; +} + +.table-hover .table-danger:hover { + background-color: #f1b0b7; +} + +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #f1b0b7; +} + +.table-light, +.table-light > th, +.table-light > td { + background-color: #fdfdfe; +} + +.table-hover .table-light:hover { + background-color: #ececf6; +} + +.table-hover .table-light:hover > td, +.table-hover .table-light:hover > th { + background-color: #ececf6; +} + +.table-dark, +.table-dark > th, +.table-dark > td { + background-color: #c6c8ca; +} + +.table-hover .table-dark:hover { + background-color: #b9bbbe; +} + +.table-hover .table-dark:hover > td, +.table-hover .table-dark:hover > th { + background-color: #b9bbbe; +} + +.table-active, +.table-active > th, +.table-active > td { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); +} + +.table .thead-dark th { + color: #fff; + background-color: #212529; + border-color: #32383e; +} + +.table .thead-light th { + color: #495057; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.table-dark { + color: #fff; + background-color: #212529; +} + +.table-dark th, +.table-dark td, +.table-dark thead th { + border-color: #32383e; +} + +.table-dark.table-bordered { + border: 0; +} + +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, 0.05); +} + +.table-dark.table-hover tbody tr:hover { + background-color: rgba(255, 255, 255, 0.075); +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-sm > .table-bordered { + border: 0; + } +} + +@media (max-width: 767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-md > .table-bordered { + border: 0; + } +} + +@media (max-width: 991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-lg > .table-bordered { + border: 0; + } +} + +@media (max-width: 1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-xl > .table-bordered { + border: 0; + } +} + +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; +} + +.table-responsive > .table-bordered { + border: 0; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} + +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} + +select.form-control:not([size]):not([multiple]) { + height: calc(2.25rem + 2px); +} + +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.form-control-file, +.form-control-range { + display: block; + width: 100%; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; + line-height: 1.5; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + margin-bottom: 0; + line-height: 1.5; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} + +.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control, +.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-prepend > .form-control-plaintext.btn, +.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control, +.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-prepend > .form-control-plaintext.btn, +.input-group-lg > .input-group-append > .form-control-plaintext.btn { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm, .input-group-sm > .form-control, +.input-group-sm > .input-group-prepend > .input-group-text, +.input-group-sm > .input-group-append > .input-group-text, +.input-group-sm > .input-group-prepend > .btn, +.input-group-sm > .input-group-append > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(1.8125rem + 2px); +} + +.form-control-lg, .input-group-lg > .form-control, +.input-group-lg > .input-group-prepend > .input-group-text, +.input-group-lg > .input-group-append > .input-group-text, +.input-group-lg > .input-group-prepend > .btn, +.input-group-lg > .input-group-append > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(2.875rem + 2px); +} + +.form-group { + margin-bottom: 1rem; +} + +.form-text { + display: block; + margin-top: 0.25rem; +} + +.form-row { + display: flex; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px; +} + +.form-row > .col, +.form-row > [class*="col-"] { + padding-right: 5px; + padding-left: 5px; +} + +.form-check { + position: relative; + display: block; + padding-left: 1.25rem; +} + +.form-check-input { + position: absolute; + margin-top: 0.3rem; + margin-left: -1.25rem; +} + +.form-check-input:disabled ~ .form-check-label { + color: #6c757d; +} + +.form-check-label { + margin-bottom: 0; +} + +.form-check-inline { + display: inline-flex; + align-items: center; + padding-left: 0; + margin-right: 0.75rem; +} + +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: 0.3125rem; + margin-left: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #28a745; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(40, 167, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:valid, .form-control.is-valid, .was-validated +.custom-select:valid, +.custom-select.is-valid { + border-color: #28a745; +} + +.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated +.custom-select:valid:focus, +.custom-select.is-valid:focus { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .form-control:valid ~ .valid-feedback, +.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, +.form-control.is-valid ~ .valid-tooltip, .was-validated +.custom-select:valid ~ .valid-feedback, +.was-validated +.custom-select:valid ~ .valid-tooltip, +.custom-select.is-valid ~ .valid-feedback, +.custom-select.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #28a745; +} + +.was-validated .form-check-input:valid ~ .valid-feedback, +.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, +.form-check-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { + color: #28a745; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { + background-color: #71dd8a; +} + +.was-validated .custom-control-input:valid ~ .valid-feedback, +.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback, +.custom-control-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { + background-color: #34ce57; +} + +.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { + border-color: #28a745; +} + +.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before { + border-color: inherit; +} + +.was-validated .custom-file-input:valid ~ .valid-feedback, +.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback, +.custom-file-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(220, 53, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated +.custom-select:invalid, +.custom-select.is-invalid { + border-color: #dc3545; +} + +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated +.custom-select:invalid:focus, +.custom-select.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .form-control:invalid ~ .invalid-feedback, +.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, +.form-control.is-invalid ~ .invalid-tooltip, .was-validated +.custom-select:invalid ~ .invalid-feedback, +.was-validated +.custom-select:invalid ~ .invalid-tooltip, +.custom-select.is-invalid ~ .invalid-feedback, +.custom-select.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} + +.was-validated .form-check-input:invalid ~ .invalid-feedback, +.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, +.form-check-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { + color: #dc3545; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { + background-color: #efa2a9; +} + +.was-validated .custom-control-input:invalid ~ .invalid-feedback, +.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback, +.custom-control-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { + background-color: #e4606d; +} + +.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { + border-color: #dc3545; +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before { + border-color: inherit; +} + +.was-validated .custom-file-input:invalid ~ .invalid-feedback, +.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback, +.custom-file-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.form-inline { + display: flex; + flex-flow: row wrap; + align-items: center; +} + +.form-inline .form-check { + width: 100%; +} + +@media (min-width: 576px) { + .form-inline label { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 0; + } + .form-inline .form-group { + display: flex; + flex: 0 0 auto; + flex-flow: row wrap; + align-items: center; + margin-bottom: 0; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-plaintext { + display: inline-block; + } + .form-inline .input-group { + width: auto; + } + .form-inline .form-check { + display: flex; + align-items: center; + justify-content: center; + width: auto; + padding-left: 0; + } + .form-inline .form-check-input { + position: relative; + margin-top: 0; + margin-right: 0.25rem; + margin-left: 0; + } + .form-inline .custom-control { + align-items: center; + justify-content: center; + } + .form-inline .custom-control-label { + margin-bottom: 0; + } +} + +.btn { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + user-select: none; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.btn:hover, .btn:focus { + text-decoration: none; +} + +.btn:focus, .btn.focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.btn.disabled, .btn:disabled { + opacity: 0.65; +} + +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active { + background-image: none; +} + +a.btn.disabled, +fieldset:disabled a.btn { + pointer-events: none; +} + +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-primary:hover { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; +} + +.btn-primary:focus, .btn-primary.focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, +.show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} + +.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, +.show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-secondary:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} + +.btn-secondary:focus, .btn-secondary.focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, +.show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #545b62; + border-color: #4e555b; +} + +.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, +.show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-success { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-success:hover { + color: #fff; + background-color: #218838; + border-color: #1e7e34; +} + +.btn-success:focus, .btn-success.focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, +.show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #1e7e34; + border-color: #1c7430; +} + +.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, +.show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-info { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-info:hover { + color: #fff; + background-color: #138496; + border-color: #117a8b; +} + +.btn-info:focus, .btn-info.focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-info.disabled, .btn-info:disabled { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, +.show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #117a8b; + border-color: #10707f; +} + +.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, +.show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-warning { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-warning:hover { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; +} + +.btn-warning:focus, .btn-warning.focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-warning.disabled, .btn-warning:disabled { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, +.show > .btn-warning.dropdown-toggle { + color: #212529; + background-color: #d39e00; + border-color: #c69500; +} + +.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, +.show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-danger:hover { + color: #fff; + background-color: #c82333; + border-color: #bd2130; +} + +.btn-danger:focus, .btn-danger.focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, +.show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #bd2130; + border-color: #b21f2d; +} + +.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, +.show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-light { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-light:hover { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; +} + +.btn-light:focus, .btn-light.focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-light.disabled, .btn-light:disabled { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, +.show > .btn-light.dropdown-toggle { + color: #212529; + background-color: #dae0e5; + border-color: #d3d9df; +} + +.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, +.show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-dark { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-dark:hover { + color: #fff; + background-color: #23272b; + border-color: #1d2124; +} + +.btn-dark:focus, .btn-dark.focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, +.show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1d2124; + border-color: #171a1d; +} + +.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, +.show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-primary { + color: #007bff; + background-color: transparent; + background-image: none; + border-color: #007bff; +} + +.btn-outline-primary:hover { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-outline-primary:focus, .btn-outline-primary.focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #007bff; + background-color: transparent; +} + +.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, +.show > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-secondary { + color: #6c757d; + background-color: transparent; + background-image: none; + border-color: #6c757d; +} + +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-outline-secondary:focus, .btn-outline-secondary.focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent; +} + +.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, +.show > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-success { + color: #28a745; + background-color: transparent; + background-image: none; + border-color: #28a745; +} + +.btn-outline-success:hover { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-outline-success:focus, .btn-outline-success.focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #28a745; + background-color: transparent; +} + +.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, +.show > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-info { + color: #17a2b8; + background-color: transparent; + background-image: none; + border-color: #17a2b8; +} + +.btn-outline-info:hover { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-outline-info:focus, .btn-outline-info.focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #17a2b8; + background-color: transparent; +} + +.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, +.show > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-warning { + color: #ffc107; + background-color: transparent; + background-image: none; + border-color: #ffc107; +} + +.btn-outline-warning:hover { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-outline-warning:focus, .btn-outline-warning.focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent; +} + +.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, +.show > .btn-outline-warning.dropdown-toggle { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-danger { + color: #dc3545; + background-color: transparent; + background-image: none; + border-color: #dc3545; +} + +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-outline-danger:focus, .btn-outline-danger.focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent; +} + +.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, +.show > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-light { + color: #f8f9fa; + background-color: transparent; + background-image: none; + border-color: #f8f9fa; +} + +.btn-outline-light:hover { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-outline-light:focus, .btn-outline-light.focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent; +} + +.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, +.show > .btn-outline-light.dropdown-toggle { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-dark { + color: #343a40; + background-color: transparent; + background-image: none; + border-color: #343a40; +} + +.btn-outline-dark:hover { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-outline-dark:focus, .btn-outline-dark.focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #343a40; + background-color: transparent; +} + +.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, +.show > .btn-outline-dark.dropdown-toggle { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-link { + font-weight: 400; + color: #007bff; + background-color: transparent; +} + +.btn-link:hover { + color: #0056b3; + text-decoration: underline; + background-color: transparent; + border-color: transparent; +} + +.btn-link:focus, .btn-link.focus { + text-decoration: underline; + border-color: transparent; + box-shadow: none; +} + +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +.btn-block { + display: block; + width: 100%; +} + +.btn-block + .btn-block { + margin-top: 0.5rem; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + transition: opacity 0.15s linear; +} + +.fade.show { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.show { + display: block; +} + +tr.collapse.show { + display: table-row; +} + +tbody.collapse.show { + display: table-row-group; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} + +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.dropup .dropdown-menu { + margin-top: 0; + margin-bottom: 0.125rem; +} + +.dropup .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-menu { + margin-top: 0; + margin-left: 0.125rem; +} + +.dropright .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} + +.dropright .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-toggle::after { + vertical-align: 0; +} + +.dropleft .dropdown-menu { + margin-top: 0; + margin-right: 0.125rem; +} + +.dropleft .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} + +.dropleft .dropdown-toggle::after { + display: none; +} + +.dropleft .dropdown-toggle::before { + display: inline-block; + width: 0; + height: 0; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} + +.dropleft .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropleft .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid #e9ecef; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} + +.dropdown-item:hover, .dropdown-item:focus { + color: #16181b; + text-decoration: none; + background-color: #f8f9fa; +} + +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #007bff; +} + +.dropdown-item.disabled, .dropdown-item:disabled { + color: #6c757d; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} + +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 0 1 auto; +} + +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover { + z-index: 1; +} + +.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group, +.btn-group-vertical .btn + .btn, +.btn-group-vertical .btn + .btn-group, +.btn-group-vertical .btn-group + .btn, +.btn-group-vertical .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} + +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} + +.dropdown-toggle-split::after { + margin-left: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} + +.btn-group-vertical .btn, +.btn-group-vertical .btn-group { + width: 100%; +} + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.btn-group-toggle > .btn, +.btn-group-toggle > .btn-group > .btn { + margin-bottom: 0; +} + +.btn-group-toggle > .btn input[type="radio"], +.btn-group-toggle > .btn input[type="checkbox"], +.btn-group-toggle > .btn-group > .btn input[type="radio"], +.btn-group-toggle > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100%; +} + +.input-group > .form-control, +.input-group > .custom-select, +.input-group > .custom-file { + position: relative; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} + +.input-group > .form-control:focus, +.input-group > .custom-select:focus, +.input-group > .custom-file:focus { + z-index: 3; +} + +.input-group > .form-control + .form-control, +.input-group > .form-control + .custom-select, +.input-group > .form-control + .custom-file, +.input-group > .custom-select + .form-control, +.input-group > .custom-select + .custom-select, +.input-group > .custom-select + .custom-file, +.input-group > .custom-file + .form-control, +.input-group > .custom-file + .custom-select, +.input-group > .custom-file + .custom-file { + margin-left: -1px; +} + +.input-group > .form-control:not(:last-child), +.input-group > .custom-select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .form-control:not(:first-child), +.input-group > .custom-select:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group > .custom-file { + display: flex; + align-items: center; +} + +.input-group > .custom-file:not(:last-child) .custom-file-label, +.input-group > .custom-file:not(:last-child) .custom-file-label::before { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .custom-file:not(:first-child) .custom-file-label, +.input-group > .custom-file:not(:first-child) .custom-file-label::before { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group-prepend, +.input-group-append { + display: flex; +} + +.input-group-prepend .btn, +.input-group-append .btn { + position: relative; + z-index: 2; +} + +.input-group-prepend .btn + .btn, +.input-group-prepend .btn + .input-group-text, +.input-group-prepend .input-group-text + .input-group-text, +.input-group-prepend .input-group-text + .btn, +.input-group-append .btn + .btn, +.input-group-append .btn + .input-group-text, +.input-group-append .input-group-text + .input-group-text, +.input-group-append .input-group-text + .btn { + margin-left: -1px; +} + +.input-group-prepend { + margin-right: -1px; +} + +.input-group-append { + margin-left: -1px; +} + +.input-group-text { + display: flex; + align-items: center; + padding: 0.375rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.input-group-text input[type="radio"], +.input-group-text input[type="checkbox"] { + margin-top: 0; +} + +.input-group > .input-group-prepend > .btn, +.input-group > .input-group-prepend > .input-group-text, +.input-group > .input-group-append:not(:last-child) > .btn, +.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .input-group-append > .btn, +.input-group > .input-group-append > .input-group-text, +.input-group > .input-group-prepend:not(:first-child) > .btn, +.input-group > .input-group-prepend:not(:first-child) > .input-group-text, +.input-group > .input-group-prepend:first-child > .btn:not(:first-child), +.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.custom-control { + position: relative; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem; +} + +.custom-control-inline { + display: inline-flex; + margin-right: 1rem; +} + +.custom-control-input { + position: absolute; + z-index: -1; + opacity: 0; +} + +.custom-control-input:checked ~ .custom-control-label::before { + color: #fff; + background-color: #007bff; +} + +.custom-control-input:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.custom-control-input:active ~ .custom-control-label::before { + color: #fff; + background-color: #b3d7ff; +} + +.custom-control-input:disabled ~ .custom-control-label { + color: #6c757d; +} + +.custom-control-input:disabled ~ .custom-control-label::before { + background-color: #e9ecef; +} + +.custom-control-label { + margin-bottom: 0; +} + +.custom-control-label::before { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + user-select: none; + background-color: #dee2e6; +} + +.custom-control-label::after { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; +} + +.custom-checkbox .custom-control-label::before { + border-radius: 0.25rem; +} + +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); +} + +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); +} + +.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-radio .custom-control-label::before { + border-radius: 50%; +} + +.custom-radio .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-radio .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); +} + +.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-select { + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; + background-size: 8px 10px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + appearance: none; +} + +.custom-select:focus { + border-color: #80bdff; + outline: 0; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); +} + +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.custom-select[multiple], .custom-select[size]:not([size="1"]) { + height: auto; + padding-right: 0.75rem; + background-image: none; +} + +.custom-select:disabled { + color: #6c757d; + background-color: #e9ecef; +} + +.custom-select::-ms-expand { + opacity: 0; +} + +.custom-select-sm { + height: calc(1.8125rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 75%; +} + +.custom-select-lg { + height: calc(2.875rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 125%; +} + +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + margin-bottom: 0; +} + +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(2.25rem + 2px); + margin: 0; + opacity: 0; +} + +.custom-file-input:focus ~ .custom-file-control { + border-color: #80bdff; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.custom-file-input:focus ~ .custom-file-control::before { + border-color: #80bdff; +} + +.custom-file-input:lang(en) ~ .custom-file-label::after { + content: "Browse"; +} + +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(2.25rem + 2px); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(calc(2.25rem + 2px) - 1px * 2); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + content: "Browse"; + background-color: #e9ecef; + border-left: 1px solid #ced4da; + border-radius: 0 0.25rem 0.25rem 0; +} + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; +} + +.nav-link:hover, .nav-link:focus { + text-decoration: none; +} + +.nav-link.disabled { + color: #6c757d; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} + +.nav-tabs .nav-item { + margin-bottom: -1px; +} + +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; +} + +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} + +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + border-radius: 0.25rem; +} + +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #007bff; +} + +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.tab-content > .tab-pane { + display: none; +} + +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; +} + +.navbar > .container, +.navbar > .container-fluid { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; +} + +.navbar-brand { + display: inline-block; + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap; +} + +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} + +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} + +.navbar-nav .dropdown-menu { + position: static; + float: none; +} + +.navbar-text { + display: inline-block; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.navbar-toggler:hover, .navbar-toggler:focus { + text-decoration: none; +} + +.navbar-toggler:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100%; +} + +@media (max-width: 575.98px) { + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-flow: row nowrap; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + flex-wrap: nowrap; + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 767.98px) { + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 768px) { + .navbar-expand-md { + flex-flow: row nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + flex-wrap: nowrap; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 991.98px) { + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 992px) { + .navbar-expand-lg { + flex-flow: row nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + flex-wrap: nowrap; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 1199.98px) { + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-flow: row nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + flex-wrap: nowrap; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +.navbar-expand { + flex-flow: row nowrap; + justify-content: flex-start; +} + +.navbar-expand > .container, +.navbar-expand > .container-fluid { + padding-right: 0; + padding-left: 0; +} + +.navbar-expand .navbar-nav { + flex-direction: row; +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} + +.navbar-expand .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} + +.navbar-expand > .container, +.navbar-expand > .container-fluid { + flex-wrap: nowrap; +} + +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} + +.navbar-expand .navbar-toggler { + display: none; +} + +.navbar-expand .dropup .dropdown-menu { + top: auto; + bottom: 100%; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.5); +} + +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} + +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} + +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .nav-link.show, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.1); +} + +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} + +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.5); +} + +.navbar-light .navbar-text a { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} + +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.5); +} + +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} + +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} + +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .nav-link.show, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} + +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.1); +} + +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} + +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.5); +} + +.navbar-dark .navbar-text a { + color: #fff; +} + +.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} + +.card > hr { + margin-right: 0; + margin-left: 0; +} + +.card > .list-group:first-child .list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.card > .list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.card-body { + flex: 1 1 auto; + padding: 1.25rem; +} + +.card-title { + margin-bottom: 0.75rem; +} + +.card-subtitle { + margin-top: -0.375rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} + +.card-link + .card-link { + margin-left: 1.25rem; +} + +.card-header { + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-header + .list-group .list-group-item:first-child { + border-top: 0; +} + +.card-footer { + padding: 0.75rem 1.25rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.625rem; + margin-left: -0.625rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + +.card-img { + width: 100%; + border-radius: calc(0.25rem - 1px); +} + +.card-img-top { + width: 100%; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img-bottom { + width: 100%; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-deck { + display: flex; + flex-direction: column; +} + +.card-deck .card { + margin-bottom: 15px; +} + +@media (min-width: 576px) { + .card-deck { + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px; + } + .card-deck .card { + display: flex; + flex: 1 0 0%; + flex-direction: column; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px; + } +} + +.card-group { + display: flex; + flex-direction: column; +} + +.card-group > .card { + margin-bottom: 15px; +} + +@media (min-width: 576px) { + .card-group { + flex-flow: row wrap; + } + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:first-child .card-img-top, + .card-group > .card:first-child .card-header { + border-top-right-radius: 0; + } + .card-group > .card:first-child .card-img-bottom, + .card-group > .card:first-child .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:last-child .card-img-top, + .card-group > .card:last-child .card-header { + border-top-left-radius: 0; + } + .card-group > .card:last-child .card-img-bottom, + .card-group > .card:last-child .card-footer { + border-bottom-left-radius: 0; + } + .card-group > .card:only-child { + border-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-top, + .card-group > .card:only-child .card-header { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-bottom, + .card-group > .card:only-child .card-footer { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { + border-radius: 0; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer { + border-radius: 0; + } +} + +.card-columns .card { + margin-bottom: 0.75rem; +} + +@media (min-width: 576px) { + .card-columns { + column-count: 3; + column-gap: 1.25rem; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + padding-left: 0.5rem; + color: #6c757d; + content: "/"; +} + +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; +} + +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; +} + +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination { + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} + +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} + +.page-link:hover { + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.page-link:focus { + z-index: 2; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.page-link:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} + +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5; +} + +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} + +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; +} + +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} + +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} + +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.badge-pill { + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; +} + +.badge-primary { + color: #fff; + background-color: #007bff; +} + +.badge-primary[href]:hover, .badge-primary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #0062cc; +} + +.badge-secondary { + color: #fff; + background-color: #6c757d; +} + +.badge-secondary[href]:hover, .badge-secondary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #545b62; +} + +.badge-success { + color: #fff; + background-color: #28a745; +} + +.badge-success[href]:hover, .badge-success[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1e7e34; +} + +.badge-info { + color: #fff; + background-color: #17a2b8; +} + +.badge-info[href]:hover, .badge-info[href]:focus { + color: #fff; + text-decoration: none; + background-color: #117a8b; +} + +.badge-warning { + color: #212529; + background-color: #ffc107; +} + +.badge-warning[href]:hover, .badge-warning[href]:focus { + color: #212529; + text-decoration: none; + background-color: #d39e00; +} + +.badge-danger { + color: #fff; + background-color: #dc3545; +} + +.badge-danger[href]:hover, .badge-danger[href]:focus { + color: #fff; + text-decoration: none; + background-color: #bd2130; +} + +.badge-light { + color: #212529; + background-color: #f8f9fa; +} + +.badge-light[href]:hover, .badge-light[href]:focus { + color: #212529; + text-decoration: none; + background-color: #dae0e5; +} + +.badge-dark { + color: #fff; + background-color: #343a40; +} + +.badge-dark[href]:hover, .badge-dark[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1d2124; +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #e9ecef; + border-radius: 0.3rem; +} + +@media (min-width: 576px) { + .jumbotron { + padding: 4rem 2rem; + } +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0; +} + +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 4rem; +} + +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; +} + +.alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} + +.alert-primary hr { + border-top-color: #9fcdff; +} + +.alert-primary .alert-link { + color: #002752; +} + +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; +} + +.alert-secondary hr { + border-top-color: #c8cbcf; +} + +.alert-secondary .alert-link { + color: #202326; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} + +.alert-success hr { + border-top-color: #b1dfbb; +} + +.alert-success .alert-link { + color: #0b2e13; +} + +.alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; +} + +.alert-info hr { + border-top-color: #abdde5; +} + +.alert-info .alert-link { + color: #062c33; +} + +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} + +.alert-warning hr { + border-top-color: #ffe8a1; +} + +.alert-warning .alert-link { + color: #533f03; +} + +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} + +.alert-danger hr { + border-top-color: #f1b0b7; +} + +.alert-danger .alert-link { + color: #491217; +} + +.alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; +} + +.alert-light hr { + border-top-color: #ececf6; +} + +.alert-light .alert-link { + color: #686868; +} + +.alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; +} + +.alert-dark hr { + border-top-color: #b9bbbe; +} + +.alert-dark .alert-link { + color: #040505; +} + +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + color: #fff; + text-align: center; + background-color: #007bff; + transition: width 0.6s ease; +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + animation: progress-bar-stripes 1s linear infinite; +} + +.media { + display: flex; + align-items: flex-start; +} + +.media-body { + flex: 1; +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} + +.list-group-item-action:hover, .list-group-item-action:focus { + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} + +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} + +.list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.list-group-item:hover, .list-group-item:focus { + z-index: 1; + text-decoration: none; +} + +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + background-color: #fff; +} + +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.list-group-flush .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} + +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0; +} + +.list-group-flush:last-child .list-group-item:last-child { + border-bottom: 0; +} + +.list-group-item-primary { + color: #004085; + background-color: #b8daff; +} + +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #004085; + background-color: #9fcdff; +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #004085; + border-color: #004085; +} + +.list-group-item-secondary { + color: #383d41; + background-color: #d6d8db; +} + +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #383d41; + background-color: #c8cbcf; +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #383d41; + border-color: #383d41; +} + +.list-group-item-success { + color: #155724; + background-color: #c3e6cb; +} + +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #155724; + background-color: #b1dfbb; +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #155724; + border-color: #155724; +} + +.list-group-item-info { + color: #0c5460; + background-color: #bee5eb; +} + +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #0c5460; + background-color: #abdde5; +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #0c5460; + border-color: #0c5460; +} + +.list-group-item-warning { + color: #856404; + background-color: #ffeeba; +} + +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #856404; + background-color: #ffe8a1; +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #856404; + border-color: #856404; +} + +.list-group-item-danger { + color: #721c24; + background-color: #f5c6cb; +} + +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #721c24; + background-color: #f1b0b7; +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #721c24; + border-color: #721c24; +} + +.list-group-item-light { + color: #818182; + background-color: #fdfdfe; +} + +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #818182; + background-color: #ececf6; +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #818182; + border-color: #818182; +} + +.list-group-item-dark { + color: #1b1e21; + background-color: #c6c8ca; +} + +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #1b1e21; + background-color: #b9bbbe; +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1e21; + border-color: #1b1e21; +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5; +} + +.close:hover, .close:focus { + color: #000; + text-decoration: none; + opacity: .75; +} + +.close:not(:disabled):not(.disabled) { + cursor: pointer; +} + +button.close { + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; +} + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} + +.modal.fade .modal-dialog { + transition: transform 0.3s ease-out; + transform: translate(0, -25%); +} + +.modal.show .modal-dialog { + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - (0.5rem * 2)); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + border-top-left-radius: 0.3rem; + border-top-right-radius: 0.3rem; +} + +.modal-header .close { + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #e9ecef; +} + +.modal-footer > :not(:first-child) { + margin-left: .25rem; +} + +.modal-footer > :not(:last-child) { + margin-right: .25rem; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + .modal-dialog-centered { + min-height: calc(100% - (1.75rem * 2)); + } + .modal-sm { + max-width: 300px; + } +} + +@media (min-width: 992px) { + .modal-lg { + max-width: 800px; + } +} + +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} + +.tooltip.show { + opacity: 0.9; +} + +.tooltip .arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} + +.tooltip .arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { + padding: 0.4rem 0; +} + +.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { + bottom: 0; +} + +.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before { + top: 0; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { + padding: 0 0.4rem; +} + +.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before { + right: 0; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { + padding: 0.4rem 0; +} + +.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { + top: 0; +} + +.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before { + bottom: 0; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { + padding: 0 0.4rem; +} + +.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before { + left: 0; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} + +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; + margin: 0 0.3rem; +} + +.popover .arrow::before, .popover .arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top, .bs-popover-auto[x-placement^="top"] { + margin-bottom: 0.5rem; +} + +.bs-popover-top .arrow, .bs-popover-auto[x-placement^="top"] .arrow { + bottom: calc((0.5rem + 1px) * -1); +} + +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before, +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + border-width: 0.5rem 0.5rem 0; +} + +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before { + bottom: 0; + border-top-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + bottom: 1px; + border-top-color: #fff; +} + +.bs-popover-right, .bs-popover-auto[x-placement^="right"] { + margin-left: 0.5rem; +} + +.bs-popover-right .arrow, .bs-popover-auto[x-placement^="right"] .arrow { + left: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} + +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before, +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + border-width: 0.5rem 0.5rem 0.5rem 0; +} + +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before { + left: 0; + border-right-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + left: 1px; + border-right-color: #fff; +} + +.bs-popover-bottom, .bs-popover-auto[x-placement^="bottom"] { + margin-top: 0.5rem; +} + +.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^="bottom"] .arrow { + top: calc((0.5rem + 1px) * -1); +} + +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before, +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + border-width: 0 0.5rem 0.5rem 0.5rem; +} + +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before { + top: 0; + border-bottom-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + top: 1px; + border-bottom-color: #fff; +} + +.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f7f7f7; +} + +.bs-popover-left, .bs-popover-auto[x-placement^="left"] { + margin-right: 0.5rem; +} + +.bs-popover-left .arrow, .bs-popover-auto[x-placement^="left"] .arrow { + right: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} + +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before, +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + border-width: 0.5rem 0 0.5rem 0.5rem; +} + +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before { + right: 0; + border-left-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + right: 1px; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + color: inherit; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} + +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 0.5rem 0.75rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-item { + position: relative; + display: none; + align-items: center; + width: 100%; + transition: transform 0.6s ease; + backface-visibility: hidden; + perspective: 1000px; +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} + +.carousel-item-next.carousel-item-left, +.carousel-item-prev.carousel-item-right { + transform: translateX(0); +} + +@supports (transform-style: preserve-3d) { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + transform: translate3d(0, 0, 0); + } +} + +.carousel-item-next, +.active.carousel-item-right { + transform: translateX(100%); +} + +@supports (transform-style: preserve-3d) { + .carousel-item-next, + .active.carousel-item-right { + transform: translate3d(100%, 0, 0); + } +} + +.carousel-item-prev, +.active.carousel-item-left { + transform: translateX(-100%); +} + +@supports (transform-style: preserve-3d) { + .carousel-item-prev, + .active.carousel-item-left { + transform: translate3d(-100%, 0, 0); + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: 0.5; +} + +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 20px; + height: 20px; + background: transparent no-repeat center center; + background-size: 100% 100%; +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 10px; + left: 0; + z-index: 15; + display: flex; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} + +.carousel-indicators li { + position: relative; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + background-color: rgba(255, 255, 255, 0.5); +} + +.carousel-indicators li::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} + +.carousel-indicators li::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.bg-primary { + background-color: #007bff !important; +} + +a.bg-primary:hover, a.bg-primary:focus, +button.bg-primary:hover, +button.bg-primary:focus { + background-color: #0062cc !important; +} + +.bg-secondary { + background-color: #6c757d !important; +} + +a.bg-secondary:hover, a.bg-secondary:focus, +button.bg-secondary:hover, +button.bg-secondary:focus { + background-color: #545b62 !important; +} + +.bg-success { + background-color: #28a745 !important; +} + +a.bg-success:hover, a.bg-success:focus, +button.bg-success:hover, +button.bg-success:focus { + background-color: #1e7e34 !important; +} + +.bg-info { + background-color: #17a2b8 !important; +} + +a.bg-info:hover, a.bg-info:focus, +button.bg-info:hover, +button.bg-info:focus { + background-color: #117a8b !important; +} + +.bg-warning { + background-color: #ffc107 !important; +} + +a.bg-warning:hover, a.bg-warning:focus, +button.bg-warning:hover, +button.bg-warning:focus { + background-color: #d39e00 !important; +} + +.bg-danger { + background-color: #dc3545 !important; +} + +a.bg-danger:hover, a.bg-danger:focus, +button.bg-danger:hover, +button.bg-danger:focus { + background-color: #bd2130 !important; +} + +.bg-light { + background-color: #f8f9fa !important; +} + +a.bg-light:hover, a.bg-light:focus, +button.bg-light:hover, +button.bg-light:focus { + background-color: #dae0e5 !important; +} + +.bg-dark { + background-color: #343a40 !important; +} + +a.bg-dark:hover, a.bg-dark:focus, +button.bg-dark:hover, +button.bg-dark:focus { + background-color: #1d2124 !important; +} + +.bg-white { + background-color: #fff !important; +} + +.bg-transparent { + background-color: transparent !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-right { + border-right: 1px solid #dee2e6 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-left { + border-left: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-right-0 { + border-right: 0 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-left-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #007bff !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #28a745 !important; +} + +.border-info { + border-color: #17a2b8 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #343a40 !important; +} + +.border-white { + border-color: #fff !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-right { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-left { + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: flex !important; + } + .d-sm-inline-flex { + display: inline-flex !important; + } +} + +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: flex !important; + } + .d-md-inline-flex { + display: inline-flex !important; + } +} + +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: flex !important; + } + .d-lg-inline-flex { + display: inline-flex !important; + } +} + +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: flex !important; + } + .d-xl-inline-flex { + display: inline-flex !important; + } +} + +@media print { + .d-print-none { + display: none !important; + } + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: flex !important; + } + .d-print-inline-flex { + display: inline-flex !important; + } +} + +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; +} + +.embed-responsive::before { + display: block; + content: ""; +} + +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.embed-responsive-21by9::before { + padding-top: 42.85714%; +} + +.embed-responsive-16by9::before { + padding-top: 56.25%; +} + +.embed-responsive-4by3::before { + padding-top: 75%; +} + +.embed-responsive-1by1::before { + padding-top: 100%; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +@media (min-width: 576px) { + .flex-sm-row { + flex-direction: row !important; + } + .flex-sm-column { + flex-direction: column !important; + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + .flex-sm-wrap { + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + justify-content: flex-start !important; + } + .justify-content-sm-end { + justify-content: flex-end !important; + } + .justify-content-sm-center { + justify-content: center !important; + } + .justify-content-sm-between { + justify-content: space-between !important; + } + .justify-content-sm-around { + justify-content: space-around !important; + } + .align-items-sm-start { + align-items: flex-start !important; + } + .align-items-sm-end { + align-items: flex-end !important; + } + .align-items-sm-center { + align-items: center !important; + } + .align-items-sm-baseline { + align-items: baseline !important; + } + .align-items-sm-stretch { + align-items: stretch !important; + } + .align-content-sm-start { + align-content: flex-start !important; + } + .align-content-sm-end { + align-content: flex-end !important; + } + .align-content-sm-center { + align-content: center !important; + } + .align-content-sm-between { + align-content: space-between !important; + } + .align-content-sm-around { + align-content: space-around !important; + } + .align-content-sm-stretch { + align-content: stretch !important; + } + .align-self-sm-auto { + align-self: auto !important; + } + .align-self-sm-start { + align-self: flex-start !important; + } + .align-self-sm-end { + align-self: flex-end !important; + } + .align-self-sm-center { + align-self: center !important; + } + .align-self-sm-baseline { + align-self: baseline !important; + } + .align-self-sm-stretch { + align-self: stretch !important; + } +} + +@media (min-width: 768px) { + .flex-md-row { + flex-direction: row !important; + } + .flex-md-column { + flex-direction: column !important; + } + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + .flex-md-wrap { + flex-wrap: wrap !important; + } + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + justify-content: flex-start !important; + } + .justify-content-md-end { + justify-content: flex-end !important; + } + .justify-content-md-center { + justify-content: center !important; + } + .justify-content-md-between { + justify-content: space-between !important; + } + .justify-content-md-around { + justify-content: space-around !important; + } + .align-items-md-start { + align-items: flex-start !important; + } + .align-items-md-end { + align-items: flex-end !important; + } + .align-items-md-center { + align-items: center !important; + } + .align-items-md-baseline { + align-items: baseline !important; + } + .align-items-md-stretch { + align-items: stretch !important; + } + .align-content-md-start { + align-content: flex-start !important; + } + .align-content-md-end { + align-content: flex-end !important; + } + .align-content-md-center { + align-content: center !important; + } + .align-content-md-between { + align-content: space-between !important; + } + .align-content-md-around { + align-content: space-around !important; + } + .align-content-md-stretch { + align-content: stretch !important; + } + .align-self-md-auto { + align-self: auto !important; + } + .align-self-md-start { + align-self: flex-start !important; + } + .align-self-md-end { + align-self: flex-end !important; + } + .align-self-md-center { + align-self: center !important; + } + .align-self-md-baseline { + align-self: baseline !important; + } + .align-self-md-stretch { + align-self: stretch !important; + } +} + +@media (min-width: 992px) { + .flex-lg-row { + flex-direction: row !important; + } + .flex-lg-column { + flex-direction: column !important; + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + .flex-lg-wrap { + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + justify-content: flex-start !important; + } + .justify-content-lg-end { + justify-content: flex-end !important; + } + .justify-content-lg-center { + justify-content: center !important; + } + .justify-content-lg-between { + justify-content: space-between !important; + } + .justify-content-lg-around { + justify-content: space-around !important; + } + .align-items-lg-start { + align-items: flex-start !important; + } + .align-items-lg-end { + align-items: flex-end !important; + } + .align-items-lg-center { + align-items: center !important; + } + .align-items-lg-baseline { + align-items: baseline !important; + } + .align-items-lg-stretch { + align-items: stretch !important; + } + .align-content-lg-start { + align-content: flex-start !important; + } + .align-content-lg-end { + align-content: flex-end !important; + } + .align-content-lg-center { + align-content: center !important; + } + .align-content-lg-between { + align-content: space-between !important; + } + .align-content-lg-around { + align-content: space-around !important; + } + .align-content-lg-stretch { + align-content: stretch !important; + } + .align-self-lg-auto { + align-self: auto !important; + } + .align-self-lg-start { + align-self: flex-start !important; + } + .align-self-lg-end { + align-self: flex-end !important; + } + .align-self-lg-center { + align-self: center !important; + } + .align-self-lg-baseline { + align-self: baseline !important; + } + .align-self-lg-stretch { + align-self: stretch !important; + } +} + +@media (min-width: 1200px) { + .flex-xl-row { + flex-direction: row !important; + } + .flex-xl-column { + flex-direction: column !important; + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xl-wrap { + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + justify-content: flex-start !important; + } + .justify-content-xl-end { + justify-content: flex-end !important; + } + .justify-content-xl-center { + justify-content: center !important; + } + .justify-content-xl-between { + justify-content: space-between !important; + } + .justify-content-xl-around { + justify-content: space-around !important; + } + .align-items-xl-start { + align-items: flex-start !important; + } + .align-items-xl-end { + align-items: flex-end !important; + } + .align-items-xl-center { + align-items: center !important; + } + .align-items-xl-baseline { + align-items: baseline !important; + } + .align-items-xl-stretch { + align-items: stretch !important; + } + .align-content-xl-start { + align-content: flex-start !important; + } + .align-content-xl-end { + align-content: flex-end !important; + } + .align-content-xl-center { + align-content: center !important; + } + .align-content-xl-between { + align-content: space-between !important; + } + .align-content-xl-around { + align-content: space-around !important; + } + .align-content-xl-stretch { + align-content: stretch !important; + } + .align-self-xl-auto { + align-self: auto !important; + } + .align-self-xl-start { + align-self: flex-start !important; + } + .align-self-xl-end { + align-self: flex-end !important; + } + .align-self-xl-center { + align-self: center !important; + } + .align-self-xl-baseline { + align-self: baseline !important; + } + .align-self-xl-stretch { + align-self: stretch !important; + } +} + +.float-left { + float: left !important; +} + +.float-right { + float: right !important; +} + +.float-none { + float: none !important; +} + +@media (min-width: 576px) { + .float-sm-left { + float: left !important; + } + .float-sm-right { + float: right !important; + } + .float-sm-none { + float: none !important; + } +} + +@media (min-width: 768px) { + .float-md-left { + float: left !important; + } + .float-md-right { + float: right !important; + } + .float-md-none { + float: none !important; + } +} + +@media (min-width: 992px) { + .float-lg-left { + float: left !important; + } + .float-lg-right { + float: right !important; + } + .float-lg-none { + float: none !important; + } +} + +@media (min-width: 1200px) { + .float-xl-left { + float: left !important; + } + .float-xl-right { + float: right !important; + } + .float-xl-none { + float: none !important; + } +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: sticky !important; +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +@supports (position: sticky) { + .sticky-top { + position: sticky; + top: 0; + z-index: 1020; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + clip-path: inset(50%); + border: 0; +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + clip-path: none; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.m-0 { + margin: 0 !important; +} + +.mt-0, +.my-0 { + margin-top: 0 !important; +} + +.mr-0, +.mx-0 { + margin-right: 0 !important; +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} + +.ml-0, +.mx-0 { + margin-left: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.mt-1, +.my-1 { + margin-top: 0.25rem !important; +} + +.mr-1, +.mx-1 { + margin-right: 0.25rem !important; +} + +.mb-1, +.my-1 { + margin-bottom: 0.25rem !important; +} + +.ml-1, +.mx-1 { + margin-left: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.mt-2, +.my-2 { + margin-top: 0.5rem !important; +} + +.mr-2, +.mx-2 { + margin-right: 0.5rem !important; +} + +.mb-2, +.my-2 { + margin-bottom: 0.5rem !important; +} + +.ml-2, +.mx-2 { + margin-left: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.mt-3, +.my-3 { + margin-top: 1rem !important; +} + +.mr-3, +.mx-3 { + margin-right: 1rem !important; +} + +.mb-3, +.my-3 { + margin-bottom: 1rem !important; +} + +.ml-3, +.mx-3 { + margin-left: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.mt-4, +.my-4 { + margin-top: 1.5rem !important; +} + +.mr-4, +.mx-4 { + margin-right: 1.5rem !important; +} + +.mb-4, +.my-4 { + margin-bottom: 1.5rem !important; +} + +.ml-4, +.mx-4 { + margin-left: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.mt-5, +.my-5 { + margin-top: 3rem !important; +} + +.mr-5, +.mx-5 { + margin-right: 3rem !important; +} + +.mb-5, +.my-5 { + margin-bottom: 3rem !important; +} + +.ml-5, +.mx-5 { + margin-left: 3rem !important; +} + +.p-0 { + padding: 0 !important; +} + +.pt-0, +.py-0 { + padding-top: 0 !important; +} + +.pr-0, +.px-0 { + padding-right: 0 !important; +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} + +.pl-0, +.px-0 { + padding-left: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.pt-1, +.py-1 { + padding-top: 0.25rem !important; +} + +.pr-1, +.px-1 { + padding-right: 0.25rem !important; +} + +.pb-1, +.py-1 { + padding-bottom: 0.25rem !important; +} + +.pl-1, +.px-1 { + padding-left: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.pt-2, +.py-2 { + padding-top: 0.5rem !important; +} + +.pr-2, +.px-2 { + padding-right: 0.5rem !important; +} + +.pb-2, +.py-2 { + padding-bottom: 0.5rem !important; +} + +.pl-2, +.px-2 { + padding-left: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.pt-3, +.py-3 { + padding-top: 1rem !important; +} + +.pr-3, +.px-3 { + padding-right: 1rem !important; +} + +.pb-3, +.py-3 { + padding-bottom: 1rem !important; +} + +.pl-3, +.px-3 { + padding-left: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.pt-4, +.py-4 { + padding-top: 1.5rem !important; +} + +.pr-4, +.px-4 { + padding-right: 1.5rem !important; +} + +.pb-4, +.py-4 { + padding-bottom: 1.5rem !important; +} + +.pl-4, +.px-4 { + padding-left: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.pt-5, +.py-5 { + padding-top: 3rem !important; +} + +.pr-5, +.px-5 { + padding-right: 3rem !important; +} + +.pb-5, +.py-5 { + padding-bottom: 3rem !important; +} + +.pl-5, +.px-5 { + padding-left: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mt-auto, +.my-auto { + margin-top: auto !important; +} + +.mr-auto, +.mx-auto { + margin-right: auto !important; +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} + +.ml-auto, +.mx-auto { + margin-left: auto !important; +} + +@media (min-width: 576px) { + .m-sm-0 { + margin: 0 !important; + } + .mt-sm-0, + .my-sm-0 { + margin-top: 0 !important; + } + .mr-sm-0, + .mx-sm-0 { + margin-right: 0 !important; + } + .mb-sm-0, + .my-sm-0 { + margin-bottom: 0 !important; + } + .ml-sm-0, + .mx-sm-0 { + margin-left: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .mt-sm-1, + .my-sm-1 { + margin-top: 0.25rem !important; + } + .mr-sm-1, + .mx-sm-1 { + margin-right: 0.25rem !important; + } + .mb-sm-1, + .my-sm-1 { + margin-bottom: 0.25rem !important; + } + .ml-sm-1, + .mx-sm-1 { + margin-left: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .mt-sm-2, + .my-sm-2 { + margin-top: 0.5rem !important; + } + .mr-sm-2, + .mx-sm-2 { + margin-right: 0.5rem !important; + } + .mb-sm-2, + .my-sm-2 { + margin-bottom: 0.5rem !important; + } + .ml-sm-2, + .mx-sm-2 { + margin-left: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .mt-sm-3, + .my-sm-3 { + margin-top: 1rem !important; + } + .mr-sm-3, + .mx-sm-3 { + margin-right: 1rem !important; + } + .mb-sm-3, + .my-sm-3 { + margin-bottom: 1rem !important; + } + .ml-sm-3, + .mx-sm-3 { + margin-left: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .mt-sm-4, + .my-sm-4 { + margin-top: 1.5rem !important; + } + .mr-sm-4, + .mx-sm-4 { + margin-right: 1.5rem !important; + } + .mb-sm-4, + .my-sm-4 { + margin-bottom: 1.5rem !important; + } + .ml-sm-4, + .mx-sm-4 { + margin-left: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .mt-sm-5, + .my-sm-5 { + margin-top: 3rem !important; + } + .mr-sm-5, + .mx-sm-5 { + margin-right: 3rem !important; + } + .mb-sm-5, + .my-sm-5 { + margin-bottom: 3rem !important; + } + .ml-sm-5, + .mx-sm-5 { + margin-left: 3rem !important; + } + .p-sm-0 { + padding: 0 !important; + } + .pt-sm-0, + .py-sm-0 { + padding-top: 0 !important; + } + .pr-sm-0, + .px-sm-0 { + padding-right: 0 !important; + } + .pb-sm-0, + .py-sm-0 { + padding-bottom: 0 !important; + } + .pl-sm-0, + .px-sm-0 { + padding-left: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .pt-sm-1, + .py-sm-1 { + padding-top: 0.25rem !important; + } + .pr-sm-1, + .px-sm-1 { + padding-right: 0.25rem !important; + } + .pb-sm-1, + .py-sm-1 { + padding-bottom: 0.25rem !important; + } + .pl-sm-1, + .px-sm-1 { + padding-left: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .pt-sm-2, + .py-sm-2 { + padding-top: 0.5rem !important; + } + .pr-sm-2, + .px-sm-2 { + padding-right: 0.5rem !important; + } + .pb-sm-2, + .py-sm-2 { + padding-bottom: 0.5rem !important; + } + .pl-sm-2, + .px-sm-2 { + padding-left: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .pt-sm-3, + .py-sm-3 { + padding-top: 1rem !important; + } + .pr-sm-3, + .px-sm-3 { + padding-right: 1rem !important; + } + .pb-sm-3, + .py-sm-3 { + padding-bottom: 1rem !important; + } + .pl-sm-3, + .px-sm-3 { + padding-left: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .pt-sm-4, + .py-sm-4 { + padding-top: 1.5rem !important; + } + .pr-sm-4, + .px-sm-4 { + padding-right: 1.5rem !important; + } + .pb-sm-4, + .py-sm-4 { + padding-bottom: 1.5rem !important; + } + .pl-sm-4, + .px-sm-4 { + padding-left: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .pt-sm-5, + .py-sm-5 { + padding-top: 3rem !important; + } + .pr-sm-5, + .px-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-5, + .py-sm-5 { + padding-bottom: 3rem !important; + } + .pl-sm-5, + .px-sm-5 { + padding-left: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mt-sm-auto, + .my-sm-auto { + margin-top: auto !important; + } + .mr-sm-auto, + .mx-sm-auto { + margin-right: auto !important; + } + .mb-sm-auto, + .my-sm-auto { + margin-bottom: auto !important; + } + .ml-sm-auto, + .mx-sm-auto { + margin-left: auto !important; + } +} + +@media (min-width: 768px) { + .m-md-0 { + margin: 0 !important; + } + .mt-md-0, + .my-md-0 { + margin-top: 0 !important; + } + .mr-md-0, + .mx-md-0 { + margin-right: 0 !important; + } + .mb-md-0, + .my-md-0 { + margin-bottom: 0 !important; + } + .ml-md-0, + .mx-md-0 { + margin-left: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .mt-md-1, + .my-md-1 { + margin-top: 0.25rem !important; + } + .mr-md-1, + .mx-md-1 { + margin-right: 0.25rem !important; + } + .mb-md-1, + .my-md-1 { + margin-bottom: 0.25rem !important; + } + .ml-md-1, + .mx-md-1 { + margin-left: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .mt-md-2, + .my-md-2 { + margin-top: 0.5rem !important; + } + .mr-md-2, + .mx-md-2 { + margin-right: 0.5rem !important; + } + .mb-md-2, + .my-md-2 { + margin-bottom: 0.5rem !important; + } + .ml-md-2, + .mx-md-2 { + margin-left: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .mt-md-3, + .my-md-3 { + margin-top: 1rem !important; + } + .mr-md-3, + .mx-md-3 { + margin-right: 1rem !important; + } + .mb-md-3, + .my-md-3 { + margin-bottom: 1rem !important; + } + .ml-md-3, + .mx-md-3 { + margin-left: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .mt-md-4, + .my-md-4 { + margin-top: 1.5rem !important; + } + .mr-md-4, + .mx-md-4 { + margin-right: 1.5rem !important; + } + .mb-md-4, + .my-md-4 { + margin-bottom: 1.5rem !important; + } + .ml-md-4, + .mx-md-4 { + margin-left: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .mt-md-5, + .my-md-5 { + margin-top: 3rem !important; + } + .mr-md-5, + .mx-md-5 { + margin-right: 3rem !important; + } + .mb-md-5, + .my-md-5 { + margin-bottom: 3rem !important; + } + .ml-md-5, + .mx-md-5 { + margin-left: 3rem !important; + } + .p-md-0 { + padding: 0 !important; + } + .pt-md-0, + .py-md-0 { + padding-top: 0 !important; + } + .pr-md-0, + .px-md-0 { + padding-right: 0 !important; + } + .pb-md-0, + .py-md-0 { + padding-bottom: 0 !important; + } + .pl-md-0, + .px-md-0 { + padding-left: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .pt-md-1, + .py-md-1 { + padding-top: 0.25rem !important; + } + .pr-md-1, + .px-md-1 { + padding-right: 0.25rem !important; + } + .pb-md-1, + .py-md-1 { + padding-bottom: 0.25rem !important; + } + .pl-md-1, + .px-md-1 { + padding-left: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .pt-md-2, + .py-md-2 { + padding-top: 0.5rem !important; + } + .pr-md-2, + .px-md-2 { + padding-right: 0.5rem !important; + } + .pb-md-2, + .py-md-2 { + padding-bottom: 0.5rem !important; + } + .pl-md-2, + .px-md-2 { + padding-left: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .pt-md-3, + .py-md-3 { + padding-top: 1rem !important; + } + .pr-md-3, + .px-md-3 { + padding-right: 1rem !important; + } + .pb-md-3, + .py-md-3 { + padding-bottom: 1rem !important; + } + .pl-md-3, + .px-md-3 { + padding-left: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .pt-md-4, + .py-md-4 { + padding-top: 1.5rem !important; + } + .pr-md-4, + .px-md-4 { + padding-right: 1.5rem !important; + } + .pb-md-4, + .py-md-4 { + padding-bottom: 1.5rem !important; + } + .pl-md-4, + .px-md-4 { + padding-left: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .pt-md-5, + .py-md-5 { + padding-top: 3rem !important; + } + .pr-md-5, + .px-md-5 { + padding-right: 3rem !important; + } + .pb-md-5, + .py-md-5 { + padding-bottom: 3rem !important; + } + .pl-md-5, + .px-md-5 { + padding-left: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mt-md-auto, + .my-md-auto { + margin-top: auto !important; + } + .mr-md-auto, + .mx-md-auto { + margin-right: auto !important; + } + .mb-md-auto, + .my-md-auto { + margin-bottom: auto !important; + } + .ml-md-auto, + .mx-md-auto { + margin-left: auto !important; + } +} + +@media (min-width: 992px) { + .m-lg-0 { + margin: 0 !important; + } + .mt-lg-0, + .my-lg-0 { + margin-top: 0 !important; + } + .mr-lg-0, + .mx-lg-0 { + margin-right: 0 !important; + } + .mb-lg-0, + .my-lg-0 { + margin-bottom: 0 !important; + } + .ml-lg-0, + .mx-lg-0 { + margin-left: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .mt-lg-1, + .my-lg-1 { + margin-top: 0.25rem !important; + } + .mr-lg-1, + .mx-lg-1 { + margin-right: 0.25rem !important; + } + .mb-lg-1, + .my-lg-1 { + margin-bottom: 0.25rem !important; + } + .ml-lg-1, + .mx-lg-1 { + margin-left: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .mt-lg-2, + .my-lg-2 { + margin-top: 0.5rem !important; + } + .mr-lg-2, + .mx-lg-2 { + margin-right: 0.5rem !important; + } + .mb-lg-2, + .my-lg-2 { + margin-bottom: 0.5rem !important; + } + .ml-lg-2, + .mx-lg-2 { + margin-left: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .mt-lg-3, + .my-lg-3 { + margin-top: 1rem !important; + } + .mr-lg-3, + .mx-lg-3 { + margin-right: 1rem !important; + } + .mb-lg-3, + .my-lg-3 { + margin-bottom: 1rem !important; + } + .ml-lg-3, + .mx-lg-3 { + margin-left: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .mt-lg-4, + .my-lg-4 { + margin-top: 1.5rem !important; + } + .mr-lg-4, + .mx-lg-4 { + margin-right: 1.5rem !important; + } + .mb-lg-4, + .my-lg-4 { + margin-bottom: 1.5rem !important; + } + .ml-lg-4, + .mx-lg-4 { + margin-left: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .mt-lg-5, + .my-lg-5 { + margin-top: 3rem !important; + } + .mr-lg-5, + .mx-lg-5 { + margin-right: 3rem !important; + } + .mb-lg-5, + .my-lg-5 { + margin-bottom: 3rem !important; + } + .ml-lg-5, + .mx-lg-5 { + margin-left: 3rem !important; + } + .p-lg-0 { + padding: 0 !important; + } + .pt-lg-0, + .py-lg-0 { + padding-top: 0 !important; + } + .pr-lg-0, + .px-lg-0 { + padding-right: 0 !important; + } + .pb-lg-0, + .py-lg-0 { + padding-bottom: 0 !important; + } + .pl-lg-0, + .px-lg-0 { + padding-left: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .pt-lg-1, + .py-lg-1 { + padding-top: 0.25rem !important; + } + .pr-lg-1, + .px-lg-1 { + padding-right: 0.25rem !important; + } + .pb-lg-1, + .py-lg-1 { + padding-bottom: 0.25rem !important; + } + .pl-lg-1, + .px-lg-1 { + padding-left: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .pt-lg-2, + .py-lg-2 { + padding-top: 0.5rem !important; + } + .pr-lg-2, + .px-lg-2 { + padding-right: 0.5rem !important; + } + .pb-lg-2, + .py-lg-2 { + padding-bottom: 0.5rem !important; + } + .pl-lg-2, + .px-lg-2 { + padding-left: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .pt-lg-3, + .py-lg-3 { + padding-top: 1rem !important; + } + .pr-lg-3, + .px-lg-3 { + padding-right: 1rem !important; + } + .pb-lg-3, + .py-lg-3 { + padding-bottom: 1rem !important; + } + .pl-lg-3, + .px-lg-3 { + padding-left: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .pt-lg-4, + .py-lg-4 { + padding-top: 1.5rem !important; + } + .pr-lg-4, + .px-lg-4 { + padding-right: 1.5rem !important; + } + .pb-lg-4, + .py-lg-4 { + padding-bottom: 1.5rem !important; + } + .pl-lg-4, + .px-lg-4 { + padding-left: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .pt-lg-5, + .py-lg-5 { + padding-top: 3rem !important; + } + .pr-lg-5, + .px-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-5, + .py-lg-5 { + padding-bottom: 3rem !important; + } + .pl-lg-5, + .px-lg-5 { + padding-left: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mt-lg-auto, + .my-lg-auto { + margin-top: auto !important; + } + .mr-lg-auto, + .mx-lg-auto { + margin-right: auto !important; + } + .mb-lg-auto, + .my-lg-auto { + margin-bottom: auto !important; + } + .ml-lg-auto, + .mx-lg-auto { + margin-left: auto !important; + } +} + +@media (min-width: 1200px) { + .m-xl-0 { + margin: 0 !important; + } + .mt-xl-0, + .my-xl-0 { + margin-top: 0 !important; + } + .mr-xl-0, + .mx-xl-0 { + margin-right: 0 !important; + } + .mb-xl-0, + .my-xl-0 { + margin-bottom: 0 !important; + } + .ml-xl-0, + .mx-xl-0 { + margin-left: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .mt-xl-1, + .my-xl-1 { + margin-top: 0.25rem !important; + } + .mr-xl-1, + .mx-xl-1 { + margin-right: 0.25rem !important; + } + .mb-xl-1, + .my-xl-1 { + margin-bottom: 0.25rem !important; + } + .ml-xl-1, + .mx-xl-1 { + margin-left: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .mt-xl-2, + .my-xl-2 { + margin-top: 0.5rem !important; + } + .mr-xl-2, + .mx-xl-2 { + margin-right: 0.5rem !important; + } + .mb-xl-2, + .my-xl-2 { + margin-bottom: 0.5rem !important; + } + .ml-xl-2, + .mx-xl-2 { + margin-left: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .mt-xl-3, + .my-xl-3 { + margin-top: 1rem !important; + } + .mr-xl-3, + .mx-xl-3 { + margin-right: 1rem !important; + } + .mb-xl-3, + .my-xl-3 { + margin-bottom: 1rem !important; + } + .ml-xl-3, + .mx-xl-3 { + margin-left: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .mt-xl-4, + .my-xl-4 { + margin-top: 1.5rem !important; + } + .mr-xl-4, + .mx-xl-4 { + margin-right: 1.5rem !important; + } + .mb-xl-4, + .my-xl-4 { + margin-bottom: 1.5rem !important; + } + .ml-xl-4, + .mx-xl-4 { + margin-left: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .mt-xl-5, + .my-xl-5 { + margin-top: 3rem !important; + } + .mr-xl-5, + .mx-xl-5 { + margin-right: 3rem !important; + } + .mb-xl-5, + .my-xl-5 { + margin-bottom: 3rem !important; + } + .ml-xl-5, + .mx-xl-5 { + margin-left: 3rem !important; + } + .p-xl-0 { + padding: 0 !important; + } + .pt-xl-0, + .py-xl-0 { + padding-top: 0 !important; + } + .pr-xl-0, + .px-xl-0 { + padding-right: 0 !important; + } + .pb-xl-0, + .py-xl-0 { + padding-bottom: 0 !important; + } + .pl-xl-0, + .px-xl-0 { + padding-left: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .pt-xl-1, + .py-xl-1 { + padding-top: 0.25rem !important; + } + .pr-xl-1, + .px-xl-1 { + padding-right: 0.25rem !important; + } + .pb-xl-1, + .py-xl-1 { + padding-bottom: 0.25rem !important; + } + .pl-xl-1, + .px-xl-1 { + padding-left: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .pt-xl-2, + .py-xl-2 { + padding-top: 0.5rem !important; + } + .pr-xl-2, + .px-xl-2 { + padding-right: 0.5rem !important; + } + .pb-xl-2, + .py-xl-2 { + padding-bottom: 0.5rem !important; + } + .pl-xl-2, + .px-xl-2 { + padding-left: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .pt-xl-3, + .py-xl-3 { + padding-top: 1rem !important; + } + .pr-xl-3, + .px-xl-3 { + padding-right: 1rem !important; + } + .pb-xl-3, + .py-xl-3 { + padding-bottom: 1rem !important; + } + .pl-xl-3, + .px-xl-3 { + padding-left: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .pt-xl-4, + .py-xl-4 { + padding-top: 1.5rem !important; + } + .pr-xl-4, + .px-xl-4 { + padding-right: 1.5rem !important; + } + .pb-xl-4, + .py-xl-4 { + padding-bottom: 1.5rem !important; + } + .pl-xl-4, + .px-xl-4 { + padding-left: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .pt-xl-5, + .py-xl-5 { + padding-top: 3rem !important; + } + .pr-xl-5, + .px-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-5, + .py-xl-5 { + padding-bottom: 3rem !important; + } + .pl-xl-5, + .px-xl-5 { + padding-left: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mt-xl-auto, + .my-xl-auto { + margin-top: auto !important; + } + .mr-xl-auto, + .mx-xl-auto { + margin-right: auto !important; + } + .mb-xl-auto, + .my-xl-auto { + margin-bottom: auto !important; + } + .ml-xl-auto, + .mx-xl-auto { + margin-left: auto !important; + } +} + +.text-justify { + text-align: justify !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +@media (min-width: 576px) { + .text-sm-left { + text-align: left !important; + } + .text-sm-right { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} + +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + .text-md-right { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} + +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + .text-lg-right { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} + +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + .text-xl-right { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.font-weight-light { + font-weight: 300 !important; +} + +.font-weight-normal { + font-weight: 400 !important; +} + +.font-weight-bold { + font-weight: 700 !important; +} + +.font-italic { + font-style: italic !important; +} + +.text-white { + color: #fff !important; +} + +.text-primary { + color: #007bff !important; +} + +a.text-primary:hover, a.text-primary:focus { + color: #0062cc !important; +} + +.text-secondary { + color: #6c757d !important; +} + +a.text-secondary:hover, a.text-secondary:focus { + color: #545b62 !important; +} + +.text-success { + color: #28a745 !important; +} + +a.text-success:hover, a.text-success:focus { + color: #1e7e34 !important; +} + +.text-info { + color: #17a2b8 !important; +} + +a.text-info:hover, a.text-info:focus { + color: #117a8b !important; +} + +.text-warning { + color: #ffc107 !important; +} + +a.text-warning:hover, a.text-warning:focus { + color: #d39e00 !important; +} + +.text-danger { + color: #dc3545 !important; +} + +a.text-danger:hover, a.text-danger:focus { + color: #bd2130 !important; +} + +.text-light { + color: #f8f9fa !important; +} + +a.text-light:hover, a.text-light:focus { + color: #dae0e5 !important; +} + +.text-dark { + color: #343a40 !important; +} + +a.text-dark:hover, a.text-dark:focus { + color: #1d2124 !important; +} + +.text-muted { + color: #6c757d !important; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} diff --git a/public/assets/css/load.css b/public/assets/css/load.css new file mode 100644 index 0000000..c5afa85 --- /dev/null +++ b/public/assets/css/load.css @@ -0,0 +1,25 @@ +.load__icon { + animation: linear load 2s infinite; + width: 32px; + height: 32px; +} + +.load__icon-wrap { + margin: auto; +} + +.load { + height: calc(100vh - 16px); + width: 100%; + display: flex; + align-items: center; +} + +@keyframes load { + from { + transform: rotate(0deg) scale(2); + } + to { + transform: rotate(360deg) scale(2); + } +} \ No newline at end of file diff --git a/public/assets/fav.ico b/public/assets/fav.ico new file mode 100644 index 0000000..dc9cde6 Binary files /dev/null and b/public/assets/fav.ico differ diff --git a/public/assets/favicon.ico b/public/assets/favicon.ico new file mode 100644 index 0000000..a11777c Binary files /dev/null and b/public/assets/favicon.ico differ diff --git a/public/assets/img/banner/shape/shape-1.png b/public/assets/img/banner/shape/shape-1.png new file mode 100644 index 0000000..0adb550 Binary files /dev/null and b/public/assets/img/banner/shape/shape-1.png differ diff --git a/public/assets/img/banner/shape/shape-2.png b/public/assets/img/banner/shape/shape-2.png new file mode 100644 index 0000000..f95caba Binary files /dev/null and b/public/assets/img/banner/shape/shape-2.png differ diff --git a/public/assets/img/banner/shape/shape-3.png b/public/assets/img/banner/shape/shape-3.png new file mode 100644 index 0000000..c168245 Binary files /dev/null and b/public/assets/img/banner/shape/shape-3.png differ diff --git a/public/assets/img/banner/shape/shape-4.png b/public/assets/img/banner/shape/shape-4.png new file mode 100644 index 0000000..d63d8f0 Binary files /dev/null and b/public/assets/img/banner/shape/shape-4.png differ diff --git a/public/assets/img/banner/shape/shape-4_tmp19510 b/public/assets/img/banner/shape/shape-4_tmp19510 new file mode 100644 index 0000000..513e431 Binary files /dev/null and b/public/assets/img/banner/shape/shape-4_tmp19510 differ diff --git a/public/assets/img/logo-white.png b/public/assets/img/logo-white.png new file mode 100644 index 0000000..0acdcad Binary files /dev/null and b/public/assets/img/logo-white.png differ diff --git a/public/assets/img/logo.svg b/public/assets/img/logo.svg new file mode 100644 index 0000000..b2b30da --- /dev/null +++ b/public/assets/img/logo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/img/main-image.png b/public/assets/img/main-image.png new file mode 100644 index 0000000..81b36be Binary files /dev/null and b/public/assets/img/main-image.png differ diff --git a/public/assets/js/config.js b/public/assets/js/config.js new file mode 100644 index 0000000..90ae9b4 --- /dev/null +++ b/public/assets/js/config.js @@ -0,0 +1,93 @@ +"use strict"; +// Wiresphere config file +// Do not delete anything from this file! + +var WiresphereConfig = { + Background: { + SolidBg: { + Color: '#463760' // Solid background color + }, + + Picture: { + Enabled: true, // Background picture true/false + Opacity: '0.07' // Background picture opacity + }, + + Gradient: { + Enabled: true, // Background animated gradient true/false + StopAColor : '88,139,148', // Background animated gradient Stop A + StopBColor : '112,53,93', // Background animated gradient Stop B + Opacity : 0.4 // Background animated gradient opacity + }, + + + Sphere3D: { + lineColor: 0xffffff, // Color of sphere outline + lineOpacity: 0.5, // Opacity of front face of sphere + backlineOpacity: 0.05, // Opacity of backface of sphere + particleColor: 0xffffff, // Color of particles + particleOpacity: 0.5, // Opacity of particles + particleSize: 5, // Size of particles + particlesAmmount: 750, // Ammount of particles + moveSpeed: 0.07, // Speed of particles + cameraXMoveMax: 1.5, // Mouse movement max rotation + cameraYMoveMax: 0.75, // Mouse movement max rotation + cameraXMoveElastic: 0.02, // Mouse movement smoothness + cameraYMoveElastic: 0.02 // Mouse movement smoothness + }, + + Noise: { + Enabled: true, // Background noise true/false + Opacity: '0.05' // Background noise opacity + } + + }, + + Colors: { + JSOverride: true, // Set to false if you want to tweak CSS + + Tagline: { // Tagline + FirstLine: '#00e0ce', // Color of first line of tagline + SecondLine: '#ffffff' // Color of second line of tagline + }, + + Buttons: { // Buttons + Outline: '#00e0ce', // Color of buttons outline + Text: '#ffffff', // Color of buttons text + TextHover: '#ffffff' // Color of buttons text on hover + }, + + SideContent: { // Side content + Background: '#111111', // Background of side content + Text: '#ffffff', // Text color of side content + ContactIcons: '#333333', // Color of contact icons + } + + }, + + Map: { + Longtitude: -73.946, // X Map location + Latitude: 40.674, // X Map location + Style: [ // X Map style - refer to Google Maps for more details + { + "stylers": [ + { "saturation": -100 }, + { "lightness": -62 }, + { "gamma": 0.47 } + ] + },{ + "elementType": "labels.text", + "stylers": [ + { "color": "#ffffff" }, + { "visibility": "simplified" } + ] + },{ + "elementType": "labels.icon", + "stylers": [ + { "gamma": 2.17 } + ] + } + ] + } + +} \ No newline at end of file diff --git a/public/assets/js/jquery-2.2.4.min.js b/public/assets/js/jquery-2.2.4.min.js new file mode 100644 index 0000000..1b4ad81 --- /dev/null +++ b/public/assets/js/jquery-2.2.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; +}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("