Compare commits
10 commits
73e38a006e
...
e3dc1afd8e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3dc1afd8e | ||
| 389d5d1820 | |||
| 8fd1f4d451 | |||
|
|
4eb83def39 | ||
|
|
881fc84207 | ||
|
|
c1c613a4b9 | ||
|
|
561c5875a7 | ||
|
|
93d1bea8e3 | ||
|
|
34a3d2196b | ||
|
|
3df0e93c2c |
902 changed files with 149174 additions and 22174 deletions
73
.env
73
.env
|
|
@ -6,38 +6,55 @@ APP_URL=https://mein.sterntours.test
|
|||
APP_OLD_URL=https://cms-stern-tours.test
|
||||
|
||||
#APP_URL_V2=https://v2.stern-tours.de
|
||||
APP_URL_V2=https://v2-sterntours.test
|
||||
APP_URL_V2=https://v2.sterntours.test
|
||||
|
||||
#APP_URL_STERN=https://www.sterntours.de
|
||||
APP_URL_STERN=https://sterntours.test
|
||||
|
||||
APP_DOMAIN_TLD=test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=192.168.1.8
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=cmssso_db1
|
||||
DB_USERNAME=kadmin
|
||||
DB_PASSWORD=KT32vQ7ix
|
||||
SUCCESS_KEY=f6077389c9ce710e554763a5de02c8ec
|
||||
|
||||
DB_CONNECTION_STERN=mysql
|
||||
DB_HOST_STERN=192.168.1.8
|
||||
# Standard Database Connection
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=global-mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=stern_crm
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=password
|
||||
|
||||
# STERN Database Connection
|
||||
DB_HOST_STERN=global-mysql
|
||||
DB_PORT_STERN=3306
|
||||
DB_DATABASE_STERN=relaunch1
|
||||
DB_USERNAME_STERN=kadmin
|
||||
DB_PASSWORD_STERN=KT32vQ7ix
|
||||
DB_DATABASE_STERN=stern_db
|
||||
DB_USERNAME_STERN=root
|
||||
DB_PASSWORD_STERN=password
|
||||
|
||||
# Docker Port Forwards
|
||||
FORWARD_DB_PORT=33064
|
||||
FORWARD_DB_PORT_STERN=33065
|
||||
FORWARD_REDIS_PORT=6379
|
||||
MYSQL_EXTRA_OPTIONS=
|
||||
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
# Vite Port for Development
|
||||
VITE_PORT=5173
|
||||
# Sail Configuration
|
||||
WWWGROUP=1000
|
||||
WWWUSER=1000
|
||||
SAIL_XDEBUG_MODE=off
|
||||
|
||||
MAIL_BBC=kevin@adametz.media
|
||||
MAIL_FEWO_EMPLOYEE=kevin@adametz.media
|
||||
|
|
@ -45,18 +62,32 @@ MAIL_FEWO_EMPLOYEE=kevin@adametz.media
|
|||
#MAIL_BBC=kontakt@stern-tours.de,thomas.stern@stern-tours.de
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_FROM_NAME="Reisebüro STERN TOURS"
|
||||
MAIL_FROM_NAME="DEV Reisebüro STERN TOURS"
|
||||
#MAIL_FROM_ADDRESS=dev@adametz.media
|
||||
#MAIL_HOST=w017e534.kasserver.com
|
||||
#MAIL_PORT=587
|
||||
#MAIL_USERNAME=m0496c96
|
||||
#MAIL_PASSWORD=mZtVp7WQcs6DC3hf
|
||||
#MAIL_ENCRYPTION=null
|
||||
|
||||
|
||||
MAIL_FROM_ADDRESS=stern@sterntours.de
|
||||
MAIL_HOST=zimbra.managedemail.de
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=stern@stern-tours.de
|
||||
MAIL_PASSWORD=13C!NlecB!Phil4beAxKl
|
||||
MAIL_ENCRYPTION=TLS
|
||||
|
||||
|
||||
#MAIL_FROM_ADDRESS=stern@sterntours.de
|
||||
#MAIL_HOST=zimbra.managedemail.de
|
||||
#MAIL_USERNAME=stern@stern-tours.de
|
||||
#MAIL_PASSWORD=13C!NlecB!Phil4beAxKl
|
||||
MAIL_PORT=587
|
||||
MAIL_ENCRYPTION=TLS
|
||||
|
||||
MAIL_FROM_ADDRESS=info@mein.sterntours.de
|
||||
MAIL_HOST=mail.your-server.de
|
||||
MAIL_USERNAME=info@mein.sterntours.de
|
||||
MAIL_PASSWORD=B7f8Ojt98v6tMz8W
|
||||
#MAIL_FROM_ADDRESS=info@mein.sterntours.de
|
||||
#MAIL_HOST=mail.your-server.de
|
||||
#MAIL_USERNAME=info@mein.sterntours.de
|
||||
#MAIL_PASSWORD=B7f8Ojt98v6tMz8W
|
||||
|
||||
#MAIL_FROM_ADDRESS=stern@stern-tours.de
|
||||
#MAIL_HOST=zimbra.managedemail.de
|
||||
|
|
|
|||
15
.gitignore
vendored
15
.gitignore
vendored
|
|
@ -25,11 +25,24 @@ Icon
|
|||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
.idea/
|
||||
.claude/
|
||||
.cursor/
|
||||
.cursorrules/
|
||||
.cursorrules.md/
|
||||
.cursorrules.md.txt/
|
||||
.cursorrules.md.txt.txt/
|
||||
.cursorrules.md.txt.txt.txt/
|
||||
|
||||
/vendor
|
||||
/node_modules
|
||||
/storage/app
|
||||
/storage/language
|
||||
/storage/framework
|
||||
/storage/logs
|
||||
/public/vendor
|
||||
.idea
|
||||
.idea/
|
||||
.vscode/
|
||||
_static/
|
||||
_work/
|
||||
_storage/
|
||||
|
|
|
|||
27
.mcp.json
Normal file
27
.mcp.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"laravel-boost": {
|
||||
"command": "php",
|
||||
"args": [
|
||||
"artisan",
|
||||
"boost:mcp"
|
||||
]
|
||||
},
|
||||
"context7": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@upstash/context7-mcp",
|
||||
"--api-key",
|
||||
"ctx7sk-119cd4ab-8983-4229-8702-e84c59c34fc9"
|
||||
]
|
||||
},
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
3533
.phpstorm.meta.php
3533
.phpstorm.meta.php
File diff suppressed because it is too large
Load diff
181
CLAUDE.md
Normal file
181
CLAUDE.md
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<laravel-boost-guidelines>
|
||||
=== foundation rules ===
|
||||
|
||||
# Laravel Boost Guidelines
|
||||
|
||||
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
|
||||
|
||||
## Foundational Context
|
||||
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
|
||||
|
||||
- php - 8.3.30
|
||||
- laravel/framework (LARAVEL) - v10
|
||||
- laravel/passport (PASSPORT) - v11
|
||||
- laravel/prompts (PROMPTS) - v0
|
||||
- laravel/mcp (MCP) - v0
|
||||
- laravel/sail (SAIL) - v1
|
||||
- phpunit/phpunit (PHPUNIT) - v10
|
||||
|
||||
## Conventions
|
||||
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
|
||||
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
|
||||
- Check for existing components to reuse before writing a new one.
|
||||
|
||||
## Verification Scripts
|
||||
- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important.
|
||||
|
||||
## Application Structure & Architecture
|
||||
- Stick to existing directory structure; don't create new base folders without approval.
|
||||
- Do not change the application's dependencies without approval.
|
||||
|
||||
## Frontend Bundling
|
||||
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
|
||||
|
||||
## Replies
|
||||
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
|
||||
|
||||
## Documentation Files
|
||||
- You must only create documentation files if explicitly requested by the user.
|
||||
|
||||
=== boost rules ===
|
||||
|
||||
## Laravel Boost
|
||||
- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
|
||||
|
||||
## Artisan
|
||||
- Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters.
|
||||
|
||||
## URLs
|
||||
- Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port.
|
||||
|
||||
## Tinker / Debugging
|
||||
- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
|
||||
- Use the `database-query` tool when you only need to read from the database.
|
||||
|
||||
## Reading Browser Logs With the `browser-logs` Tool
|
||||
- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
|
||||
- Only recent browser logs will be useful - ignore old logs.
|
||||
|
||||
## Searching Documentation (Critically Important)
|
||||
- Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.
|
||||
- The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
|
||||
- You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches.
|
||||
- Search the documentation before making code changes to ensure we are taking the correct approach.
|
||||
- Use multiple, broad, simple, topic-based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
|
||||
- Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
|
||||
|
||||
### Available Search Syntax
|
||||
- You can and should pass multiple queries at once. The most relevant results will be returned first.
|
||||
|
||||
1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'.
|
||||
2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit".
|
||||
3. Quoted Phrases (Exact Position) - query="infinite scroll" - words must be adjacent and in that order.
|
||||
4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit".
|
||||
5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms.
|
||||
|
||||
=== php rules ===
|
||||
|
||||
## PHP
|
||||
|
||||
- Always use curly braces for control structures, even if it has one line.
|
||||
|
||||
### Constructors
|
||||
- Use PHP 8 constructor property promotion in `__construct()`.
|
||||
- <code-snippet>public function __construct(public GitHub $github) { }</code-snippet>
|
||||
- Do not allow empty `__construct()` methods with zero parameters unless the constructor is private.
|
||||
|
||||
### Type Declarations
|
||||
- Always use explicit return type declarations for methods and functions.
|
||||
- Use appropriate PHP type hints for method parameters.
|
||||
|
||||
<code-snippet name="Explicit Return Types and Method Params" lang="php">
|
||||
protected function isAccessible(User $user, ?string $path = null): bool
|
||||
{
|
||||
...
|
||||
}
|
||||
</code-snippet>
|
||||
|
||||
## Comments
|
||||
- Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on.
|
||||
|
||||
## PHPDoc Blocks
|
||||
- Add useful array shape type definitions for arrays when appropriate.
|
||||
|
||||
## Enums
|
||||
- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
|
||||
|
||||
=== laravel/core rules ===
|
||||
|
||||
## Do Things the Laravel Way
|
||||
|
||||
- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool.
|
||||
- If you're creating a generic PHP class, use `php artisan make:class`.
|
||||
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
|
||||
|
||||
### Database
|
||||
- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins.
|
||||
- Use Eloquent models and relationships before suggesting raw database queries.
|
||||
- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
|
||||
- Generate code that prevents N+1 query problems by using eager loading.
|
||||
- Use Laravel's query builder for very complex database operations.
|
||||
|
||||
### Model Creation
|
||||
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
|
||||
|
||||
### APIs & Eloquent Resources
|
||||
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
|
||||
|
||||
### Controllers & Validation
|
||||
- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages.
|
||||
- Check sibling Form Requests to see if the application uses array or string based validation rules.
|
||||
|
||||
### Queues
|
||||
- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
|
||||
|
||||
### Authentication & Authorization
|
||||
- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
|
||||
|
||||
### URL Generation
|
||||
- When generating links to other pages, prefer named routes and the `route()` function.
|
||||
|
||||
### Configuration
|
||||
- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
|
||||
|
||||
### Testing
|
||||
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
|
||||
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
|
||||
- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
|
||||
|
||||
### Vite Error
|
||||
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
|
||||
|
||||
=== laravel/v10 rules ===
|
||||
|
||||
## Laravel 10
|
||||
|
||||
- Use the `search-docs` tool to get version-specific documentation.
|
||||
- Middleware typically live in `app/Http/Middleware/` and service providers in `app/Providers/`.
|
||||
- Laravel 10 has a `bootstrap/app.php` file that creates the application instance and binds kernel contracts, but does not use it for application configuration like Laravel 11:
|
||||
- Middleware registration is in `app/Http/Kernel.php`
|
||||
- Exception handling is in `app/Exceptions/Handler.php`
|
||||
- Console commands and schedule registration is in `app/Console/Kernel.php`
|
||||
- Rate limits likely exist in `RouteServiceProvider` or `app/Http/Kernel.php`
|
||||
- When using Eloquent model casts, you must use `protected $casts = [];` and not the `casts()` method. The `casts()` method isn't available on models in Laravel 10.
|
||||
|
||||
=== phpunit/core rules ===
|
||||
|
||||
## PHPUnit
|
||||
|
||||
- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `php artisan make:test --phpunit {name}` to create a new test.
|
||||
- If you see a test using "Pest", convert it to PHPUnit.
|
||||
- Every time a test has been updated, run that singular test.
|
||||
- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
|
||||
- Tests should test all of the happy paths, failure paths, and weird paths.
|
||||
- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files; these are core to the application.
|
||||
|
||||
### Running Tests
|
||||
- Run the minimal number of tests, using an appropriate filter, before finalizing.
|
||||
- To run all tests: `php artisan test --compact`.
|
||||
- To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`.
|
||||
- To filter on a particular test name: `php artisan test --compact --filter=testName` (recommended after making a change to a related file).
|
||||
</laravel-boost-guidelines>
|
||||
455
INIT.md
Normal file
455
INIT.md
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
# Sterntours Laravel Projekt - Initialisierung & Setup
|
||||
|
||||
Diese Dokumentation beschreibt die Initialisierung und Einrichtung des Sterntours Laravel-Projekts.
|
||||
|
||||
## 📋 Inhaltsverzeichnis
|
||||
|
||||
1. [Voraussetzungen](#voraussetzungen)
|
||||
2. [Schnellstart](#schnellstart)
|
||||
3. [Manuelle Installation](#manuelle-installation)
|
||||
4. [Projekt-Struktur](#projekt-struktur)
|
||||
5. [Umgebungskonfiguration](#umgebungskonfiguration)
|
||||
6. [Datenbanken](#datenbanken)
|
||||
7. [Domains & Routing](#domains--routing)
|
||||
8. [Häufige Befehle](#häufige-befehle)
|
||||
9. [Fehlerbehebung](#fehlerbehebung)
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
Bevor du das Projekt initialisierst, stelle sicher, dass folgende Software installiert ist:
|
||||
|
||||
- **Docker Desktop** (Version 20.10+)
|
||||
- [Download für macOS](https://www.docker.com/products/docker-desktop)
|
||||
- [Download für Windows](https://www.docker.com/products/docker-desktop)
|
||||
- [Download für Linux](https://docs.docker.com/engine/install/)
|
||||
|
||||
- **Composer** (Version 2.0+)
|
||||
- [Installation Guide](https://getcomposer.org/download/)
|
||||
|
||||
- **Node.js & NPM** (Version 16+ empfohlen)
|
||||
- [Download](https://nodejs.org/)
|
||||
|
||||
- **Git** (für Versionskontrolle)
|
||||
- [Download](https://git-scm.com/)
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart
|
||||
|
||||
Das Projekt kann mit einem einzigen Befehl initialisiert werden:
|
||||
|
||||
```bash
|
||||
bash init.sh
|
||||
```
|
||||
|
||||
Das Script führt automatisch alle notwendigen Schritte aus:
|
||||
|
||||
1. ✓ Prüft Docker-Installation
|
||||
2. ✓ Erstellt `.env` Datei
|
||||
3. ✓ Installiert Composer-Dependencies
|
||||
4. ✓ Installiert NPM-Dependencies
|
||||
5. ✓ Generiert Application Key
|
||||
6. ✓ Erstellt Docker-Netzwerke
|
||||
7. ✓ Startet Docker-Container
|
||||
8. ✓ Führt Datenbank-Migrationen aus
|
||||
9. ✓ Erstellt Storage-Links
|
||||
10. ✓ Optimiert die Application
|
||||
|
||||
---
|
||||
|
||||
## Manuelle Installation
|
||||
|
||||
Falls du das Projekt manuell einrichten möchtest:
|
||||
|
||||
### 1. Repository klonen
|
||||
|
||||
```bash
|
||||
git clone <repository-url> sterntours
|
||||
cd sterntours
|
||||
```
|
||||
|
||||
### 2. Umgebungsvariablen konfigurieren
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Bearbeite die `.env` Datei nach Bedarf (siehe [Umgebungskonfiguration](#umgebungskonfiguration)).
|
||||
|
||||
### 3. Dependencies installieren
|
||||
|
||||
```bash
|
||||
# Composer Dependencies
|
||||
composer install
|
||||
|
||||
# NPM Dependencies
|
||||
npm install
|
||||
```
|
||||
|
||||
### 4. Application Key generieren
|
||||
|
||||
```bash
|
||||
php artisan key:generate
|
||||
```
|
||||
|
||||
### 5. Docker Proxy-Netzwerk erstellen
|
||||
|
||||
```bash
|
||||
docker network create proxy
|
||||
```
|
||||
|
||||
### 6. Docker Container starten (Laravel Sail)
|
||||
|
||||
```bash
|
||||
./vendor/bin/sail up -d
|
||||
```
|
||||
|
||||
### 7. Datenbank migrieren
|
||||
|
||||
```bash
|
||||
./vendor/bin/sail artisan migrate
|
||||
```
|
||||
|
||||
### 8. Storage Links erstellen
|
||||
|
||||
```bash
|
||||
./vendor/bin/sail artisan storage:link
|
||||
```
|
||||
|
||||
### 9. Cache optimieren
|
||||
|
||||
```bash
|
||||
./vendor/bin/sail artisan config:cache
|
||||
./vendor/bin/sail artisan route:cache
|
||||
./vendor/bin/sail artisan view:cache
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Projekt-Struktur
|
||||
|
||||
```
|
||||
sterntours/
|
||||
├── app/ # Application Code
|
||||
│ ├── Console/ # Artisan Commands
|
||||
│ ├── Http/ # Controllers, Middleware
|
||||
│ ├── Models/ # Eloquent Models
|
||||
│ ├── Services/ # Business Logic
|
||||
│ └── Repositories/ # Data Access Layer
|
||||
├── config/ # Konfigurationsdateien
|
||||
├── database/ # Migrations, Seeds, Factories
|
||||
├── public/ # Öffentliche Assets
|
||||
├── resources/ # Views, Assets (Sass, JS)
|
||||
├── routes/ # Route Definitionen
|
||||
├── storage/ # Logs, Cache, Uploads
|
||||
├── tests/ # Unit & Feature Tests
|
||||
├── docker-compose.yml # Docker Setup
|
||||
├── init.sh # Initialisierungsskript
|
||||
└── INIT.md # Diese Datei
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Umgebungskonfiguration
|
||||
|
||||
### Wichtige .env Variablen
|
||||
|
||||
#### Haupt-Datenbank (CRM)
|
||||
```env
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=stern_crm
|
||||
DB_USERNAME=sail
|
||||
DB_PASSWORD=password
|
||||
```
|
||||
|
||||
#### Stern-Datenbank (Legacy)
|
||||
```env
|
||||
DB_CONNECTION_STERN=mysql
|
||||
DB_HOST_STERN=mysql-stern
|
||||
DB_PORT_STERN=3306
|
||||
DB_DATABASE_STERN=stern_db
|
||||
DB_USERNAME_STERN=sail
|
||||
DB_PASSWORD_STERN=password
|
||||
```
|
||||
|
||||
#### Mail-Konfiguration (Mailpit)
|
||||
```env
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailpit
|
||||
MAIL_PORT=1025
|
||||
MAIL_ENCRYPTION=null
|
||||
```
|
||||
|
||||
#### Redis Cache
|
||||
```env
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Datenbanken
|
||||
|
||||
Das Projekt verwendet **zwei separate MySQL-Datenbanken**:
|
||||
|
||||
### 1. stern_crm (Haupt-CRM)
|
||||
- **Port:** 33064
|
||||
- **Verwendung:** Haupt-Application, Kundenverwaltung
|
||||
- **Host in Container:** mysql
|
||||
|
||||
### 2. stern_db (Legacy Datenbank)
|
||||
- **Port:** 33065
|
||||
- **Verwendung:** Alte Stern-Tours Daten
|
||||
- **Host in Container:** mysql-stern
|
||||
|
||||
### Datenbankzugriff von außen
|
||||
|
||||
```bash
|
||||
# CRM Datenbank
|
||||
mysql -h 127.0.0.1 -P 33064 -u sail -p stern_crm
|
||||
|
||||
# Stern Datenbank
|
||||
mysql -h 127.0.0.1 -P 33065 -u sail -p stern_db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Domains & Routing
|
||||
|
||||
Das Projekt verwendet **Traefik** als Reverse Proxy und ist über folgende Domains erreichbar:
|
||||
|
||||
| Domain | Zweck | Port |
|
||||
|--------|-------|------|
|
||||
| `https://mein.sterntours.test` | Haupt-Application | 443 |
|
||||
| `https://sterntours.test` | Alternative URL | 443 |
|
||||
| `https://assets.sterntours.test` | Vite Dev-Server | 5173 |
|
||||
| `https://sterntours-mail.test` | Mailpit Dashboard | 8025 |
|
||||
|
||||
### Hosts-Datei konfigurieren
|
||||
|
||||
Füge folgende Einträge zu deiner `/etc/hosts` (Linux/Mac) oder `C:\Windows\System32\drivers\etc\hosts` (Windows) hinzu:
|
||||
|
||||
```
|
||||
127.0.0.1 mein.sterntours.test
|
||||
127.0.0.1 sterntours.test
|
||||
127.0.0.1 assets.sterntours.test
|
||||
127.0.0.1 sterntours-mail.test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Häufige Befehle
|
||||
|
||||
### Docker Container
|
||||
|
||||
```bash
|
||||
# Container starten
|
||||
./vendor/bin/sail up -d
|
||||
|
||||
# Container stoppen
|
||||
./vendor/bin/sail down
|
||||
|
||||
# Container neu bauen
|
||||
./vendor/bin/sail build --no-cache
|
||||
|
||||
# Logs anzeigen
|
||||
./vendor/bin/sail logs -f
|
||||
|
||||
# Spezifischen Service anzeigen
|
||||
./vendor/bin/sail logs mysql -f
|
||||
```
|
||||
|
||||
### Artisan Befehle
|
||||
|
||||
```bash
|
||||
# Migrationen ausführen
|
||||
./vendor/bin/sail artisan migrate
|
||||
|
||||
# Migrationen zurücksetzen
|
||||
./vendor/bin/sail artisan migrate:rollback
|
||||
|
||||
# Seeds ausführen
|
||||
./vendor/bin/sail artisan db:seed
|
||||
|
||||
# Cache leeren
|
||||
./vendor/bin/sail artisan cache:clear
|
||||
./vendor/bin/sail artisan config:clear
|
||||
./vendor/bin/sail artisan route:clear
|
||||
./vendor/bin/sail artisan view:clear
|
||||
|
||||
# Cache optimieren
|
||||
./vendor/bin/sail artisan config:cache
|
||||
./vendor/bin/sail artisan route:cache
|
||||
./vendor/bin/sail artisan view:cache
|
||||
```
|
||||
|
||||
### Composer
|
||||
|
||||
```bash
|
||||
# Packages installieren
|
||||
./vendor/bin/sail composer install
|
||||
|
||||
# Package hinzufügen
|
||||
./vendor/bin/sail composer require <package>
|
||||
|
||||
# Package entfernen
|
||||
./vendor/bin/sail composer remove <package>
|
||||
|
||||
# Autoload aktualisieren
|
||||
./vendor/bin/sail composer dump-autoload
|
||||
```
|
||||
|
||||
### NPM / Assets
|
||||
|
||||
```bash
|
||||
# Dependencies installieren
|
||||
npm install
|
||||
|
||||
# Development Build
|
||||
npm run dev
|
||||
|
||||
# Production Build
|
||||
npm run prod
|
||||
|
||||
# Watch Mode
|
||||
npm run watch
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
```bash
|
||||
# Alle Tests ausführen
|
||||
./vendor/bin/sail test
|
||||
|
||||
# Spezifische Test-Datei
|
||||
./vendor/bin/sail test tests/Feature/ExampleTest.php
|
||||
|
||||
# Mit Coverage
|
||||
./vendor/bin/sail test --coverage
|
||||
```
|
||||
|
||||
### Shell / SSH
|
||||
|
||||
```bash
|
||||
# Shell im Container öffnen
|
||||
./vendor/bin/sail shell
|
||||
|
||||
# Root Shell
|
||||
./vendor/bin/sail root-shell
|
||||
|
||||
# MySQL Shell
|
||||
./vendor/bin/sail mysql
|
||||
|
||||
# Redis CLI
|
||||
./vendor/bin/sail redis
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
### Problem: "Docker is not running"
|
||||
|
||||
**Lösung:** Starte Docker Desktop und warte, bis es vollständig gestartet ist.
|
||||
|
||||
```bash
|
||||
# macOS/Linux
|
||||
sudo systemctl start docker
|
||||
|
||||
# Windows
|
||||
Starte Docker Desktop über das Startmenü
|
||||
```
|
||||
|
||||
### Problem: "Port already in use"
|
||||
|
||||
**Lösung:** Prüfe, welche Ports belegt sind und ändere sie in der `.env` Datei:
|
||||
|
||||
```bash
|
||||
# Ports prüfen
|
||||
lsof -i :33064
|
||||
lsof -i :33065
|
||||
|
||||
# In .env ändern
|
||||
FORWARD_DB_PORT=33064
|
||||
FORWARD_DB_PORT_STERN=33065
|
||||
```
|
||||
|
||||
### Problem: "Network proxy not found"
|
||||
|
||||
**Lösung:** Erstelle das Traefik Proxy-Netzwerk manuell:
|
||||
|
||||
```bash
|
||||
docker network create proxy
|
||||
```
|
||||
|
||||
### Problem: "Permission denied" beim init.sh
|
||||
|
||||
**Lösung:** Mache das Script ausführbar:
|
||||
|
||||
```bash
|
||||
chmod +x init.sh
|
||||
./init.sh
|
||||
```
|
||||
|
||||
### Problem: "Class not found"
|
||||
|
||||
**Lösung:** Regeneriere Composer Autoload:
|
||||
|
||||
```bash
|
||||
./vendor/bin/sail composer dump-autoload
|
||||
./vendor/bin/sail artisan clear-compiled
|
||||
```
|
||||
|
||||
### Problem: "Migration failed"
|
||||
|
||||
**Lösung:** Prüfe Datenbankverbindung und setze zurück:
|
||||
|
||||
```bash
|
||||
# Verbindung testen
|
||||
./vendor/bin/sail artisan tinker
|
||||
>>> DB::connection()->getPdo();
|
||||
|
||||
# Migrationen zurücksetzen
|
||||
./vendor/bin/sail artisan migrate:fresh
|
||||
```
|
||||
|
||||
### Problem: "Vite/Assets nicht geladen"
|
||||
|
||||
**Lösung:** Starte den Dev-Server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# oder
|
||||
npm run watch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support & Kontakt
|
||||
|
||||
Bei Fragen oder Problemen:
|
||||
|
||||
1. Prüfe die [Fehlerbehebung](#fehlerbehebung)
|
||||
2. Prüfe die [Laravel Dokumentation](https://laravel.com/docs)
|
||||
3. Prüfe die [Laravel Sail Dokumentation](https://laravel.com/docs/sail)
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 1.0.0 (2025-11-07)
|
||||
- ✓ Initiales Setup-Script erstellt
|
||||
- ✓ Dokumentation erstellt
|
||||
- ✓ Docker Compose Konfiguration
|
||||
- ✓ Dual-Datenbank Setup
|
||||
- ✓ Traefik Routing konfiguriert
|
||||
|
||||
---
|
||||
|
||||
**Viel Erfolg mit dem Projekt! 🚀**
|
||||
|
||||
19446
_ide_helper.php
19446
_ide_helper.php
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
122
app/Console/Commands/CleanupNewsletterBlockedEmails.php
Normal file
122
app/Console/Commands/CleanupNewsletterBlockedEmails.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\NewsletterContact;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CleanupNewsletterBlockedEmails extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'newsletter:cleanup-blocked-emails {--dry-run : Nur anzeigen, ohne zu löschen}';
|
||||
|
||||
/**
|
||||
* The console description of the command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Entfernt Newsletter-Kontakte mit blockierten E-Mail-Adressen (Alias/Proxy von Buchungsplattformen)';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info('Suche nach blockierten E-Mail-Adressen...');
|
||||
|
||||
$dryRun = $this->option('dry-run');
|
||||
|
||||
// Liste der blockierten Domains
|
||||
$blockedDomains = [
|
||||
'@guest.booking.com',
|
||||
'@messages.homeaway.com',
|
||||
'@fewo.check24.de',
|
||||
'@booking.com',
|
||||
'@homeaway.com',
|
||||
'@check24.de',
|
||||
'@partner.booking.com',
|
||||
];
|
||||
|
||||
$stats = [
|
||||
'found' => 0,
|
||||
'deleted' => 0,
|
||||
];
|
||||
|
||||
// Hole alle Newsletter-Kontakte
|
||||
$contacts = NewsletterContact::all();
|
||||
|
||||
$this->info("Prüfe {$contacts->count()} Kontakte...");
|
||||
|
||||
$bar = $this->output->createProgressBar($contacts->count());
|
||||
$bar->start();
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
$emailLower = strtolower($contact->email);
|
||||
$isBlockedEmail = false;
|
||||
|
||||
foreach ($blockedDomains as $domain) {
|
||||
if (str_ends_with($emailLower, strtolower($domain))) {
|
||||
$isBlockedEmail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isBlockedEmail) {
|
||||
$stats['found']++;
|
||||
|
||||
if ($dryRun) {
|
||||
$this->newLine();
|
||||
$this->warn("Würde löschen: {$contact->email} (ID: {$contact->id})");
|
||||
} else {
|
||||
// Log erstellen vor dem Löschen
|
||||
$contact->logs()->create([
|
||||
'action' => 'deleted',
|
||||
'description' => 'Kontakt entfernt - blockierte E-Mail-Domain (Buchungsplattform-Alias)',
|
||||
]);
|
||||
|
||||
$contact->delete();
|
||||
$stats['deleted']++;
|
||||
}
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->newLine(2);
|
||||
|
||||
// Statistiken ausgeben
|
||||
if ($dryRun) {
|
||||
$this->info('Dry-Run abgeschlossen!');
|
||||
$this->table(
|
||||
['Statistik', 'Anzahl'],
|
||||
[
|
||||
['Gefundene blockierte E-Mails', $stats['found']],
|
||||
]
|
||||
);
|
||||
|
||||
if ($stats['found'] > 0) {
|
||||
$this->newLine();
|
||||
$this->info('Führe den Befehl ohne --dry-run aus, um die Kontakte zu löschen:');
|
||||
$this->comment('php artisan newsletter:cleanup-blocked-emails');
|
||||
}
|
||||
} else {
|
||||
$this->info('Bereinigung abgeschlossen!');
|
||||
$this->table(
|
||||
['Statistik', 'Anzahl'],
|
||||
[
|
||||
['Gefundene blockierte E-Mails', $stats['found']],
|
||||
['Gelöschte Kontakte', $stats['deleted']],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
160
app/Console/Commands/ContactsFindDuplicates.php
Normal file
160
app/Console/Commands/ContactsFindDuplicates.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Phase 1 — Schritt 1: Duplikate identifizieren
|
||||
*
|
||||
* Sucht Kunden-Datensätze, die vermutlich dieselbe Person repräsentieren.
|
||||
* Drei Erkennungs-Stufen (absteigend nach Konfidenz):
|
||||
*
|
||||
* HIGH — gleiche E-Mail (nicht leer)
|
||||
* MEDIUM — gleicher Name + Vorname + Geburtsdatum
|
||||
* LOW — gleicher Name + Vorname + PLZ
|
||||
*
|
||||
* Verwendung:
|
||||
* php artisan contacts:find-duplicates
|
||||
* php artisan contacts:find-duplicates --export=duplicates.csv
|
||||
* php artisan contacts:find-duplicates --confidence=HIGH
|
||||
*/
|
||||
class ContactsFindDuplicates extends Command
|
||||
{
|
||||
protected $signature = 'contacts:find-duplicates
|
||||
{--export= : Pfad zur CSV-Ausgabedatei}
|
||||
{--confidence= : Nur diese Konfidenz-Stufe ausgeben (HIGH|MEDIUM|LOW)}';
|
||||
|
||||
protected $description = 'Identifiziert doppelte Customer-Datensätze anhand von E-Mail, Name/Geburtsdatum oder Name/PLZ';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$this->info('Suche nach Duplikaten in der customer-Tabelle...');
|
||||
$this->newLine();
|
||||
|
||||
$groups = collect();
|
||||
|
||||
// ── HIGH: gleiche E-Mail ──────────────────────────────────────────
|
||||
if ($this->shouldCheck('HIGH')) {
|
||||
$emailDupes = DB::table('contacts')
|
||||
->select('email', DB::raw('COUNT(*) as cnt'), DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC) as ids'))
|
||||
->whereNotNull('email')
|
||||
->where('email', '!=', '')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('email')
|
||||
->having('cnt', '>', 1)
|
||||
->get();
|
||||
|
||||
foreach ($emailDupes as $row) {
|
||||
$groups->push([
|
||||
'confidence' => 'HIGH',
|
||||
'reason' => 'E-Mail: ' . $row->email,
|
||||
'ids' => $row->ids,
|
||||
'count' => $row->cnt,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->line(sprintf('<fg=green>HIGH</> (gleiche E-Mail): %d Gruppen', $emailDupes->count()));
|
||||
}
|
||||
|
||||
// ── MEDIUM: Name + Vorname + Geburtsdatum ────────────────────────
|
||||
if ($this->shouldCheck('MEDIUM')) {
|
||||
$nameBdDupes = DB::table('contacts')
|
||||
->select(
|
||||
'name', 'firstname', 'birthdate',
|
||||
DB::raw('COUNT(*) as cnt'),
|
||||
DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC) as ids')
|
||||
)
|
||||
->whereNotNull('name')
|
||||
->whereNotNull('firstname')
|
||||
->whereNotNull('birthdate')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('name', 'firstname', 'birthdate')
|
||||
->having('cnt', '>', 1)
|
||||
->get();
|
||||
|
||||
foreach ($nameBdDupes as $row) {
|
||||
$groups->push([
|
||||
'confidence' => 'MEDIUM',
|
||||
'reason' => "Name: {$row->firstname} {$row->name}, GD: {$row->birthdate}",
|
||||
'ids' => $row->ids,
|
||||
'count' => $row->cnt,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->line(sprintf('<fg=yellow>MEDIUM</> (Name+GD): %d Gruppen', $nameBdDupes->count()));
|
||||
}
|
||||
|
||||
// ── LOW: Name + Vorname + PLZ ─────────────────────────────────────
|
||||
if ($this->shouldCheck('LOW')) {
|
||||
$nameZipDupes = DB::table('contacts')
|
||||
->select(
|
||||
'name', 'firstname', 'zip',
|
||||
DB::raw('COUNT(*) as cnt'),
|
||||
DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC) as ids')
|
||||
)
|
||||
->whereNotNull('name')
|
||||
->whereNotNull('firstname')
|
||||
->whereNotNull('zip')
|
||||
->where('zip', '!=', '')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('name', 'firstname', 'zip')
|
||||
->having('cnt', '>', 1)
|
||||
->get();
|
||||
|
||||
foreach ($nameZipDupes as $row) {
|
||||
$groups->push([
|
||||
'confidence' => 'LOW',
|
||||
'reason' => "Name: {$row->firstname} {$row->name}, PLZ: {$row->zip}",
|
||||
'ids' => $row->ids,
|
||||
'count' => $row->cnt,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->line(sprintf('<fg=red>LOW</> (Name+PLZ): %d Gruppen', $nameZipDupes->count()));
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->info(sprintf('Gesamt: %d Duplikat-Gruppen gefunden', $groups->count()));
|
||||
|
||||
if ($groups->isEmpty()) {
|
||||
$this->info('Keine Duplikate — nichts zu tun.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
// Tabellen-Ausgabe
|
||||
$this->table(
|
||||
['Konfidenz', 'Grund', 'IDs (neueste zuerst)', 'Anzahl'],
|
||||
$groups->map(fn ($g) => [$g['confidence'], $g['reason'], $g['ids'], $g['count']])->all()
|
||||
);
|
||||
|
||||
// CSV-Export
|
||||
if ($export = $this->option('export')) {
|
||||
$this->exportCsv($groups->all(), $export);
|
||||
$this->info("CSV gespeichert: {$export}");
|
||||
} else {
|
||||
$this->newLine();
|
||||
$this->line('Tipp: --export=duplicates.csv für CSV-Export');
|
||||
$this->line('Tipp: php artisan contacts:merge-duplicates --dry-run zum Prüfen');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function shouldCheck(string $level): bool
|
||||
{
|
||||
$filter = strtoupper((string) $this->option('confidence'));
|
||||
return $filter === '' || $filter === $level;
|
||||
}
|
||||
|
||||
private function exportCsv(array $groups, string $path): void
|
||||
{
|
||||
$handle = fopen($path, 'w');
|
||||
fputcsv($handle, ['Konfidenz', 'Grund', 'IDs (neueste zuerst)', 'Anzahl']);
|
||||
foreach ($groups as $group) {
|
||||
fputcsv($handle, [$group['confidence'], $group['reason'], $group['ids'], $group['count']]);
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
233
app/Console/Commands/ContactsMergeDuplicates.php
Normal file
233
app/Console/Commands/ContactsMergeDuplicates.php
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Phase 1 — Schritt 2: Duplikate zusammenführen
|
||||
*
|
||||
* Strategie: Der neueste Datensatz (höchstes updated_at, dann höchste id)
|
||||
* wird Master. Alle anderen Datensätze derselben Gruppe erhalten
|
||||
* merged_into_id = master_id und werden nicht mehr zurückgegeben.
|
||||
*
|
||||
* Alle FK-Referenzen in lead, booking, customer_mails, lead_mails
|
||||
* werden auf den Master umgestellt.
|
||||
*
|
||||
* Verwendung:
|
||||
* php artisan contacts:merge-duplicates --dry-run # Vorschau, keine Änderung
|
||||
* php artisan contacts:merge-duplicates --confidence=HIGH # Nur sichere Duplikate
|
||||
* php artisan contacts:merge-duplicates # Ausführen
|
||||
*/
|
||||
class ContactsMergeDuplicates extends Command
|
||||
{
|
||||
protected $signature = 'contacts:merge-duplicates
|
||||
{--dry-run : Zeigt was passieren würde, ohne Daten zu ändern}
|
||||
{--confidence= : Nur diese Konfidenz-Stufe verarbeiten (HIGH|MEDIUM|LOW)}
|
||||
{--force : Überspringt Sicherheitsabfrage}';
|
||||
|
||||
protected $description = 'Führt doppelte Customer-Datensätze zusammen (neuester wird Master)';
|
||||
|
||||
private bool $dryRun = false;
|
||||
private int $mergedCount = 0;
|
||||
private int $updatedLeads = 0;
|
||||
private int $updatedBookings = 0;
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$this->dryRun = (bool) $this->option('dry-run');
|
||||
|
||||
if ($this->dryRun) {
|
||||
$this->warn('DRY-RUN Modus — keine Daten werden verändert');
|
||||
} else {
|
||||
$this->warn('ACHTUNG: Diese Operation verändert Produktionsdaten.');
|
||||
if (!$this->option('force') && !$this->confirm('Fortfahren?')) {
|
||||
$this->info('Abgebrochen.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
|
||||
DB::transaction(function () {
|
||||
$this->processLevel(
|
||||
'HIGH',
|
||||
fn () => $this->findByEmail()
|
||||
);
|
||||
|
||||
$this->processLevel(
|
||||
'MEDIUM',
|
||||
fn () => $this->findByNameBirthdate()
|
||||
);
|
||||
|
||||
$this->processLevel(
|
||||
'LOW',
|
||||
fn () => $this->findByNameZip()
|
||||
);
|
||||
});
|
||||
|
||||
$this->newLine();
|
||||
$this->info(sprintf(
|
||||
'%s %d Duplikate zusammengeführt | %d leads aktualisiert | %d bookings aktualisiert',
|
||||
$this->dryRun ? '[DRY-RUN]' : '',
|
||||
$this->mergedCount,
|
||||
$this->updatedLeads,
|
||||
$this->updatedBookings
|
||||
));
|
||||
|
||||
if ($this->dryRun) {
|
||||
$this->newLine();
|
||||
$this->line('Zum Ausführen: php artisan contacts:merge-duplicates');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Duplikat-Gruppen ermitteln
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private function findByEmail(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->select('email', DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids'))
|
||||
->whereNotNull('email')
|
||||
->where('email', '!=', '')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('email')
|
||||
->having(DB::raw('COUNT(*)'), '>', 1)
|
||||
->pluck('ids')
|
||||
->map(fn ($ids) => explode(',', $ids))
|
||||
->all();
|
||||
}
|
||||
|
||||
private function findByNameBirthdate(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->select(DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids'))
|
||||
->whereNotNull('name')
|
||||
->whereNotNull('firstname')
|
||||
->whereNotNull('birthdate')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('name', 'firstname', 'birthdate')
|
||||
->having(DB::raw('COUNT(*)'), '>', 1)
|
||||
->pluck('ids')
|
||||
->map(fn ($ids) => explode(',', $ids))
|
||||
->all();
|
||||
}
|
||||
|
||||
private function findByNameZip(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->select(DB::raw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids'))
|
||||
->whereNotNull('name')
|
||||
->whereNotNull('firstname')
|
||||
->whereNotNull('zip')
|
||||
->where('zip', '!=', '')
|
||||
->whereNull('merged_into_id')
|
||||
->groupBy('name', 'firstname', 'zip')
|
||||
->having(DB::raw('COUNT(*)'), '>', 1)
|
||||
->pluck('ids')
|
||||
->map(fn ($ids) => explode(',', $ids))
|
||||
->all();
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Verarbeitung
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private function processLevel(string $level, callable $finder): void
|
||||
{
|
||||
if ($filter = $this->option('confidence')) {
|
||||
if (strtoupper($filter) !== $level) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$groups = $finder();
|
||||
|
||||
if (empty($groups)) {
|
||||
$this->line("[{$level}] Keine Duplikate.");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line(sprintf('[%s] %d Gruppe(n) gefunden', $level, count($groups)));
|
||||
|
||||
foreach ($groups as $ids) {
|
||||
$masterId = (int) $ids[0]; // erster = neuester
|
||||
$duplicateIds = array_map('intval', array_slice($ids, 1));
|
||||
|
||||
$this->line(sprintf(
|
||||
' Master: #%d ← Duplikate: %s',
|
||||
$masterId,
|
||||
implode(', ', array_map(fn ($id) => '#' . $id, $duplicateIds))
|
||||
));
|
||||
|
||||
foreach ($duplicateIds as $dupeId) {
|
||||
$this->mergeInto($masterId, $dupeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function mergeInto(int $masterId, int $dupeId): void
|
||||
{
|
||||
// 1. Leads umhängen
|
||||
$leadCount = DB::table('inquiries')->where('customer_id', $dupeId)->count();
|
||||
if ($leadCount > 0) {
|
||||
$this->line(" lead.customer_id: {$leadCount} Zeile(n) → #{$masterId}");
|
||||
if (!$this->dryRun) {
|
||||
DB::table('inquiries')
|
||||
->where('customer_id', $dupeId)
|
||||
->update(['customer_id' => $masterId]);
|
||||
}
|
||||
$this->updatedLeads += $leadCount;
|
||||
}
|
||||
|
||||
// 2. Bookings umhängen
|
||||
$bookingCount = DB::table('booking')->where('customer_id', $dupeId)->count();
|
||||
if ($bookingCount > 0) {
|
||||
$this->line(" booking.customer_id: {$bookingCount} Zeile(n) → #{$masterId}");
|
||||
if (!$this->dryRun) {
|
||||
DB::table('booking')
|
||||
->where('customer_id', $dupeId)
|
||||
->update(['customer_id' => $masterId]);
|
||||
}
|
||||
$this->updatedBookings += $bookingCount;
|
||||
}
|
||||
|
||||
// 3. customer_mails umhängen
|
||||
$mailCount = DB::table('customer_mails')->where('customer_id', $dupeId)->count();
|
||||
if ($mailCount > 0) {
|
||||
$this->line(" customer_mails.customer_id: {$mailCount} Zeile(n) → #{$masterId}");
|
||||
if (!$this->dryRun) {
|
||||
DB::table('customer_mails')
|
||||
->where('customer_id', $dupeId)
|
||||
->update(['customer_id' => $masterId]);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. lead_mails umhängen
|
||||
$leadMailCount = DB::table('lead_mails')->where('customer_id', $dupeId)->count();
|
||||
if ($leadMailCount > 0) {
|
||||
$this->line(" lead_mails.customer_id: {$leadMailCount} Zeile(n) → #{$masterId}");
|
||||
if (!$this->dryRun) {
|
||||
DB::table('lead_mails')
|
||||
->where('customer_id', $dupeId)
|
||||
->update(['customer_id' => $masterId]);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Duplikat als zusammengeführt markieren
|
||||
if (!$this->dryRun) {
|
||||
DB::table('contacts')
|
||||
->where('id', $dupeId)
|
||||
->update([
|
||||
'merged_into_id' => $masterId,
|
||||
'merged_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->mergedCount++;
|
||||
}
|
||||
}
|
||||
254
app/Console/Commands/SyncNewsletterFerienwohnungen.php
Normal file
254
app/Console/Commands/SyncNewsletterFerienwohnungen.php
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\TravelUserBookingFewo;
|
||||
use App\Models\TravelUser;
|
||||
use App\Models\NewsletterContact;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SyncNewsletterFerienwohnungen extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'newsletter:sync-ferienwohnungen {--force : Force full sync}';
|
||||
|
||||
/**
|
||||
* The console description of the command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Synchronisiert Ferienwohnungs-Buchungen mit Newsletter-Kontakten';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info('Starte Synchronisation von Ferienwohnungs-Buchungen...');
|
||||
|
||||
$force = $this->option('force');
|
||||
|
||||
// Statistiken
|
||||
$stats = [
|
||||
'processed' => 0,
|
||||
'created' => 0,
|
||||
'updated' => 0,
|
||||
'skipped' => 0,
|
||||
'errors' => 0,
|
||||
];
|
||||
|
||||
// Hole alle Buchungen mit TravelUser und invoice_number
|
||||
$query = TravelUserBookingFewo::with(['travel_user'])
|
||||
->whereNotNull('travel_user_id')
|
||||
->whereNotNull('invoice_number')
|
||||
->where('invoice_number', '!=', '')
|
||||
// Nur wenn invoice_number eine reine Nummer ist (keine Storno etc.)
|
||||
->whereRaw('invoice_number REGEXP "^[0-9]+$"')
|
||||
->whereHas('travel_user', function ($q) {
|
||||
$q->whereNotNull('email')
|
||||
->where('email', '!=', '');
|
||||
})
|
||||
// Nur Buchungen, bei denen die Reise bereits beendet ist (to_date in der Vergangenheit)
|
||||
->whereNotNull('to_date')
|
||||
->where('to_date', '<', now());
|
||||
|
||||
if (!$force) {
|
||||
// Nur Buchungen der letzten 30 Tage (basierend auf Rückreisedatum) wenn nicht --force
|
||||
$query->where('to_date', '>=', now()->subDays(30));
|
||||
}
|
||||
|
||||
$bookings = $query->get();
|
||||
|
||||
$this->info("Verarbeite {$bookings->count()} Buchungen...");
|
||||
|
||||
$bar = $this->output->createProgressBar($bookings->count());
|
||||
$bar->start();
|
||||
|
||||
foreach ($bookings as $booking) {
|
||||
try {
|
||||
$stats['processed']++;
|
||||
|
||||
$travelUser = $booking->travel_user;
|
||||
|
||||
// Validiere E-Mail
|
||||
if (!$travelUser || !$travelUser->email || !filter_var($travelUser->email, FILTER_VALIDATE_EMAIL)) {
|
||||
$stats['skipped']++;
|
||||
$bar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filtere Alias/Proxy E-Mail-Adressen von Buchungsplattformen
|
||||
$blockedDomains = [
|
||||
'@guest.booking.com',
|
||||
'@messages.homeaway.com',
|
||||
'@fewo.check24.de',
|
||||
'@booking.com',
|
||||
'@homeaway.com',
|
||||
'@check24.de',
|
||||
'@partner.booking.com',
|
||||
];
|
||||
|
||||
$emailLower = strtolower($travelUser->email);
|
||||
$isBlockedEmail = false;
|
||||
foreach ($blockedDomains as $domain) {
|
||||
if (str_ends_with($emailLower, strtolower($domain))) {
|
||||
$isBlockedEmail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isBlockedEmail) {
|
||||
$stats['skipped']++;
|
||||
$bar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Prüfe ob invoice_number wirklich eine reine Zahl ist
|
||||
if (!preg_match('/^[0-9]+$/', $booking->invoice_number)) {
|
||||
$stats['skipped']++;
|
||||
$bar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generiere Hash für Duplikat-Erkennung
|
||||
$syncHash = NewsletterContact::generateSyncHash(
|
||||
$travelUser->email,
|
||||
NewsletterContact::SOURCE_BOOKING_FERIENWOHNUNGEN
|
||||
);
|
||||
|
||||
// Suche oder erstelle Kontakt
|
||||
$contact = NewsletterContact::withTrashed()
|
||||
->where('email', strtolower(trim($travelUser->email)))
|
||||
->first();
|
||||
|
||||
$isNew = false;
|
||||
|
||||
if (!$contact) {
|
||||
// Neuer Kontakt
|
||||
$contact = new NewsletterContact();
|
||||
$isNew = true;
|
||||
$stats['created']++;
|
||||
} else {
|
||||
// Wenn gelöscht, wiederherstellen
|
||||
if ($contact->trashed()) {
|
||||
$contact->restore();
|
||||
}
|
||||
$stats['updated']++;
|
||||
}
|
||||
|
||||
// Aktualisiere Kontaktdaten
|
||||
$contact->email = strtolower(trim($travelUser->email));
|
||||
$contact->firstname = $travelUser->first_name ?: $contact->firstname;
|
||||
$contact->lastname = $travelUser->last_name ?: $contact->lastname;
|
||||
|
||||
// Setze Gruppe Ferienwohnungen
|
||||
$contact->group_ferienwohnungen = true;
|
||||
|
||||
// Source nur bei neuem Kontakt setzen (wenn noch nicht aus Kulturreisen)
|
||||
if ($isNew) {
|
||||
$contact->source = NewsletterContact::SOURCE_BOOKING_FERIENWOHNUNGEN;
|
||||
$contact->subscribed_at = $booking->booking_date ?
|
||||
\Carbon\Carbon::parse($booking->booking_date) :
|
||||
$booking->created_at;
|
||||
}
|
||||
|
||||
// Referenz zum TravelUser
|
||||
$contact->travel_user_id = $travelUser->id;
|
||||
|
||||
// Aktualisiere Buchungsstatistiken
|
||||
// Nur Buchungen mit invoice_number (reine Nummer) zählen
|
||||
$userBookings = TravelUserBookingFewo::where('travel_user_id', $travelUser->id)
|
||||
->whereNotNull('invoice_number')
|
||||
->where('invoice_number', '!=', '')
|
||||
->whereRaw('invoice_number REGEXP "^[0-9]+$"')
|
||||
->count();
|
||||
|
||||
$contact->total_bookings_ferienwohnungen = $userBookings;
|
||||
|
||||
// Letztes Buchungsdatum
|
||||
$lastBooking = TravelUserBookingFewo::where('travel_user_id', $travelUser->id)
|
||||
->whereNotNull('invoice_number')
|
||||
->where('invoice_number', '!=', '')
|
||||
->whereRaw('invoice_number REGEXP "^[0-9]+$"')
|
||||
->orderBy('booking_date', 'DESC')
|
||||
->first();
|
||||
|
||||
if ($lastBooking && $lastBooking->booking_date) {
|
||||
$lastBookingDate = \Carbon\Carbon::parse($lastBooking->booking_date);
|
||||
if (!$contact->last_booking_at || $lastBookingDate->gt($contact->last_booking_at)) {
|
||||
$contact->last_booking_at = $lastBookingDate;
|
||||
}
|
||||
}
|
||||
|
||||
// Letztes Reiseenddatum (to_date) - nur abgeschlossene Reisen
|
||||
$lastTravelEndBooking = TravelUserBookingFewo::where('travel_user_id', $travelUser->id)
|
||||
->whereNotNull('invoice_number')
|
||||
->where('invoice_number', '!=', '')
|
||||
->whereRaw('invoice_number REGEXP "^[0-9]+$"')
|
||||
->whereNotNull('to_date')
|
||||
->where('to_date', '<', now())
|
||||
->orderBy('to_date', 'DESC')
|
||||
->first();
|
||||
|
||||
if ($lastTravelEndBooking && $lastTravelEndBooking->to_date) {
|
||||
$lastTravelEndDate = \Carbon\Carbon::parse($lastTravelEndBooking->to_date);
|
||||
if (!$contact->last_travel_end_date || $lastTravelEndDate->gt($contact->last_travel_end_date)) {
|
||||
$contact->last_travel_end_date = $lastTravelEndDate;
|
||||
}
|
||||
}
|
||||
|
||||
// Status
|
||||
if ($isNew || $contact->status === NewsletterContact::STATUS_INACTIVE) {
|
||||
$contact->status = NewsletterContact::STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
$contact->sync_hash = $syncHash;
|
||||
$contact->last_synced_at = now();
|
||||
|
||||
$contact->save();
|
||||
|
||||
// Log erstellen
|
||||
if ($isNew) {
|
||||
$contact->logs()->create([
|
||||
'action' => 'booking_added',
|
||||
'description' => 'Kontakt durch Ferienwohnungs-Buchung erstellt',
|
||||
'metadata' => [
|
||||
'booking_id' => $booking->id,
|
||||
'invoice_number' => $booking->invoice_number,
|
||||
],
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$stats['errors']++;
|
||||
$this->error("Fehler bei Buchung {$booking->id}: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->newLine(2);
|
||||
|
||||
// Statistiken ausgeben
|
||||
$this->info('Synchronisation abgeschlossen!');
|
||||
$this->table(
|
||||
['Statistik', 'Anzahl'],
|
||||
[
|
||||
['Verarbeitet', $stats['processed']],
|
||||
['Neu erstellt', $stats['created']],
|
||||
['Aktualisiert', $stats['updated']],
|
||||
['Übersprungen', $stats['skipped']],
|
||||
['Fehler', $stats['errors']],
|
||||
]
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
227
app/Console/Commands/SyncNewsletterKulturreisen.php
Normal file
227
app/Console/Commands/SyncNewsletterKulturreisen.php
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Customer;
|
||||
use App\Models\NewsletterContact;
|
||||
use App\Models\Status;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SyncNewsletterKulturreisen extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'newsletter:sync-kulturreisen {--force : Force full sync}';
|
||||
|
||||
/**
|
||||
* The console description of the command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Synchronisiert Kulturreisen-Buchungen mit Newsletter-Kontakten';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info('Starte Synchronisation von Kulturreisen-Buchungen...');
|
||||
|
||||
$force = $this->option('force');
|
||||
|
||||
// Statistiken
|
||||
$stats = [
|
||||
'processed' => 0,
|
||||
'created' => 0,
|
||||
'updated' => 0,
|
||||
'skipped' => 0,
|
||||
'errors' => 0,
|
||||
];
|
||||
|
||||
// Hole alle Buchungen mit Kunden
|
||||
$query = Booking::with(['customer', 'lead.status'])
|
||||
->whereNotNull('customer_id')
|
||||
->whereHas('customer', function ($q) {
|
||||
$q->whereNotNull('email')
|
||||
->where('email', '!=', '');
|
||||
})
|
||||
// Nur Buchungen, bei denen die Reise bereits beendet ist (end_date in der Vergangenheit)
|
||||
->whereNotNull('end_date')
|
||||
->where('end_date', '<', now());
|
||||
|
||||
if (!$force) {
|
||||
// Nur Buchungen der letzten 30 Tage (basierend auf Rückreisedatum) wenn nicht --force
|
||||
$query->where('end_date', '>=', now()->subDays(30));
|
||||
}
|
||||
|
||||
$bookings = $query->get();
|
||||
|
||||
$this->info("Verarbeite {$bookings->count()} Buchungen...");
|
||||
|
||||
$bar = $this->output->createProgressBar($bookings->count());
|
||||
$bar->start();
|
||||
|
||||
foreach ($bookings as $booking) {
|
||||
try {
|
||||
$stats['processed']++;
|
||||
|
||||
$customer = $booking->customer;
|
||||
|
||||
// Validiere E-Mail
|
||||
if (!$customer || !$customer->email || !filter_var($customer->email, FILTER_VALIDATE_EMAIL)) {
|
||||
$stats['skipped']++;
|
||||
$bar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filtere Alias/Proxy E-Mail-Adressen von Buchungsplattformen
|
||||
$blockedDomains = [
|
||||
'@guest.booking.com',
|
||||
'@messages.homeaway.com',
|
||||
'@fewo.check24.de',
|
||||
'@booking.com',
|
||||
'@homeaway.com',
|
||||
'@check24.de',
|
||||
'@partner.booking.com',
|
||||
];
|
||||
|
||||
$emailLower = strtolower($customer->email);
|
||||
$isBlockedEmail = false;
|
||||
foreach ($blockedDomains as $domain) {
|
||||
if (str_ends_with($emailLower, strtolower($domain))) {
|
||||
$isBlockedEmail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isBlockedEmail) {
|
||||
$stats['skipped']++;
|
||||
$bar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generiere Hash für Duplikat-Erkennung
|
||||
$syncHash = NewsletterContact::generateSyncHash(
|
||||
$customer->email,
|
||||
NewsletterContact::SOURCE_BOOKING_KULTURREISEN
|
||||
);
|
||||
|
||||
// Suche oder erstelle Kontakt
|
||||
$contact = NewsletterContact::withTrashed()
|
||||
->where('email', strtolower(trim($customer->email)))
|
||||
->first();
|
||||
|
||||
$isNew = false;
|
||||
|
||||
if (!$contact) {
|
||||
// Neuer Kontakt
|
||||
$contact = new NewsletterContact();
|
||||
$isNew = true;
|
||||
$stats['created']++;
|
||||
} else {
|
||||
// Wenn gelöscht, wiederherstellen
|
||||
if ($contact->trashed()) {
|
||||
$contact->restore();
|
||||
}
|
||||
$stats['updated']++;
|
||||
}
|
||||
|
||||
// Aktualisiere Kontaktdaten
|
||||
$contact->email = strtolower(trim($customer->email));
|
||||
$contact->firstname = $customer->firstname ?: $contact->firstname;
|
||||
$contact->lastname = $customer->name ?: $contact->lastname;
|
||||
|
||||
// Setze Gruppe Kulturreisen
|
||||
$contact->group_kulturreisen = true;
|
||||
|
||||
// Source nur bei neuem Kontakt setzen
|
||||
if ($isNew) {
|
||||
$contact->source = NewsletterContact::SOURCE_BOOKING_KULTURREISEN;
|
||||
$contact->subscribed_at = $booking->booking_date ?: $booking->created_at;
|
||||
}
|
||||
|
||||
// Referenz zum Customer
|
||||
$contact->customer_id = $customer->id;
|
||||
|
||||
// Aktualisiere Buchungsstatistiken
|
||||
$customerBookings = Booking::where('customer_id', $customer->id)->count();
|
||||
$contact->total_bookings_kulturreisen = $customerBookings;
|
||||
|
||||
// Letztes Buchungsdatum
|
||||
$lastBooking = Booking::where('customer_id', $customer->id)
|
||||
->orderBy('booking_date', 'DESC')
|
||||
->first();
|
||||
|
||||
if ($lastBooking && $lastBooking->booking_date) {
|
||||
$contact->last_booking_at = $lastBooking->booking_date;
|
||||
}
|
||||
|
||||
// Letztes Reiseenddatum (end_date) - nur abgeschlossene Reisen
|
||||
$lastTravelEndBooking = Booking::where('customer_id', $customer->id)
|
||||
->whereNotNull('end_date')
|
||||
->where('end_date', '<', now())
|
||||
->orderBy('end_date', 'DESC')
|
||||
->first();
|
||||
|
||||
if ($lastTravelEndBooking && $lastTravelEndBooking->end_date) {
|
||||
if (!$contact->last_travel_end_date || $lastTravelEndBooking->end_date->gt($contact->last_travel_end_date)) {
|
||||
$contact->last_travel_end_date = $lastTravelEndBooking->end_date;
|
||||
}
|
||||
}
|
||||
|
||||
// Status
|
||||
if ($isNew || $contact->status === NewsletterContact::STATUS_INACTIVE) {
|
||||
$contact->status = NewsletterContact::STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
$contact->sync_hash = $syncHash;
|
||||
$contact->last_synced_at = now();
|
||||
|
||||
$contact->save();
|
||||
|
||||
// Log erstellen
|
||||
if ($isNew) {
|
||||
$contact->logs()->create([
|
||||
'action' => 'booking_added',
|
||||
'description' => 'Kontakt durch Kulturreisen-Buchung erstellt',
|
||||
'metadata' => [
|
||||
'booking_id' => $booking->id,
|
||||
// Metadaten-Key bleibt `lead_id`; Wert kommt aus booking.inquiry_id.
|
||||
'lead_id' => $booking->inquiry_id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$stats['errors']++;
|
||||
$this->error("Fehler bei Buchung {$booking->id}: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->newLine(2);
|
||||
|
||||
// Statistiken ausgeben
|
||||
$this->info('Synchronisation abgeschlossen!');
|
||||
$this->table(
|
||||
['Statistik', 'Anzahl'],
|
||||
[
|
||||
['Verarbeitet', $stats['processed']],
|
||||
['Neu erstellt', $stats['created']],
|
||||
['Aktualisiert', $stats['updated']],
|
||||
['Übersprungen', $stats['skipped']],
|
||||
['Fehler', $stats['errors']],
|
||||
]
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
18
app/Console/Commands/readme.md
Normal file
18
app/Console/Commands/readme.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Newsletter-Synchronisation (wie gewohnt):
|
||||
|
||||
# Normale Synchronisation (letzte 30 Tage)
|
||||
|
||||
php artisan newsletter:sync-ferienwohnungenphp artisan newsletter:sync-kulturreisen
|
||||
|
||||
# Vollständige Synchronisation
|
||||
|
||||
php artisan newsletter:sync-ferienwohnungen --forcephp artisan newsletter:sync-kulturreisen --force
|
||||
#Bereinigung bestehender blockierter E-Mails:
|
||||
|
||||
# Erst testen (zeigt nur an, was gelöscht würde)
|
||||
|
||||
php artisan newsletter:cleanup-blocked-emails --dry-run
|
||||
|
||||
# Tatsächlich löschen
|
||||
|
||||
php artisan newsletter:cleanup-blocked-emails
|
||||
|
|
@ -22,10 +22,14 @@ class Kernel extends ConsoleKernel
|
|||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
// $schedule->command('inspire')
|
||||
// ->hourly();
|
||||
// Duplikate täglich um 02:00 Uhr automatisch zusammenführen (nur HIGH-Konfidenz = exakte E-Mail-Treffer)
|
||||
$schedule->command('contacts:merge-duplicates --confidence=HIGH --force')
|
||||
->dailyAt('02:00')
|
||||
->withoutOverlapping()
|
||||
->runInBackground()
|
||||
->appendOutputTo(storage_path('logs/contacts-merge.log'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -35,7 +39,7 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
|
|
|||
76
app/Exports/NewsletterExport.php
Normal file
76
app/Exports/NewsletterExport.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\NewsletterContact;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
|
||||
class NewsletterExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize
|
||||
{
|
||||
protected $contacts;
|
||||
|
||||
public function __construct($contacts)
|
||||
{
|
||||
$this->contacts = $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function collection()
|
||||
{
|
||||
return $this->contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'ID',
|
||||
'E-Mail',
|
||||
'Vorname',
|
||||
'Nachname',
|
||||
'Gruppe Kulturreisen',
|
||||
'Gruppe Ferienwohnungen',
|
||||
'Status',
|
||||
'Herkunft',
|
||||
'Buchungen Kulturreisen',
|
||||
'Buchungen Ferienwohnungen',
|
||||
'Letzte Buchung',
|
||||
'Letzte Reise',
|
||||
'Angemeldet am',
|
||||
'Abgemeldet am',
|
||||
'Erstellt am',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NewsletterContact $contact
|
||||
* @return array
|
||||
*/
|
||||
public function map($contact): array
|
||||
{
|
||||
return [
|
||||
$contact->id,
|
||||
$contact->email,
|
||||
$contact->firstname,
|
||||
$contact->lastname,
|
||||
$contact->group_kulturreisen ? 'Ja' : 'Nein',
|
||||
$contact->group_ferienwohnungen ? 'Ja' : 'Nein',
|
||||
$contact->status_label,
|
||||
$contact->source_label,
|
||||
$contact->total_bookings_kulturreisen,
|
||||
$contact->total_bookings_ferienwohnungen,
|
||||
$contact->last_booking_at ? $contact->last_booking_at->format('d.m.Y') : '',
|
||||
$contact->last_travel_end_date ? $contact->last_travel_end_date->format('d.m.Y') : '',
|
||||
$contact->subscribed_at ? $contact->subscribed_at->format('d.m.Y H:i') : '',
|
||||
$contact->unsubscribed_at ? $contact->unsubscribed_at->format('d.m.Y H:i') : '',
|
||||
$contact->created_at->format('d.m.Y H:i'),
|
||||
];
|
||||
}
|
||||
}
|
||||
313
app/Helper/BookingDocument.php
Normal file
313
app/Helper/BookingDocument.php
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
<?php
|
||||
namespace App\Helper;
|
||||
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\BookingDocument as BookingDocumentModel;
|
||||
|
||||
class BookingDocument
|
||||
{
|
||||
|
||||
private static $files_count = 0;
|
||||
|
||||
|
||||
public static function showButton($identifier, Booking $booking){
|
||||
switch($identifier){
|
||||
case 'registration':
|
||||
return $booking->price > 0 ? true : false;
|
||||
break;
|
||||
case 'confirmation':
|
||||
return $booking->hasDocument('registration') > 0 ? true : false;
|
||||
break;
|
||||
case 'storno':
|
||||
return $booking->hasDocument('confirmation') > 0 ? true : false;
|
||||
break;
|
||||
case 'coupon':
|
||||
return $booking->hasDocument('confirmation') > 0 ? true : false;
|
||||
case 'voucher':
|
||||
return $booking->hasDocument('confirmation') > 0 ? true : false;
|
||||
case 'voucher_agency':
|
||||
return $booking->hasDocument('confirmation') > 0 ? true : false;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
functions to make the html table for the booking documents
|
||||
*/
|
||||
public static function getFilesCount(){
|
||||
return self::$files_count++;
|
||||
}
|
||||
|
||||
public static function getBookingDocumentsHTMLTable($identifier, Booking $booking, $look = 'show'){
|
||||
$ret = "";
|
||||
$files = self::getBookingDocuments($identifier, $booking->id);
|
||||
if($files && $files->count() > 0){
|
||||
$ret .= self::makeHTMLTable($files, $identifier, 'v3', $look);
|
||||
}
|
||||
$files = self::getV2BookingDocuments($identifier, $booking);
|
||||
if($files && $files->count() > 0){
|
||||
$ret .= self::makeHTMLTable($files, $identifier, 'v2', $look);
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getBookingDocuments($identifier, $booking_id){
|
||||
|
||||
switch($identifier){
|
||||
case 'registration':
|
||||
$files = BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'registration')->get();
|
||||
break;
|
||||
case 'confirmation':
|
||||
$files = BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'confirmation')->get();
|
||||
break;
|
||||
case 'storno':
|
||||
$files = null; //BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'storno')->get();
|
||||
break;
|
||||
case 'coupon':
|
||||
$files = null; //BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'coupon')->get();
|
||||
break;
|
||||
case 'voucher':
|
||||
$files = BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'voucher')->get();
|
||||
break;
|
||||
case 'voucher_agency':
|
||||
$files = BookingDocumentModel::where('booking_id', $booking_id)->where('identifier', 'voucher_agency')->get();
|
||||
break;
|
||||
default:
|
||||
$files = null;
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
|
||||
public static function getV2BookingDocuments($identifier, Booking $booking){
|
||||
|
||||
switch($identifier){
|
||||
case 'registration':
|
||||
$files = $booking->booking_applications;
|
||||
break;
|
||||
case 'confirmation':
|
||||
$files = $booking->booking_confirmations;
|
||||
break;
|
||||
case 'storno':
|
||||
$files = $booking->booking_stornos;
|
||||
break;
|
||||
case 'coupon':
|
||||
$files = $booking->coupons;
|
||||
break;
|
||||
case 'voucher':
|
||||
$files = $booking->booking_vouchers;
|
||||
break;
|
||||
case 'voucher_agency':
|
||||
$files = $booking->booking_voucher_agencys;
|
||||
break;
|
||||
default:
|
||||
$files = null;
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
private static function makeHTMLTable($files, $identifier, $version, $look){
|
||||
$ret = "";
|
||||
|
||||
foreach($files as $file){
|
||||
;
|
||||
if($version === 'v2'){
|
||||
$file_details = self::getV2FileDetails($file, $identifier, $look);
|
||||
}
|
||||
if($version === 'v3'){
|
||||
$file_details = self::getV3FileDetails($file, $identifier, $look);
|
||||
}
|
||||
if(isset($file_details)){
|
||||
$ret .= "<tr>";
|
||||
$ret .= "<th scope='row'>".self::getFilesCount()."</th>";
|
||||
$ret .= "<td>";
|
||||
$ret .= "<a href='".$file_details->route."' target='_blank' class='badge badge-md badge-".$file_details->color."'>";
|
||||
$ret .= "<i class='fa fa-file-pdf mr-1 ".(($file_details->opacity) ? 'opacity-50' : '')."'></i> ".$file_details->name;
|
||||
$ret .= "</a>";
|
||||
$ret .= "</td>";
|
||||
$ret .= "<td>".$file_details->cell."</td>";
|
||||
$ret .= "<td>".$file_details->date."</td>";
|
||||
$ret .= "<td>";
|
||||
if($look === 'show'){
|
||||
$ret .= "<a href='".$file_details->donwload."' class='btn btn-xs btn-default' title='Download' data-placement='left' rel='tooltip'>";
|
||||
$ret .= "<i class='fa fa-download'></i>";
|
||||
$ret .= "</a>";
|
||||
}
|
||||
if($look === 'mail'){
|
||||
|
||||
$ret .= "<button data-target='".$file_details->route."' data-name='".$file_details->name.".pdf' class='btn btn-xs btn-primary add-file-to-attachment'";
|
||||
$ret .= " title='als Anhang hinzufügen' data-placement='left' rel='tooltip'>";
|
||||
$ret .= "<i class='fa fa-cloud-download-alt'></i>";
|
||||
$ret .= "</button>";
|
||||
}
|
||||
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
}
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function getV3FileDetails($file, $identifier, $look){
|
||||
$ret = new \stdClass();
|
||||
switch($identifier){
|
||||
case 'registration':
|
||||
$ret->name = "Buchnungsauftrag ".$file->data->number;
|
||||
$ret->color = "primary";
|
||||
$ret->cell = self::getCellLabel($look, 'GP').": ".\App\Services\Util::_number_format((float) $file->data->total)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->data->date, 'date');
|
||||
break;
|
||||
case 'confirmation':
|
||||
$ret->name = "Reisebestätigung ".$file->data->number;
|
||||
$ret->color = "success";
|
||||
$ret->cell = self::getCellLabel($look, 'GP').": ".\App\Services\Util::_number_format($file->data->total)." € <br>
|
||||
".self::getCellLabel($look, 'AZ').": ".\App\Services\Util::_number_format($file->data->deposit)." € <br>
|
||||
".self::getCellLabel($look, 'RZ').": ".\App\Services\Util::_number_format($file->data->final_payment)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->data->date, 'date');
|
||||
break;
|
||||
case 'storno':
|
||||
$ret->name = "Stornobestätigung ".$file->data->number;
|
||||
$ret->color = "danger";
|
||||
$ret->cell = self::getCellLabel($look, 'SB').": ".\App\Services\Util::_number_format($file->total)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->data->date, 'date');
|
||||
break;
|
||||
case 'coupon':
|
||||
$ret->name = "Gutschein ".$file->number;
|
||||
$ret->color = "warning";
|
||||
$ret->cell = self::getCellLabel($look, 'GW').": ".\App\Services\Util::_number_format($file->value)." € |
|
||||
bis: ".\App\Services\Util::_format_date($file->valid_date, 'date')." |
|
||||
".(($file->is_redeemed) ? '<i class="fa fa-check-circle text-success"></i> '.\App\Services\Util::_format_date($file->redeem_date, 'date') : '<i class="fa fa-times-circle text-danger"></i>')."";
|
||||
$ret->date = \App\Services\Util::_format_date($file->issue_date, 'date');
|
||||
break;
|
||||
case 'voucher':
|
||||
$ret->name = " Voucher ".$file->data->number;
|
||||
$ret->color = "dark";
|
||||
$ret->cell = self::getCellLabel($look, 'VC');
|
||||
$ret->date = \App\Services\Util::_format_date($file->data->date, 'date');
|
||||
break;
|
||||
case 'voucher_agency':
|
||||
$ret->name = "Voucher-Agentur ".$file->data->number;
|
||||
$ret->color = "dark";
|
||||
$ret->cell = self::getCellLabel($look, 'VA');
|
||||
$ret->date = \App\Services\Util::_format_date($file->data->date, 'date');
|
||||
break;
|
||||
default:
|
||||
$ret->name = "";
|
||||
$ret->color = "";
|
||||
$ret->cell = "";
|
||||
$ret->date = "";
|
||||
}
|
||||
$ret->route = $file->getURL('file');
|
||||
$ret->donwload = $file->getURL('download');
|
||||
$ret->opacity = false;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function getV2FileDetails($file, $identifier, $look){
|
||||
$ret = new \stdClass();
|
||||
|
||||
switch($identifier){
|
||||
case 'registration':
|
||||
$ret->name = "Reiseanmeldung";
|
||||
$ret->color = "primary";
|
||||
$ret->cell = self::getCellLabel($look, 'GP').": ".\App\Services\Util::_number_format($file->total)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->updated_at, 'date');
|
||||
break;
|
||||
case 'confirmation':
|
||||
$ret->name = "Reisebestätigung";
|
||||
$ret->color = "success";
|
||||
$ret->cell = self::getCellLabel($look, 'GP').": ".\App\Services\Util::_number_format($file->total)." € <br>
|
||||
".self::getCellLabel($look, 'AZ').": ".\App\Services\Util::_number_format($file->deposit)." € <br>
|
||||
".self::getCellLabel($look, 'RZ').": ".\App\Services\Util::_number_format($file->final_payment)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->updated_at, 'date');
|
||||
break;
|
||||
case 'storno':
|
||||
$ret->name = "Stornobestätigung";
|
||||
$ret->color = "danger";
|
||||
$ret->cell = self::getCellLabel($look, 'SB').": ".\App\Services\Util::_number_format($file->total)." €";
|
||||
$ret->date = \App\Services\Util::_format_date($file->updated_at, 'date');
|
||||
|
||||
if($file->booking_document){
|
||||
$ret->name .= " ".$file->booking_document->data->number;
|
||||
|
||||
$ret->cell = self::getCellLabel($look, 'SB').": ".\App\Services\Util::_number_format($file->storno)." €";
|
||||
$ret->route = $file->booking_document->getURL('file');
|
||||
$ret->donwload = $file->booking_document->getURL('download');
|
||||
$ret->opacity = false;
|
||||
return $ret;
|
||||
}
|
||||
break;
|
||||
case 'coupon':
|
||||
$ret->name = "Gutschein ".$file->number;
|
||||
$ret->color = "warning";
|
||||
$ret->cell = self::getCellLabel($look, 'GW').": ".\App\Services\Util::_number_format($file->value)." € |
|
||||
bis: ".\App\Services\Util::_format_date($file->valid_date, 'date')." |
|
||||
".(($file->is_redeemed) ? '<i class="fa fa-check-circle text-success"></i> '.\App\Services\Util::_format_date($file->redeem_date, 'date') : '<i class="fa fa-times-circle text-danger"></i>')."";
|
||||
$ret->date = \App\Services\Util::_format_date($file->issue_date, 'date');
|
||||
if($file->booking_document){
|
||||
$ret->route = $file->booking_document->getURL('file');
|
||||
$ret->donwload = $file->booking_document->getURL('download');
|
||||
$ret->opacity = false;
|
||||
return $ret;
|
||||
}
|
||||
break;
|
||||
case 'voucher':
|
||||
$ret->name = " Voucher ID ".$file->id;
|
||||
$ret->color = "dark";
|
||||
$ret->cell = self::getCellLabel($look, 'VC');
|
||||
$ret->date = \App\Services\Util::_format_date($file->updated_at, 'date');
|
||||
break;
|
||||
case 'voucher_agency':
|
||||
$ret->name = "Voucher-Agentur ID ".$file->id;
|
||||
$ret->color = "dark";
|
||||
$ret->cell = self::getCellLabel($look, 'VA');
|
||||
$ret->date = \App\Services\Util::_format_date($file->updated_at, 'date');
|
||||
break;
|
||||
default:
|
||||
$ret->name = "";
|
||||
$ret->color = "";
|
||||
$ret->cell = "";
|
||||
$ret->date = "";
|
||||
}
|
||||
$ret->route = route('customer_file_show', [$identifier, $file->id]);
|
||||
$ret->donwload = route('customer_file_show', [$identifier, $file->id, true]);
|
||||
$ret->opacity = true;
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getCellLabel($look, $identifier){
|
||||
|
||||
switch($identifier){
|
||||
case 'GP':
|
||||
return $look === 'mail' ? 'GP' : 'Reise | Gesamtpreis';
|
||||
break;
|
||||
case 'AZ':
|
||||
return $look === 'mail' ? 'AZ' : 'Anzahlung';
|
||||
break;
|
||||
case 'RZ':
|
||||
return $look === 'mail' ? 'RZ' : 'Restzahlung';
|
||||
break;
|
||||
case 'SB':
|
||||
return $look === 'mail' ? 'GB' : 'Storno | Betrag';
|
||||
break;
|
||||
case 'GW':
|
||||
return $look === 'mail' ? 'W' : 'Gutschein | Wert';
|
||||
break;
|
||||
case 'VC':
|
||||
return $look === 'mail' ? 'für Kunden' : 'Voucher für den Kunden';
|
||||
break;
|
||||
case 'VA':
|
||||
return $look === 'mail' ? 'für Agentur' : 'Voucher für die Agentur';
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
namespace App\Helper;
|
||||
|
||||
use Form;
|
||||
use App\Models\Draft;
|
||||
use App\Models\Airline;
|
||||
use App\Models\Country;
|
||||
use App\Models\CMSAuthor;
|
||||
use App\Models\DraftType;
|
||||
use App\Models\Insurance;
|
||||
|
|
@ -19,7 +17,6 @@ use App\Models\IQTravelGroup;
|
|||
use App\Models\TravelCompany;
|
||||
use App\Models\TravelCountry;
|
||||
use App\Models\TravelProgram;
|
||||
use App\Models\IQTravelGroupItem;
|
||||
use App\Models\TravelNationality;
|
||||
use App\Models\TravelBookingFewoChannel;
|
||||
|
||||
|
|
@ -52,6 +49,16 @@ class HTMLHelper
|
|||
6 => 'Samstag',
|
||||
];
|
||||
|
||||
private static $shortDays = [
|
||||
0 => 'So',
|
||||
1 => 'Mo',
|
||||
2 => 'Di',
|
||||
3 => 'Mi',
|
||||
4 => 'Do',
|
||||
5 => 'Fr',
|
||||
6 => 'Sa',
|
||||
];
|
||||
|
||||
public static $de_days = [
|
||||
1 => 'Montag',
|
||||
2 => 'Dienstag',
|
||||
|
|
@ -75,7 +82,9 @@ class HTMLHelper
|
|||
private static $salutation = [
|
||||
1 => 'Herr',
|
||||
2 => 'Frau',
|
||||
3 => 'Firma',
|
||||
3 => 'Divers/keine Anrede',
|
||||
4 => 'Firma',
|
||||
|
||||
];
|
||||
|
||||
|
||||
|
|
@ -87,6 +96,10 @@ class HTMLHelper
|
|||
return self::$days[$i];
|
||||
}
|
||||
|
||||
public static function getShortDay($i){
|
||||
return self::$shortDays[$i];
|
||||
}
|
||||
|
||||
public static function getDeDays(){
|
||||
return self::$de_days;
|
||||
}
|
||||
|
|
@ -118,6 +131,18 @@ class HTMLHelper
|
|||
|
||||
}
|
||||
|
||||
public static function getSelectedOptions($values, $id = null, $empty = false){
|
||||
$ret = "";
|
||||
if($empty){
|
||||
$ret .= '<option value="">'.$empty.'</option>\n';
|
||||
}
|
||||
foreach ($values as $key => $value){
|
||||
$attr = ($key == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$key.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getActiveIcon($active){
|
||||
return $active ? '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>' : '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
}
|
||||
|
|
@ -141,7 +166,6 @@ class HTMLHelper
|
|||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function getYearSelectOptions(){
|
||||
$start = date("Y", strtotime("-5 years", time()));
|
||||
$end = date("Y", strtotime("+1 years", time()));
|
||||
|
|
@ -407,13 +431,18 @@ class HTMLHelper
|
|||
return $ret;
|
||||
}
|
||||
|
||||
public static function getWeekdaysString($weekdays = []){
|
||||
public static function getWeekdaysString($weekdays = [], $short = false){
|
||||
|
||||
$ret = "";
|
||||
if(count($weekdays)){
|
||||
if(is_array($weekdays) && count($weekdays)){
|
||||
foreach($weekdays as $weekday){
|
||||
if($weekday !== NULL){
|
||||
$ret .= self::getDay($weekday).', ';
|
||||
if($short){
|
||||
$ret .= self::getShortDay($weekday).', ';
|
||||
}else{
|
||||
$ret .= self::getDay($weekday).', ';
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if($ret != ""){
|
||||
|
|
@ -445,7 +474,10 @@ class HTMLHelper
|
|||
|
||||
$dom = new \DOMDocument('1.0', 'UTF-8');
|
||||
//@$dom->loadHTML();
|
||||
|
||||
if($html == ""){
|
||||
return "";
|
||||
}
|
||||
|
||||
@$dom->loadHTML( mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
||||
if(isset($arg['src'])){
|
||||
|
||||
|
|
@ -454,11 +486,13 @@ class HTMLHelper
|
|||
foreach ($images as $image) {
|
||||
|
||||
$src = $image->getAttribute('src');
|
||||
$host = config('app.url_stern');
|
||||
if(strpos($src, $host) === false){
|
||||
$src = $host."/".ltrim($src, '/');
|
||||
if(strpos($src, 'http') === false){
|
||||
$host = config('app.url_stern');
|
||||
if(strpos($src, $host) === false){
|
||||
$src = $host."/".ltrim($src, '/');
|
||||
}
|
||||
$image->setAttribute('src', $src);
|
||||
}
|
||||
$image->setAttribute('src', $src);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
namespace App\Helper;
|
||||
|
||||
use App\Models\IQContentSiteField;
|
||||
use App\Models\IQContentTree;
|
||||
use App\Models\IQContentTreeNode;
|
||||
|
||||
class HTMLTreeHelper
|
||||
class TreeHTML
|
||||
{
|
||||
|
||||
private static $uri = null;
|
||||
|
|
@ -113,6 +113,7 @@ class HTMLTreeHelper
|
|||
<h6 class="small font-weight-bold text-expanded text-uppercase">'.$categories.'</h6>';
|
||||
} else {
|
||||
|
||||
/*
|
||||
$site_field = IQContentSiteField::findSiteField($node, 'main-navi', 'menu-navi-image');
|
||||
|
||||
$img_src = (isset($site_field->content) ? $site_field->content : '/images/navi_images-assets/titelbild.jpg');
|
||||
|
|
@ -120,6 +121,7 @@ class HTMLTreeHelper
|
|||
<img src="'.$img_src.'" alt="" class="d-block ui-w-60">
|
||||
<span class="media-body font-weight-semibold ml-2">' . ($link == $node->identifier ? '<strong>' : '') . $node->name . '</span>' . ($link == $node->identifier ? '</strong>' : '') . '
|
||||
</a>';
|
||||
*/
|
||||
}
|
||||
|
||||
if ($children && $lvl == 0) {
|
||||
|
|
@ -3,199 +3,42 @@
|
|||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Arrangement;
|
||||
use App\Models\Booking;
|
||||
use App\Models\BookingServiceItem;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Lead;
|
||||
use App\Models\Participant;
|
||||
use App\Models\TravelBooking;
|
||||
use App\Repositories\DraftRepository;
|
||||
|
||||
use App\Services\BookingImport;
|
||||
|
||||
class BookingController extends Controller
|
||||
{
|
||||
private $successStatus = 200;
|
||||
private $successKey = 'f6077389c9ce710e554763a5de02c8ec';
|
||||
private int $successStatus = 200;
|
||||
private string $successKey;
|
||||
|
||||
protected $draftRepo;
|
||||
|
||||
public function __construct(DraftRepository $draftRepo)
|
||||
public function __construct()
|
||||
{
|
||||
$this->draftRepo = $draftRepo;
|
||||
$this->successKey = config('app.success_key');
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
|
||||
$request = \Request::all();
|
||||
if($request['key'] !== $this->successKey){
|
||||
if (!isset($request['key']) || $request['key'] !== $this->successKey) {
|
||||
return response()->json(['error' => "key"], 401);
|
||||
}
|
||||
$travel_booking = TravelBooking::find($request['travel_booking_id']);
|
||||
|
||||
// $travel_booking = TravelBooking::find(2458);
|
||||
if(!$travel_booking){
|
||||
if (!$travel_booking) {
|
||||
return response()->json(['error' => 'no-booking-found'], $this->successStatus);
|
||||
}
|
||||
|
||||
// ---- createCustomer
|
||||
$data = [
|
||||
'salutation_id' => $travel_booking->salutation_id,
|
||||
'name' => $travel_booking->last_name,
|
||||
'firstname' => $travel_booking->first_name,
|
||||
'street' => $travel_booking->street,
|
||||
'zip' => $travel_booking->zipcode,
|
||||
'city' => $travel_booking->city,
|
||||
'country_id' => $travel_booking->country_id,
|
||||
'phone' => $travel_booking->phone,
|
||||
'phonemobile' => $travel_booking->mobile,
|
||||
'email' => $travel_booking->email
|
||||
];
|
||||
$customer = Customer::create($data);
|
||||
$booking = BookingImport::importFrom($travel_booking);
|
||||
|
||||
// ---- createLead
|
||||
$data = [
|
||||
'customer_id' => $customer->id,
|
||||
'request_date' => $travel_booking->created,
|
||||
'travelperiod_start' => $travel_booking->selected_start_date,
|
||||
'travelperiod_end' => $travel_booking->selected_end_date,
|
||||
'remarks' => $travel_booking->comments,
|
||||
'sf_guard_user_id' => 15,
|
||||
'is_closed' => true,
|
||||
'initialcontacttype_id' => 14,
|
||||
'status_id' => 7,
|
||||
'website_id' => 1,
|
||||
];
|
||||
$lead = Lead::create($data);
|
||||
$lead->updateNextDueDate();
|
||||
|
||||
$comfort = false;
|
||||
if(isset($travel_booking->drafts['comfort']) && $travel_booking->drafts['comfort']){
|
||||
$comfort = true;
|
||||
}
|
||||
$data = [
|
||||
'booking_date' => $travel_booking->created->format('Y-m-d'),
|
||||
'customer_id' => $customer->id,
|
||||
'lead_id' => $lead->id,
|
||||
'new_drafts' => $travel_booking->drafts === null ? 0 : 1,
|
||||
'sf_guard_user_id' => 15,
|
||||
'branch_id' => 4,
|
||||
'travel_country_id' => isset($travel_booking->selected_travel['travel_country_id'][0]) ? $travel_booking->selected_travel['travel_country_id'][0] : null,
|
||||
'travel_category_id' => isset($travel_booking->selected_travel['travel_category_id']) ? $travel_booking->selected_travel['travel_category_id'] : null,
|
||||
'pax' => $travel_booking->selected_adults,
|
||||
'title' => isset($travel_booking->selected_travel['travel_title']) ? $travel_booking->selected_travel['travel_title'] : "",
|
||||
'comfort' => $comfort,
|
||||
'start_date' => $travel_booking->selected_start_date->format('Y-m-d'),
|
||||
'end_date' => $travel_booking->selected_end_date->format('Y-m-d'),
|
||||
'website_id' => 1,
|
||||
'travel_number' => isset($travel_booking->selected_travel['travel_number']) ? $travel_booking->selected_travel['travel_number'] : null,
|
||||
/*'participant_name' => isset($travel_booking->participants[0]['last_name']) ? $travel_booking->participants[0]['last_name'] : null,
|
||||
'participant_firstname' => isset($travel_booking->participants[0]['first_name']) ? $travel_booking->participants[0]['first_name'] : null,
|
||||
'participant_birthdate' => isset($travel_booking->participants[0]['birthday']) ? date( "Y-m-d", strtotime($travel_booking->participants[0]['birthday'])) : null,
|
||||
'participant_salutation_id' => isset($travel_booking->participants[0]['gender']) ? $travel_booking->participants[0]['gender'] : null,
|
||||
'nationality_id' => isset($travel_booking->participants[0]['nationality']) ? $travel_booking->participants[0]['nationality'] : null,*/
|
||||
'participant_name' => null,
|
||||
'participant_firstname' => null,
|
||||
'participant_birthdate' => null,
|
||||
'participant_salutation_id' => null,
|
||||
'nationality_id' => null,
|
||||
'travel_company_id' => null,
|
||||
'price' => $travel_booking->price,
|
||||
'price_total' => $travel_booking->price_total,
|
||||
'deposit_total' => $travel_booking->deposit_total,
|
||||
'final_payment' => $travel_booking->final_payment,
|
||||
'final_payment_date' => $travel_booking->final_payment_date->format('Y-m-d'),
|
||||
'travelagenda_id' => isset($travel_booking->selected_travel['travelagenda_id']) ? $travel_booking->selected_travel['travelagenda_id'] : null,
|
||||
];
|
||||
|
||||
//createBooking
|
||||
$booking = Booking::create($data);
|
||||
|
||||
//createTraveler
|
||||
if($travel_booking->participants){
|
||||
foreach ($travel_booking->participants as $key => $participant){
|
||||
Participant::create([
|
||||
'booking_id' => $booking->id,
|
||||
'participant_name' => $participant['last_name'],
|
||||
'participant_firstname' => $participant['first_name'],
|
||||
'participant_birthdate' => date( "Y-m-d", strtotime($participant['birthday'])),
|
||||
'participant_salutation_id' => $participant['gender'],
|
||||
'participant_child' => $participant['child'],
|
||||
'nationality_id' =>$participant['nationality'],
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//createServiceItem //service_items
|
||||
if($travel_booking->service_items){
|
||||
foreach ($travel_booking->service_items as $key => $service_item){
|
||||
BookingServiceItem::create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_company_id' => $service_item['travel_company_id'],
|
||||
'service_price' => $service_item['service_price'],
|
||||
'service_price_refund' => 0,
|
||||
'commission' => $service_item['commission'],
|
||||
'travel_date' => $service_item['travel_date'],
|
||||
'name' => $service_item['name'],
|
||||
'is_commission_locked' => 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
//createServiceItem //insurances
|
||||
if($travel_booking->insurances){
|
||||
foreach ($travel_booking->insurances as $key => $service_item){
|
||||
BookingServiceItem::create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_company_id' => $service_item['travel_company_id'],
|
||||
'service_price' => $service_item['price'],
|
||||
'service_price_refund' => 0,
|
||||
'commission' => $service_item['commission'],
|
||||
'travel_date' => $service_item['travel_date'],
|
||||
'name' => $service_item['name'],
|
||||
'is_commission_locked' => 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//createArrangement
|
||||
if($travel_booking->arrangements) {
|
||||
foreach ($travel_booking->arrangements as $key => $arrangement){
|
||||
Arrangement::create([
|
||||
'state' => isset($arrangement['state']) ? $arrangement['state'] : null,
|
||||
'begin' => isset($arrangement['end']) ? $arrangement['end'] : null,
|
||||
'end' => isset($arrangement['end']) ? $arrangement['end'] : null,
|
||||
'type_s' => isset($arrangement['type_s']) ? $arrangement['type_s'] : null,
|
||||
'data_s' => isset($arrangement['data_s']) ? $arrangement['data_s'] : null,
|
||||
'view_position' => isset($arrangement['view_position']) ? $arrangement['view_position'] : null,
|
||||
'booking_id' => $booking->id,
|
||||
'type_id' => $arrangement['type_id'],
|
||||
'in_pdf' => isset($arrangement['in_pdf']) ? $arrangement['in_pdf'] : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
//createDrafts
|
||||
|
||||
if($travel_booking->drafts) {
|
||||
$this->draftRepo->create_drafts_from_booking($booking->id, $travel_booking->drafts);
|
||||
}
|
||||
|
||||
$travel_booking->crm_booking_id = $booking->id;
|
||||
$travel_booking->save();
|
||||
$ret= [
|
||||
'url_v1' => make_old_url('/index.php/booking/'.$booking->id.'/edit'),
|
||||
$ret = [
|
||||
'url_v1' => make_old_url('/index.php/booking/' . $booking->id . '/edit'),
|
||||
'url_v3' => route('booking_detail', $booking->id),
|
||||
'lead_id' => $lead->id
|
||||
// API-Feld bleibt `lead_id` aus Abwärtskompatibilität für API-Konsumenten;
|
||||
// Wert kommt nach Modul 3 Phase 2 aus booking.inquiry_id.
|
||||
'lead_id' => $booking->inquiry_id
|
||||
];
|
||||
return response()->json(['success' => "import", "ret" => $ret], $this->successStatus);
|
||||
//return response()->json(['error' => 'no-node'], $this->successStatus);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\CMSInfo;
|
||||
use App\Models\CMSInfoAvailable;
|
||||
use App\Models\CMSInfoHoliday;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Helper\HTMLHelper;
|
||||
|
||||
|
||||
class CMSContentInfoController extends Controller
|
||||
|
|
|
|||
185
app/Http/Controllers/API/NavigationController.php
Normal file
185
app/Http/Controllers/API/NavigationController.php
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\NavigationTreeService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class NavigationController extends Controller
|
||||
{
|
||||
protected $navigationService;
|
||||
|
||||
public function __construct(NavigationTreeService $navigationService)
|
||||
{
|
||||
$this->navigationService = $navigationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den kompletten Navigationsbaum zurück
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getNavigationTree(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$tree = $this->navigationService->getNavigationTree();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $tree,
|
||||
'meta' => [
|
||||
'total_nodes' => $this->navigationService->countNodes($tree),
|
||||
'generated_at' => now()->toIso8601String()
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen spezifischen Teil des Navigationsbaums zurück
|
||||
*
|
||||
* @param int $rootId Die ID des Root-Knotens
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getNavigationSubTree(int $rootId): JsonResponse
|
||||
{
|
||||
try {
|
||||
$tree = $this->navigationService->getNavigationSubTree($rootId);
|
||||
|
||||
if (!$tree) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => 'Navigation node not found'
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $tree,
|
||||
'meta' => [
|
||||
'total_nodes' => $this->navigationService->countNodes([$tree]),
|
||||
'generated_at' => now()->toIso8601String()
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt eine flache Liste aller Navigationspunkte zurück (ohne Hierarchie)
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getFlatNavigationList(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$list = $this->navigationService->getFlatNavigationList();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $list,
|
||||
'meta' => [
|
||||
'total_nodes' => count($list),
|
||||
'generated_at' => now()->toIso8601String()
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt nur die aktiven Navigationspunkte zurück
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getActiveNavigationTree(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$tree = $this->navigationService->getNavigationTree(true);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $tree,
|
||||
'meta' => [
|
||||
'total_nodes' => $this->navigationService->countNodes($tree),
|
||||
'generated_at' => now()->toIso8601String()
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den Breadcrumb-Pfad für eine bestimmte Seite zurück
|
||||
*
|
||||
* @param int $pageId
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getBreadcrumb(int $pageId): JsonResponse
|
||||
{
|
||||
try {
|
||||
$breadcrumb = $this->navigationService->getBreadcrumb($pageId);
|
||||
|
||||
if (empty($breadcrumb)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => 'Page not found'
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $breadcrumb,
|
||||
'meta' => [
|
||||
'depth' => count($breadcrumb),
|
||||
'generated_at' => now()->toIso8601String()
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Navigation-Cache
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function clearCache(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$this->navigationService->clearCache();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Navigation cache cleared successfully'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,8 +30,15 @@ class UserController extends Controller
|
|||
return response()->json(['error' => 'Unauthorised'], 401);
|
||||
|
||||
}
|
||||
return response()->json(['error' => 'Unauthorised', 'email' => request('email')], 401);
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
return "testing";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register api
|
||||
* api.mein.sterntours.de
|
||||
|
|
|
|||
396
app/Http/Controllers/Admin/ReportBookingController.php
Normal file
396
app/Http/Controllers/Admin/ReportBookingController.php
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Request;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Status;
|
||||
use App\Services\Util;
|
||||
use App\Models\Booking;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Exports\ReportCollectionExport;
|
||||
|
||||
class ReportBookingController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function bookings()
|
||||
{
|
||||
$data = [
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.bookings', $data);
|
||||
}
|
||||
|
||||
public function checkBookings()
|
||||
{
|
||||
$data = [
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.check_bookings', $data);
|
||||
}
|
||||
|
||||
//checkBookingsDatatable
|
||||
|
||||
private function prozessBookingSearch()
|
||||
{
|
||||
|
||||
$query = Booking::with( 'customer', 'lead', 'booking_strono','service_provider_entries', 'service_provider_entries.service_provider')->select('booking.*');
|
||||
|
||||
|
||||
if(Request::get('filter_db_lead_status_id') != ""){
|
||||
$query->whereHas('lead', function ($q) {
|
||||
$q->whereIn('status_id', Request::get('filter_db_lead_status_id'));
|
||||
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_lead_status_id') != ""){
|
||||
$query->whereHas('lead', function ($q) {
|
||||
$q->whereIn('status_id', Request::get('filter_lead_status_id'));
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_travel_company_id') != ""){
|
||||
$query->whereIn("travel_company_id", Request::get('filter_travel_company_id'));
|
||||
}
|
||||
|
||||
if(Request::get('filter_travel_date_from') != ""){
|
||||
$travel_date_from = Carbon::parse(Request::get('filter_travel_date_from'))->format("Y-m-d");
|
||||
$query->where("start_date", '>=', $travel_date_from);
|
||||
}
|
||||
if(Request::get('filter_travel_date_to') != ""){
|
||||
$travel_date_to = Carbon::parse(Request::get('filter_travel_date_to'))->format("Y-m-d");
|
||||
$query->where("start_date", '<=', $travel_date_to);
|
||||
}
|
||||
|
||||
if(Request::get('filter_booking_date_from') != ""){
|
||||
$filter_booking_date_from = Carbon::parse(Request::get('filter_booking_date_from'))->format("Y-m-d");
|
||||
$query->where("booking_date", '>=', $filter_booking_date_from);
|
||||
}
|
||||
if(Request::get('filter_booking_date_to') != ""){
|
||||
$filter_booking_date_from = Carbon::parse(Request::get('filter_booking_date_to'))->format("Y-m-d");
|
||||
$query->where("booking_date", '<=', $filter_booking_date_from);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function bookingsDatatable()
|
||||
{
|
||||
$query = $this->prozessBookingSearch();
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->with('price_total_sum', function() use ($query) {
|
||||
$price1 = with(clone $query)->whereNull('canceled')->sum('price');
|
||||
$price2 = with(clone $query)->whereNotNull('canceled')->sum('price_canceled');
|
||||
return Util::_number_format($price1+$price2);
|
||||
})
|
||||
->with('price_total_total_sum', function() use ($query) {
|
||||
return Util::_number_format($query->sum('price_total'));
|
||||
})
|
||||
->with('proceed_total_sum', function() use ($query) {
|
||||
if($query->count() > 200){
|
||||
return 'max 200 ';
|
||||
}
|
||||
$all = $query->get();
|
||||
$proceeds = 0;
|
||||
foreach ($all as $v){
|
||||
$proceeds += $v->proceeds(true);
|
||||
}
|
||||
return Util::_number_format($proceeds);
|
||||
})
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="' . $booking->id . '" href="' . route('booking_detail', [$booking->id]) . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('customer.fullName', function (Booking $booking) {
|
||||
return $booking->customer->fullName();
|
||||
})
|
||||
->addColumn('price', function (Booking $booking) {
|
||||
return $booking->booking_strono ? $booking->price_canceled : $booking->price;
|
||||
})
|
||||
->addColumn('proceeds', function (Booking $booking) {
|
||||
return $booking->proceeds();
|
||||
})
|
||||
->addColumn('start_date', function (Booking $booking) {
|
||||
return $booking->getStartDateFormat();
|
||||
})
|
||||
->addColumn('end_date', function (Booking $booking) {
|
||||
return $booking->getEndDateFormat();
|
||||
})
|
||||
->addColumn('booking_date', function (Booking $booking) {
|
||||
return $booking->getBookingDateFormat();
|
||||
})
|
||||
->addColumn('booking_strono_date', function (Booking $booking) {
|
||||
return $booking->booking_strono ? $booking->booking_strono->storno_date->format("d.m.Y") : "";
|
||||
})
|
||||
->addColumn('service_provider.names', function (Booking $booking) {
|
||||
$ret = "";
|
||||
if($booking->service_provider_entries){
|
||||
foreach ($booking->service_provider_entries as $service_provider_entry){
|
||||
$ret .= '<span class="ui-stars">'.$service_provider_entry->service_provider->name." | ";
|
||||
$ret .= $service_provider_entry->getAmountFinalEur()." | ";
|
||||
$ret .= $service_provider_entry->is_cleared ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>';
|
||||
$ret .= "</span><br>";
|
||||
}
|
||||
}
|
||||
return $ret === "" ? "-" : $ret;
|
||||
})
|
||||
->addColumn('lead.status_id', function (Booking $booking) {
|
||||
if($booking->lead && $booking->lead->status_id){
|
||||
$color = $booking->lead->status->color;
|
||||
$icon = "";
|
||||
if($booking->lead->status_id == 14 && $booking->lead->is_rebook){
|
||||
$color = '#94ae59';
|
||||
$icon = '<i class="fa fa-check-circle"></i> ';
|
||||
}
|
||||
if($booking->lead->status_id == 14 && !$booking->lead->is_rebook){
|
||||
$icon = '<i class="fa fa-times-circle"></i> ';
|
||||
}
|
||||
return '<span data-order="'.$booking->lead->status_id.'"><span class="badge badge-dark" style="background-color: '.$color.'">'.$icon.$booking->lead->status->name.'</span></span>';
|
||||
}
|
||||
return '<span data-order="0">-</span>';
|
||||
})
|
||||
->filterColumn('customer.fullName', function ($query, $keyword) {
|
||||
if ($keyword != "") {
|
||||
$query->whereHas('customer', function ($q) use ($keyword) {
|
||||
$q->where("name", 'LIKE', '%' . $keyword . '%')
|
||||
->orWhere('firstname', 'LIKE', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('start_date', 'start_date $1')
|
||||
->orderColumn('end_date', 'end_date $1')
|
||||
->orderColumn('price', 'price $1')
|
||||
->orderColumn('booking_date', 'booking_date $1')
|
||||
->orderColumn('customer.fullName', 'customer.firstname $1')
|
||||
->orderColumn('customer.firstname', 'customer.firstname $1')
|
||||
->orderColumn('customer.name', 'customer.name $1')
|
||||
//->orderColumn('lead.status_id', 'lead.status_id $1')
|
||||
//->orderColumn('is_cleared', 'is_cleared $1')
|
||||
->rawColumns(['id', 'lead.status_id', 'service_provider.names'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
public function bookingsExport(){
|
||||
|
||||
$query = $this->prozessBookingSearch();
|
||||
|
||||
$order = explode(",", Request::get('order'));
|
||||
$orderByNum = [
|
||||
0 => "id",
|
||||
2 => "merlin_order_number",
|
||||
3 => "price",
|
||||
4 => "price_total",
|
||||
7 => "start_date",
|
||||
8 => "end_date",
|
||||
9 => "booking_date",
|
||||
];
|
||||
if(isset($order[0])) {
|
||||
$column = isset($orderByNum[$order[0]]) ? $orderByNum[$order[0]] : "start_date";
|
||||
$direction = isset($order[1]) ? strtoupper($order[1]) : "ASC";
|
||||
$query->orderBy($column, $direction);
|
||||
}
|
||||
|
||||
$filename = "file-".date('Y-m-d-H-i-s');
|
||||
$exports = $query->get();
|
||||
$columns = [];
|
||||
|
||||
if(Request::get('export') === "export"){
|
||||
$filename = "Buchungen_".date('Y-m-d-H-i-s');
|
||||
|
||||
$headers = array(
|
||||
'BuchungsID',
|
||||
'Status',
|
||||
'Storno',
|
||||
'MyJack Nr.',
|
||||
'Organisation',
|
||||
'Reisepreis',
|
||||
'Erlös',
|
||||
'Kunde',
|
||||
'Reisedatum',
|
||||
'bis',
|
||||
'Buchungsdatum',
|
||||
'Reiseland',
|
||||
'Reiseprogramm',
|
||||
'Reiseteilnehmer',
|
||||
'Leistungsträger',
|
||||
'Zahlung',
|
||||
'Zahlungsdatum',
|
||||
'Rechnungsnummer',
|
||||
'abgeschlossen',
|
||||
);
|
||||
$total_price = 0;
|
||||
$total_price_total = 0;
|
||||
$total_proceeds = 0;
|
||||
$total_amount_final = 0;
|
||||
|
||||
foreach($exports as $export) {
|
||||
$storno_date = $export->booking_strono ? $export->booking_strono->storno_date->format("d.m.Y") : "";
|
||||
if($export->service_provider_entries->count()){
|
||||
$new = true;
|
||||
foreach ($export->service_provider_entries as $service_provider_entry){
|
||||
if($new){
|
||||
$total_price += $export->isCanceled() ? $export->getPriceCanceledRaw() : $export->getPriceRaw();
|
||||
$total_price_total += $export->getPriceTotalRaw();
|
||||
$total_proceeds += $export->proceeds(true);
|
||||
}
|
||||
$total_amount_final += $service_provider_entry->getAmountFinalEurRaw();
|
||||
$columns[] = array(
|
||||
'BuchungsID' => $new ? $export->id : "",
|
||||
'Status' => $new ? $export->lead->status->name : "",
|
||||
'Storno' => $new ? $storno_date : "",
|
||||
'MyJack Nr.' => $new ? $export->merlin_order_number : "",
|
||||
'Organisation' => $new ? ($export->isCanceled() ? $export->price_canceled : $export->price) : "",
|
||||
'Reisepreis' => $new ? $export->price_total : "",
|
||||
'Erlös' => $new ? $export->proceeds() : "",
|
||||
'Kunde' => $new ? $export->customer->fullName() : "",
|
||||
'Reisedatum' => $new ? $export->getStartDateFormat() : "",
|
||||
'bis' => $new ? $export->getEndDateFormat() : "",
|
||||
'Buchungsdatum' => $new ? $export->getBookingDateFormat() : "",
|
||||
'Reiseland' => $new && $export->travel_country ? $export->travel_country->name : "",
|
||||
'Reiseprogramm' => $new && $export->travel_agenda ? $export->travel_agenda->name : "",
|
||||
'Reiseteilnehmer' => $new ? $export->pax : "",
|
||||
'Leistungsträger' => $service_provider_entry->service_provider->name,
|
||||
'Zahlung' => $service_provider_entry->getAmountFinalEur(),
|
||||
'Zahlungsdatum' => $service_provider_entry->getPaymentDateFormat(),
|
||||
'Rechnungsnummer' => $service_provider_entry->invoice_number,
|
||||
'abgeschlossen' => $service_provider_entry->is_cleared ? 'J' : 'N',
|
||||
|
||||
);
|
||||
$new = false;
|
||||
}
|
||||
}else{
|
||||
|
||||
//$total_price += $export->booking->isCanceled() ? $export->booking->getPriceCanceledRaw() : $export->booking->getPriceRaw();
|
||||
$total_price += $export->isCanceled() ? $export->getPriceCanceledRaw() : $export->getPriceRaw();
|
||||
$columns[] = array(
|
||||
'BuchungsID' => $export->id,
|
||||
'Status' => $export->lead->status->name,
|
||||
'Storno' => $storno_date,
|
||||
'MyJack Nr.' => $export->merlin_order_number,
|
||||
'Organisation' => $export->price,
|
||||
'Organisation' => $export->isCanceled() ? $export->price_canceled : $export->price,
|
||||
'Reisepreis' => $export->price_total,
|
||||
'Erlös' => $export->proceeds(),
|
||||
'Kunde' => $export->customer->fullName(),
|
||||
'Reisedatum' => $export->getStartDateFormat(),
|
||||
'bis' => $export->getEndDateFormat(),
|
||||
'Buchungsdatum' => $export->getBookingDateFormat(),
|
||||
'Reiseland' => $export->travel_country ? $export->travel_country->name : "",
|
||||
'Reiseprogramm' => $export->travel_agenda ? $export->travel_agenda->name : "",
|
||||
'Reiseteilnehmer' => $export->pax,
|
||||
'Leistungsträger' => "",
|
||||
'Zahlung' => "",
|
||||
'Zahlungsdatum' => "",
|
||||
'Rechnungsnummer' => "",
|
||||
'abgeschlossen' => "",
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
$columns[] = array(
|
||||
'BuchungsID' => "Total",
|
||||
'Status' => "",
|
||||
'Storno' => "",
|
||||
'MyJack Nr.' => "",
|
||||
'Organisation' => Util::_number_format($total_price),
|
||||
'Reisepreis' => Util::_number_format($total_price_total),
|
||||
'Erlös' => Util::_number_format($total_proceeds),
|
||||
'Kunde' => "",
|
||||
'Reisedatum' => "",
|
||||
'bis' => "",
|
||||
'Buchungsdatum' => "",
|
||||
'Reiseland' => "",
|
||||
'Reiseprogramm' => "",
|
||||
'Reiseteilnehmer' => "",
|
||||
'Leistungsträger' => "",
|
||||
'Zahlung' => Util::_number_format($total_amount_final),
|
||||
'Zahlungsdatum' => "",
|
||||
'Rechnungsnummer' => "",
|
||||
'abgeschlossen' => "",
|
||||
);
|
||||
}
|
||||
return Excel::download(new ReportCollectionExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
|
||||
public function checkBookingsDatatable()
|
||||
{
|
||||
$query = $this->prozessBookingSearch();
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="' . $booking->id . '" href="' . route('booking_detail', [$booking->id]) . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('old_crm', function (Booking $booking) {
|
||||
return '<a data-order="'.$booking->id.'" href="'.make_old_url('booking/'.$booking->id.'/edit').'" data-id="'.$booking->id.'">'.$booking->id.'</a>';
|
||||
})
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="' . $booking->id . '" href="' . route('booking_detail', [$booking->id]) . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('price', function (Booking $booking) {
|
||||
return $booking->price;
|
||||
})
|
||||
->addColumn('service_total', function (Booking $booking) {
|
||||
return $booking->getServiceTotal();
|
||||
})
|
||||
->addColumn('price_total', function (Booking $booking) {
|
||||
return $booking->price_total;
|
||||
})
|
||||
->addColumn('check_total', function (Booking $booking) {
|
||||
$check = $booking->getPriceRaw() + $booking->getServiceTotal(true);
|
||||
return ($booking->getPriceTotalRaw() != $check) ? '<span class="badge badge-danger">'.Util::_number_format($check).'</span>' : "";
|
||||
})
|
||||
->addColumn('price_canceled', function (Booking $booking) {
|
||||
return $booking->isCanceled() ? $booking->price_canceled : "";
|
||||
})
|
||||
|
||||
->addColumn('start_date', function (Booking $booking) {
|
||||
return $booking->getStartDateFormat();
|
||||
})
|
||||
->addColumn('end_date', function (Booking $booking) {
|
||||
return $booking->getEndDateFormat();
|
||||
})
|
||||
->addColumn('booking_date', function (Booking $booking) {
|
||||
return $booking->getBookingDateFormat();
|
||||
})
|
||||
|
||||
->addColumn('lead.status_id', function (Booking $booking) {
|
||||
if($booking->lead && $booking->lead->status_id){
|
||||
$color = $booking->lead->status->color;
|
||||
$icon = "";
|
||||
if($booking->lead->status_id == 14 && $booking->lead->is_rebook){
|
||||
$color = '#94ae59';
|
||||
$icon = '<i class="fa fa-check-circle"></i> ';
|
||||
}
|
||||
if($booking->lead->status_id == 14 && !$booking->lead->is_rebook){
|
||||
$icon = '<i class="fa fa-times-circle"></i> ';
|
||||
}
|
||||
return '<span data-order="'.$booking->lead->status_id.'"><span class="badge badge-dark" style="background-color: '.$color.'">'.$icon.$booking->lead->status->name.'</span></span>';
|
||||
}
|
||||
return '<span data-order="0">-</span>';
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('old_crm', 'old_crm $1')
|
||||
->orderColumn('start_date', 'start_date $1')
|
||||
->orderColumn('end_date', 'end_date $1')
|
||||
->orderColumn('price', 'price $1')
|
||||
->orderColumn('booking_date', 'booking_date $1')
|
||||
->orderColumn('customer.firstname', 'customer.firstname $1')
|
||||
->orderColumn('customer.name', 'customer.name $1')
|
||||
//->orderColumn('lead.status_id', 'lead.status_id $1')
|
||||
//->orderColumn('is_cleared', 'is_cleared $1')
|
||||
->rawColumns(['id', 'old_crm', 'check_total', 'lead.status_id'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -11,6 +11,7 @@ use App\Models\Status;
|
|||
use App\Services\Util;
|
||||
use App\Models\Booking;
|
||||
use App\Models\TravelAgenda;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\ServiceProvider;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -29,6 +30,8 @@ class ReportController extends Controller
|
|||
{
|
||||
$data = [
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.bookings', $data);
|
||||
}
|
||||
|
|
@ -38,10 +41,24 @@ class ReportController extends Controller
|
|||
$data = [
|
||||
'serviceProviders' => ServiceProvider::all(),
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.service_providers', $data);
|
||||
}
|
||||
|
||||
public function checkBookings()
|
||||
{
|
||||
$data = [
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.check_bookings', $data);
|
||||
}
|
||||
|
||||
//checkBookingsDatatable
|
||||
|
||||
private function prozessBookingSearch()
|
||||
{
|
||||
|
||||
|
|
@ -59,6 +76,10 @@ class ReportController extends Controller
|
|||
$q->whereIn('status_id', Request::get('filter_lead_status_id'));
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_travel_company_id') != ""){
|
||||
$query->whereIn("travel_company_id", Request::get('filter_travel_company_id'));
|
||||
}
|
||||
|
||||
if(Request::get('filter_travel_date_from') != ""){
|
||||
$travel_date_from = Carbon::parse(Request::get('filter_travel_date_from'))->format("Y-m-d");
|
||||
$query->where("start_date", '>=', $travel_date_from);
|
||||
|
|
@ -86,7 +107,9 @@ class ReportController extends Controller
|
|||
|
||||
return \DataTables::eloquent($query)
|
||||
->with('price_total_sum', function() use ($query) {
|
||||
return Util::_number_format($query->sum('price'));
|
||||
$price1 = with(clone $query)->whereNull('canceled')->sum('price');
|
||||
$price2 = with(clone $query)->whereNotNull('canceled')->sum('price_canceled');
|
||||
return Util::_number_format($price1+$price2);
|
||||
})
|
||||
->with('price_total_total_sum', function() use ($query) {
|
||||
return Util::_number_format($query->sum('price_total'));
|
||||
|
|
@ -108,6 +131,9 @@ class ReportController extends Controller
|
|||
->addColumn('customer.fullName', function (Booking $booking) {
|
||||
return $booking->customer->fullName();
|
||||
})
|
||||
->addColumn('price', function (Booking $booking) {
|
||||
return $booking->booking_strono ? $booking->price_canceled : $booking->price;
|
||||
})
|
||||
->addColumn('proceeds', function (Booking $booking) {
|
||||
return $booking->proceeds();
|
||||
})
|
||||
|
|
@ -161,6 +187,7 @@ class ReportController extends Controller
|
|||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('start_date', 'start_date $1')
|
||||
->orderColumn('end_date', 'end_date $1')
|
||||
->orderColumn('price', 'price $1')
|
||||
->orderColumn('booking_date', 'booking_date $1')
|
||||
->orderColumn('customer.fullName', 'customer.firstname $1')
|
||||
->orderColumn('customer.firstname', 'customer.firstname $1')
|
||||
|
|
@ -230,7 +257,7 @@ class ReportController extends Controller
|
|||
$new = true;
|
||||
foreach ($export->service_provider_entries as $service_provider_entry){
|
||||
if($new){
|
||||
$total_price += $export->getPriceRaw();
|
||||
$total_price += $export->isCanceled() ? $export->getPriceCanceledRaw() : $export->getPriceRaw();
|
||||
$total_price_total += $export->getPriceTotalRaw();
|
||||
$total_proceeds += $export->proceeds(true);
|
||||
}
|
||||
|
|
@ -240,7 +267,7 @@ class ReportController extends Controller
|
|||
'Status' => $new ? $export->lead->status->name : "",
|
||||
'Storno' => $new ? $storno_date : "",
|
||||
'MyJack Nr.' => $new ? $export->merlin_order_number : "",
|
||||
'Organisation' => $new ? $export->price : "",
|
||||
'Organisation' => $new ? ($export->isCanceled() ? $export->price_canceled : $export->price) : "",
|
||||
'Reisepreis' => $new ? $export->price_total : "",
|
||||
'Erlös' => $new ? $export->proceeds() : "",
|
||||
'Kunde' => $new ? $export->customer->fullName() : "",
|
||||
|
|
@ -260,13 +287,16 @@ class ReportController extends Controller
|
|||
$new = false;
|
||||
}
|
||||
}else{
|
||||
$total_price += $export->getPriceRaw();
|
||||
|
||||
//$total_price += $export->booking->isCanceled() ? $export->booking->getPriceCanceledRaw() : $export->booking->getPriceRaw();
|
||||
$total_price += $export->isCanceled() ? $export->getPriceCanceledRaw() : $export->getPriceRaw();
|
||||
$columns[] = array(
|
||||
'BuchungsID' => $export->id,
|
||||
'Status' => $export->lead->status->name,
|
||||
'Storno' => $storno_date,
|
||||
'MyJack Nr.' => $export->merlin_order_number,
|
||||
'Organisation' => $export->price,
|
||||
'Organisation' => $export->isCanceled() ? $export->price_canceled : $export->price,
|
||||
'Reisepreis' => $export->price_total,
|
||||
'Erlös' => $export->proceeds(),
|
||||
'Kunde' => $export->customer->fullName(),
|
||||
|
|
@ -330,7 +360,11 @@ class ReportController extends Controller
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
if(Request::get('filter_travel_company_id') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$q->whereIn("travel_company_id", Request::get('filter_travel_company_id'));
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_is_cleared') != ""){
|
||||
$query->where('is_cleared', '=', Request::get('filter_is_cleared'));
|
||||
}
|
||||
|
|
@ -366,8 +400,11 @@ class ReportController extends Controller
|
|||
$price = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
$price += in_array($v->booking->lead_id, $isset) ? 0 : $v->booking->getPriceRaw();
|
||||
$isset[] = $v->booking->lead_id;
|
||||
if(!in_array($v->booking->inquiry_id, $isset)){
|
||||
$price += $v->booking->isCanceled() ? $v->booking->getPriceCanceledRaw() : $v->booking->getPriceRaw();
|
||||
}
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
|
||||
}
|
||||
return Util::_number_format($price);
|
||||
})
|
||||
|
|
@ -379,8 +416,8 @@ class ReportController extends Controller
|
|||
$price = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
$price += in_array($v->booking->lead_id, $isset) ? 0 : $v->booking->getPriceTotalRaw();
|
||||
$isset[] = $v->booking->lead_id;
|
||||
$price += in_array($v->booking->inquiry_id, $isset) ? 0 : $v->booking->getPriceTotalRaw();
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
}
|
||||
return Util::_number_format($price);
|
||||
})
|
||||
|
|
@ -392,8 +429,8 @@ class ReportController extends Controller
|
|||
$proceeds = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
$proceeds += in_array($v->booking->lead_id, $isset) ? 0 : $v->booking->proceeds(true);
|
||||
$isset[] = $v->booking->lead_id;
|
||||
$proceeds += in_array($v->booking->inquiry_id, $isset) ? 0 : $v->booking->proceeds(true);
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
}
|
||||
return Util::_number_format($proceeds);
|
||||
/*$all = $query->get();
|
||||
|
|
@ -409,6 +446,9 @@ class ReportController extends Controller
|
|||
->addColumn('booking.customer.fullName', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->customer->fullName();
|
||||
})
|
||||
->addColumn('booking.price', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->booking_strono ? $serviceProviderEntry->booking->price_canceled : $serviceProviderEntry->booking->price;
|
||||
})
|
||||
->addColumn('booking.proceeds', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->proceeds();
|
||||
})
|
||||
|
|
@ -447,6 +487,7 @@ class ReportController extends Controller
|
|||
}
|
||||
})
|
||||
->orderColumn('booking.id', 'booking.id $1')
|
||||
->orderColumn('booking.price', 'booking.price $1')
|
||||
->orderColumn('booking.start_date', 'booking.start_date $1')
|
||||
->orderColumn('booking.end_date', 'booking.end_date $1')
|
||||
->orderColumn('booking.customer.firstname', 'booking.customer.firstname $1')
|
||||
|
|
@ -513,7 +554,7 @@ class ReportController extends Controller
|
|||
foreach($exports as $export) {
|
||||
$new = in_array($export->booking->id, $isset) ? false : true;
|
||||
if($new){
|
||||
$total_price += $export->booking->getPriceRaw();
|
||||
$total_price += $export->booking->isCanceled() ? $export->booking->getPriceCanceledRaw() : $export->booking->getPriceRaw();
|
||||
$total_price_total += $export->booking->getPriceTotalRaw();
|
||||
$total_proceeds += $export->booking->proceeds(true);
|
||||
}
|
||||
|
|
@ -521,10 +562,10 @@ class ReportController extends Controller
|
|||
$ctemps[$export->booking->id][] = array(
|
||||
'Zähler' => $new ? $export->getCounter() : "",
|
||||
'MyJack Nr.' => $new ? $export->booking->merlin_order_number : "",
|
||||
'CRM Nr' => $new ? $export->booking->lead_id : "",
|
||||
'CRM Nr' => $new ? $export->booking->inquiry_id : "",
|
||||
'Kunde' => $new ? $export->booking->customer->name : "",
|
||||
'Reisedatum' => $new ? $export->booking->getStartDateFormat() : "",
|
||||
'Organisation' => $new ? $export->booking->price : "",
|
||||
'Organisation' => $new ? ($export->booking->isCanceled() ? $export->booking->price_canceled : $export->booking->price) : "",
|
||||
'Gesamtreisepreis' => $new ? $export->booking->price_total : "",
|
||||
'Reiseland' => $new && $export->booking->travel_country ? $export->booking->travel_country->name : "",
|
||||
'Reiseprogramm' => $new && $export->booking->travel_agenda ? $export->booking->travel_agenda->name : "",
|
||||
|
|
@ -589,7 +630,7 @@ class ReportController extends Controller
|
|||
$ctemps[$export->booking->id][] = array(
|
||||
'Zähler' => $new ? $export->getCounter() : "",
|
||||
'MyJack Nr.' => $new ? $export->booking->merlin_order_number : "",
|
||||
'CRM Nr' => $new ? $export->booking->lead_id : "",
|
||||
'CRM Nr' => $new ? $export->booking->inquiry_id : "",
|
||||
'Kunde' => $new ? $export->booking->customer->name : "",
|
||||
'Reisedatum' => $new ? $export->booking->getStartDateFormat() : "",
|
||||
'Reiseland' => $new && $export->booking->travel_country ? $export->booking->travel_country->name : "",
|
||||
|
|
@ -622,6 +663,75 @@ class ReportController extends Controller
|
|||
}
|
||||
return Excel::download(new ReportCollectionExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
|
||||
public function checkBookingsDatatable()
|
||||
{
|
||||
$query = $this->prozessBookingSearch();
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="' . $booking->id . '" href="' . route('booking_detail', [$booking->id]) . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('old_crm', function (Booking $booking) {
|
||||
return '<a data-order="'.$booking->id.'" href="'.make_old_url('booking/'.$booking->id.'/edit').'" data-id="'.$booking->id.'">'.$booking->id.'</a>';
|
||||
})
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="' . $booking->id . '" href="' . route('booking_detail', [$booking->id]) . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('price', function (Booking $booking) {
|
||||
return $booking->price;
|
||||
})
|
||||
->addColumn('service_total', function (Booking $booking) {
|
||||
return $booking->getServiceTotal();
|
||||
})
|
||||
->addColumn('price_total', function (Booking $booking) {
|
||||
return $booking->price_total;
|
||||
})
|
||||
->addColumn('check_total', function (Booking $booking) {
|
||||
$check = $booking->getPriceRaw() + $booking->getServiceTotal(true);
|
||||
return ($booking->getPriceTotalRaw() != $check) ? '<span class="badge badge-danger">'.Util::_number_format($check).'</span>' : "";
|
||||
})
|
||||
->addColumn('price_canceled', function (Booking $booking) {
|
||||
return $booking->isCanceled() ? $booking->price_canceled : "";
|
||||
})
|
||||
|
||||
->addColumn('start_date', function (Booking $booking) {
|
||||
return $booking->getStartDateFormat();
|
||||
})
|
||||
->addColumn('end_date', function (Booking $booking) {
|
||||
return $booking->getEndDateFormat();
|
||||
})
|
||||
->addColumn('booking_date', function (Booking $booking) {
|
||||
return $booking->getBookingDateFormat();
|
||||
})
|
||||
|
||||
->addColumn('lead.status_id', function (Booking $booking) {
|
||||
if($booking->lead && $booking->lead->status_id){
|
||||
$color = $booking->lead->status->color;
|
||||
$icon = "";
|
||||
if($booking->lead->status_id == 14 && $booking->lead->is_rebook){
|
||||
$color = '#94ae59';
|
||||
$icon = '<i class="fa fa-check-circle"></i> ';
|
||||
}
|
||||
if($booking->lead->status_id == 14 && !$booking->lead->is_rebook){
|
||||
$icon = '<i class="fa fa-times-circle"></i> ';
|
||||
}
|
||||
return '<span data-order="'.$booking->lead->status_id.'"><span class="badge badge-dark" style="background-color: '.$color.'">'.$icon.$booking->lead->status->name.'</span></span>';
|
||||
}
|
||||
return '<span data-order="0">-</span>';
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('old_crm', 'old_crm $1')
|
||||
->orderColumn('start_date', 'start_date $1')
|
||||
->orderColumn('end_date', 'end_date $1')
|
||||
->orderColumn('price', 'price $1')
|
||||
->orderColumn('booking_date', 'booking_date $1')
|
||||
->orderColumn('customer.firstname', 'customer.firstname $1')
|
||||
->orderColumn('customer.name', 'customer.name $1')
|
||||
//->orderColumn('lead.status_id', 'lead.status_id $1')
|
||||
//->orderColumn('is_cleared', 'is_cleared $1')
|
||||
->rawColumns(['id', 'old_crm', 'check_total', 'lead.status_id'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
205
app/Http/Controllers/Admin/ReportFewoController.php
Normal file
205
app/Http/Controllers/Admin/ReportFewoController.php
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
use HTMLHelper;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Status;
|
||||
use App\Services\Util;
|
||||
use App\Models\Booking;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Models\TravelAgenda;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\ServiceProvider;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ServiceProviderEntry;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Models\TravelUserBookingFewo;
|
||||
use App\Exports\ReportCollectionExport;
|
||||
|
||||
class ReportFewoController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function fewo()
|
||||
{
|
||||
$data = [
|
||||
'filter_fewo_options' => FewoLodging::get()->pluck('name', 'id'),
|
||||
|
||||
];
|
||||
return view('admin.report.fewo', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//checkFewoDatatable
|
||||
|
||||
private function prozessFewoSearch()
|
||||
{
|
||||
|
||||
$query = TravelUserBookingFewo::with('travel_booking_fewo_channel')->with('fewo_lodging')
|
||||
->select('travel_user_booking_fewos.*')
|
||||
->where('deleted_at', '=', null);
|
||||
|
||||
if(Request::get('filter_option_fewo_id') != ""){
|
||||
$query->where('fewo_lodging_id', '=', Request::get('filter_option_fewo_id'));
|
||||
}
|
||||
|
||||
if(Request::get('filter_date_from') != ""){
|
||||
$date_from = Carbon::parse(Request::get('filter_date_from'))->format("Y-m-d");
|
||||
$query->where("from_date", '>=', $date_from);
|
||||
}
|
||||
if(Request::get('filter_date_to') != ""){
|
||||
$date_to = Carbon::parse(Request::get('filter_date_to'))->format("Y-m-d");
|
||||
$query->where("from_date", '<=', $date_to);
|
||||
}
|
||||
|
||||
if(Request::get('filter_booking_date_from') != ""){
|
||||
$booking_date_from = Carbon::parse(Request::get('filter_booking_date_from'))->format("Y-m-d");
|
||||
$query->where("booking_date", '>=', $booking_date_from);
|
||||
}
|
||||
if(Request::get('filter_booking_date_to') != ""){
|
||||
$booking_date_to = Carbon::parse(Request::get('filter_booking_date_to'))->format("Y-m-d");
|
||||
$query->where("booking_date", '<=', $booking_date_to);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function fewoDatatable()
|
||||
{
|
||||
$query = $this->prozessFewoSearch();
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->with('price_total_sum', function() use ($query) {
|
||||
if($query->count() > 2000){
|
||||
return 'max 2000 ';
|
||||
}
|
||||
$all = $query->get();
|
||||
$proceeds = 0;
|
||||
foreach ($all as $v){
|
||||
$proceeds += $v->getPriceTotalRaw();
|
||||
}
|
||||
return Util::_number_format($proceeds);
|
||||
})
|
||||
->addColumn('id', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
return '<a data-order="'.$travel_user_booking_fewo->id.'" href="' . route('travel_user_booking_fewo_detail', [$travel_user_booking_fewo->id]) . '" class="">' . $travel_user_booking_fewo->id . '</a>';
|
||||
|
||||
// return '<a data-order="' . $travel_user_booking_fewo->id . '" href="' . route('booking_detail', [$travel_user_booking_fewo->id]) . '" data-id="' . $travel_user_booking_fewo->id . '">' . $travel_user_booking_fewo->id . '</a>';
|
||||
})
|
||||
->addColumn('travel_user', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
return '<a href="' . route('travel_user_detail', [$travel_user_booking_fewo->travel_user_id]) . '">'.$travel_user_booking_fewo->travel_user->first_name.' '.$travel_user_booking_fewo->travel_user->last_name.'</a>';
|
||||
})
|
||||
|
||||
/* ->addColumn('start_date', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
return $travel_user_booking_fewo->getStartDateFormat();
|
||||
})
|
||||
->addColumn('end_date', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
return $travel_user_booking_fewo->getEndDateFormat();
|
||||
})
|
||||
/* ->addColumn('booking_date', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
return $travel_user_booking_fewo->getBookingDateFormat();
|
||||
})
|
||||
*/
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('from_date', 'from_date $1')
|
||||
->orderColumn('to_date', 'to_date $1')
|
||||
->orderColumn('price_total', 'price_total $1')
|
||||
->orderColumn('booking_date', 'booking_date $1')
|
||||
->orderColumn('invoice_number', 'invoice_number $1')
|
||||
|
||||
|
||||
//->orderColumn('lead.status_id', 'lead.status_id $1')
|
||||
//->orderColumn('is_cleared', 'is_cleared $1')
|
||||
->rawColumns(['id', 'travel_user'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
public function fewoExport(){
|
||||
|
||||
$query = $this->prozessFewoSearch();
|
||||
$order = explode(",", Request::get('order'));
|
||||
$orderByNum = [
|
||||
0 => 'id',
|
||||
1 => 'fewo_lodging.name',
|
||||
2 => 'travel_user',
|
||||
3 => 'from_date',
|
||||
4 => 'to_date',
|
||||
5 => 'adults',
|
||||
6 => 'children',
|
||||
7 => 'persons',
|
||||
8 => 'price_total',
|
||||
9 => 'booking_date',
|
||||
10 => 'invoice_number',
|
||||
];
|
||||
if(isset($order[0])) {
|
||||
$column = isset($orderByNum[$order[0]]) ? $orderByNum[$order[0]] : "id";
|
||||
$direction = isset($order[1]) ? strtoupper($order[1]) : "ASC";
|
||||
$query->orderBy($column, $direction);
|
||||
}
|
||||
|
||||
$filename = "file-".date('Y-m-d-H-i-s');
|
||||
$exports = $query->get();
|
||||
$columns = [];
|
||||
|
||||
if(Request::get('export') === "export"){
|
||||
$filename = "Buchungen_Fewo_".date('Y-m-d-H-i-s');
|
||||
|
||||
$headers = array(
|
||||
'BuchungsID',
|
||||
'FeWo',
|
||||
'Kunde',
|
||||
'vom',
|
||||
'bis',
|
||||
'Erwachsene',
|
||||
'Kinder',
|
||||
'Gesamt',
|
||||
'Betrag',
|
||||
'Buchungsdatum',
|
||||
'R-Nr',
|
||||
);
|
||||
$total_price_total = 0;
|
||||
|
||||
foreach($exports as $export) {
|
||||
$total_price_total += $export->getPriceTotalRaw();
|
||||
$columns[] = array(
|
||||
'BuchungsID' => $export->id,
|
||||
'FeWo' => $export->fewo_lodging->name,
|
||||
'Kunde' => $export->travel_user_id ? $export->travel_user->first_name.' '.$export->travel_user->last_name : " ",
|
||||
'vom' => $export->from_date,
|
||||
'bis' => $export->to_date,
|
||||
'Erwachsene' => $export->adults,
|
||||
'Kinder' => $export->children,
|
||||
'Gesamt' => $export->persons,
|
||||
'Betrag' => $export->price_total,
|
||||
'Buchungsdatum' => $export->booking_date,
|
||||
'R-Nr' => $export->invoice_number,
|
||||
);
|
||||
}
|
||||
|
||||
$columns[] = array(
|
||||
|
||||
'BuchungsID' => "Total",
|
||||
'FeWo' => "",
|
||||
'Kunde' => "",
|
||||
'vom' => "",
|
||||
'bis' => "",
|
||||
'Erwachsene' => "",
|
||||
'Kinder' => "",
|
||||
'Gesamt' => Util::_number_format($total_price_total),
|
||||
'Betrag' => "",
|
||||
'Buchungsdatum' => "",
|
||||
'R-Nr' => "",
|
||||
);
|
||||
}
|
||||
return Excel::download(new ReportCollectionExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
|
||||
}
|
||||
217
app/Http/Controllers/Admin/ReportLeadsController.php
Normal file
217
app/Http/Controllers/Admin/ReportLeadsController.php
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
use HTMLHelper;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Lead;
|
||||
use App\Models\Status;
|
||||
use App\Services\Util;
|
||||
use App\Models\Booking;
|
||||
use App\Models\LeadMail;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Models\TravelAgenda;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\ServiceProvider;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ServiceProviderEntry;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Models\TravelUserBookingFewo;
|
||||
use App\Exports\ReportCollectionExport;
|
||||
|
||||
class ReportLeadsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function leads()
|
||||
{
|
||||
// $query = Lead::with('customer')->with('sf_guard_user')->with('status')->select('lead.*');
|
||||
|
||||
$data = [
|
||||
'filter_leads_options' => [], //need ??? FewoLodging::get()->pluck('name', 'id'),
|
||||
|
||||
];
|
||||
return view('admin.report.leads', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//checkLeadsDatatable
|
||||
|
||||
private function prozessLeadsSearch()
|
||||
{
|
||||
|
||||
$query = Lead::with('customer')->with('sf_guard_user')->with('status')
|
||||
->select('inquiries.*');
|
||||
//->where('deleted_at', '=', null);
|
||||
|
||||
/*
|
||||
if(Request::get('filter_option_leads_id') != ""){
|
||||
$query->where('...?', '=', Request::get('filter_option_leads_id'));
|
||||
}
|
||||
*/
|
||||
if(Request::get('filter_date_from') != ""){
|
||||
$date_from = Carbon::parse(Request::get('filter_date_from'))->format("Y-m-d");
|
||||
$query->where("request_date", '>=', $date_from);
|
||||
}
|
||||
if(Request::get('filter_date_to') != ""){
|
||||
$date_to = Carbon::parse(Request::get('filter_date_to'))->format("Y-m-d");
|
||||
$query->where("request_date", '<=', $date_to);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function leadsDatatable()
|
||||
{
|
||||
$query = $this->prozessLeadsSearch();
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
|
||||
->addColumn('id', function (Lead $lead) {
|
||||
return '<a data-order="'.$lead->id.'" href="'.route('lead_detail', [$lead->id]).'" data-id="'.$lead->id.'">'.$lead->id.'</a>';
|
||||
})
|
||||
->addColumn('customer_id', function (Lead $lead) {
|
||||
return '<a data-order="'.$lead->customer_id.'" href="'.route('customer_detail', [$lead->customer_id]).'" data-id="'.$lead->customer_id.'">'.$lead->customer_id.'</a>';
|
||||
})
|
||||
->addColumn('request_date', function (Lead $lead) {
|
||||
return Carbon::parse($lead->request_date)->format(\Util::formatDateDB());
|
||||
})
|
||||
->addColumn('travel_country', function (Lead $lead) {
|
||||
return $lead->getTravelCountryDestco();
|
||||
})
|
||||
|
||||
->addColumn('status', function (Lead $lead) {
|
||||
return $lead->getStatusBadge();
|
||||
})
|
||||
->addColumn('lead_notice', function (Lead $lead) {
|
||||
return $lead->lead_notices->count() ? '<span data-order="1" class="badge badge-pill badge-success" data-lead_id="'.$lead->id.'" data-action="get_popover_lead_notice" data-placement="top" data-toggle="popover" title="letzte Notiz"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('last_lead_email', function (Lead $lead) {
|
||||
|
||||
if($lead->lead_mails->count()){
|
||||
$lead_mail = $lead->lead_mails_sent_at->last();
|
||||
$badge = $lead_mail->is_answer ? 'badge-default' : 'badge-secondary';
|
||||
$badge = !$lead_mail->send ? $badge : 'badge-success';
|
||||
return '<a data-order="'.$lead_mail->getSentAtRaw().'" href="#" data-toggle="modal"
|
||||
data-target="#modals-load-content"
|
||||
data-id="show-mail"
|
||||
data-url="mail"
|
||||
data-preview="true"
|
||||
data-lead_id="'.$lead->id.'"
|
||||
data-lead_mail_id="'.$lead_mail->id.'"
|
||||
data-action="show-lead-mail"
|
||||
data-redirect="back"
|
||||
data-route="'.route('lead_mail_modal_load').'">
|
||||
<span class="badge '.$badge.'">'
|
||||
.($lead_mail->send ? '<i class="fa fa-check-circle"></i>' : '<i class="fa fa-times-circle"></i>').' '
|
||||
.$lead_mail->sent_at.'</span>
|
||||
</a>';
|
||||
}
|
||||
return '<span data-order="">-</span>';
|
||||
})
|
||||
->addColumn('action_delete', function (Lead $lead) {
|
||||
return '<a href="' . route('lead_delete', [$lead->id, 'lead']) . '" class="btn icon-btn btn-sm btn-danger" onclick="return confirm(\''.__('Really delete entry?').'\');"><span class="fa fa-trash"></span></a>';
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('customer_id', 'customer_id $1')
|
||||
->orderColumn('request_date', 'request_date $1')
|
||||
->orderColumn('status', 'status_id $1')
|
||||
|
||||
->orderColumn('last_lead_email', function ($query, $order) {
|
||||
|
||||
$query->whereHas('lead_mails',
|
||||
function ($q) use ($order) {
|
||||
// $q->select('sent_at')->where('sent_at', DB::raw("(select max('sent_at') customer_mails)")); //)
|
||||
})->orderBy(
|
||||
LeadMail::select('sent_at')
|
||||
->whereColumn('lead_id', 'inquiries.id')
|
||||
->orderBy('sent_at', 'DESC')
|
||||
->limit(1)
|
||||
, $order);
|
||||
})
|
||||
|
||||
->filterColumn('id', function($query, $keyword) {
|
||||
if($keyword != ""){
|
||||
$query->where('id', 'LIKE', '%'.$keyword.'%');
|
||||
}
|
||||
})
|
||||
->filterColumn('customer_id', function($query, $keyword) {
|
||||
if($keyword != ""){
|
||||
$query->where('customer_id', 'LIKE', '%'.$keyword.'%');
|
||||
}
|
||||
})
|
||||
->rawColumns(['action_edit', 'customer_id', 'sf_guard_user_id', 'id', 'status', 'last_lead_email', 'travel_country', 'lead_notice', 'action_delete'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
public function leadsExport(){
|
||||
|
||||
$query = $this->prozessLeadsSearch();
|
||||
$order = explode(",", Request::get('order'));
|
||||
|
||||
|
||||
$orderByNum = [
|
||||
0 => 'id',
|
||||
1 => 'customer_id',
|
||||
2 => 'customer.firstname',
|
||||
3 => 'customer.name',
|
||||
4 => 'customer.email',
|
||||
5 => 'request_date',
|
||||
6 => 'travel_country',
|
||||
7 => 'sf_guard_user.last_name',
|
||||
8 => 'status',
|
||||
9 => 'last_lead_email',
|
||||
];
|
||||
if(isset($order[0])) {
|
||||
$column = isset($orderByNum[$order[0]]) ? $orderByNum[$order[0]] : "id";
|
||||
$direction = isset($order[1]) ? strtoupper($order[1]) : "ASC";
|
||||
$query->orderBy($column, $direction);
|
||||
}
|
||||
|
||||
$filename = "file-".date('Y-m-d-H-i-s');
|
||||
$exports = $query->get();
|
||||
$columns = [];
|
||||
|
||||
if(Request::get('export') === "export"){
|
||||
$filename = "Buchungen_Anfragen_".date('Y-m-d-H-i-s');
|
||||
|
||||
$headers = array(
|
||||
'LeadID',
|
||||
'KundenID',
|
||||
'Vorname',
|
||||
'Nachname',
|
||||
'E-Mail',
|
||||
'Anfrage-Datum',
|
||||
'Reiseland',
|
||||
'Sachbearbeiter',
|
||||
'Status',
|
||||
'Letzte E-Mail',
|
||||
);
|
||||
|
||||
foreach($exports as $export) {
|
||||
$columns[] = array(
|
||||
'LeadID' => $export->id,
|
||||
'KundenID' => $export->customer_id,
|
||||
'Vorname' => $export->customer ? $export->customer->firstname : " ",
|
||||
'Nachname' => $export->customer ? $export->customer->name : " ",
|
||||
'E-Mail' => $export->customer ? $export->customer->email : " ",
|
||||
'Anfrage-Datum' => _format_date($export->request_date),
|
||||
'Reiseland' => $export->getTravelCountryDestco(false),
|
||||
'Sachbearbeiter' => $export->sf_guard_user->last_name,
|
||||
'Status' => $export->status->name,
|
||||
'Letzte E-Mail' => $export->lead_mails->count() ? $export->lead_mails_sent_at->last()->sent_at : " ",
|
||||
);
|
||||
}
|
||||
}
|
||||
return Excel::download(new ReportCollectionExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
|
||||
}
|
||||
388
app/Http/Controllers/Admin/ReportProviderController.php
Normal file
388
app/Http/Controllers/Admin/ReportProviderController.php
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Request;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Status;
|
||||
use App\Services\Util;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\ServiceProvider;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ServiceProviderEntry;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Exports\ReportCollectionExport;
|
||||
|
||||
class ReportProviderController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function providers()
|
||||
{
|
||||
$data = [
|
||||
'serviceProviders' => ServiceProvider::all(),
|
||||
'filter_lead_status' => Status::get()->pluck('name', 'id')->toArray(),
|
||||
'filter_travel_companies' => TravelCompany::where('active', true)->get()->pluck('name', 'id')->toArray(),
|
||||
|
||||
];
|
||||
return view('admin.report.service_providers', $data);
|
||||
}
|
||||
|
||||
private function prozessProvidersSearch(){
|
||||
|
||||
$query = ServiceProviderEntry::with('booking', 'service_provider', 'booking.customer', 'booking.lead')->select('service_provider_entry.*')
|
||||
->join('booking', 'service_provider_entry.booking_id', '=', 'booking.id' );
|
||||
|
||||
if(Request::get('filter_db_lead_status_id') != ""){
|
||||
$query->whereHas('booking', function ($qe) {
|
||||
$qe->whereHas('lead', function ($q) {
|
||||
$q->whereIn('status_id', Request::get('filter_db_lead_status_id'));
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_lead_status_id') != ""){
|
||||
$query->whereHas('booking', function ($qe) {
|
||||
$qe->whereHas('lead', function ($q) {
|
||||
$q->whereIn('status_id', Request::get('filter_lead_status_id'));
|
||||
});
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_travel_company_id') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$q->whereIn("travel_company_id", Request::get('filter_travel_company_id'));
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_is_cleared') != ""){
|
||||
$query->where('is_cleared', '=', Request::get('filter_is_cleared'));
|
||||
}
|
||||
if(Request::get('filter_service_provider_id') != ""){
|
||||
$query->where('service_provider_id', '=', Request::get('filter_service_provider_id'));
|
||||
}
|
||||
if(Request::get('filter_travel_date_from') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$travel_date_from = Carbon::parse(Request::get('filter_travel_date_from'))->format("Y-m-d");
|
||||
$q->where("start_date", '>=', $travel_date_from);
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_travel_date_to') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$travel_date_to = Carbon::parse(Request::get('filter_travel_date_to'))->format("Y-m-d");
|
||||
$q->where("start_date", '<=', $travel_date_to);
|
||||
});
|
||||
}
|
||||
|
||||
if(Request::get('filter_booking_date_from') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$filter_booking_date_from = Carbon::parse(Request::get('filter_booking_date_from'))->format("Y-m-d");
|
||||
$q->where("booking_date", '>=', $filter_booking_date_from);
|
||||
});
|
||||
}
|
||||
if(Request::get('filter_booking_date_to') != ""){
|
||||
$query->whereHas('booking', function ($q) {
|
||||
$filter_booking_date_to = Carbon::parse(Request::get('filter_booking_date_to'))->format("Y-m-d");
|
||||
$q->where("booking_date", '<=', $filter_booking_date_to);
|
||||
});
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function providersDatatable()
|
||||
{
|
||||
$query = $this->prozessProvidersSearch();
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->with('price_total_sum', function() use ($query) {
|
||||
if($query->count() > 200){
|
||||
return 'max 200 ';
|
||||
}
|
||||
$all = $query->get();
|
||||
$price = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
if(!in_array($v->booking->inquiry_id, $isset)){
|
||||
$price += $v->booking->isCanceled() ? $v->booking->getPriceCanceledRaw() : $v->booking->getPriceRaw();
|
||||
}
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
|
||||
}
|
||||
return Util::_number_format($price);
|
||||
})
|
||||
->with('price_total_total_sum', function() use ($query) {
|
||||
if($query->count() > 200){
|
||||
return 'max 200 ';
|
||||
}
|
||||
$all = $query->get();
|
||||
$price = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
$price += in_array($v->booking->inquiry_id, $isset) ? 0 : $v->booking->getPriceTotalRaw();
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
}
|
||||
return Util::_number_format($price);
|
||||
})
|
||||
->with('proceed_total_sum', function() use ($query) {
|
||||
if($query->count() > 200){
|
||||
return 'max 200 ';
|
||||
}
|
||||
$all = $query->get();
|
||||
$proceeds = 0;
|
||||
$isset = [];
|
||||
foreach ($all as $v){
|
||||
$proceeds += in_array($v->booking->inquiry_id, $isset) ? 0 : $v->booking->proceeds(true);
|
||||
$isset[] = $v->booking->inquiry_id;
|
||||
}
|
||||
return Util::_number_format($proceeds);
|
||||
/*$all = $query->get();
|
||||
$proceeds = 0;
|
||||
foreach ($all as $v){
|
||||
$proceeds += $v->proceeds(true);
|
||||
}
|
||||
return Util::_number_format($proceeds);*/
|
||||
})
|
||||
->addColumn('booking.id', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return '<a data-order="' . $serviceProviderEntry->booking->id . '" href="' . route('booking_detail', [$serviceProviderEntry->booking->id]) . '" data-id="' . $serviceProviderEntry->booking->id . '">' . $serviceProviderEntry->booking->id . '</a>';
|
||||
})
|
||||
->addColumn('booking.customer.fullName', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->customer->fullName();
|
||||
})
|
||||
->addColumn('booking.price', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->booking_strono ? $serviceProviderEntry->booking->price_canceled : $serviceProviderEntry->booking->price;
|
||||
})
|
||||
->addColumn('booking.proceeds', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->proceeds();
|
||||
})
|
||||
->addColumn('booking.start_date', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->getStartDateFormat();
|
||||
})
|
||||
->addColumn('booking.end_date', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->getEndDateFormat();
|
||||
})
|
||||
->addColumn('booking.booking_date', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->booking->getBookingDateFormat();
|
||||
})
|
||||
->addColumn('is_cleared', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
return $serviceProviderEntry->is_cleared ? ' <span data-order="1" class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>' : '<span data-order="0" class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('booking.lead.status_id', function (ServiceProviderEntry $serviceProviderEntry) {
|
||||
if($serviceProviderEntry->booking->lead && $serviceProviderEntry->booking->lead->status_id){
|
||||
$color = $serviceProviderEntry->booking->lead->status->color;
|
||||
$icon = "";
|
||||
if($serviceProviderEntry->booking->lead->status_id == 14 && $serviceProviderEntry->booking->lead->is_rebook){
|
||||
$color = '#94ae59';
|
||||
$icon = '<i class="fa fa-check-circle"></i> ';
|
||||
}
|
||||
if($serviceProviderEntry->booking->lead->status_id == 14 && !$serviceProviderEntry->booking->lead->is_rebook){
|
||||
$icon = '<i class="fa fa-times-circle"></i> ';
|
||||
}
|
||||
return '<span data-order="'.$serviceProviderEntry->booking->lead->status_id.'"><span class="badge badge-dark" style="background-color: '.$color.'">'.$icon.$serviceProviderEntry->booking->lead->status->name.'</span></span>';
|
||||
}
|
||||
return '<span data-order="0">-</span>';
|
||||
})
|
||||
->filterColumn('booking.customer.fullName', function ($query, $keyword) {
|
||||
if ($keyword != "") {
|
||||
$query->whereHas('booking', function ($q) use ($keyword) {
|
||||
$q->whereHas('customer', function ($q) use ($keyword) {
|
||||
$q->where("name", 'LIKE', '%' . $keyword . '%')
|
||||
->orWhere('firstname', 'LIKE', '%' . $keyword . '%');
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
->orderColumn('booking.id', 'booking.id $1')
|
||||
->orderColumn('booking.price', 'booking.price $1')
|
||||
->orderColumn('booking.start_date', 'booking.start_date $1')
|
||||
->orderColumn('booking.end_date', 'booking.end_date $1')
|
||||
->orderColumn('booking.booking_date', 'booking.booking_date $1')
|
||||
->orderColumn('booking.customer.firstname', 'booking.customer.firstname $1')
|
||||
->orderColumn('booking.customer.name', 'booking.customer.name $1')
|
||||
->orderColumn('is_cleared', 'is_cleared $1')
|
||||
->rawColumns(['is_cleared', 'booking.id', 'booking.lead.status_id'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
public function providersExport()
|
||||
{
|
||||
$query = $this->prozessProvidersSearch();
|
||||
|
||||
$order = explode(",", Request::get('order'));
|
||||
$orderByNum = [
|
||||
0 => "id",
|
||||
1 => "booking.id", //booking
|
||||
4 => "booking.merlin_order_number",//booking
|
||||
5 => "booking.price",//booking
|
||||
6 => "booking.price_total",//booking
|
||||
9 => "booking.start_date",//booking
|
||||
10 => "booking.end_date",//booking
|
||||
11 => "booking.booking_date",//booking
|
||||
12 => "is_cleared",
|
||||
];
|
||||
|
||||
if(isset($order[0])){
|
||||
$column = isset($orderByNum[$order[0]]) ? $orderByNum[$order[0]] : "start_date";
|
||||
$direction = isset($order[1]) ? strtoupper($order[1]) : "ASC";
|
||||
$query->orderBy($column, $direction);;
|
||||
}
|
||||
|
||||
$filename = "file-".date('Y-m-d-H-i-s');
|
||||
$exports = $query->get();
|
||||
$ctemps = [];
|
||||
$columns = [];
|
||||
|
||||
if(Request::get('export') === "export"){
|
||||
$filename = "Export_".date('Y-m-d-H-i-s');
|
||||
|
||||
$headers = array(
|
||||
'Zähler',
|
||||
'MyJack Nr.',
|
||||
'CRM Nr',
|
||||
'Kunde',
|
||||
'Reisedatum',
|
||||
'bis',
|
||||
'Buchungsdatum',
|
||||
'Organisation',
|
||||
'Gesamtreisepreis',
|
||||
'Reiseland',
|
||||
'Reiseprogramm',
|
||||
'Reiseteilnehmer',
|
||||
'Leistungsträger',
|
||||
'Rechnungsnummer',
|
||||
'Zahlung',
|
||||
'Zahlungsdatum',
|
||||
'Erlös',
|
||||
'Konto',
|
||||
);
|
||||
$isset = [];
|
||||
$total_price = 0;
|
||||
$total_price_total = 0;
|
||||
$total_amount_final = 0;
|
||||
$total_proceeds = 0;
|
||||
foreach($exports as $export) {
|
||||
$new = in_array($export->booking->id, $isset) ? false : true;
|
||||
if($new){
|
||||
$total_price += $export->booking->isCanceled() ? $export->booking->getPriceCanceledRaw() : $export->booking->getPriceRaw();
|
||||
$total_price_total += $export->booking->getPriceTotalRaw();
|
||||
$total_proceeds += $export->booking->proceeds(true);
|
||||
}
|
||||
$total_amount_final += $export->getAmountFinalEurRaw();
|
||||
$ctemps[$export->booking->id][] = array(
|
||||
'Zähler' => $new ? $export->getCounter() : "",
|
||||
'MyJack Nr.' => $new ? $export->booking->merlin_order_number : "",
|
||||
'CRM Nr' => $new ? $export->booking->inquiry_id : "",
|
||||
'Kunde' => $new ? $export->booking->customer->name : "",
|
||||
'Reisedatum' => $new ? $export->booking->getStartDateFormat() : "",
|
||||
'bis' => $new ? $export->booking->getEndDateFormat() : "",
|
||||
'Buchungsdatum' => $export->booking->getBookingDateFormat(),
|
||||
'Organisation' => $new ? ($export->booking->isCanceled() ? $export->booking->price_canceled : $export->booking->price) : "",
|
||||
'Gesamtreisepreis' => $new ? $export->booking->price_total : "",
|
||||
'Reiseland' => $new && $export->booking->travel_country ? $export->booking->travel_country->name : "",
|
||||
'Reiseprogramm' => $new && $export->booking->travel_agenda ? $export->booking->travel_agenda->name : "",
|
||||
'Reiseteilnehmer' => $new ? $export->booking->pax : "",
|
||||
'Leistungsträger' => $export->service_provider->name,
|
||||
'Rechnungsnummer' => $export->invoice_number,
|
||||
'Zahlung' => $export->getAmountFinalEur(),
|
||||
'Zahlungsdatum' => $export->getPaymentDateFormat(),
|
||||
'Erlös' => $new ? $export->booking->proceeds() : "",
|
||||
'Konto' => $export->booking->getKontoNumber()
|
||||
);
|
||||
$isset[] = $export->booking->id;
|
||||
}
|
||||
foreach($ctemps as $bid => $value){
|
||||
$columns = array_merge($columns, $value);
|
||||
}
|
||||
$columns[] = array(
|
||||
'Zähler' => "Total",
|
||||
'MyJack Nr.' => "",
|
||||
'CRM Nr' => "",
|
||||
'Kunde' =>"",
|
||||
'Reisedatum' => "",
|
||||
'bis' => "",
|
||||
'Buchungsdatum' => "",
|
||||
'Organisation' => Util::_number_format($total_price),
|
||||
'Gesamtreisepreis' => Util::_number_format($total_price_total),
|
||||
'Reiseland' => "",
|
||||
'Reiseprogramm' => "",
|
||||
'Reiseteilnehmer' => "",
|
||||
'Leistungsträger' => "",
|
||||
'Rechnungsnummer' => "",
|
||||
'Zahlung' => Util::_number_format($total_amount_final),
|
||||
'Zahlungsdatum' => "",
|
||||
'Erlös' => Util::_number_format($total_proceeds),
|
||||
'Konto' => ""
|
||||
);
|
||||
}
|
||||
if(Request::get('export') === "export_lt"){
|
||||
$filename = "Export_LT_".date('Y-m-d-H-i-s');
|
||||
|
||||
$headers = array(
|
||||
'Zähler',
|
||||
'MyJack Nr.',
|
||||
'CRM Nr',
|
||||
'Kunde',
|
||||
'Reisedatum',
|
||||
'bis',
|
||||
'Buchungsdatum',
|
||||
'Reiseland',
|
||||
'Reiseprogramm',
|
||||
'Reiseteilnehmer',
|
||||
'Leistungsträger',
|
||||
'Rechnungsnummer',
|
||||
'Zahlung',
|
||||
'ZahlungVorgang',
|
||||
);
|
||||
$isset = [];
|
||||
$total_amount_final = 0;
|
||||
$payments_total = 0;
|
||||
foreach($exports as $export) {
|
||||
$new = in_array($export->booking->id, $isset) ? false : true;
|
||||
if($new) {
|
||||
$payments_total += $export->booking->getServiceProviderPaymentsTotal(true);
|
||||
}
|
||||
$total_amount_final += $export->getAmountFinalEurRaw();
|
||||
$ctemps[$export->booking->id][] = array(
|
||||
'Zähler' => $new ? $export->getCounter() : "",
|
||||
'MyJack Nr.' => $new ? $export->booking->merlin_order_number : "",
|
||||
'CRM Nr' => $new ? $export->booking->inquiry_id : "",
|
||||
'Kunde' => $new ? $export->booking->customer->name : "",
|
||||
'Reisedatum' => $new ? $export->booking->getStartDateFormat() : "",
|
||||
'bis' => $new ? $export->booking->getEndDateFormat() : "",
|
||||
'Buchungsdatum' => $new ? $export->booking->getBookingDateFormat() : "",
|
||||
'Reiseland' => $new && $export->booking->travel_country ? $export->booking->travel_country->name : "",
|
||||
'Reiseprogramm' => $new && $export->booking->travel_agenda ? $export->booking->travel_agenda->name : "",
|
||||
'Reiseteilnehmer' => $new ? $export->booking->pax : "",
|
||||
'Leistungsträger' => $export->service_provider->name,
|
||||
'Rechnungsnummer' => $export->invoice_number,
|
||||
'Zahlung' => $export->getAmountFinalEur(),
|
||||
'ZahlungVorgang' => $export->booking->getServiceProviderPaymentsTotal(),
|
||||
);
|
||||
$isset[] = $export->booking->id;
|
||||
}
|
||||
foreach($ctemps as $bid => $value){
|
||||
$columns = array_merge($columns, $value);
|
||||
}
|
||||
$columns[] = array(
|
||||
'Zähler' => "Total",
|
||||
'MyJack Nr.' => "",
|
||||
'CRM Nr' => "",
|
||||
'Kunde' => "",
|
||||
'Reisedatum' => "",
|
||||
'bis',
|
||||
'Buchungsdatum' => "",
|
||||
'Reiseland' => "",
|
||||
'Reiseprogramm' => "",
|
||||
'Reiseteilnehmer' => "",
|
||||
'Leistungsträger' => "",
|
||||
'Rechnungsnummer' => "",
|
||||
'Zahlung' => Util::_number_format($total_amount_final),
|
||||
'ZahlungVorgang' => Util::_number_format($payments_total),
|
||||
);
|
||||
}
|
||||
return Excel::download(new ReportCollectionExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ use App\User;
|
|||
use Validator;
|
||||
use DataTables;
|
||||
use App\Models\Account;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Helper\HTMLHelper;
|
||||
use App\Services\MyGoogle2FA;
|
||||
use App\Mail\MailVerifyContact;
|
||||
use App\Repositories\UserRepository;
|
||||
|
|
@ -36,20 +36,19 @@ class AdminUserController extends Controller
|
|||
];
|
||||
$user = User::findOrFail(8);
|
||||
|
||||
/* $MyGoogle2FA = new MyGoogle2FA();
|
||||
/* $MyGoogle2FA = new MyGoogle2FA();
|
||||
$valid = $MyGoogle2FA->init($user)->check2Fa('676493');
|
||||
dd($valid); */
|
||||
dd($valid); */
|
||||
|
||||
return view('admin.users', $data);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
if($id == "new"){
|
||||
if ($id == "new") {
|
||||
$user = new User();
|
||||
}else{
|
||||
} else {
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
}
|
||||
/*if(!$user->account){
|
||||
$user->account = new Account();
|
||||
|
|
@ -60,21 +59,19 @@ class AdminUserController extends Controller
|
|||
'isFromAdmin' => 'true',
|
||||
];
|
||||
return view('admin.user_edit', $data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
|
||||
if($data['user_id'] === "new"){
|
||||
if ($data['user_id'] === "new") {
|
||||
$rules = array(
|
||||
'name' => 'required',
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'email-confirm' => 'required|same:email',
|
||||
);
|
||||
}else{
|
||||
} else {
|
||||
$rules = array(
|
||||
'name' => 'required'
|
||||
);
|
||||
|
|
@ -84,27 +81,24 @@ class AdminUserController extends Controller
|
|||
return back()->withRequest(Request::all())->withErrors($validator);
|
||||
}
|
||||
|
||||
if($data['user_id'] === "new"){
|
||||
if ($data['user_id'] === "new") {
|
||||
$user = User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => env('APP_KEY'),
|
||||
]);
|
||||
$unique = false;
|
||||
do{
|
||||
do {
|
||||
$confirmation_code = str_random(30);
|
||||
if( User::where('confirmation_code', '=', $confirmation_code)->count() == 0){
|
||||
if (User::where('confirmation_code', '=', $confirmation_code)->count() == 0) {
|
||||
$unique = true;
|
||||
}
|
||||
}
|
||||
while(!$unique);
|
||||
} while (!$unique);
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->save();
|
||||
|
||||
Mail::to($user->email)->send(new MailVerifyContact($confirmation_code, $user));
|
||||
|
||||
|
||||
}else{
|
||||
} else {
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
$user->name = $data['name'];
|
||||
$user->save();
|
||||
|
|
@ -121,54 +115,54 @@ class AdminUserController extends Controller
|
|||
|
||||
\Session()->flash('alert-success', "Kontakt gelöscht");
|
||||
return redirect('/admin/users');
|
||||
|
||||
}
|
||||
|
||||
public function loadModal($id){
|
||||
public function loadModal($id)
|
||||
{
|
||||
|
||||
if(Request::ajax()) {
|
||||
if (Request::ajax()) {
|
||||
$data = Request::all();
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
if(isset($data['action'])){
|
||||
if($data['action'] === 'show-user-roles'){
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'show-user-roles') {
|
||||
$fill = [
|
||||
'user' => $user,
|
||||
'action' => $data['action'],
|
||||
'groups' => config('permissions.groups'),
|
||||
'roles' => config('permissions.roles')
|
||||
];
|
||||
return view("admin.user_modal", $fill )->render();
|
||||
return view("admin.user_modal", $fill)->render();
|
||||
}
|
||||
if($data['action'] === 'show-user-active'){
|
||||
if ($data['action'] === 'show-user-active') {
|
||||
$fill = [
|
||||
'user' => $user,
|
||||
'action' => $data['action'],
|
||||
];
|
||||
return view("admin.active_modal", $fill )->render();
|
||||
return view("admin.active_modal", $fill)->render();
|
||||
}
|
||||
|
||||
|
||||
if($data['action'] === 'show-user-google2fa'){
|
||||
|
||||
if($user->isGoogle2Fa()){
|
||||
if ($data['action'] === 'show-user-google2fa') {
|
||||
|
||||
if ($user->isGoogle2Fa()) {
|
||||
$MyGoogle2FA = new MyGoogle2FA();
|
||||
$MyGoogle2FA->init($user);
|
||||
$MyGoogle2FA->init($user);
|
||||
$fill = [
|
||||
'user' => $user,
|
||||
'action' => 'delete-user-google2fa',
|
||||
'MyGoogle2FA' => $MyGoogle2FA,
|
||||
];
|
||||
return view("admin.google2fa_delete_modal", $fill )->render();
|
||||
}else{
|
||||
return view("admin.google2fa_delete_modal", $fill)->render();
|
||||
} else {
|
||||
$MyGoogle2FA = new MyGoogle2FA();
|
||||
$MyGoogle2FA->init($user)->generate();
|
||||
$MyGoogle2FA->init($user)->generate();
|
||||
$fill = [
|
||||
'user' => $user,
|
||||
'action' => 'activate-user-google2fa',
|
||||
'MyGoogle2FA' => $MyGoogle2FA,
|
||||
];
|
||||
return view("admin.google2fa_modal", $fill )->render();
|
||||
return view("admin.google2fa_modal", $fill)->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -176,9 +170,10 @@ class AdminUserController extends Controller
|
|||
return false;
|
||||
}
|
||||
|
||||
public function updateModal($action = false){
|
||||
public function updateModal($action = false)
|
||||
{
|
||||
|
||||
if($action=== 'show-user-roles'){
|
||||
if ($action === 'show-user-roles') {
|
||||
$data = Request::all();
|
||||
$user = User::findOrFail($data['id']);
|
||||
$user->permissions = isset($data['permissions']) ? $data['permissions'] : [];
|
||||
|
|
@ -187,17 +182,15 @@ class AdminUserController extends Controller
|
|||
$user->active = isset($data['active']) ? true : false;
|
||||
$user->save();
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
}
|
||||
if($action=== 'show-user-active'){
|
||||
if ($action === 'show-user-active') {
|
||||
$data = Request::all();
|
||||
$user = User::findOrFail($data['id']);
|
||||
$user->active = isset($data['active']) ? true : false;
|
||||
$user->save();
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
}
|
||||
if($action=== 'activate-user-google2fa'){
|
||||
if ($action === 'activate-user-google2fa') {
|
||||
$data = Request::all();
|
||||
$user = User::findOrFail($data['id']);
|
||||
$user->google2fa = true;
|
||||
|
|
@ -205,7 +198,7 @@ class AdminUserController extends Controller
|
|||
\Session()->flash('alert-save', true);
|
||||
}
|
||||
|
||||
if($action=== 'delete-user-google2fa'){
|
||||
if ($action === 'delete-user-google2fa') {
|
||||
$data = Request::all();
|
||||
$user = User::findOrFail($data['id']);
|
||||
$user->google2fa = false;
|
||||
|
|
@ -228,23 +221,22 @@ class AdminUserController extends Controller
|
|||
return '<a href="' . route('admin_user_edit', [$user->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('admin', function (User $user) {
|
||||
return '<a href="#" data-url="'.route('admin_user_load_modal', $user->id).'" data-data="'.$user->id.'" data-action="show-user-roles" class="update_modal_data_show">'.HTMLHelper::getRoleLabel($user->admin, '<i class="fa fa-edit"></i> Rechte + ','').'</a>';
|
||||
return '<a href="#" data-url="' . route('admin_user_load_modal', $user->id) . '" data-data="' . $user->id . '" data-action="show-user-roles" class="update_modal_data_show">' . HTMLHelper::getRoleLabel($user->admin, '<i class="fa fa-edit"></i> Rechte + ', '') . '</a>';
|
||||
})
|
||||
->addColumn('google2fa', function (User $user) {
|
||||
$icon = $user->google2fa ? '<i class="fa fa-check-circle"></i>' : '<i class="fa fa-times-circle"></i>';
|
||||
$color = $user->google2fa ? 'primary' : 'danger';
|
||||
return ' <a href="#" data-url="'.route('admin_user_load_modal', $user->id).'" data-data="'.$user->id.'" data-action="show-user-google2fa" class="update_modal_data_show btn btn-sm btn-'.$color.'">'.$icon.' google2fa</a>';
|
||||
return ' <a href="#" data-url="' . route('admin_user_load_modal', $user->id) . '" data-data="' . $user->id . '" data-action="show-user-google2fa" class="update_modal_data_show btn btn-sm btn-' . $color . '">' . $icon . ' google2fa</a>';
|
||||
})
|
||||
->addColumn('confirmed', function (User $user) {
|
||||
return $user->confirmed ? '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>' : '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('active', function (User $user) {
|
||||
$active = $user->active ? '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>' : '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
return ' <a href="#" data-url="'.route('admin_user_load_modal', $user->id).'" data-data="'.$user->id.'" data-action="show-user-active" class="update_modal_data_show">'.$active.'</a>';
|
||||
|
||||
return ' <a href="#" data-url="' . route('admin_user_load_modal', $user->id) . '" data-data="' . $user->id . '" data-action="show-user-active" class="update_modal_data_show">' . $active . '</a>';
|
||||
})
|
||||
->addColumn('action_delete', function (User $user) {
|
||||
return '<a href="' . route('admin_user_delete', [$user->id]) . '" class="btn icon-btn btn-sm btn-danger" onclick="return confirm(\''.__('Really delete entry?').'\');"><span class="fa fa-trash"></span></a>';
|
||||
return '<a href="' . route('admin_user_delete', [$user->id]) . '" class="btn icon-btn btn-sm btn-danger" onclick="return confirm(\'' . __('Really delete entry?') . '\');"><span class="fa fa-trash"></span></a>';
|
||||
})
|
||||
->orderColumn('confirmed', 'confirmed $1')
|
||||
->orderColumn('active', 'active $1')
|
||||
|
|
@ -252,8 +244,4 @@ class AdminUserController extends Controller
|
|||
->rawColumns(['action_edit', 'admin', 'confirmed', 'active', 'action_delete', 'google2fa'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class LoginController extends Controller
|
|||
$user->last_login = date('Y-m-d H:i:s');
|
||||
$user->save();
|
||||
}
|
||||
|
||||
protected function handleUserWasAuthenticated(Request $request, $throttles)
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -2,30 +2,35 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Request;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Booking;
|
||||
use App\Models\BookingFile;
|
||||
use App\Models\Participant;
|
||||
use App\Models\BookingNotice;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\ServiceProvider;
|
||||
use App\Models\BookingDraftItem;
|
||||
use App\Models\BookingServiceItem;
|
||||
use App\Models\Participant;
|
||||
use App\Models\ServiceProviderEntry;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Repositories\DraftRepository;
|
||||
use App\Repositories\BookingRepository;
|
||||
use App\Repositories\CustomerRepository;
|
||||
use App\Repositories\BookingPDFRepository;
|
||||
use App\Repositories\BookingFileRepository;
|
||||
use App\Repositories\CustomerFileRepository;
|
||||
use App\Repositories\CustomerMailRepository;
|
||||
|
||||
class BookingController extends Controller
|
||||
{
|
||||
|
||||
protected $bookingRepo;
|
||||
protected $custRepo;
|
||||
|
||||
public function __construct(BookingRepository $bookingRepo)
|
||||
{
|
||||
public function __construct(BookingRepository $bookingRepo, CustomerRepository $custRepo)
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
$this->bookingRepo = $bookingRepo;
|
||||
$this->custRepo = $custRepo;
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
|
|
@ -39,11 +44,10 @@ class BookingController extends Controller
|
|||
|
||||
public function detail($id)
|
||||
{
|
||||
if($id == "new") {
|
||||
if ($id == "new") {
|
||||
$booking = new Booking();
|
||||
$id = 'new';
|
||||
|
||||
}else{
|
||||
} else {
|
||||
$booking = Booking::findOrFail($id);
|
||||
$booking->getPassolutionPDF(true);
|
||||
$id = $booking->id;
|
||||
|
|
@ -54,178 +58,231 @@ class BookingController extends Controller
|
|||
'show_modal_quill_preview' => true,
|
||||
];
|
||||
return view('booking.detail', $data);
|
||||
|
||||
}
|
||||
|
||||
public function store($id)
|
||||
public function store(Request $request, $id)
|
||||
{
|
||||
// \Session()->flash('alert-save', '1');
|
||||
$data = $request->all();
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if($data['action'] === 'save_notice'){
|
||||
$booking = $this->bookingRepo->updateNotice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingNotice");
|
||||
}
|
||||
if($data['action'] === 'edit_notice'){
|
||||
$booking = $this->bookingRepo->updateNotice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingNotice");
|
||||
}
|
||||
|
||||
if($data['action'] === 'save_lead_status'){
|
||||
$booking = $this->bookingRepo->updateLeadStatus($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingLead");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking'){
|
||||
$booking = $this->bookingRepo->updateBooking($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingBooking");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking_services'){
|
||||
$booking = $this->bookingRepo->updateBookingServices($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingServices");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking_number'){
|
||||
$booking = $this->bookingRepo->updateBookingNumber($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingMyJack");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking_price'){
|
||||
$booking = $this->bookingRepo->updateBookingPrice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingPrice");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_service_provider_entry'){
|
||||
$booking = $this->bookingRepo->updateServiceProviderEntry($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingProvider");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking_service_item'){
|
||||
$booking = $this->bookingRepo->updateBookingServiceItem($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingProvider");
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_booking_participant'){
|
||||
$booking = $this->bookingRepo->updateBookingParticipant($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingParticipant");
|
||||
}
|
||||
|
||||
if($id === "new") {
|
||||
if ($id === "new") {
|
||||
$booking = new Booking();
|
||||
}else{
|
||||
} else {
|
||||
$booking = Booking::findOrFail($id);
|
||||
}
|
||||
|
||||
// $booking->merlin_order_number = $data['merlin_order_number'];
|
||||
// $booking->save();
|
||||
$i = 1;
|
||||
|
||||
if($data['action'] === 'addItemUp'){
|
||||
if ($data['action'] === 'convertArrangementsToDrafts') {
|
||||
if (!$booking->arrangements || $booking->arrangements->count() == 0) {
|
||||
\Session()->flash('alert-warning', __('Keine Arrangements zum Konvertieren vorhanden'));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
$this->bookingRepo->convertArrangementsToDrafts($booking);
|
||||
\Session()->flash('alert-success', __('Arrangements wurden erfolgreich in die neue Draft-Struktur übernommen'));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
if ($data['action'] === 'loadDraftToBooking') {
|
||||
if (!isset($data['draft_id']) || !$data['draft_id']) {
|
||||
\Session()->flash('alert-error', __('Keine Vorlage ausgewählt'));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
$this->bookingRepo->loadDraftToBooking($booking->id, $data['draft_id']);
|
||||
\Session()->flash('alert-success', __('Vorlage wurde erfolgreich geladen'));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
if ($data['action'] === 'deleteAllChecked') {
|
||||
if (!isset($data['draft_item_delete']) || !$data['draft_item_delete']) {
|
||||
\Session()->flash('alert-error', 'Es wurden keine Leistungen ausgewählt');
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
foreach ($data['draft_item_delete'] as $draft_item_delete_id => $v) {
|
||||
$booking_draft_item = BookingDraftItem::findOrFail($draft_item_delete_id);
|
||||
if ($booking_draft_item->booking_id === $booking->id) {
|
||||
$booking_draft_item->delete();
|
||||
}
|
||||
}
|
||||
$booking->calculate_price_total();
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
if ($data['action'] === 'save_notice') {
|
||||
$booking = $this->bookingRepo->updateNotice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingNotice");
|
||||
}
|
||||
if ($data['action'] === 'edit_notice') {
|
||||
$booking = $this->bookingRepo->updateNotice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingNotice");
|
||||
}
|
||||
if (strpos($data['action'], 'createPDF') !== false) {
|
||||
$bookingPDF = new BookingPDFRepository($booking);
|
||||
$bookingPDF->createPDF($id, $data);
|
||||
\Session()->flash('alert-success', 'PDF Datei erstellt');
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingFiles");
|
||||
}
|
||||
|
||||
$redirect = route('booking_detail', [$booking->id]);
|
||||
|
||||
$i = 1;
|
||||
if ($data['action'] === 'addItemUp') {
|
||||
$travel_program_id = null;
|
||||
$request_date = null;
|
||||
$comfort = 0;
|
||||
if(count($booking->booking_draft_items)){
|
||||
if (count($booking->booking_draft_items)) {
|
||||
$first_booking_draft_item = $booking->booking_draft_items()->first();
|
||||
$travel_program_id = $first_booking_draft_item->travel_program_id;
|
||||
$request_date = $first_booking_draft_item->request_date;
|
||||
$comfort = $first_booking_draft_item->comfort;
|
||||
}
|
||||
$booking->booking_draft_items()->create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_program_id' => $travel_program_id,
|
||||
'fewo_lodging_id' => null,
|
||||
'travel_class_id' => null,
|
||||
'draft_item_id' => null,
|
||||
'draft_type_id' => null,
|
||||
'request_date' => $request_date,
|
||||
'days_start' => null,
|
||||
'days_duration' => null,
|
||||
'start_date' => null,
|
||||
'end_date' => null,
|
||||
'service' => '',
|
||||
'price_adult' => null,
|
||||
'adult' => null ,
|
||||
'price_children' => 0,
|
||||
'children' => 0,
|
||||
'price' => 0,
|
||||
'pos' => $i,
|
||||
'in_pdf' => true,
|
||||
'comfort' => $comfort
|
||||
]);
|
||||
$i++;
|
||||
$add_draft_items_up_number = isset($data['add_draft_items_up_number']) ? intval($data['add_draft_items_up_number']) : 1;
|
||||
for ($j = 0; $j < $add_draft_items_up_number; $j++) {
|
||||
$booking->booking_draft_items()->create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_program_id' => $travel_program_id,
|
||||
'fewo_lodging_id' => null,
|
||||
'travel_class_id' => null,
|
||||
'draft_item_id' => null,
|
||||
'draft_type_id' => null,
|
||||
'request_date' => $request_date,
|
||||
'days_start' => null,
|
||||
'days_duration' => null,
|
||||
'start_date' => null,
|
||||
'end_date' => null,
|
||||
'service' => '',
|
||||
'price_adult' => null,
|
||||
'adult' => null,
|
||||
'price_children' => 0,
|
||||
'children' => 0,
|
||||
'price' => 0,
|
||||
'pos' => $i,
|
||||
'in_pdf' => true,
|
||||
'comfort' => $comfort
|
||||
]);
|
||||
$i++;
|
||||
}
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
if(isset($data['draft_item'])){
|
||||
|
||||
foreach ($data['draft_item'] as $booking_draft_item_id => $draft_item){
|
||||
|
||||
if (isset($data['draft_item'])) {
|
||||
foreach ($data['draft_item'] as $booking_draft_item_id => $draft_item) {
|
||||
$BookingDraftItem = BookingDraftItem::findOrFail($booking_draft_item_id);
|
||||
|
||||
$draft_item['price_adult'] = isset($draft_item['price_adult']) ? $draft_item['price_adult'] : null;
|
||||
$draft_item['adult'] = isset($draft_item['adult']) ? $draft_item['adult'] : null;
|
||||
$draft_item['price_children'] = isset($draft_item['price_children']) ? $draft_item['price_children'] : null;
|
||||
$draft_item['children'] = isset($draft_item['children']) ? $draft_item['children'] : null;
|
||||
$draft_item['price'] = isset($draft_item['price']) ? $draft_item['price'] : null;
|
||||
|
||||
$draft_item['pos'] = $i++;
|
||||
$draft_item['in_pdf'] = isset($draft_item['in_pdf']) ? true : false;
|
||||
$BookingDraftItem->fill($draft_item);
|
||||
|
||||
$BookingDraftItem->save();
|
||||
}
|
||||
}
|
||||
if($data['action'] === 'addItemDown'){
|
||||
|
||||
if ($data['action'] === 'addItemDown') {
|
||||
$travel_program_id = null;
|
||||
$request_date = null;
|
||||
$comfort = 0;
|
||||
if(count($booking->booking_draft_items)){
|
||||
if (count($booking->booking_draft_items)) {
|
||||
$first_booking_draft_item = $booking->booking_draft_items()->first();
|
||||
$travel_program_id = $first_booking_draft_item->travel_program_id;
|
||||
$request_date = $first_booking_draft_item->request_date;
|
||||
$comfort = $first_booking_draft_item->comfort;
|
||||
}
|
||||
$booking->booking_draft_items()->create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_program_id' => $travel_program_id,
|
||||
'fewo_lodging_id' => null,
|
||||
'travel_class_id' => null,
|
||||
'draft_item_id' => null,
|
||||
'draft_type_id' => null,
|
||||
'request_date' => $request_date,
|
||||
'days_start' => null,
|
||||
'days_duration' => null,
|
||||
'start_date' => null,
|
||||
'end_date' => null,
|
||||
'service' => '',
|
||||
'price_adult' => null,
|
||||
'adult' => null ,
|
||||
'price_children' => 0,
|
||||
'children' => 0,
|
||||
'price' => 0,
|
||||
'pos' => $i,
|
||||
'in_pdf' => true,
|
||||
'comfort' => $comfort
|
||||
]);
|
||||
$add_draft_items_up_number = isset($data['add_draft_items_down_number']) ? intval($data['add_draft_items_down_number']) : 1;
|
||||
for ($j = 0; $j < $add_draft_items_up_number; $j++) {
|
||||
$booking->booking_draft_items()->create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_program_id' => $travel_program_id,
|
||||
'fewo_lodging_id' => null,
|
||||
'travel_class_id' => null,
|
||||
'draft_item_id' => null,
|
||||
'draft_type_id' => null,
|
||||
'request_date' => $request_date,
|
||||
'days_start' => null,
|
||||
'days_duration' => null,
|
||||
'start_date' => null,
|
||||
'end_date' => null,
|
||||
'service' => '',
|
||||
'price_adult' => null,
|
||||
'adult' => null,
|
||||
'price_children' => 0,
|
||||
'children' => 0,
|
||||
'price' => 0,
|
||||
'pos' => $i,
|
||||
'in_pdf' => true,
|
||||
'comfort' => $comfort
|
||||
]);
|
||||
$i++;
|
||||
}
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
$data['action'] === 'saveCustomer' || $data['action'] === 'saveAll' || $data['action'] === 'save_lead_status' || $data['action'] === 'update_booking' ||
|
||||
$data['action'] === 'update_booking_services' || $data['action'] === 'update_booking_number' || $data['action'] === 'update_booking_price' ||
|
||||
$data['action'] === 'update_service_provider_entry' || $data['action'] === 'update_booking_service_item' || $data['action'] === 'update_booking_participant'
|
||||
) {
|
||||
$customer = $this->custRepo->updateCustomerFromBooking($id, $data);
|
||||
$booking = $this->bookingRepo->updateLeadStatus($id, $data);
|
||||
$booking = $this->bookingRepo->updateBooking($id, $data);
|
||||
$booking = $this->bookingRepo->updateBookingServices($id, $data);
|
||||
$booking = $this->bookingRepo->updateBookingNumber($id, $data);
|
||||
$booking = $this->bookingRepo->updateBookingPrice($id, $data);
|
||||
$booking = $this->bookingRepo->updateServiceProviderEntry($id, $data);
|
||||
$booking = $this->bookingRepo->updateBookingServiceItem($id, $data);
|
||||
$booking = $this->bookingRepo->updateBookingParticipant($id, $data);
|
||||
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
||||
|
||||
switch ($data['action']) {
|
||||
case 'saveCustomer':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingCustomer");
|
||||
break;
|
||||
case 'saveAll':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
break;
|
||||
case 'update_booking':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingBooking");
|
||||
break;
|
||||
case 'save_lead_status':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingLead");
|
||||
break;
|
||||
case 'update_booking_services':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingServices");
|
||||
break;
|
||||
case 'update_booking_number':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingMyJack");
|
||||
break;
|
||||
case 'update_booking_price':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingPrice");
|
||||
break;
|
||||
case 'update_service_provider_entry':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingProvider");
|
||||
break;
|
||||
case 'update_booking_service_item':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingCompany");
|
||||
break;
|
||||
case 'update_booking_participant':
|
||||
$redirect = redirect(route('booking_detail', [$booking->id]) . "#collapseBookingParticipant");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$booking->calculate_price_total();
|
||||
|
||||
if(strpos($data['action'], 'up_') !== false) {
|
||||
if (strpos($data['action'], 'up_') !== false) {
|
||||
$reId = intval(str_replace('up_', '', $data['action']));
|
||||
$d_from = BookingDraftItem::findOrFail($reId);
|
||||
$d_to = $booking->findBeforeDraftItemRelation($reId);
|
||||
if($d_to) {
|
||||
if ($d_to) {
|
||||
$t_pos = $d_from->pos;
|
||||
$d_from->pos = $d_to->pos;
|
||||
$d_to->pos = $t_pos;
|
||||
|
|
@ -233,11 +290,11 @@ class BookingController extends Controller
|
|||
$d_to->save();
|
||||
}
|
||||
}
|
||||
if(strpos($data['action'], 'down_') !== false) {
|
||||
if (strpos($data['action'], 'down_') !== false) {
|
||||
$reId = intval(str_replace('down_', '', $data['action']));
|
||||
$d_from = BookingDraftItem::findOrFail($reId);
|
||||
$d_to = $booking->findAfterDraftItemRelation($reId);
|
||||
if($d_to) {
|
||||
if ($d_to) {
|
||||
$t_pos = $d_from->pos;
|
||||
$d_from->pos = $d_to->pos;
|
||||
$d_to->pos = $t_pos;
|
||||
|
|
@ -246,14 +303,15 @@ class BookingController extends Controller
|
|||
}
|
||||
}
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('booking_detail', [$booking->id]));
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
public function loadModal(){
|
||||
$data = Request::all();
|
||||
public function loadModal(Request $request)
|
||||
{
|
||||
$data = $request->all();
|
||||
$ret = "";
|
||||
if(Request::ajax()) {
|
||||
if ($data['action'] === "new-customer-mail" || $data['action'] === "reply-customer-mail" || $data['action'] === "show-customer-mail" || $data['action'] === "edit-customer-mail"){
|
||||
if ($request->ajax()) {
|
||||
if ($data['action'] === "new-customer-mail" || $data['action'] === "reply-customer-mail" || $data['action'] === "show-customer-mail" || $data['action'] === "edit-customer-mail") {
|
||||
$data['customers'] = [];
|
||||
if ($data['action'] === "new-customer-mail" && isset($data['booking_id']) && $booking = Booking::find($data['booking_id'])) {
|
||||
$tmp = [];
|
||||
|
|
@ -266,86 +324,119 @@ class BookingController extends Controller
|
|||
$ret = CustomerMailRepository::loadModal($data);
|
||||
}
|
||||
|
||||
if($data['action'] === "modal-upload-booking-file") {
|
||||
if ($data['action'] === "modal-upload-booking-file") {
|
||||
$ret = view("booking.upload_modal", compact('data'))->render();
|
||||
}
|
||||
|
||||
if($data['action'] === "edit_notice") {
|
||||
if ($data['action'] === "edit_notice") {
|
||||
$value = BookingNotice::findOrFail($data['id']);
|
||||
$ret = view("booking.edit_notice_modal", compact('data', 'value'))->render();
|
||||
}
|
||||
|
||||
if($data['action'] === "upload-booking-file"){
|
||||
if($data['booking_id']){
|
||||
if ($data['action'] === "createPDF_Coupon") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$data['has_coupon'] = $booking->hasDocument('coupon');
|
||||
$data['default_value'] = config('booking.coupon_default_value');
|
||||
$data['issue_date'] = date('d.m.Y');
|
||||
$data['valid_date'] = \Carbon::now()->addMonths(config('booking.coupon_valid_date_month'))->format('d.m.Y');
|
||||
$ret = view("booking.modal_create_coupon", compact('data'))->render();
|
||||
}
|
||||
|
||||
if ($data['action'] === "createPDF_Storno") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$data['price'] = $booking->price;
|
||||
if ($data['has_storno'] = $booking->hasDocument('storno')) {
|
||||
$document_storno = $booking->getDocument('storno');
|
||||
$data['storno_date'] = \Carbon::parse($document_storno->data->storno_date)->format('d.m.Y');
|
||||
$data['storno_print'] = \Carbon::parse($document_storno->data->storno_print)->format('d.m.Y');
|
||||
$data['storno_status_id'] = $document_storno->data->storno_status_id;
|
||||
$data['storno_level'] = $document_storno->data->storno_level;
|
||||
$data['storno_level_number'] = _number_format($document_storno->data->storno_level);
|
||||
$data['storno_total_price'] = '';
|
||||
} else {
|
||||
$data['storno_date'] = date('d.m.Y');
|
||||
$data['storno_print'] = date('d.m.Y');
|
||||
$data['storno_status_id'] = null;
|
||||
$data['storno_level'] = 100;
|
||||
$data['storno_level_number'] = '';
|
||||
$data['storno_total_price'] = '';
|
||||
}
|
||||
|
||||
$ret = view("booking.modal_create_storno", compact('data'))->render();
|
||||
}
|
||||
|
||||
if ($data['action'] === "upload-booking-file") {
|
||||
if ($data['booking_id']) {
|
||||
$bookingFileRepo = new BookingFileRepository(new BookingFile());
|
||||
$bookingFileRepo->_set('disk', 'booking');
|
||||
$bookingFileRepo->_set('booking_id', $data['booking_id']);
|
||||
$bookingFileRepo->_set('dir', '/files/'.date('Y/m').'/');
|
||||
$bookingFileRepo->_set('dir', '/files/' . date('Y/m') . '/');
|
||||
$bookingFileRepo->_set('identifier', 'booking');
|
||||
return $bookingFileRepo->uploadFile(Request::all());
|
||||
return $bookingFileRepo->uploadFile($request->all());
|
||||
}
|
||||
}
|
||||
}
|
||||
return response()->json(['response' => $data, 'html'=>$ret]);
|
||||
return response()->json(['response' => $data, 'html' => $ret]);
|
||||
}
|
||||
|
||||
public function draftItemDelete($id){
|
||||
$boking_draft_item = BookingDraftItem::findOrFail($id);
|
||||
$booking = $boking_draft_item->booking;
|
||||
$boking_draft_item->delete();
|
||||
public function draftItemDelete($id)
|
||||
{
|
||||
$booking_draft_item = BookingDraftItem::findOrFail($id);
|
||||
$booking = $booking_draft_item->booking;
|
||||
$booking_draft_item->delete();
|
||||
$booking->calculate_price_total();
|
||||
|
||||
\Session()->flash('alert-success', __('Eintrag gelöscht'));
|
||||
return redirect(route('booking_detail', [$booking->id]));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
public function action($action, $id=false){
|
||||
public function action(Request $request, $action, $id = false)
|
||||
{
|
||||
|
||||
if(!$booking = Booking::find($id)){
|
||||
if (!$booking = Booking::find($id)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
if($action === 'change_travel_dates'){
|
||||
$draftRepo = new DraftRepository($booking);
|
||||
$draftRepo->change_dates_drafts_from_booking(Request::get('change_travel_start_date'));
|
||||
\Session()->flash('alert-success', __('Datum der Reise wurde geändert'));
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingOrganisation");
|
||||
if ($action === 'change_travel_dates') {
|
||||
$draftRepo = new DraftRepository($booking);
|
||||
$draftRepo->change_dates_drafts_from_booking($request->get('change_travel_start_date'));
|
||||
\Session()->flash('alert-success', __('Datum der Reise wurde geändert'));
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingOrganisation");
|
||||
}
|
||||
|
||||
if($action === 'service_provider_entry_add_discount'){
|
||||
$ServiceProvider = ServiceProvider::where('type', 'discount')->where('active',true)->first();
|
||||
if ($action === 'service_provider_entry_add_discount') {
|
||||
$ServiceProvider = ServiceProvider::where('type', 'discount')->where('active', true)->first();
|
||||
ServiceProviderEntry::create([
|
||||
'booking_id' => $booking->id,
|
||||
'service_provider_id' => $ServiceProvider->id,
|
||||
'type' => 'discount',
|
||||
]);
|
||||
\Session()->flash('alert-success', __('Leistungsträger neuer Rabatt hinzugefügt'));
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingProvider");
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingProvider");
|
||||
}
|
||||
|
||||
if($action === 'service_provider_entry_add_payment'){
|
||||
$ServiceProvider = ServiceProvider::where('type', 'payment')->where('active',true)->first();
|
||||
if ($action === 'service_provider_entry_add_payment') {
|
||||
$ServiceProvider = ServiceProvider::where('type', 'payment')->where('active', true)->first();
|
||||
ServiceProviderEntry::create([
|
||||
'booking_id' => $booking->id,
|
||||
'service_provider_id' => $ServiceProvider->id,
|
||||
'type' => 'payment',
|
||||
]);
|
||||
\Session()->flash('alert-success', __('Leistungsträger neue Zahlung hinzugefügt'));
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingProvider");
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingProvider");
|
||||
}
|
||||
|
||||
if($action === 'booking_service_item_add'){
|
||||
$TravelCompany = TravelCompany::where('active',true)->first();
|
||||
if ($action === 'booking_service_item_add') {
|
||||
$TravelCompany = TravelCompany::where('active', true)->first();
|
||||
BookingServiceItem::create([
|
||||
'booking_id' => $booking->id,
|
||||
'travel_company_id' => $TravelCompany->id,
|
||||
'travel_date' => now(),
|
||||
]);
|
||||
\Session()->flash('alert-success', __('Reiseveranstalter neue Leistung hinzugefügt'));
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingCompany");
|
||||
}
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingCompany");
|
||||
}
|
||||
|
||||
if($action === 'booking_participant_add'){
|
||||
if ($action === 'booking_participant_add') {
|
||||
Participant::create([
|
||||
'booking_id' => $booking->id,
|
||||
'nationality_id' => 1,
|
||||
|
|
@ -353,75 +444,156 @@ class BookingController extends Controller
|
|||
|
||||
]);
|
||||
\Session()->flash('alert-success', __('Neuen Teilnehmer hinzugefügt'));
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingParticipant");
|
||||
}
|
||||
|
||||
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingParticipant");
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($id, $del="booking"){
|
||||
public function delete($id, $del = "booking")
|
||||
{
|
||||
|
||||
if($del === 'booking') {
|
||||
//$model = Booking::findOrFail($id);
|
||||
//$model->delete();
|
||||
\Session()->flash('alert-success', __('Löschen noch nicht programmiert'));
|
||||
}
|
||||
if($del === 'booking_file'){
|
||||
if ($del === 'booking_file') {
|
||||
$booking_file = BookingFile::findOrFail($id);
|
||||
$booking = $booking_file->booking;
|
||||
$fileRepo = new BookingFileRepository($booking_file);
|
||||
$fileRepo->_set('disk', 'booking');
|
||||
$fileRepo->delete();
|
||||
$booking_file->delete();
|
||||
$this->deleteBookingFile($booking_file);
|
||||
\Session()->flash('alert-success', 'Datei gelöscht');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingFiles");
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingFiles");
|
||||
}
|
||||
if($del === 'booking_notice'){
|
||||
if ($del === 'booking_notice') {
|
||||
$booking_notice = BookingNotice::findOrFail($id);
|
||||
$booking = $booking_notice->booking;
|
||||
$booking_notice->delete();
|
||||
\Session()->flash('alert-success', 'Notiz gelöscht');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingNotice");
|
||||
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingNotice");
|
||||
}
|
||||
|
||||
if($del === 'passolution_file'){
|
||||
|
||||
if ($del === 'passolution_file') {
|
||||
$booking = Booking::findOrFail($id);
|
||||
$booking->resyncPassolutionPDF();
|
||||
\Session()->flash('alert-success', 'Passolution erneuert');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingFiles");
|
||||
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingFiles");
|
||||
}
|
||||
|
||||
if($del === 'service_provider_entry'){
|
||||
if ($del === 'service_provider_entry') {
|
||||
$ServiceProviderEntry = ServiceProviderEntry::findOrFail($id);
|
||||
$booking = $ServiceProviderEntry->booking;
|
||||
$ServiceProviderEntry->delete();
|
||||
\Session()->flash('alert-success', 'Leistungsträger gelöscht');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingProvider");
|
||||
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingProvider");
|
||||
}
|
||||
|
||||
if($del === 'booking_service_item'){
|
||||
if ($del === 'booking_service_item') {
|
||||
$BookingServiceItem = BookingServiceItem::findOrFail($id);
|
||||
$booking = $BookingServiceItem->booking;
|
||||
$BookingServiceItem->delete();
|
||||
\Session()->flash('alert-success', 'Reiseveranstalter gelöscht');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingCompany");
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingCompany");
|
||||
}
|
||||
|
||||
if($del === 'participant'){
|
||||
if ($del === 'participant') {
|
||||
$Participant = Participant::findOrFail($id);
|
||||
$booking = $Participant->booking;
|
||||
$Participant->delete();
|
||||
\Session()->flash('alert-success', 'Teilnehmer gelöscht');
|
||||
return redirect(route('booking_detail', [$booking->id])."#collapseBookingParticipant");
|
||||
return redirect(route('booking_detail', [$booking->id]) . "#collapseBookingParticipant");
|
||||
}
|
||||
|
||||
return redirect(route('requests'));
|
||||
}
|
||||
|
||||
|
||||
private function deleteBookingFile($booking_file)
|
||||
{
|
||||
$fileRepo = new BookingFileRepository($booking_file);
|
||||
$fileRepo->_set('disk', 'booking');
|
||||
$fileRepo->delete();
|
||||
$booking_file->delete();
|
||||
}
|
||||
|
||||
private function deleteCustomerFile($customer_file)
|
||||
{
|
||||
$fileRepo = new CustomerFileRepository($customer_file);
|
||||
$fileRepo->_set('disk', 'customer');
|
||||
$fileRepo->delete();
|
||||
$customer_file->delete();
|
||||
}
|
||||
|
||||
private function deleteBookingDocument($booking_document)
|
||||
{
|
||||
$booking_document->deleteFile();
|
||||
$booking_document->delete();
|
||||
}
|
||||
|
||||
public function deleteComplete($id)
|
||||
{
|
||||
$booking = Booking::findOrFail($id);
|
||||
|
||||
if ($booking->booking_files) {
|
||||
foreach ($booking->booking_files as $booking_file) {
|
||||
$this->deleteBookingFile($booking_file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($booking->booking_notices) {
|
||||
foreach ($booking->booking_notices as $booking_notice) {
|
||||
$booking_notice->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->service_provider_entries) {
|
||||
foreach ($booking->service_provider_entries as $service_provider_entry) {
|
||||
$service_provider_entry->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->booking_service_items) {
|
||||
foreach ($booking->booking_service_items as $booking_service_item) {
|
||||
$booking_service_item->delete();
|
||||
}
|
||||
}
|
||||
|
||||
if ($booking->booking_provider_services) {
|
||||
foreach ($booking->booking_provider_services as $booking_provider_service) {
|
||||
$booking_provider_service->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->booking_country_services) {
|
||||
foreach ($booking->booking_country_services as $booking_country_service) {
|
||||
$booking_country_service->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->participants) {
|
||||
foreach ($booking->participants as $participant) {
|
||||
$participant->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->customer_mails) {
|
||||
foreach ($booking->customer_mails_reverse as $customer_mail) {
|
||||
if ($customer_mail->customer_files) {
|
||||
foreach ($customer_mail->customer_files as $customer_file) {
|
||||
$this->deleteCustomerFile($customer_file);
|
||||
}
|
||||
}
|
||||
$customer_mail->delete();
|
||||
}
|
||||
}
|
||||
if ($booking->booking_documents) {
|
||||
foreach ($booking->booking_documents as $booking_document) {
|
||||
if ($booking_document->identifier === 'coupon') {
|
||||
//coupon set booking ID to null <- is need by the customer
|
||||
$booking_document->booking_id = null;
|
||||
$booking_document->save();
|
||||
} else {
|
||||
$this->deleteBookingDocument($booking_document);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($booking->coupons) {
|
||||
foreach ($booking->coupons as $coupon) {
|
||||
//coupon set booking ID to null <- is need by the customer
|
||||
$coupon->booking_id = null;
|
||||
$coupon->save();
|
||||
}
|
||||
}
|
||||
$booking->delete();
|
||||
\Session()->flash('alert-success', 'Buchung gelöscht');
|
||||
return redirect(route('requests'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@ namespace App\Http\Controllers\CMS;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CMSContent;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Services\BookingFewo;
|
||||
use App\Services\CreatePDF;
|
||||
use App\Services\Util;
|
||||
use Request;
|
||||
|
||||
|
|
@ -256,16 +253,6 @@ class CMSBookingController extends Controller
|
|||
return redirect(route('cms_booking_content_detail', [$id]));
|
||||
}
|
||||
|
||||
/* if($data['action'] === 'previewPDF'){
|
||||
$pdf_content = BookingFewo::getFeWoCMSContentForPDF($this->identifier_content, $identifier_fewo);
|
||||
$pdf_file = new CreatePDF('pdf.fewo_instructions');
|
||||
return $pdf_file->create([
|
||||
'contents' => $pdf_content,
|
||||
'fewo' => $fewo
|
||||
]
|
||||
);
|
||||
}
|
||||
*/
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('cms_booking_content'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ class CMSContentController extends Controller
|
|||
//store in cms old Datebase
|
||||
\App\Models\Sym\CmsContent::create($data);
|
||||
}else{
|
||||
if($data['identifier'] === 'fewo-email-file'){
|
||||
$data['integer'] = isset($data['default_travel_info']) ? 1 : 0;
|
||||
}
|
||||
$model = CMSContent::find($data['id']);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use App\Models\CMSContent;
|
|||
use App\Models\CMSInfo;
|
||||
use App\Models\CMSInfoAvailable;
|
||||
use App\Models\CMSInfoHoliday;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Helper\HTMLHelper;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\CMSContent;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Services\BookingFewo;
|
||||
use App\Services\CreatePDF;
|
||||
use App\Libraries\CreatePDF;
|
||||
use App\Services\Util;
|
||||
use Request;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ namespace App\Http\Controllers\CMS;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Feedback;
|
||||
use Carbon\Carbon;
|
||||
use IqContent\LaravelFilemanager\Lfm;
|
||||
use Request;
|
||||
|
||||
class CMSFeedbackController extends Controller
|
||||
|
|
@ -38,6 +39,8 @@ class CMSFeedbackController extends Controller
|
|||
$feedback = new Feedback();
|
||||
$id = 'new';
|
||||
$feedback->status = 1;
|
||||
$feedback->content_new = "";
|
||||
|
||||
|
||||
}else{
|
||||
$feedback = Feedback::findOrFail($id);
|
||||
|
|
@ -46,6 +49,7 @@ class CMSFeedbackController extends Controller
|
|||
$data = [
|
||||
'feedback' => $feedback,
|
||||
'id' => $id,
|
||||
'lfm_helper' => app(Lfm::class),
|
||||
];
|
||||
return view('cms.feedback.detail', $data);
|
||||
|
||||
|
|
@ -67,15 +71,18 @@ class CMSFeedbackController extends Controller
|
|||
$feedback->show_in_navi = 1;
|
||||
$feedback->catalog_id = 1;
|
||||
|
||||
|
||||
}else{
|
||||
$feedback = Feedback::findOrFail($id);
|
||||
}
|
||||
|
||||
|
||||
$feedback->title = $data['title'];
|
||||
$feedback->status = isset($data['status']) ? true : false;
|
||||
$feedback->slug = $data['slug'];
|
||||
$feedback->date = $data['date'];
|
||||
$feedback->content = $data['content'];
|
||||
$feedback->content_new = $data['content_new'];
|
||||
$feedback->box_body = $data['image'];
|
||||
|
||||
$feedback->description = $data['description'];
|
||||
$feedback->pagetitle = $data['pagetitle'];
|
||||
$feedback->keywords = $data['keywords'];
|
||||
|
|
@ -93,6 +100,9 @@ class CMSFeedbackController extends Controller
|
|||
if($first_feedback = $parent_feedback->children->first()){
|
||||
$feedback->lft = $first_feedback->lft;
|
||||
$feedback->rgt = $first_feedback->rgt;
|
||||
}else{
|
||||
$feedback->lft = $parent_feedback->lft +1;
|
||||
$feedback->rgt = $parent_feedback->lft +2;
|
||||
}
|
||||
$feedback->tree_root = $parent_feedback->tree_root;
|
||||
|
||||
|
|
|
|||
118
app/Http/Controllers/CMS/CMSNewsController.php
Normal file
118
app/Http/Controllers/CMS/CMSNewsController.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\CMS;
|
||||
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\News;
|
||||
use App\Models\Page;
|
||||
use Carbon\Carbon;
|
||||
use IqContent\LaravelFilemanager\Lfm;
|
||||
use Illuminate\Support\Str;
|
||||
use Request;
|
||||
|
||||
class CMSNewsController extends Controller
|
||||
{
|
||||
|
||||
/*
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'news' => News::all(), //News::where('lvl', 1)->get(),
|
||||
];
|
||||
return view('cms.news.index', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
if ($id === "new") {
|
||||
$news = new News();
|
||||
$id = 'new';
|
||||
$news->status = 1;
|
||||
$news->content_new = "";
|
||||
} else {
|
||||
$news = News::findOrFail($id);
|
||||
$id = $news->id;
|
||||
}
|
||||
$data = [
|
||||
'news' => $news,
|
||||
'id' => $id,
|
||||
'lfm_helper' => app(Lfm::class),
|
||||
];
|
||||
return view('cms.news.detail', $data);
|
||||
}
|
||||
|
||||
|
||||
public function store($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if ($id === "new") {
|
||||
$news = new News();
|
||||
$news->model = 'news';
|
||||
$news->owner_second = 0;
|
||||
$news->show_in_navi = 1;
|
||||
$news->catalog_id = 1;
|
||||
} else {
|
||||
$news = News::findOrFail($id);
|
||||
}
|
||||
|
||||
$news->title = $data['title'];
|
||||
$news->status = isset($data['status']) ? true : false;
|
||||
$news->slug = Str::slug($data['slug']);
|
||||
$news->date = $data['date'];
|
||||
$news->content_new = $data['content_new'];
|
||||
$news->box_body = $data['image'];
|
||||
$news->description = $data['description'];
|
||||
$news->pagetitle = $data['pagetitle'];
|
||||
$news->keywords = $data['keywords'];
|
||||
|
||||
$news->order = (new Carbon($news->date))->format('Ymd') * -1;
|
||||
$root_news = News::where('cms_settings', 'news_root')->first();
|
||||
|
||||
if ($id != $root_news->id) {
|
||||
//root ID = 3126
|
||||
$news->lvl = 1;
|
||||
$news->owner = $root_news->id;
|
||||
$news->parent_id = $root_news->id;
|
||||
$news->tree_root = $root_news->id;
|
||||
if ($first_news = $root_news->children->first()) {
|
||||
$news->lft = $first_news->lft;
|
||||
$news->rgt = $first_news->rgt;
|
||||
} else {
|
||||
$news->lft = $root_news->lft + 1;
|
||||
$news->rgt = $root_news->lft + 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$news->save();
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('cms_news_detail', [$news->id]));
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$news = News::findOrFail($id);
|
||||
|
||||
//TODO
|
||||
//check for delete, only delete lvl 2 .,...?
|
||||
if ($news->lvl != 1) {
|
||||
abort(404);
|
||||
die();
|
||||
}
|
||||
|
||||
$news->delete();
|
||||
\Session()->flash('alert-success', __('News gelöscht'));
|
||||
return redirect(route('cms_news'));
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,15 @@ class CMSTravelGuideController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function test()
|
||||
{
|
||||
//make tree
|
||||
$data = [
|
||||
];
|
||||
|
||||
return view('cms.travel_guide.test', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
if($id === "new") {
|
||||
|
|
|
|||
312
app/Http/Controllers/ContactController.php
Normal file
312
app/Http/Controllers/ContactController.php
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Repositories\ContactRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
public function __construct(private readonly ContactRepository $contactRepo)
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
}
|
||||
|
||||
public function index(): \Illuminate\View\View
|
||||
{
|
||||
return view('contact.index');
|
||||
}
|
||||
|
||||
public function detail(string $id): \Illuminate\View\View
|
||||
{
|
||||
if ($id === 'new') {
|
||||
$contact = new Contact();
|
||||
} else {
|
||||
$contact = Contact::with(['salutation', 'leads', 'bookings', 'mergedContacts'])
|
||||
->findOrFail((int) $id);
|
||||
}
|
||||
|
||||
return view('contact.detail', [
|
||||
'contact' => $contact,
|
||||
'id' => $id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request, string $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$data = $request->except('_token');
|
||||
|
||||
if (!isset($data['action'])) {
|
||||
abort(403, 'keine Action');
|
||||
}
|
||||
|
||||
if ($id === 'new') {
|
||||
$contact = $this->contactRepo->createContact($data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('contact_detail', [$contact->id]) . '#collapseContactDetail');
|
||||
}
|
||||
|
||||
$this->contactRepo->updateContact($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
||||
return redirect(route('contact_detail', [$id]) . '#collapseContactDetail');
|
||||
}
|
||||
|
||||
public function history(int $id): \Illuminate\View\View
|
||||
{
|
||||
$contact = Contact::with([
|
||||
'leads.sf_guard_user',
|
||||
'bookings.travel_country',
|
||||
'bookings.travel_agenda',
|
||||
'bookings.sf_guard_user',
|
||||
'bookings.lead',
|
||||
])->findOrFail($id);
|
||||
|
||||
return view('contact._detail_history', [
|
||||
'contact' => $contact,
|
||||
'modal' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(int $id): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$contact = Contact::withoutGlobalScope('not_merged')->findOrFail($id);
|
||||
|
||||
$leadsCount = $contact->leads()->count();
|
||||
$bookingCount = $contact->bookings()->count();
|
||||
|
||||
if ($leadsCount > 0 || $bookingCount > 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => sprintf(
|
||||
'Kontakt kann nicht gelöscht werden: %s%s vorhanden.',
|
||||
$leadsCount > 0 ? $leadsCount . ' Anfrage(n)' : '',
|
||||
$bookingCount > 0 ? ($leadsCount > 0 ? ' und ' : '') . $bookingCount . ' Buchung(en)' : ''
|
||||
),
|
||||
], 422);
|
||||
}
|
||||
|
||||
$contact->delete();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function duplicates(): \Illuminate\View\View
|
||||
{
|
||||
$counts = [
|
||||
'HIGH' => $this->countDuplicateGroups('email'),
|
||||
'MEDIUM' => $this->countDuplicateGroups('name_birthdate'),
|
||||
'LOW' => $this->countDuplicateGroups('name_zip'),
|
||||
];
|
||||
|
||||
return view('contact.duplicates', compact('counts'));
|
||||
}
|
||||
|
||||
public function getDuplicateGroups(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$confidence = strtoupper($request->input('confidence', 'HIGH'));
|
||||
|
||||
$groups = match ($confidence) {
|
||||
'HIGH' => $this->findByEmail(),
|
||||
'MEDIUM' => $this->findByNameBirthdate(),
|
||||
'LOW' => $this->findByNameZip(),
|
||||
default => [],
|
||||
};
|
||||
|
||||
// Für jede Gruppe die vollständigen Kontakt-Daten laden
|
||||
$result = [];
|
||||
foreach ($groups as $ids) {
|
||||
$contacts = Contact::withoutGlobalScopes()
|
||||
->withCount(['leads', 'bookings'])
|
||||
->whereIn('id', $ids)
|
||||
->whereNull('merged_into_id')
|
||||
->whereNull('deleted_at')
|
||||
->orderByRaw('FIELD(id, ' . implode(',', $ids) . ')')
|
||||
->get(['id', 'firstname', 'name', 'email', 'zip', 'city', 'phone', 'phonemobile', 'birthdate', 'created_at', 'updated_at']);
|
||||
|
||||
if ($contacts->count() < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'master' => $contacts->first(),
|
||||
'duplicates' => $contacts->skip(1)->values(),
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
public function merge(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$masterId = (int) $request->input('master_id');
|
||||
$dupeId = (int) $request->input('duplicate_id');
|
||||
|
||||
if (!$masterId || !$dupeId || $masterId === $dupeId) {
|
||||
return response()->json(['success' => false, 'message' => 'Ungültige IDs.'], 422);
|
||||
}
|
||||
|
||||
$master = Contact::withoutGlobalScopes()->find($masterId);
|
||||
$dupe = Contact::withoutGlobalScopes()->find($dupeId);
|
||||
|
||||
if (!$master || !$dupe) {
|
||||
return response()->json(['success' => false, 'message' => 'Kontakt nicht gefunden.'], 404);
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($masterId, $dupeId) {
|
||||
DB::table('inquiries')->where('customer_id', $dupeId)->update(['customer_id' => $masterId]);
|
||||
DB::table('booking')->where('customer_id', $dupeId)->update(['customer_id' => $masterId]);
|
||||
DB::table('customer_mails')->where('customer_id', $dupeId)->update(['customer_id' => $masterId]);
|
||||
DB::table('lead_mails')->where('customer_id', $dupeId)->update(['customer_id' => $masterId]);
|
||||
DB::table('contacts')->where('id', $dupeId)->update([
|
||||
'merged_into_id' => $masterId,
|
||||
'merged_at' => now(),
|
||||
]);
|
||||
});
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
// ── Duplikat-Hilfs-Queries ────────────────────────────────────────────────
|
||||
|
||||
private function countDuplicateGroups(string $type): int
|
||||
{
|
||||
return match ($type) {
|
||||
'email' => DB::table('contacts')->selectRaw('COUNT(*) as cnt')->whereNotNull('email')->where('email', '!=', '')->whereNull('merged_into_id')->whereNull('deleted_at')->groupBy('email')->havingRaw('COUNT(*) > 1')->get()->count(),
|
||||
'name_birthdate' => DB::table('contacts')->selectRaw('COUNT(*) as cnt')->whereNotNull('name')->whereNotNull('firstname')->whereNotNull('birthdate')->whereNull('merged_into_id')->whereNull('deleted_at')->groupBy('name', 'firstname', 'birthdate')->havingRaw('COUNT(*) > 1')->get()->count(),
|
||||
'name_zip' => DB::table('contacts')->selectRaw('COUNT(*) as cnt')->whereNotNull('name')->whereNotNull('firstname')->whereNotNull('zip')->where('zip', '!=', '')->whereNull('merged_into_id')->whereNull('deleted_at')->groupBy('name', 'firstname', 'zip')->havingRaw('COUNT(*) > 1')->get()->count(),
|
||||
default => 0,
|
||||
};
|
||||
}
|
||||
|
||||
private function findByEmail(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->selectRaw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids')
|
||||
->whereNotNull('email')->where('email', '!=', '')
|
||||
->whereNull('merged_into_id')->whereNull('deleted_at')
|
||||
->groupBy('email')->havingRaw('COUNT(*) > 1')
|
||||
->pluck('ids')->map(fn ($s) => array_map('intval', explode(',', $s)))->all();
|
||||
}
|
||||
|
||||
private function findByNameBirthdate(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->selectRaw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids')
|
||||
->whereNotNull('name')->whereNotNull('firstname')->whereNotNull('birthdate')
|
||||
->whereNull('merged_into_id')->whereNull('deleted_at')
|
||||
->groupBy('name', 'firstname', 'birthdate')->havingRaw('COUNT(*) > 1')
|
||||
->pluck('ids')->map(fn ($s) => array_map('intval', explode(',', $s)))->all();
|
||||
}
|
||||
|
||||
private function findByNameZip(): array
|
||||
{
|
||||
return DB::table('contacts')
|
||||
->selectRaw('GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) as ids')
|
||||
->whereNotNull('name')->whereNotNull('firstname')
|
||||
->whereNotNull('zip')->where('zip', '!=', '')
|
||||
->whereNull('merged_into_id')->whereNull('deleted_at')
|
||||
->groupBy('name', 'firstname', 'zip')->havingRaw('COUNT(*) > 1')
|
||||
->pluck('ids')->map(fn ($s) => array_map('intval', explode(',', $s)))->all();
|
||||
}
|
||||
|
||||
public function restore(int $id): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$contact = Contact::onlyTrashed()->withoutGlobalScope('not_merged')->findOrFail($id);
|
||||
$contact->restore();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function getContacts(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$showDeleted = $request->filled('filter_deleted');
|
||||
|
||||
// Reihenfolge wichtig: select() zuerst, dann withCount() — sonst überschreibt
|
||||
// select() die COUNT-Subqueries die withCount() per addSelect() eingetragen hat.
|
||||
$query = $showDeleted
|
||||
? Contact::onlyTrashed()->withoutGlobalScope('not_merged')->select('contacts.*')->withCount(['leads', 'bookings'])
|
||||
: Contact::select('contacts.*')->withCount(['leads', 'bookings']);
|
||||
|
||||
// Zusatzfilter aus der UI (werden als extra GET-Parameter gesendet)
|
||||
if ($request->filled('filter_has_leads')) {
|
||||
$query->has('leads');
|
||||
}
|
||||
if ($request->filled('filter_has_bookings')) {
|
||||
$query->has('bookings');
|
||||
}
|
||||
if ($request->filled('filter_has_email')) {
|
||||
$query->whereNotNull('email')->where('email', '!=', '');
|
||||
}
|
||||
|
||||
return DataTables::eloquent($query)
|
||||
->addColumn('action_edit', function (Contact $contact) use ($showDeleted) {
|
||||
if ($showDeleted) {
|
||||
return '';
|
||||
}
|
||||
return '<a href="' . route('contact_detail', [$contact->id]) . '" class="btn icon-btn btn-sm btn-primary" title="Öffnen"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('action_delete', function (Contact $contact) use ($showDeleted) {
|
||||
if ($showDeleted) {
|
||||
return '<button class="btn icon-btn btn-xs btn-success ml-1 btn-contact-restore" '
|
||||
. 'data-id="' . $contact->id . '" '
|
||||
. 'data-name="' . e($contact->fullName()) . '" '
|
||||
. 'title="Wiederherstellen"><span class="fa fa-undo"></span></button>';
|
||||
}
|
||||
return '<button class="btn icon-btn btn-xs btn-danger ml-1 btn-contact-delete" '
|
||||
. 'data-id="' . $contact->id . '" '
|
||||
. 'data-name="' . e($contact->fullName()) . '" '
|
||||
. 'title="Löschen"><span class="fa fa-trash"></span></button>';
|
||||
})
|
||||
->addColumn('id', function (Contact $contact) use ($showDeleted) {
|
||||
if ($showDeleted) {
|
||||
return '<span data-order="' . $contact->id . '">' . $contact->id . '</span>';
|
||||
}
|
||||
return '<a data-order="' . $contact->id . '" href="' . route('contact_detail', [$contact->id]) . '">' . $contact->id . '</a>';
|
||||
})
|
||||
->addColumn('raw_id', fn(Contact $contact) => $contact->id)
|
||||
->addColumn('leads_count', fn(Contact $contact) => $contact->leads_count)
|
||||
->addColumn('bookings_count', fn(Contact $contact) => $contact->bookings_count)
|
||||
->addColumn('deleted_at', fn(Contact $contact) => $contact->deleted_at?->format('d.m.Y H:i') ?? '')
|
||||
->orderColumn('id', 'customer.id $1')
|
||||
->orderColumn('deleted_at', 'customer.deleted_at $1')
|
||||
->filterColumn('id', function ($query, $keyword) {
|
||||
if ($keyword !== '') {
|
||||
$query->where('contacts.id', 'LIKE', '%' . $keyword . '%');
|
||||
}
|
||||
})
|
||||
->filterColumn('name', function ($query, $keyword) {
|
||||
if ($keyword !== '') {
|
||||
$query->where(function ($q) use ($keyword) {
|
||||
$q->where('name', 'LIKE', '%' . $keyword . '%')
|
||||
->orWhere('firstname', 'LIKE', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
})
|
||||
->filter(function ($query) use ($request) {
|
||||
$location = $request->input('filter_location');
|
||||
if ($location && $location !== '') {
|
||||
$query->where(function ($q) use ($location) {
|
||||
$q->where('zip', 'LIKE', '%' . $location . '%')
|
||||
->orWhere('city', 'LIKE', '%' . $location . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$search = $request->input('search.value');
|
||||
if ($search && $search !== '') {
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('firstname', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('email', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('phone', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('phonemobile', 'LIKE', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
}, true)
|
||||
->rawColumns(['action_edit', 'action_delete', 'id'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -47,10 +47,14 @@ class CustomerController extends Controller
|
|||
public function store($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if(!isset($data['action'])){
|
||||
abort(403, 'keine Action');
|
||||
}
|
||||
//save
|
||||
$customer = $this->custRepo->updateCustomer($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
||||
if($data['action'] === 'saveCustomer'){
|
||||
$customer = $this->custRepo->updateCustomer($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('customer_detail', [$id]).'#collapseCustomerDetail');
|
||||
}
|
||||
return back();
|
||||
|
|
@ -64,7 +68,7 @@ class CustomerController extends Controller
|
|||
|
||||
public function getCustomers()
|
||||
{
|
||||
$query = Customer::with('salutation')->select('customer.*');
|
||||
$query = Customer::with('salutation')->select('contacts.*');
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('action_edit', function (Customer $customer) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class CustomerFewoMailController extends Controller
|
|||
$customer_mail->save();
|
||||
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
|
@ -128,14 +128,14 @@ class CustomerFewoMailController extends Controller
|
|||
}else{
|
||||
\Session()->flash('alert-success', "Mail gesendet!");
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function replyMail(CustomerFewoMailRepository $customerFewoMailRepository){
|
||||
$data = Request::all();
|
||||
$customerFewoMailRepository->replyStore($data);
|
||||
\Session()->flash('alert-success', "Mail gespeichert!");
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function getEmailTemplates()
|
||||
|
|
|
|||
|
|
@ -3,24 +3,25 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
use App\Models\BookingApplication;
|
||||
use App\Models\BookingConfirmation;
|
||||
use App\Models\BookingStorno;
|
||||
use App\Models\BookingVoucher;
|
||||
use App\Models\Coupon;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Models\InsuranceCertificate;
|
||||
use App\Models\TravelInsurance;
|
||||
use App\Repositories\CustomerFileRepository;
|
||||
use App\Services\BookingFewo;
|
||||
use App\Services\CreateCouponPDF;
|
||||
use App\Services\CreatePDF;
|
||||
use App\Services\Util;
|
||||
use Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Request;
|
||||
use Response;
|
||||
use App\Models\Coupon;
|
||||
use App\Services\Util;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Libraries\CreatePDF;
|
||||
use App\Models\BookingStorno;
|
||||
use App\Services\BookingFewo;
|
||||
use App\Models\BookingVoucher;
|
||||
use App\Models\TravelInsurance;
|
||||
use App\Libraries\CreateCouponPDF;
|
||||
use App\Models\BookingApplication;
|
||||
use App\Models\BookingConfirmation;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use App\Models\BookingVoucherAgency;
|
||||
use App\Models\InsuranceCertificate;
|
||||
use App\Repositories\CustomerFileRepository;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class CustomerFileController extends Controller
|
||||
{
|
||||
|
|
@ -45,20 +46,21 @@ class CustomerFileController extends Controller
|
|||
$content_disposition = $cd ? 'attachment' : 'inline';
|
||||
$file = false;
|
||||
$filename = "";
|
||||
|
||||
switch ($model){
|
||||
case 'booking_application':
|
||||
case 'registration':
|
||||
if($booking_application = BookingApplication::find($id)){
|
||||
$filename = "Buchungsauftrag-".$booking_application->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_application->binary_data);
|
||||
}
|
||||
break;
|
||||
case 'booking_confirmation':
|
||||
case 'confirmation':
|
||||
if($booking_confirmation = BookingConfirmation::find($id)){
|
||||
$filename = "Reisebestaetigung-".$booking_confirmation->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_confirmation->binary_data);
|
||||
}
|
||||
break;
|
||||
case 'booking_storno':
|
||||
case 'storno':
|
||||
if($booking_stornos = BookingStorno::find($id)){
|
||||
$filename = "Reisestornierung-".$booking_stornos->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_stornos->binary_data);
|
||||
|
|
@ -67,17 +69,23 @@ class CustomerFileController extends Controller
|
|||
case 'coupon':
|
||||
if($coupon = Coupon::find($id)){
|
||||
$filename = "Gutschein-".$coupon->number.".pdf";
|
||||
|
||||
$pdf = new CreateCouponPDF($coupon);
|
||||
$pdf->create();
|
||||
return $pdf->output($filename, $cd);
|
||||
|
||||
}
|
||||
break;
|
||||
case 'booking_voucher':
|
||||
if($booking_vouchers = BookingVoucher::find($id)){
|
||||
$filename = "Voucher-".$booking_vouchers->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_vouchers->binary_data);
|
||||
case 'voucher':
|
||||
if($booking_voucher = BookingVoucher::find($id)){
|
||||
$filename = "Voucher-".$booking_voucher->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_voucher->binary_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'voucher_agency':
|
||||
if($booking_voucher_agency = BookingVoucherAgency::find($id)){
|
||||
$filename = "Voucher-Agentur-".$booking_voucher_agency->booking->getBookingNumber().".pdf";
|
||||
$file = base64_decode($booking_voucher_agency->binary_data);
|
||||
}
|
||||
break;
|
||||
case 'insurance_certificate':
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class CustomerMailController extends Controller
|
|||
|
||||
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
|
@ -148,14 +148,14 @@ class CustomerMailController extends Controller
|
|||
}else{
|
||||
\Session()->flash('alert-success', "Mail gesendet!");
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function replyMail(CustomerMailRepository $customerMailRepository){
|
||||
$data = Request::all();
|
||||
$customerMailRepository->replyStore($data);
|
||||
\Session()->flash('alert-success', "Mail gespeichert!");
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function getEmailTemplates()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Helper\HTMLHelper;
|
||||
use Carbon\Carbon;
|
||||
use Composer\DependencyResolver\Request;
|
||||
use DataTables;
|
||||
|
|
|
|||
|
|
@ -13,67 +13,84 @@ class FileController extends Controller
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
public function __construct() {}
|
||||
|
||||
|
||||
public function show($id = null, $disk = null, $do='file')
|
||||
public function show($id = null, $disk = null, $do = 'file')
|
||||
{
|
||||
$path = "";
|
||||
$filename = "";
|
||||
if ($disk === 'customer'){
|
||||
$file = \App\Models\CustomerFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
if ($disk === 'travel_user'){
|
||||
$file = \App\Models\CustomerFewoFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
|
||||
switch ($disk) {
|
||||
case 'customer':
|
||||
$file = \App\Models\CustomerFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'travel_user':
|
||||
$file = \App\Models\CustomerFewoFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'booking':
|
||||
$file = \App\Models\BookingFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'general':
|
||||
$file = \App\Models\GeneralFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'booking_fewo':
|
||||
$file = \App\Models\TravelUserBookingFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'lead':
|
||||
$file = \App\Models\LeadFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'cms_file':
|
||||
$file = \App\Models\CMSContent::findOrFail($id);
|
||||
$filename = $file->name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
case 'booking_document':
|
||||
$file = \App\Models\BookingDocument::findOrFail($id);
|
||||
$filename = $file->name;
|
||||
$path = $file->getPath();
|
||||
break;
|
||||
}
|
||||
|
||||
if ($disk === 'booking'){
|
||||
$file = \App\Models\BookingFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
|
||||
if ($disk === 'general'){
|
||||
$file = \App\Models\GeneralFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
|
||||
if ($disk === 'booking_fewo'){
|
||||
$file = \App\Models\TravelUserBookingFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
|
||||
if ($disk === 'lead'){
|
||||
$file = \App\Models\LeadFile::findOrFail($id);
|
||||
$filename = $file->original_name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
|
||||
|
||||
if ($disk === 'cms_file'){
|
||||
$file = \App\Models\CMSContent::findOrFail($id);
|
||||
$filename = $file->name;
|
||||
$path = $file->getPath();
|
||||
}
|
||||
|
||||
if (file_exists($path)) {
|
||||
if($do === "download"){
|
||||
return Response::download($path, $filename);
|
||||
|
||||
// Cache-Control Header für PDFs und andere Dateien, die sich häufig ändern
|
||||
$headers = [
|
||||
'Cache-Control' => 'no-cache, no-store, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
];
|
||||
|
||||
switch ($do) {
|
||||
case 'file':
|
||||
return Response::file($path, $headers);
|
||||
break;
|
||||
case 'download':
|
||||
return Response::download($path, $filename, $headers);
|
||||
break;
|
||||
case 'url':
|
||||
return $path . $filename;
|
||||
break;
|
||||
}
|
||||
return Response::file($path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function showExpert($type = null, $class = null, $year = null, $file = null, $do = null) {
|
||||
public function showExpert($type = null, $class = null, $year = null, $file = null, $do = null)
|
||||
{
|
||||
|
||||
/*if ($type == 'xls') {
|
||||
$path = storage_path("app/export/");
|
||||
|
|
@ -81,35 +98,39 @@ class FileController extends Controller
|
|||
}*/
|
||||
$path = "";
|
||||
$filename = "";
|
||||
$headers = [];
|
||||
$headers = [
|
||||
'Cache-Control' => 'no-cache, no-store, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
];
|
||||
|
||||
if ($class === 'invoices' || $class === 'infos'){
|
||||
if ($class === 'invoices' || $class === 'infos') {
|
||||
$headers = [
|
||||
'Content-Type: application/pdf',
|
||||
'Pragma: no-cache',
|
||||
'Cache-Control: no-store,no-cache, must-revalidate, post-check=0, pre-check=0'
|
||||
];
|
||||
$dir = $year."/";
|
||||
$dir = $year . "/";
|
||||
$filename = $file;
|
||||
if ($type === 'fewo') {
|
||||
if(Storage::disk('fewo_invoices')->exists( $dir.$filename )){
|
||||
$path = Storage::disk('fewo_invoices')->path($dir.$filename);
|
||||
if (Storage::disk('fewo_invoices')->exists($dir . $filename)) {
|
||||
$path = Storage::disk('fewo_invoices')->path($dir . $filename);
|
||||
}
|
||||
}
|
||||
if ($type === 'fewo') {
|
||||
if(Storage::disk('fewo_infos')->exists( $dir.$filename )){
|
||||
$path = Storage::disk('fewo_infos')->path($dir.$filename);
|
||||
if (Storage::disk('fewo_infos')->exists($dir . $filename)) {
|
||||
$path = Storage::disk('fewo_infos')->path($dir . $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists($path)) {
|
||||
if($do === "download"){
|
||||
if ($do === "download") {
|
||||
return Response::download($path, $filename, $headers);
|
||||
}
|
||||
if($do === "file"){
|
||||
if ($do === "file") {
|
||||
return Response::file($path, $headers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,6 @@ use Request;
|
|||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -202,7 +202,6 @@ class ContentTreeController extends Controller
|
|||
$data['user_id'] = \Auth::user()->id;
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
$data['search'] = isset($data['search']) ? true : false;
|
||||
|
||||
if (isset($data['action'])) {
|
||||
switch ($data['action']) {
|
||||
case 'tree-content' :
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\IQ;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Request;
|
||||
use IqContent\LaravelFilemanager\Controllers\LfmController;
|
||||
|
||||
class ContentAssetController extends LfmController
|
||||
{
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'models' => [],
|
||||
'lfm_helper' => $this->helper,
|
||||
'modal' => false,
|
||||
];
|
||||
return view('iq.content.assets.index', $data);
|
||||
}
|
||||
|
||||
public function modal(){
|
||||
$data = [
|
||||
'models' => [],
|
||||
'lfm_helper' => $this->helper,
|
||||
'modal' => true,
|
||||
];
|
||||
return view('iq.content.assets.body', $data);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\Lead;
|
||||
use App\Models\LeadFile;
|
||||
use App\Models\LeadMail;
|
||||
use App\Models\LeadNotice;
|
||||
use App\Models\StatusHistory;
|
||||
use App\Models\LeadParticipant;
|
||||
use App\Repositories\LeadRepository;
|
||||
use App\Models\StatusHistory;
|
||||
use App\Repositories\CustomerRepository;
|
||||
use App\Repositories\LeadFileRepository;
|
||||
use App\Repositories\LeadRepository;
|
||||
use App\Services\Util;
|
||||
use Carbon;
|
||||
use Request;
|
||||
use Session;
|
||||
|
||||
class LeadController extends Controller
|
||||
{
|
||||
|
|
@ -38,6 +40,7 @@ class LeadController extends Controller
|
|||
|
||||
public function detail($id)
|
||||
{
|
||||
|
||||
if($id === "new") {
|
||||
$lead = new Lead();
|
||||
$id = 'new';
|
||||
|
|
@ -47,6 +50,7 @@ class LeadController extends Controller
|
|||
$lead->getPassolutionPDF(true);
|
||||
$id = $lead->id;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'lead' => $lead,
|
||||
'id' => $id,
|
||||
|
|
@ -59,19 +63,34 @@ class LeadController extends Controller
|
|||
public function store($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if(!isset($data['action'])){
|
||||
abort(403, 'keine Action');
|
||||
}
|
||||
//save
|
||||
|
||||
if($data['action'] === 'createBooking'){
|
||||
$lead = $this->leadRepo->createBooking($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('lead_detail', [$id]).'#collapseLeadBooking');
|
||||
}
|
||||
|
||||
if($data['action'] === 'saveCustomer'){
|
||||
|
||||
if($data['action'] === 'saveCustomer' || $data['action'] === 'saveLead' || $data['action'] === 'saveStatus' || $data['action'] === 'update_lead_participant'){
|
||||
//@dd($data);
|
||||
$customer = $this->custRepo->updateCustomerFromLead($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
$lead = $this->leadRepo->updateLead($id, $data);
|
||||
$lead = $this->leadRepo->updateLeadParticipant($id, $data);
|
||||
|
||||
}
|
||||
if($data['action'] === 'saveCustomer'){
|
||||
return redirect(route('lead_detail', [$id]).'#collapseLeadCustomer');
|
||||
}
|
||||
|
||||
if($data['action'] === 'saveLead'){
|
||||
$lead = $this->leadRepo->updateLead($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('lead_detail', [$id]).'#collapseLeadDetail');
|
||||
}
|
||||
|
||||
if($data['action'] === 'update_lead_participant'){
|
||||
return redirect(route('lead_detail', [$lead->id])."#collapseBookingParticipant");
|
||||
}
|
||||
if($data['action'] === 'saveStatus'){
|
||||
$lead = $this->leadRepo->updateLeadStatus($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
|
@ -88,11 +107,7 @@ class LeadController extends Controller
|
|||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('lead_detail', [$lead->id])."#collapseLeadNotice");
|
||||
}
|
||||
if($data['action'] === 'update_lead_participant'){
|
||||
$lead = $this->leadRepo->updateLeadParticipant($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('lead_detail', [$lead->id])."#collapseBookingParticipant");
|
||||
}
|
||||
|
||||
|
||||
|
||||
return back();
|
||||
|
|
@ -165,6 +180,11 @@ class LeadController extends Controller
|
|||
|
||||
if($del === 'lead') {
|
||||
$lead = Lead::findOrFail($id);
|
||||
|
||||
if($lead->bookings->count()){
|
||||
\Session()->flash('alert-error', 'Kann nicht gelöscht werden, die Anfrage hat Buchungen');
|
||||
return redirect(route('lead_detail', [$lead->id])."#collapseLeadBooking");
|
||||
}
|
||||
//Files
|
||||
$leadFiles = LeadFile::where('lead_id', $lead->id)->get();
|
||||
foreach ($leadFiles as $leadFile) {
|
||||
|
|
@ -212,7 +232,7 @@ class LeadController extends Controller
|
|||
|
||||
public function getLeads()
|
||||
{
|
||||
$query = Lead::with('customer')->with('sf_guard_user')->with('status')->select('lead.*');
|
||||
$query = Lead::with('customer')->with('sf_guard_user')->with('status')->select('inquiries.*');
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('action_edit', function (Lead $lead) {
|
||||
|
|
@ -227,6 +247,10 @@ class LeadController extends Controller
|
|||
->addColumn('request_date', function (Lead $lead) {
|
||||
return Carbon::parse($lead->request_date)->format(\Util::formatDateDB());
|
||||
})
|
||||
->addColumn('travel_country', function (Lead $lead) {
|
||||
return $lead->getTravelCountryDestco();
|
||||
})
|
||||
|
||||
->addColumn('status', function (Lead $lead) {
|
||||
return $lead->getStatusBadge();
|
||||
})
|
||||
|
|
@ -262,6 +286,7 @@ class LeadController extends Controller
|
|||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('customer_id', 'customer_id $1')
|
||||
->orderColumn('request_date', 'request_date $1')
|
||||
->orderColumn('status', 'status_id $1')
|
||||
|
||||
->orderColumn('last_lead_email', function ($query, $order) {
|
||||
|
|
@ -271,7 +296,7 @@ class LeadController extends Controller
|
|||
// $q->select('sent_at')->where('sent_at', DB::raw("(select max('sent_at') customer_mails)")); //)
|
||||
})->orderBy(
|
||||
LeadMail::select('sent_at')
|
||||
->whereColumn('lead_id', 'lead.id')
|
||||
->whereColumn('lead_id', 'inquiries.id')
|
||||
->orderBy('sent_at', 'DESC')
|
||||
->limit(1)
|
||||
, $order);
|
||||
|
|
@ -287,7 +312,7 @@ class LeadController extends Controller
|
|||
$query->where('customer_id', 'LIKE', '%'.$keyword.'%');
|
||||
}
|
||||
})
|
||||
->rawColumns(['action_edit', 'customer_id', 'sf_guard_user_id', 'id', 'status', 'last_lead_email', 'lead_notice', 'action_delete'])
|
||||
->rawColumns(['action_edit', 'customer_id', 'sf_guard_user_id', 'id', 'status', 'last_lead_email', 'travel_country', 'lead_notice', 'action_delete'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class LeadMailController extends Controller
|
|||
\Session()->flash('alert-success', __('E-Mail weitergeleitet'));
|
||||
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
|
@ -110,14 +110,14 @@ class LeadMailController extends Controller
|
|||
}else{
|
||||
\Session()->flash('alert-success', "Mail gesendet!");
|
||||
}
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
public function replyMail(LeadMailRepository $LeadMailRepository){
|
||||
$data = Request::all();
|
||||
$LeadMailRepository->replyStore($data);
|
||||
\Session()->flash('alert-success', "Mail gespeichert!");
|
||||
return back();
|
||||
return back()->with('collapse_shows', $data['collapse_shows'] ? $data['collapse_shows'] : []);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
165
app/Http/Controllers/NavigationTreeController.php
Normal file
165
app/Http/Controllers/NavigationTreeController.php
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\NavigationTreeService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class NavigationTreeController extends Controller
|
||||
{
|
||||
protected $navigationService;
|
||||
|
||||
public function __construct(NavigationTreeService $navigationService)
|
||||
{
|
||||
$this->navigationService = $navigationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt die Navigationsbaum-Übersicht
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('navigation.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Navigationsbaum-Daten als JSON zurück (Frontend-Struktur)
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getData(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$includeHidden = $request->get('include_hidden', true);
|
||||
$tree = $this->navigationService->getFrontendNavigationTree($includeHidden);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $tree,
|
||||
'meta' => [
|
||||
'total_nodes' => $this->navigationService->countNodes($tree),
|
||||
'include_hidden' => $includeHidden,
|
||||
'structure' => 'frontend'
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht im Navigationsbaum
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function search(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$query = $request->get('query', '');
|
||||
$flatList = $this->navigationService->getFlatNavigationList();
|
||||
|
||||
// Filtere nach Suchbegriff
|
||||
$results = array_filter($flatList, function ($node) use ($query) {
|
||||
return stripos($node['title'], $query) !== false
|
||||
|| stripos($node['slug'], $query) !== false
|
||||
|| stripos($node['url'], $query) !== false;
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => array_values($results),
|
||||
'meta' => [
|
||||
'query' => $query,
|
||||
'total_results' => count($results)
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exportiert den Navigationsbaum als JSON-Datei
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
try {
|
||||
$includeHidden = $request->get('include_hidden', true);
|
||||
$tree = $this->navigationService->getFrontendNavigationTree($includeHidden);
|
||||
|
||||
$filename = 'navigation-tree-frontend-' . date('Y-m-d-His') . '.json';
|
||||
$json = json_encode($tree, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
return response($json)
|
||||
->header('Content-Type', 'application/json')
|
||||
->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
|
||||
} catch (\Exception $e) {
|
||||
return back()->with('error', 'Export fehlgeschlagen: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Cache
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function clearCache()
|
||||
{
|
||||
try {
|
||||
$this->navigationService->clearCache();
|
||||
return back()->with('success', 'Navigation-Cache erfolgreich gelöscht');
|
||||
} catch (\Exception $e) {
|
||||
return back()->with('error', 'Cache-Löschung fehlgeschlagen: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt die Statistiken
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function stats(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$allTree = $this->navigationService->getNavigationTree(false);
|
||||
$activeTree = $this->navigationService->getNavigationTree(true);
|
||||
|
||||
$flatList = $this->navigationService->getFlatNavigationList();
|
||||
|
||||
// Zähle verschiedene Typen
|
||||
$stats = [
|
||||
'total_pages' => count($flatList),
|
||||
'total_nodes' => $this->navigationService->countNodes($allTree),
|
||||
'active_nodes' => $this->navigationService->countNodes($activeTree),
|
||||
'inactive_nodes' => $this->navigationService->countNodes($allTree) - $this->navigationService->countNodes($activeTree),
|
||||
'travel_programs' => count(array_filter($flatList, fn($n) => $n['is_travel_program'])),
|
||||
'fewo_lodgings' => count(array_filter($flatList, fn($n) => $n['is_fewo_lodging'])),
|
||||
'country_pages' => count(array_filter($flatList, fn($n) => $n['is_country_page'])),
|
||||
];
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $stats
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
391
app/Http/Controllers/NewsletterController.php
Normal file
391
app/Http/Controllers/NewsletterController.php
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\NewsletterContact;
|
||||
use App\Models\NewsletterLog;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Exports\NewsletterExport;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class NewsletterController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste aller Newsletter-Kontakte
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'statistics' => $this->getStatistics(),
|
||||
];
|
||||
return view('newsletter.index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables Daten für die Liste
|
||||
*/
|
||||
public function getDatatable(Request $request)
|
||||
{
|
||||
$query = NewsletterContact::query()
|
||||
->select([
|
||||
'id',
|
||||
'email',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'group_kulturreisen',
|
||||
'group_ferienwohnungen',
|
||||
'status',
|
||||
'source',
|
||||
'total_bookings_kulturreisen',
|
||||
'total_bookings_ferienwohnungen',
|
||||
'last_booking_at',
|
||||
'last_travel_end_date',
|
||||
'created_at',
|
||||
]);
|
||||
|
||||
// Filter nach Gruppe
|
||||
if ($request->has('group') && $request->group != '') {
|
||||
if ($request->group == 'kulturreisen') {
|
||||
$query->where('group_kulturreisen', true);
|
||||
} elseif ($request->group == 'ferienwohnungen') {
|
||||
$query->where('group_ferienwohnungen', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter nach Status
|
||||
if ($request->has('status') && $request->status != '') {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
|
||||
// Filter nach Source
|
||||
if ($request->has('source') && $request->source != '') {
|
||||
$query->where('source', $request->source);
|
||||
}
|
||||
|
||||
// Filter nach Datum der letzten Buchung (von)
|
||||
if ($request->has('travel_from') && $request->travel_from != '') {
|
||||
$query->whereDate('last_travel_end_date', '>=', Carbon::parse($request->travel_from)->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
// Filter nach Datum der letzten Buchung (bis)
|
||||
if ($request->has('travel_to') && $request->travel_to != '') {
|
||||
$query->whereDate('last_travel_end_date', '<=', Carbon::parse($request->travel_to)->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
return DataTables::of($query)
|
||||
->addColumn('full_name', function ($contact) {
|
||||
return $contact->full_name ?: '-';
|
||||
})
|
||||
->addColumn('groups', function ($contact) {
|
||||
$html = '';
|
||||
if ($contact->group_kulturreisen) {
|
||||
$html .= '<span class="badge badge-info">Kulturreisen</span> ';
|
||||
}
|
||||
if ($contact->group_ferienwohnungen) {
|
||||
$html .= '<span class="badge badge-primary">Ferienwohnungen</span>';
|
||||
}
|
||||
return $html ?: '-';
|
||||
})
|
||||
->addColumn('status_badge', function ($contact) {
|
||||
return '<span class="badge badge-' . $contact->status_color . '">' . $contact->status_label . '</span>';
|
||||
})
|
||||
->addColumn('total_bookings', function ($contact) {
|
||||
$html = '';
|
||||
if ($contact->total_bookings_kulturreisen > 0) {
|
||||
$html .= '<span class="badge badge-secondary">K: ' . $contact->total_bookings_kulturreisen . '</span> ';
|
||||
}
|
||||
if ($contact->total_bookings_ferienwohnungen > 0) {
|
||||
$html .= '<span class="badge badge-secondary">F: ' . $contact->total_bookings_ferienwohnungen . '</span>';
|
||||
}
|
||||
return $html ?: '0';
|
||||
})
|
||||
->addColumn('last_booking', function ($contact) {
|
||||
return $contact->last_booking_at ? $contact->last_booking_at->format('d.m.Y') : '-';
|
||||
})
|
||||
->addColumn('last_travel', function ($contact) {
|
||||
return $contact->last_travel_end_date ? $contact->last_travel_end_date->format('d.m.Y') : '-';
|
||||
})
|
||||
->addColumn('source_label', function ($contact) {
|
||||
return $contact->source_label;
|
||||
})
|
||||
->addColumn('created', function ($contact) {
|
||||
return $contact->created_at->format('d.m.Y');
|
||||
})
|
||||
->addColumn('actions', function ($contact) {
|
||||
$html = '<div class="btn-group">';
|
||||
$html .= '<a href="' . route('newsletter.detail', $contact->id) . '" class="btn btn-sm btn-info"><i class="fa fa-eye"></i></a>';
|
||||
$html .= '<a href="' . route('newsletter.edit', $contact->id) . '" class="btn btn-sm btn-primary"><i class="fa fa-edit"></i></a>';
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
})
|
||||
->rawColumns(['groups', 'status_badge', 'total_bookings', 'actions'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailansicht eines Kontakts
|
||||
*/
|
||||
public function detail($id)
|
||||
{
|
||||
$contact = NewsletterContact::with(['customer', 'travel_user', 'logs.user'])
|
||||
->findOrFail($id);
|
||||
|
||||
$data = [
|
||||
'contact' => $contact,
|
||||
];
|
||||
|
||||
return view('newsletter.detail', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formular zum Bearbeiten eines Kontakts
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
if ($id === 'new') {
|
||||
$contact = new NewsletterContact();
|
||||
$contact->status = NewsletterContact::STATUS_ACTIVE;
|
||||
$contact->source = NewsletterContact::SOURCE_MANUAL;
|
||||
} else {
|
||||
$contact = NewsletterContact::findOrFail($id);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'contact' => $contact,
|
||||
'id' => $id,
|
||||
];
|
||||
|
||||
return view('newsletter.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichern eines Kontakts
|
||||
*/
|
||||
public function store($id, Request $request)
|
||||
{
|
||||
$rules = [
|
||||
'email' => 'required|email',
|
||||
'status' => 'required|in:' . implode(',', [
|
||||
NewsletterContact::STATUS_ACTIVE,
|
||||
NewsletterContact::STATUS_INACTIVE,
|
||||
NewsletterContact::STATUS_UNSUBSCRIBED,
|
||||
NewsletterContact::STATUS_BOUNCED,
|
||||
]),
|
||||
];
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
if ($id === 'new') {
|
||||
$contact = new NewsletterContact();
|
||||
$isNew = true;
|
||||
} else {
|
||||
$contact = NewsletterContact::findOrFail($id);
|
||||
$isNew = false;
|
||||
}
|
||||
|
||||
// Speichere alte Werte für Log
|
||||
$oldStatus = $contact->status;
|
||||
$oldGroups = [
|
||||
'kulturreisen' => $contact->group_kulturreisen,
|
||||
'ferienwohnungen' => $contact->group_ferienwohnungen,
|
||||
];
|
||||
|
||||
$contact->email = strtolower(trim($request->email));
|
||||
$contact->firstname = $request->firstname;
|
||||
$contact->lastname = $request->lastname;
|
||||
$contact->status = $request->status;
|
||||
$contact->source = $request->source ?? NewsletterContact::SOURCE_MANUAL;
|
||||
$contact->group_kulturreisen = $request->has('group_kulturreisen');
|
||||
$contact->group_ferienwohnungen = $request->has('group_ferienwohnungen');
|
||||
$contact->notes = $request->notes;
|
||||
|
||||
if ($isNew) {
|
||||
$contact->subscribed_at = now();
|
||||
}
|
||||
|
||||
$contact->save();
|
||||
|
||||
// Log erstellen
|
||||
if ($isNew) {
|
||||
$contact->logs()->create([
|
||||
'action' => 'subscribed',
|
||||
'description' => 'Kontakt manuell erstellt',
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
} else {
|
||||
// Status geändert?
|
||||
if ($oldStatus !== $contact->status) {
|
||||
$contact->logs()->create([
|
||||
'action' => 'status_changed',
|
||||
'description' => 'Status geändert von ' . NewsletterContact::$statusLabels[$oldStatus] . ' zu ' . $contact->status_label,
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
|
||||
// Gruppen geändert?
|
||||
if (
|
||||
$oldGroups['kulturreisen'] !== $contact->group_kulturreisen ||
|
||||
$oldGroups['ferienwohnungen'] !== $contact->group_ferienwohnungen
|
||||
) {
|
||||
$contact->logs()->create([
|
||||
'action' => 'group_changed',
|
||||
'description' => 'Gruppenzugehörigkeit geändert',
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
\Session()->flash('alert-success', $isNew ? 'Kontakt erstellt' : 'Kontakt aktualisiert');
|
||||
|
||||
return redirect()->route('newsletter.detail', $contact->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kontakt löschen (soft delete)
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$contact = NewsletterContact::findOrFail($id);
|
||||
|
||||
$contact->logs()->create([
|
||||
'action' => 'unsubscribed',
|
||||
'description' => 'Kontakt gelöscht',
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
|
||||
$contact->delete();
|
||||
|
||||
\Session()->flash('alert-success', 'Kontakt gelöscht');
|
||||
|
||||
return redirect()->route('newsletter.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Kontakt abmelden
|
||||
*/
|
||||
public function unsubscribe($id, Request $request)
|
||||
{
|
||||
$contact = NewsletterContact::findOrFail($id);
|
||||
$contact->unsubscribe($request->reason);
|
||||
|
||||
\Session()->flash('alert-success', 'Kontakt abgemeldet');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kontakt wieder aktivieren
|
||||
*/
|
||||
public function resubscribe($id)
|
||||
{
|
||||
$contact = NewsletterContact::findOrFail($id);
|
||||
$contact->resubscribe();
|
||||
|
||||
\Session()->flash('alert-success', 'Kontakt wieder aktiviert');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronisation starten
|
||||
*/
|
||||
public function sync(Request $request)
|
||||
{
|
||||
$type = $request->get('type', 'all');
|
||||
$force = $request->has('force');
|
||||
|
||||
$output = [];
|
||||
|
||||
if ($type === 'all' || $type === 'kulturreisen') {
|
||||
Artisan::call('newsletter:sync-kulturreisen', $force ? ['--force' => true] : []);
|
||||
$output['kulturreisen'] = Artisan::output();
|
||||
}
|
||||
|
||||
if ($type === 'all' || $type === 'ferienwohnungen') {
|
||||
Artisan::call('newsletter:sync-ferienwohnungen', $force ? ['--force' => true] : []);
|
||||
$output['ferienwohnungen'] = Artisan::output();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-success', 'Synchronisation abgeschlossen');
|
||||
|
||||
return back()->with('sync_output', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export von Kontakten
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
$query = NewsletterContact::query();
|
||||
|
||||
// Filter nach Gruppe
|
||||
if ($request->has('group') && $request->group != '') {
|
||||
if ($request->group == 'kulturreisen') {
|
||||
$query->where('group_kulturreisen', true);
|
||||
} elseif ($request->group == 'ferienwohnungen') {
|
||||
$query->where('group_ferienwohnungen', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter nach Status
|
||||
if ($request->has('status') && $request->status != '') {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
|
||||
// Filter nach Source
|
||||
if ($request->has('source') && $request->source != '') {
|
||||
$query->where('source', $request->source);
|
||||
}
|
||||
|
||||
// Filter nach Datum der letzten Reise (von)
|
||||
if ($request->has('travel_from') && $request->travel_from != '') {
|
||||
$query->whereDate('last_travel_end_date', '>=', Carbon::parse($request->travel_from)->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
// Filter nach Datum der letzten Reise (bis)
|
||||
if ($request->has('travel_to') && $request->travel_to != '') {
|
||||
$query->whereDate('last_travel_end_date', '<=', Carbon::parse($request->travel_to)->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
$contacts = $query->get();
|
||||
|
||||
// Dateiname mit Datum und Filter-Infos
|
||||
$group = $request->get('group', 'all');
|
||||
$status = $request->get('status', 'all');
|
||||
$filename = 'newsletter_' . $group . '_' . $status . '_' . date('Y-m-d') . '.csv';
|
||||
|
||||
return Excel::download(new NewsletterExport($contacts), $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistiken für Dashboard
|
||||
*/
|
||||
private function getStatistics()
|
||||
{
|
||||
return [
|
||||
'total' => NewsletterContact::count(),
|
||||
'active' => NewsletterContact::where('status', NewsletterContact::STATUS_ACTIVE)->count(),
|
||||
'kulturreisen' => NewsletterContact::where('group_kulturreisen', true)->count(),
|
||||
'ferienwohnungen' => NewsletterContact::where('group_ferienwohnungen', true)->count(),
|
||||
'with_bookings' => NewsletterContact::withBookings()->count(),
|
||||
'multiple_bookers' => NewsletterContact::multipleBookers()->count(),
|
||||
'unsubscribed' => NewsletterContact::where('status', NewsletterContact::STATUS_UNSUBSCRIBED)->count(),
|
||||
'last_sync' => NewsletterContact::max('last_synced_at'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Request;
|
||||
use DataTables;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Status;
|
||||
use App\Models\Airline;
|
||||
use App\Models\Airport;
|
||||
use App\Models\Booking;
|
||||
use App\Models\SfGuardUser;
|
||||
use App\Models\CustomerMail;
|
||||
use App\Models\SfGuardUser;
|
||||
use App\Models\Status;
|
||||
use App\Models\Sym\TravelCountry;
|
||||
use App\Models\TravelAgenda;
|
||||
use App\Models\TravelCompany;
|
||||
use App\Models\Sym\TravelCountry;
|
||||
use App\Models\TravelCountryService;
|
||||
use App\Repositories\CustomerMailRepository;
|
||||
use Carbon\Carbon;
|
||||
use DataTables;
|
||||
use Request;
|
||||
|
||||
class RequestController extends Controller
|
||||
{
|
||||
|
|
@ -22,15 +22,27 @@ class RequestController extends Controller
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
$this->middleware(['admin', '2fa']);
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
{
|
||||
// Get distinct travel_country_ids from bookings that are not null
|
||||
$usedCountryIds = Booking::whereNotNull('travel_country_id')
|
||||
->distinct()
|
||||
->pluck('travel_country_id');
|
||||
|
||||
// Fetch the corresponding TravelCountry models and create an associative array [id => name]
|
||||
$travel_countries = TravelCountry::whereIn('id', $usedCountryIds)
|
||||
->pluck('name', 'id') // Use country id as key
|
||||
->toArray();
|
||||
|
||||
//dd($travel_countries); // Keep this for debugging if needed
|
||||
|
||||
$travel_countries = Booking::join('travel_country', 'travel_country_id', '=', 'travel_country.id')->get()->pluck('name', 'travel_country_id')->unique()->toArray();
|
||||
$filter_lead_status = Status::get()->pluck('name', 'id')->toArray();
|
||||
$filter_travel_company = TravelCompany::get()->pluck('name', 'id')->toArray();
|
||||
$filter_airports = Airport::get()->pluck('name', 'id')->toArray();
|
||||
|
||||
$filter_paying_out = Booking::$paying_out_types;
|
||||
$filter_paying_out_status = Booking::$paying_out_status_types;
|
||||
$filter_refund = Booking::$refund_types;
|
||||
|
|
@ -56,8 +68,10 @@ class RequestController extends Controller
|
|||
'filter_refund' => $filter_refund,
|
||||
'filter_xx_tkt' => $filter_xx_tkt,
|
||||
'filter_airlines' => $filter_airlines,
|
||||
'filter_sf_guard_user' => $filter_sf_guard_user
|
||||
'filter_sf_guard_user' => $filter_sf_guard_user,
|
||||
'filter_airports' => $filter_airports,
|
||||
];
|
||||
|
||||
return view('request.index', $data);
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +89,7 @@ class RequestController extends Controller
|
|||
wirte old where has state to new has travel_documents
|
||||
$bs = Booking::whereHas('arrangements', function($q){
|
||||
$q->where('state', '!=', NULL);
|
||||
})->where('lead_id', '!=', NULL)->where('new_drafts', 0)->get();
|
||||
})->where('inquiry_id', '!=', NULL)->where('new_drafts', 0)->get();
|
||||
|
||||
foreach ($bs as $b){
|
||||
$b->travel_documents = true;
|
||||
|
|
@ -84,57 +98,62 @@ class RequestController extends Controller
|
|||
}
|
||||
die();
|
||||
*/
|
||||
private function getSearchRequests(){
|
||||
private function getSearchRequests()
|
||||
{
|
||||
|
||||
$query = Booking::with('lead')->with('customer')->with('customer_mails')->with('customer_mails')->select('booking.*')->where('lead_id', '!=', NULL);
|
||||
$query = Booking::with('lead')->with('customer')->with('customer_mails')->with('customer_mails')->select('booking.*')->where('inquiry_id', '!=', NULL);
|
||||
|
||||
if(Request::get('full_firstname_search') != ""){
|
||||
if (Request::get('full_firstname_search') != "") {
|
||||
$query->whereHas('customer', function ($q) {
|
||||
$q->where('firstname', 'LIKE', '%'.Request::get('full_firstname_search').'%');
|
||||
}); }
|
||||
if(Request::get('full_lastname_search') != ""){
|
||||
$query->whereHas('customer', function ($q) {
|
||||
$q->where('name', 'LIKE', '%'.Request::get('full_lastname_search').'%');
|
||||
$q->where('firstname', 'LIKE', '%' . Request::get('full_firstname_search') . '%');
|
||||
});
|
||||
}
|
||||
if(Request::get('travel_option_country_id') != ""){
|
||||
$country_ids = TravelCountry::where('contact_lands', 'LIKE', '%"'.Request::get('travel_option_country_id').'"%')->get()->pluck('id');
|
||||
if (Request::get('full_lastname_search') != "") {
|
||||
$query->whereHas('customer', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . Request::get('full_lastname_search') . '%');
|
||||
});
|
||||
}
|
||||
if (Request::get('travel_option_country_id') != "") {
|
||||
$country_ids = TravelCountry::where('contact_lands', 'LIKE', '%"' . Request::get('travel_option_country_id') . '"%')->get()->pluck('id');
|
||||
$country_ids[] = Request::get('travel_option_country_id');
|
||||
$query->whereIn('travel_country_id', $country_ids);
|
||||
}
|
||||
if(Request::get('travel_option_agenda_id') != ""){
|
||||
if (Request::get('travel_option_agenda_id') != "") {
|
||||
$query->where('travelagenda_id', '=', Request::get('travel_option_agenda_id'));
|
||||
}
|
||||
if(Request::get('travel_option_company_id') != ""){
|
||||
if (Request::get('travel_option_company_id') != "") {
|
||||
$query->where('travel_company_id', '=', Request::get('travel_option_company_id'));
|
||||
}
|
||||
if(Request::get('travel_option_lead_status_id') != ""){
|
||||
if (Request::get('travel_option_lead_status_id') != "") {
|
||||
$query->whereHas('lead', function ($q) {
|
||||
$q->whereIn('status_id', Request::get('travel_option_lead_status_id'));
|
||||
});
|
||||
}
|
||||
if(Request::get('travel_option_paying_out') != ""){
|
||||
if (Request::get('travel_option_paying_out') != "") {
|
||||
$query->where('paying_out', '=', Request::get('travel_option_paying_out'));
|
||||
}
|
||||
if(Request::get('travel_option_paying_out_status') != ""){
|
||||
if (Request::get('travel_option_paying_out_status') != "") {
|
||||
$query->where('paying_out_status', '=', Request::get('travel_option_paying_out_status'));
|
||||
}
|
||||
if(Request::get('travel_option_refund') != ""){
|
||||
if (Request::get('travel_option_refund') != "") {
|
||||
$query->where('refund', '=', Request::get('travel_option_refund'));
|
||||
}
|
||||
if(Request::get('travel_option_xx_tkt') != ""){
|
||||
if (Request::get('travel_option_xx_tkt') != "") {
|
||||
$query->where('xx_tkt', '=', Request::get('travel_option_xx_tkt'));
|
||||
}
|
||||
if(Request::get('travel_option_airline_id') != ""){
|
||||
$query->where('airline_ids', 'LIKE', '%'.Request::get('travel_option_airline_id').'%');
|
||||
if (Request::get('travel_option_airline_id') != "") {
|
||||
$query->where('airline_ids', 'LIKE', '%' . Request::get('travel_option_airline_id') . '%');
|
||||
}
|
||||
if (Request::get('travel_option_airport_id') != "") {
|
||||
$query->where('airport_id', '=', Request::get('travel_option_airport_id'));
|
||||
}
|
||||
|
||||
|
||||
// $query->where('end_date', '<=', $now);
|
||||
if(Request::get('travel_option_search')){
|
||||
if (Request::get('travel_option_search')) {
|
||||
$now = Carbon::now();
|
||||
|
||||
switch (Request::get('travel_option_search')){
|
||||
switch (Request::get('travel_option_search')) {
|
||||
case 'before_2':
|
||||
$query->whereBetween('start_date', [Carbon::now()->modify('-2 month'), $now]);
|
||||
|
||||
|
|
@ -156,242 +175,245 @@ class RequestController extends Controller
|
|||
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$start = null;
|
||||
$end = null;
|
||||
if(Request::get('arrival_start_date') != ""){
|
||||
if (Request::get('arrival_start_date') != "") {
|
||||
$arrStart = explode(".", Request::get('arrival_start_date'));
|
||||
if(count($arrStart) == 3){
|
||||
if (count($arrStart) == 3) {
|
||||
$start = Carbon::create($arrStart[2], $arrStart[1], $arrStart[0], 0, 0, 0);
|
||||
}
|
||||
}
|
||||
if(Request::get('arrival_end_date') != ""){
|
||||
if (Request::get('arrival_end_date') != "") {
|
||||
$arrEnd = explode(".", Request::get('arrival_end_date'));
|
||||
if(count($arrEnd) == 3){
|
||||
if (count($arrEnd) == 3) {
|
||||
$end = Carbon::create($arrEnd[2], $arrEnd[1], $arrEnd[0], 23, 59, 59);
|
||||
}
|
||||
}
|
||||
if($start && $end){
|
||||
if ($start && $end) {
|
||||
$query->whereBetween('start_date', [$start, $end]);
|
||||
}
|
||||
if($start && !$end){
|
||||
if ($start && !$end) {
|
||||
$query->where('start_date', '>=', $start);
|
||||
}
|
||||
if(!$start && $end){
|
||||
if (!$start && $end) {
|
||||
$query->where('start_date', '<=', $end);
|
||||
}
|
||||
|
||||
$start = null;
|
||||
$end = null;
|
||||
if(Request::get('departure_start_date') != ""){
|
||||
if (Request::get('departure_start_date') != "") {
|
||||
$arrStart = explode(".", Request::get('departure_start_date'));
|
||||
if(count($arrStart) == 3){
|
||||
if (count($arrStart) == 3) {
|
||||
$start = Carbon::create($arrStart[2], $arrStart[1], $arrStart[0], 0, 0, 0);
|
||||
}
|
||||
}
|
||||
if(Request::get('departure_end_date') != ""){
|
||||
if (Request::get('departure_end_date') != "") {
|
||||
$arrEnd = explode(".", Request::get('departure_end_date'));
|
||||
if(count($arrEnd) == 3){
|
||||
if (count($arrEnd) == 3) {
|
||||
$end = Carbon::create($arrEnd[2], $arrEnd[1], $arrEnd[0], 23, 59, 59);
|
||||
}
|
||||
}
|
||||
if($start && $end){
|
||||
if ($start && $end) {
|
||||
$query->whereBetween('end_date', [$start, $end]);
|
||||
}
|
||||
if($start && !$end){
|
||||
if ($start && !$end) {
|
||||
$query->where('end_date', '>=', $start);
|
||||
}
|
||||
if(!$start && $end){
|
||||
if (!$start && $end) {
|
||||
$query->where('end_date', '<=', $end);
|
||||
}
|
||||
}
|
||||
|
||||
if(Request::get('sort_travel_country_id') != ""){
|
||||
if (Request::get('sort_travel_country_id') != "") {
|
||||
$query->where('travel_country_id', '=', Request::get('sort_travel_country_id'));
|
||||
}
|
||||
if(Request::get('sort_travelagenda_id') != ""){
|
||||
if (Request::get('sort_travelagenda_id') != "") {
|
||||
$query->where('travelagenda_id', '=', Request::get('sort_travelagenda_id'));
|
||||
}
|
||||
|
||||
if(Request::get('sort_sf_guard_user_id') != ""){
|
||||
if (Request::get('sort_sf_guard_user_id') != "") {
|
||||
$query->where('sf_guard_user_id', '=', Request::get('sort_sf_guard_user_id'));
|
||||
}
|
||||
|
||||
if(Request::get('sort_travel_documents') != ""){
|
||||
if (Request::get('sort_travel_documents') != "") {
|
||||
$query->where('travel_documents', '=', Request::get('sort_travel_documents'));
|
||||
}
|
||||
|
||||
if(Request::get('full_lead_id_search') != ""){
|
||||
$query->where('lead_id', 'LIKE', '%'.Request::get('full_lead_id_search'). '%');
|
||||
if (Request::get('full_lead_id_search') != "") {
|
||||
$query->where('inquiry_id', 'LIKE', '%' . Request::get('full_lead_id_search') . '%');
|
||||
}
|
||||
if(Request::get('full_booking_id_search') != ""){
|
||||
$query->where('id', 'LIKE', '%'.Request::get('full_booking_id_search').'%');
|
||||
if (Request::get('full_booking_id_search') != "") {
|
||||
$query->where('id', 'LIKE', '%' . Request::get('full_booking_id_search') . '%');
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getAjaxRequests(){
|
||||
public function getAjaxRequests()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if(Request::ajax()) {
|
||||
if(isset($data['action']) && $data['action'] === "get_popover_booking_services") {
|
||||
if (Request::ajax()) {
|
||||
if (isset($data['action']) && $data['action'] === "get_popover_booking_services") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$ret = "";
|
||||
$count = false;
|
||||
foreach($booking->travel_country->getContactLandsModels() as $TravelCountry){
|
||||
if($TravelCountry->stern_travel_country){
|
||||
$hl = $TravelCountry->stern_travel_country->name."<br>";
|
||||
foreach ($booking->travel_country->getContactLandsModels() as $TravelCountry) {
|
||||
if ($TravelCountry->stern_travel_country) {
|
||||
$hl = $TravelCountry->stern_travel_country->name . "<br>";
|
||||
$tmp = "";
|
||||
foreach($TravelCountry->stern_travel_country->travel_country_services as $travel_country_service){
|
||||
foreach ($TravelCountry->stern_travel_country->travel_country_services as $travel_country_service) {
|
||||
$tmp .= \App\Models\BookingCountryService::getStatus($travel_country_service->id, $booking->id) ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$travel_country_service->name.'</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> '.$travel_country_service->name.'</span>';
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $travel_country_service->name . '</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> ' . $travel_country_service->name . '</span>';
|
||||
$tmp .= '<br>';
|
||||
}
|
||||
if($tmp !== ""){
|
||||
$ret .= $hl.$tmp;
|
||||
if ($tmp !== "") {
|
||||
$ret .= $hl . $tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($booking->service_provider_entries->count()){
|
||||
foreach($booking->service_provider_entries as $service_provider_entry){
|
||||
if($service_provider_entry->service_provider->service_provider_services->count()){
|
||||
$hl = $service_provider_entry->service_provider->name."<br>";
|
||||
if ($booking->service_provider_entries->count()) {
|
||||
foreach ($booking->service_provider_entries as $service_provider_entry) {
|
||||
if ($service_provider_entry->service_provider->service_provider_services->count()) {
|
||||
$hl = $service_provider_entry->service_provider->name . "<br>";
|
||||
$tmp = "";
|
||||
foreach($service_provider_entry->service_provider->service_provider_services as $service_provider_service){
|
||||
foreach ($service_provider_entry->service_provider->service_provider_services as $service_provider_service) {
|
||||
$tmp .= \App\Models\BookingProviderService::getStatus($service_provider_service->id, $booking->id) ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$service_provider_service->name.'</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> '.$service_provider_service->name.'</span>';
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $service_provider_service->name . '</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> ' . $service_provider_service->name . '</span>';
|
||||
$tmp .= '<br>';
|
||||
}
|
||||
if($tmp !== ""){
|
||||
$ret .= $hl.$tmp;
|
||||
if ($tmp !== "") {
|
||||
$ret .= $hl . $tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($booking->booking_service_items->count()){
|
||||
foreach($booking->booking_service_items as $booking_service_item){
|
||||
if($booking_service_item->travel_company->travel_company_services->count()){
|
||||
$hl = $booking_service_item->travel_company->name."<br>";
|
||||
if ($booking->booking_service_items->count()) {
|
||||
foreach ($booking->booking_service_items as $booking_service_item) {
|
||||
if ($booking_service_item->travel_company->travel_company_services->count()) {
|
||||
$hl = $booking_service_item->travel_company->name . "<br>";
|
||||
$tmp = "";
|
||||
foreach($booking_service_item->travel_company->travel_company_services as $travel_company_service){
|
||||
foreach ($booking_service_item->travel_company->travel_company_services as $travel_company_service) {
|
||||
$tmp .= \App\Models\BookingCompanyService::getStatus($travel_company_service->id, $booking->id) ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$travel_company_service->name.'</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> '.$travel_company_service->name.'</span>';
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $travel_company_service->name . '</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> ' . $travel_company_service->name . '</span>';
|
||||
$tmp .= '<br>';
|
||||
}
|
||||
if($tmp !== ""){
|
||||
$ret .= $hl.$tmp;
|
||||
if ($tmp !== "") {
|
||||
$ret .= $hl . $tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret === "" ? 'keine Leistungen definiert' : $ret;
|
||||
return $ret === "" ? 'keine Leistungen definiert' : $ret;
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] === "get_popover_booking_notice"){
|
||||
|
||||
if (isset($data['action']) && $data['action'] === "get_popover_booking_notice") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$ret = "";
|
||||
if($booking->booking_notices->count()){
|
||||
if ($booking->booking_notices->count()) {
|
||||
$booking_notice = $booking->booking_notices->first();
|
||||
return $booking_notice->getSmallerMessage(500);
|
||||
}
|
||||
return $ret === "" ? 'keine E-Notiz' : $ret;
|
||||
return $ret === "" ? 'keine E-Notiz' : $ret;
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] === "get_popover_booking_last_email"){
|
||||
if (isset($data['action']) && $data['action'] === "get_popover_booking_last_email") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$ret = "";
|
||||
if($booking->customer_mails->count()){
|
||||
if ($booking->customer_mails->count()) {
|
||||
$customer_mail = $booking->customer_mails_sent_at->last();
|
||||
return "<h6>".$customer_mail->subject."</h6>".$customer_mail->message;
|
||||
}
|
||||
return $ret === "" ? 'keine E-Mail' : $ret;
|
||||
return "<h6>" . $customer_mail->subject . "</h6>" . $customer_mail->message;
|
||||
}
|
||||
return $ret === "" ? 'keine E-Mail' : $ret;
|
||||
}
|
||||
if(isset($data['action']) && $data['action'] === "get_popover_booking_participants_pass"){
|
||||
if (isset($data['action']) && $data['action'] === "get_popover_booking_participants_pass") {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$ret = "";
|
||||
if($booking->participant_firstname){
|
||||
$ret .= $booking->participant_pass ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$booking->participant_firstname." ".$booking->participant_lastname.'</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> '.$booking->participant_firstname." ".$booking->participant_lastname.'</span>';
|
||||
$ret .= "<br>";
|
||||
if ($booking->participant_firstname) {
|
||||
$ret .= $booking->participant_pass ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $booking->participant_firstname . " " . $booking->participant_lastname . '</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> ' . $booking->participant_firstname . " " . $booking->participant_lastname . '</span>';
|
||||
$ret .= "<br>";
|
||||
}
|
||||
if($booking->participants->count()){
|
||||
foreach($booking->participants as $participant){
|
||||
if ($booking->participants->count()) {
|
||||
foreach ($booking->participants as $participant) {
|
||||
$ret .= $participant->participant_pass ?
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$participant->participant_firstname." ".$participant->participant_lastname.'</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> '.$participant->participant_firstname." ".$participant->participant_lastname.'</span>';
|
||||
'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $participant->participant_firstname . " " . $participant->participant_lastname . '</span>' :
|
||||
'<span class="badge badge-pill badge-danger""><i class="fa fa-times"></i> ' . $participant->participant_firstname . " " . $participant->participant_lastname . '</span>';
|
||||
$ret .= "<br>";
|
||||
}
|
||||
}
|
||||
return $ret === "" ? 'keine Teilnehmer' : $ret;
|
||||
}
|
||||
|
||||
|
||||
$query = $this->getSearchRequests();
|
||||
$ret = $query->get()->pluck('travelagenda_id', 'id')->unique()->toArray();
|
||||
return TravelAgenda::whereIn('id', $ret)->get()->pluck('name', 'id');
|
||||
}
|
||||
}
|
||||
|
||||
public function loadModal(){
|
||||
public function loadModal()
|
||||
{
|
||||
$data = Request::all();
|
||||
$ret = "";
|
||||
if(Request::ajax()){
|
||||
if($data['action'] === 'new-customer-mail'){
|
||||
if (Request::ajax()) {
|
||||
if ($data['action'] === 'new-customer-mail') {
|
||||
$data['customers'] = [];
|
||||
$query = $this->getSearchRequests();
|
||||
$bookings = $query->orderBy('id', 'DESC')->limit(50)->get();
|
||||
foreach ($bookings as $booking){
|
||||
foreach ($bookings as $booking) {
|
||||
$tmp = [];
|
||||
$tmp['email'] = $booking->customer ? $booking->customer->email : "";
|
||||
$tmp['name'] = $booking->customer ? $booking->customer->firstname." ".$booking->customer->name." | " : "- | ";
|
||||
$tmp['name'] .= $booking->travel_country_id ? $booking->travel_country->name." | " : "- | ";
|
||||
$tmp['name'] .= $booking->travelagenda_id ? $booking->travel_agenda->name."" : "-";
|
||||
$tmp['name'] = $booking->customer ? $booking->customer->firstname . " " . $booking->customer->name . " | " : "- | ";
|
||||
$tmp['name'] .= $booking->travel_country_id ? $booking->travel_country->name . " | " : "- | ";
|
||||
$tmp['name'] .= $booking->travelagenda_id ? $booking->travel_agenda->name . "" : "-";
|
||||
$data['customers'][$booking->id] = $tmp;
|
||||
}
|
||||
$ret = CustomerMailRepository::loadModal($data);
|
||||
}
|
||||
if($data['action'] === 'show-customer-mail'){
|
||||
if ($data['action'] === 'show-customer-mail') {
|
||||
$booking = Booking::findOrFail($data['booking_id']);
|
||||
$ret = "";
|
||||
if($booking->customer_mails->count()){
|
||||
if ($booking->customer_mails->count()) {
|
||||
$ret = CustomerMailRepository::loadModal($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return response()->json(['response' => $data, 'html'=>$ret]);
|
||||
return response()->json(['response' => $data, 'html' => $ret]);
|
||||
}
|
||||
|
||||
public function getRequests()
|
||||
{
|
||||
|
||||
$query = $this->getSearchRequests();
|
||||
|
||||
return DataTables::eloquent($query)
|
||||
->addColumn('action_booking_edit', function (Booking $booking) {
|
||||
return '<a href="' . route('booking_detail', [$booking->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('action_booking_edit', function (Booking $booking) {
|
||||
return '<a href="' . route('booking_detail', [$booking->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('id', function (Booking $booking) {
|
||||
return '<a data-order="'.$booking->id.'" href="'.make_old_url('booking/'.$booking->id.'/edit').'" data-id="'.$booking->id.'">'.$booking->id.'</a>';
|
||||
return '<a data-order="' . $booking->id . '" href="' . make_old_url('booking/' . $booking->id . '/edit') . '" data-id="' . $booking->id . '">' . $booking->id . '</a>';
|
||||
})
|
||||
->addColumn('action_lead_edit', function (Booking $booking) {
|
||||
return '<a href="' . route('lead_detail', [$booking->lead_id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
return '<a href="' . route('lead_detail', [$booking->inquiry_id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('lead_id', function (Booking $booking) {
|
||||
return '<a data-order="'.$booking->lead_id.'" href="'.make_old_url('leads/'.$booking->lead_id.'/edit').'" data-id="'.$booking->lead_id.'">'.$booking->lead_id.'</a>';
|
||||
return '<a data-order="' . $booking->inquiry_id . '" href="' . make_old_url('leads/' . $booking->inquiry_id . '/edit') . '" data-id="' . $booking->inquiry_id . '">' . $booking->inquiry_id . '</a>';
|
||||
})
|
||||
->addColumn('travel_country_id', function (Booking $booking) {
|
||||
return '<span data-order="'.($booking->travel_country_id ? $booking->travel_country_id : 0).'">'.($booking->travel_country_id ? $booking->travel_country->name : "-").'</span>';
|
||||
return '<span data-order="' . ($booking->travel_country_id ? $booking->travel_country_id : 0) . '">' . ($booking->travel_country_id ? $booking->travel_country->name : "-") . '</span>';
|
||||
})
|
||||
->addColumn('travelagenda_id', function (Booking $booking) {
|
||||
return '<span data-order="'.($booking->travelagenda_id ? $booking->travelagenda_id : 0).'">'.($booking->travelagenda_id ? $booking->travel_agenda->name : "-").'</span>';
|
||||
return '<span data-order="' . ($booking->travelagenda_id ? $booking->travelagenda_id : 0) . '">' . ($booking->travelagenda_id ? $booking->travel_agenda->name : "-") . '</span>';
|
||||
})
|
||||
->addColumn('travel_company_id', function (Booking $booking) {
|
||||
return '<span data-order="'.($booking->travel_company_id ? $booking->travel_company_id : 0).'">'.($booking->travel_company ? $booking->travel_company->name : "-").'</span>';
|
||||
return '<span data-order="' . ($booking->travel_company_id ? $booking->travel_company_id : 0) . '">' . ($booking->travel_company ? $booking->travel_company->name : "-") . '</span>';
|
||||
})
|
||||
->addColumn('airport_id', function (Booking $booking) {
|
||||
return '<span data-order="' . ($booking->airport_id ? $booking->airport_id : 0) . '">' . ($booking->airport ? $booking->airport->name : "-") . '</span>';
|
||||
})
|
||||
->addColumn('comfort', function (Booking $booking) {
|
||||
return $booking->comfort ? ' <span data-order="1" class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>' : '<span data-order="0" class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>';
|
||||
|
|
@ -406,92 +428,94 @@ class RequestController extends Controller
|
|||
return $booking->travel_documents ? '<span data-order="1" class="badge badge-pill badge-success" title="Reiseunterlagen vollständig" data-placement="top" rel="tooltip"><i class="fa fa-check"></i></span>' : '<span data-order="0" class="badge badge-pill badge-danger" title="Reiseunterlagen nicht vollständig" data-placement="top" rel="tooltip"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('booking_services', function (Booking $booking) {
|
||||
return $booking->hasBookingServicesUnchecked() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="'.$booking->id.'" data-action="get_popover_booking_services" data-placement="top" data-toggle="popover" title="ServiceLeistungen"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger" data-booking_id="'.$booking->id.'" data-action="get_popover_booking_services" data-placement="top" data-toggle="popover" title="ServiceLeistungen"><i class="fa fa-times"></i></span>';
|
||||
return $booking->hasBookingServicesUnchecked() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="' . $booking->id . '" data-action="get_popover_booking_services" data-placement="top" data-toggle="popover" title="ServiceLeistungen"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger" data-booking_id="' . $booking->id . '" data-action="get_popover_booking_services" data-placement="top" data-toggle="popover" title="ServiceLeistungen"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('booking_notice', function (Booking $booking) {
|
||||
return $booking->booking_notices->count() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="'.$booking->id.'" data-action="get_popover_booking_notice" data-placement="top" data-toggle="popover" title="letzte Notiz"><i class="fa fa-check"></i></span>' :
|
||||
return $booking->booking_notices->count() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="' . $booking->id . '" data-action="get_popover_booking_notice" data-placement="top" data-toggle="popover" title="letzte Notiz"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger" title="keine Notiz" data-placement="top" rel="tooltip"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('sf_guard_user_id', function (Booking $booking) {
|
||||
return '<span data-order="'.($booking->sf_guard_user_id ? $booking->sf_guard_user_id : 0).'">'.($booking->sf_guard_user_id? $booking->sf_guard_user->first_name." ".$booking->sf_guard_user->last_name : "-").'</span>';
|
||||
return '<span data-order="' . ($booking->sf_guard_user_id ? $booking->sf_guard_user_id : 0) . '">' . ($booking->sf_guard_user_id ? $booking->sf_guard_user->first_name . " " . $booking->sf_guard_user->last_name : "-") . '</span>';
|
||||
})
|
||||
->addColumn('lead.status_id', function (Booking $booking) {
|
||||
if($booking->lead){
|
||||
if ($booking->lead) {
|
||||
return $booking->lead->getStatusBadge($booking);
|
||||
}
|
||||
return '<span data-order="0">-</span>';
|
||||
})
|
||||
->addColumn('last_customer_email', function (Booking $booking) {
|
||||
if($booking->customer_mails->count()){
|
||||
$customer_mail = $booking->customer_mails_sent_at->last();
|
||||
$badge = $customer_mail->is_answer ? 'badge-default' : 'badge-secondary';
|
||||
$badge = !$customer_mail->send ? $badge : 'badge-success';
|
||||
return '<a data-order="'.$customer_mail->getSentAtRaw().'" href="#" data-toggle="modal"
|
||||
if ($booking->customer_mails->count()) {
|
||||
$customer_mail = $booking->customer_mails_sent_at->last();
|
||||
$badge = $customer_mail->is_answer ? 'badge-default' : 'badge-secondary';
|
||||
$badge = !$customer_mail->send ? $badge : 'badge-success';
|
||||
return '<a data-order="' . $customer_mail->getSentAtRaw() . '" href="#" data-toggle="modal"
|
||||
data-target="#modals-load-content"
|
||||
data-id="show-mail"
|
||||
data-url="mail"
|
||||
data-preview="true"
|
||||
data-booking_id="'.$booking->id.'"
|
||||
data-customer_mail_id="'.$customer_mail->id.'"
|
||||
data-booking_id="' . $booking->id . '"
|
||||
data-customer_mail_id="' . $customer_mail->id . '"
|
||||
data-action="show-customer-mail"
|
||||
data-redirect="back"
|
||||
data-route="'.route('requests_modal_load').'">
|
||||
<span class="badge '.$badge.'">'
|
||||
.($customer_mail->send ? '<i class="fa fa-check-circle"></i>' : '<i class="fa fa-times-circle"></i>').' '
|
||||
.$customer_mail->sent_at.'</span>
|
||||
data-route="' . route('requests_modal_load') . '">
|
||||
<span class="badge ' . $badge . '">'
|
||||
. ($customer_mail->send ? '<i class="fa fa-check-circle"></i>' : '<i class="fa fa-times-circle"></i>') . ' '
|
||||
. $customer_mail->sent_at . '</span>
|
||||
</a>';
|
||||
}
|
||||
return '<span data-order="">-</span>';
|
||||
|
||||
})
|
||||
->addColumn('booking_participants_pass', function (Booking $booking) {
|
||||
return $booking->hasBookingParticipantsPass() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="'.$booking->id.'" data-action="get_popover_booking_participants_pass" data-placement="top" data-toggle="popover" title="Teilnehmer Pass"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger" data-booking_id="'.$booking->id.'" data-action="get_popover_booking_participants_pass" data-placement="top" data-toggle="popover" title="Teilnehmer Pass"><i class="fa fa-times"></i></span>';
|
||||
return $booking->hasBookingParticipantsPass() ? '<span data-order="1" class="badge badge-pill badge-success" data-booking_id="' . $booking->id . '" data-action="get_popover_booking_participants_pass" data-placement="top" data-toggle="popover" title="Teilnehmer Pass"><i class="fa fa-check"></i></span>' :
|
||||
'<span data-order="0" class="badge badge-pill badge-danger" data-booking_id="' . $booking->id . '" data-action="get_popover_booking_participants_pass" data-placement="top" data-toggle="popover" title="Teilnehmer Pass"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
|
||||
|
||||
->addColumn('paying_out', function (Booking $booking) {
|
||||
$icon = "";
|
||||
$badge = $booking->getPayingOutColor();
|
||||
if($booking->paying_out_status == 1){ //offen
|
||||
if ($booking->paying_out_status == 1) { //offen
|
||||
$icon = '<i class="fa fa-times-circle"></i> ';
|
||||
}
|
||||
if($booking->paying_out_status == 2){ //erledigt
|
||||
if ($booking->paying_out_status == 2) { //erledigt
|
||||
$badge = 'success';
|
||||
$icon = '<i class="fa fa-check-circle"></i> ';
|
||||
}
|
||||
return '<span data-order="'.$booking->paying_out.'"><span class="badge badge-'.$booking->getPayingOutColor().'">'.$icon.$booking->getPayingOutType().'</span></span>';
|
||||
return '<span data-order="' . $booking->paying_out . '"><span class="badge badge-' . $booking->getPayingOutColor() . '">' . $icon . $booking->getPayingOutType() . '</span></span>';
|
||||
})
|
||||
->addColumn('paying_out_status', function (Booking $booking) {
|
||||
return '<span data-order="'.$booking->paying_out_status.'"><span class="badge badge-'.$booking->getPayingOutStatusColor().'">'.$booking->getPayingOutStatusType().'</span></span>';
|
||||
return '<span data-order="' . $booking->paying_out_status . '"><span class="badge badge-' . $booking->getPayingOutStatusColor() . '">' . $booking->getPayingOutStatusType() . '</span></span>';
|
||||
})
|
||||
->addColumn('airline_ids', function (Booking $booking) {
|
||||
return $booking->airline_ids ? '<span data-order="'.$booking->getAirlinesIDs().'">'. $booking->getAirlinesAsNames().'</span>' : '-';
|
||||
return $booking->airline_ids ? '<span data-order="' . $booking->getAirlinesIDs() . '">' . $booking->getAirlinesAsNames() . '</span>' : '-';
|
||||
})
|
||||
->addColumn('refund', function (Booking $booking) {
|
||||
return '<span data-order="'.$booking->refund_date.'"><span class="badge badge-'.$booking->getRefundColor().'">'.$booking->getRefundTypeList().'</span></span>';
|
||||
return '<span data-order="' . $booking->refund_date . '"><span class="badge badge-' . $booking->getRefundColor() . '">' . $booking->getRefundTypeList() . '</span></span>';
|
||||
})
|
||||
->addColumn('hold', function (Booking $booking) {
|
||||
return $booking->hold ? ' <span data-order="1" class="badge badge-pill badge-success" title="Hold" data-placement="top" rel="tooltip"><i class="fa fa-check"></i></span>' : '<span data-order="0" class="badge badge-pill badge-danger" title="Hold" data-placement="top" rel="tooltip"><i class="fa fa-times"></i></span>';
|
||||
})
|
||||
->addColumn('xx_tkt', function (Booking $booking) {
|
||||
return '<span data-order="'.$booking->xx_tkt_date.'"><span class="badge badge-'.$booking->getXxTktColor().'">'.$booking->getXxTktTypeList().'</span></span>';
|
||||
return '<span data-order="' . $booking->xx_tkt_date . '"><span class="badge badge-' . $booking->getXxTktColor() . '">' . $booking->getXxTktTypeList() . '</span></span>';
|
||||
})
|
||||
|
||||
->orderColumn('last_customer_email', function ($query, $order) {
|
||||
|
||||
$query->whereHas('customer_mails',
|
||||
function ($q) use ($order) {
|
||||
// $q->select('sent_at')->where('sent_at', DB::raw("(select max('sent_at') customer_mails)")); //)
|
||||
})->orderBy(
|
||||
$query->whereHas(
|
||||
'customer_mails',
|
||||
function ($q) use ($order) {
|
||||
// $q->select('sent_at')->where('sent_at', DB::raw("(select max('sent_at') customer_mails)")); //)
|
||||
}
|
||||
)->orderBy(
|
||||
CustomerMail::select('sent_at')
|
||||
->whereColumn('booking_id', 'booking.id')
|
||||
->orderBy('sent_at', 'DESC')
|
||||
->limit(1)
|
||||
, $order);
|
||||
->limit(1),
|
||||
$order
|
||||
);
|
||||
})
|
||||
|
||||
/*
|
||||
/*
|
||||
->filterColumn('travelagenda_id', function($query, $keyword) {
|
||||
if($keyword != ""){
|
||||
$query->whereRaw("travelagenda_id = ?", $keyword);
|
||||
|
|
@ -499,7 +523,7 @@ class RequestController extends Controller
|
|||
}
|
||||
})
|
||||
*/
|
||||
->orderColumn('lead_id', 'lead_id $1')
|
||||
->orderColumn('lead_id', 'inquiry_id $1')
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('travel_country_id', 'travel_country_id $1')
|
||||
->orderColumn('travelagenda_id', 'travelagenda_id $1')
|
||||
|
|
@ -515,9 +539,7 @@ class RequestController extends Controller
|
|||
->orderColumn('xx_tkt', 'xx_tkt_date $1')
|
||||
->orderColumn('comfort', 'comfort $1')
|
||||
//->orderColumn('travel_documents', 'travel_documents $1')
|
||||
->rawColumns(['action_lead_edit', 'comfort', 'lead_id', 'booking_participants_pass', 'action_booking_edit', 'travel_country_id', 'travelagenda_id', 'travel_company_id', 'sf_guard_user_id', 'airline_ids', 'lead.status_id', 'last_customer_email', 'id', 'travel_documents', 'booking_services', 'booking_notice', 'paying_out', 'paying_out_status', 'airline_id', 'refund', 'hold', 'xx_tkt'])
|
||||
->rawColumns(['action_lead_edit', 'comfort', 'lead_id', 'booking_participants_pass', 'action_booking_edit', 'travel_country_id', 'travelagenda_id', 'travel_company_id', 'sf_guard_user_id', 'airline_ids', 'lead.status_id', 'last_customer_email', 'id', 'travel_documents', 'booking_services', 'booking_notice', 'paying_out', 'paying_out_status', 'airline_id', 'airport_id', 'refund', 'hold', 'xx_tkt'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
65
app/Http/Controllers/Settings/AirportController.php
Normal file
65
app/Http/Controllers/Settings/AirportController.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use Request;
|
||||
|
||||
use App\Models\Airport;
|
||||
use App\Models\Booking;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class AirportController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
public function index($step = false)
|
||||
{
|
||||
$data = [
|
||||
'airports' => Airport::all(),
|
||||
];
|
||||
return view('settings.airport.index', $data);
|
||||
}
|
||||
|
||||
public function update(){
|
||||
|
||||
$data = Request::all();
|
||||
if($data['id'] === "new"){
|
||||
$model = Airport::create([
|
||||
'code' => $data['code'],
|
||||
'name' => $data['name'],
|
||||
'city' => $data['city'],
|
||||
'country' => $data['country'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
]);
|
||||
}else{
|
||||
$model = Airport::find($data['id']);
|
||||
$model->name = $data['name'];
|
||||
$model->code = $data['code'];
|
||||
$model->city = isset($data['city']) ? $data['city'] : NULL;
|
||||
$model->country = isset($data['country']) ? $data['country'] : NULL;
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_settings_airport'));
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
||||
if(Booking::where('airport_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
$model = Airport::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -18,6 +18,8 @@ class EmailsController extends Controller
|
|||
|
||||
protected $identifier_booking_file;
|
||||
protected $identifier_fewo_file;
|
||||
protected $identifier_lead_file;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class ServiceProviderController extends Controller
|
|||
$model = new ServiceProvider();
|
||||
$id = 'new';
|
||||
$model->active = 1;
|
||||
$model->id = 0;
|
||||
}else{
|
||||
$model = ServiceProvider::findOrFail($id);
|
||||
$id = $model->id;
|
||||
|
|
@ -49,7 +50,6 @@ class ServiceProviderController extends Controller
|
|||
public function update($id){
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if(isset($data['update-action'])){
|
||||
if($data['update-action'] === 'save-service-provider-service'){
|
||||
$data['active'] = true;//isset($data['active']) ? true : false;
|
||||
|
|
@ -70,7 +70,6 @@ class ServiceProviderController extends Controller
|
|||
|
||||
|
||||
$data['contact_emails'] = isset($data['contact_emails']) ? Util::_explodeLines($data['contact_emails']) : null;
|
||||
|
||||
if($id === "new"){
|
||||
$model = ServiceProvider::create($data);
|
||||
}else{
|
||||
|
|
@ -87,8 +86,17 @@ class ServiceProviderController extends Controller
|
|||
public function delete($id, $del="service_provider"){
|
||||
|
||||
if($del === 'service_provider') {
|
||||
abort(404, 'Noch keine Funktion');
|
||||
//abort(403, 'Noch keine Funktion');
|
||||
$model = ServiceProvider::findOrFail($id);
|
||||
if($model->service_provider_entries->count() > 0){
|
||||
\Session()->flash('alert-error', 'Der Leistungträger kann nicht gelöscht werden, dieser hat Einträge');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
if($model->service_provider_services->count() > 0){
|
||||
\Session()->flash('alert-error', 'Der Leistungträger kann nicht gelöscht werden, dieser hat Einträge Service');
|
||||
return redirect()->back();
|
||||
}
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect()->back();
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ class TravelAgendaController extends Controller
|
|||
|
||||
public function delete($id){
|
||||
|
||||
if(Booking::where('travelagenda_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird verwendet');
|
||||
if(Booking::where('travelagenda_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Buchnungen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use App\Models\TravelArrivalPoint;
|
||||
use Request;
|
||||
|
||||
class TravelArrivalPointController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
{
|
||||
$data = [
|
||||
'travel_arrival_point' => TravelArrivalPoint::all(),
|
||||
];
|
||||
return view('settings.travel_arrival_point.index', $data);
|
||||
}
|
||||
|
||||
|
||||
public function update(){
|
||||
|
||||
$data = Request::all();
|
||||
if($data['id'] === "new"){
|
||||
$model = TravelArrivalPoint::create([
|
||||
'name' => $data['name'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
'travel_country_id' => $data['travel_country_id'],
|
||||
|
||||
]);
|
||||
}else{
|
||||
$model = TravelArrivalPoint::find($data['id']);
|
||||
$model->name = $data['name'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->travel_country_id = $data['travel_country_id'];
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_settings_travel_arrival_point'));
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
||||
$model = TravelArrivalPoint::findOrFail($id);
|
||||
if($model->travel_programs->count() > 0){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Reiseprogrammen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
67
app/Http/Controllers/Settings/TravelCategoryController.php
Normal file
67
app/Http/Controllers/Settings/TravelCategoryController.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\TravelCategory;
|
||||
use Request;
|
||||
|
||||
class TravelCategoryController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
{
|
||||
$data = [
|
||||
'travel_category' => TravelCategory::all(),
|
||||
];
|
||||
return view('settings.travel_category.index', $data);
|
||||
}
|
||||
|
||||
|
||||
public function update(){
|
||||
|
||||
$data = Request::all();
|
||||
if($data['id'] === "new"){
|
||||
$model = TravelCategory::create([
|
||||
'name' => $data['name'],
|
||||
'active' => isset($data['active']) ? true : false
|
||||
|
||||
]);
|
||||
}else{
|
||||
$model = TravelCategory::find($data['id']);
|
||||
$model->name = $data['name'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_settings_travel_category'));
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
|
||||
$model = TravelCategory::findOrFail($id);
|
||||
if($model->bookings->count() > 0){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Buchnungen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
if($model->travel_programs->count() > 0){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Programmen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
if($model->leads->count() > 0){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Anfragen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -27,11 +27,11 @@ class TravelCompanyController extends Controller
|
|||
|
||||
public function detail($id, $step = false)
|
||||
{
|
||||
if($id === "new") {
|
||||
if ($id == "new") {
|
||||
$model = new TravelCompany();
|
||||
$id = 'new';
|
||||
$model->active = 1;
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCompany::findOrFail($id);
|
||||
$id = $model->id;
|
||||
}
|
||||
|
|
@ -45,20 +45,21 @@ class TravelCompanyController extends Controller
|
|||
return view('settings.travel_company.detail', $data);
|
||||
}
|
||||
|
||||
public function update($id){
|
||||
public function update($id)
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
|
||||
if(isset($data['update-action'])){
|
||||
if($data['update-action'] === 'save-travel-company-service'){
|
||||
$data['active'] = true;//isset($data['active']) ? true : false;
|
||||
if (isset($data['update-action'])) {
|
||||
if ($data['update-action'] === 'save-travel-company-service') {
|
||||
$data['active'] = true; //isset($data['active']) ? true : false;
|
||||
$travel_company = TravelCompany::findOrFail($id);
|
||||
$data['travel_company_id'] = $travel_company->id;
|
||||
|
||||
if($data['travel_company_service_id'] === 'new'){
|
||||
if ($data['travel_company_service_id'] === 'new') {
|
||||
$model = TravelCompanyService::create($data);
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCompanyService::find($data['travel_company_service_id']);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
|
@ -69,9 +70,9 @@ class TravelCompanyController extends Controller
|
|||
}
|
||||
|
||||
$data['contact_emails'] = isset($data['contact_emails']) ? Util::_explodeLines($data['contact_emails']) : null;
|
||||
if($id === "new"){
|
||||
if ($id === "new") {
|
||||
$model = TravelCompany::create($data);
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCompany::find($id);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
|
@ -79,12 +80,12 @@ class TravelCompanyController extends Controller
|
|||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_settings_travel_company_detail', [$model->id, $data['action']]));
|
||||
|
||||
}
|
||||
|
||||
public function delete($id, $del="travel_company"){
|
||||
public function delete($id, $del = "travel_company")
|
||||
{
|
||||
|
||||
if($del === 'travel_country') {
|
||||
if ($del === 'travel_country') {
|
||||
abort(404, 'Noch keine Funktion');
|
||||
$model = TravelCompany::findOrFail($id);
|
||||
$model->delete();
|
||||
|
|
@ -92,11 +93,11 @@ class TravelCompanyController extends Controller
|
|||
return redirect()->back();
|
||||
}
|
||||
|
||||
if($del === 'company_service'){
|
||||
if ($del === 'company_service') {
|
||||
$service = TravelCompanyService::findOrFail($id);
|
||||
$travel_company = $service->travel_company;
|
||||
//check as entry
|
||||
if($service->booking_company_services->count() > 0){
|
||||
if ($service->booking_company_services->count() > 0) {
|
||||
\Session()->flash('alert-error', 'Die Leistung kann nicht gelöscht werden, diese hat Einträge bei den Buchungen');
|
||||
return redirect(route('admin_settings_travel_company_detail', [$travel_company->id, 'services']));
|
||||
}
|
||||
|
|
@ -105,7 +106,4 @@ class TravelCompanyController extends Controller
|
|||
return redirect(route('admin_settings_travel_company_detail', [$travel_company->id, 'services']));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ class TravelCountryController extends Controller
|
|||
|
||||
public function detail($id, $step = false)
|
||||
{
|
||||
if($id === "new") {
|
||||
if ($id == "new") {
|
||||
$model = new TravelCountry();
|
||||
$id = 'new';
|
||||
$model->active_backend = 1;
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCountry::findOrFail($id);
|
||||
$id = $model->id;
|
||||
}
|
||||
|
|
@ -62,15 +62,15 @@ class TravelCountryController extends Controller
|
|||
{
|
||||
$data = Request::all();
|
||||
|
||||
if(isset($data['update-action'])){
|
||||
if($data['update-action'] === 'save-travel-county-service'){
|
||||
$data['active'] = true;//isset($data['active']) ? true : false;
|
||||
if (isset($data['update-action'])) {
|
||||
if ($data['update-action'] === 'save-travel-county-service') {
|
||||
$data['active'] = true; //isset($data['active']) ? true : false;
|
||||
$travel_country = TravelCountry::findOrFail($id);
|
||||
$data['travel_country_id'] = $travel_country->id;
|
||||
$data['crm_travel_country_id'] = $travel_country->crm_id;
|
||||
if($data['travel_county_service_id'] === 'new'){
|
||||
if ($data['travel_county_service_id'] === 'new') {
|
||||
$model = TravelCountryService::create($data);
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCountryService::find($data['travel_county_service_id']);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
|
@ -81,7 +81,7 @@ class TravelCountryController extends Controller
|
|||
}
|
||||
|
||||
$data['contact_emails'] = isset($data['contact_emails']) ? Util::_explodeLines($data['contact_emails']) : null;
|
||||
if(!isset($data['contact_lands'])){
|
||||
if (!isset($data['contact_lands'])) {
|
||||
$data['contact_lands'] = null;
|
||||
}
|
||||
$data['action'] = isset($data['action']) ? $data['action'] : false;
|
||||
|
|
@ -90,9 +90,9 @@ class TravelCountryController extends Controller
|
|||
$data['active_frontend'] = isset($data['active_frontend']) ? true : false;
|
||||
$data['active_backend'] = isset($data['active_backend']) ? true : false;
|
||||
*/
|
||||
if($id === "new"){
|
||||
if ($id === "new") {
|
||||
$model = TravelCountry::create($data);
|
||||
}else{
|
||||
} else {
|
||||
$model = TravelCountry::find($id);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
|
@ -106,11 +106,11 @@ class TravelCountryController extends Controller
|
|||
}
|
||||
//TODO for this time
|
||||
$tc = \App\Models\Sym\TravelCountry::find($model->crm_id);
|
||||
if(!$tc){
|
||||
if (!$tc) {
|
||||
$tc = \App\Models\Sym\TravelCountry::create($data);
|
||||
$model->crm_id = $tc->id;
|
||||
$model->save();
|
||||
}else {
|
||||
} else {
|
||||
$tc->fill($data);
|
||||
$tc->save();
|
||||
}
|
||||
|
|
@ -119,17 +119,18 @@ class TravelCountryController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function delete($id, $del="travel_country"){
|
||||
public function delete($id, $del = "travel_country")
|
||||
{
|
||||
|
||||
if($del === 'travel_country'){
|
||||
if ($del === 'travel_country') {
|
||||
$model = TravelCountry::findOrFail($id);
|
||||
if($model->travel_nationality_requirements){
|
||||
foreach($model->travel_nationality_requirements as $travel_nationality_requirement){
|
||||
if ($model->travel_nationality_requirements) {
|
||||
foreach ($model->travel_nationality_requirements as $travel_nationality_requirement) {
|
||||
$travel_nationality_requirement->delete();
|
||||
}
|
||||
}
|
||||
$tc = \App\Models\Sym\TravelCountry::find($model->crm_id);
|
||||
if($tc){
|
||||
if ($tc) {
|
||||
$tc->delete();
|
||||
}
|
||||
$model->delete();
|
||||
|
|
@ -137,7 +138,7 @@ class TravelCountryController extends Controller
|
|||
return redirect()->back();
|
||||
}
|
||||
|
||||
if($del === 'general_file'){
|
||||
if ($del === 'general_file') {
|
||||
$general_file = GeneralFile::findOrFail($id);
|
||||
$travel_country = $general_file->travel_country;
|
||||
$fileRepo = new GeneralFileRepository($general_file);
|
||||
|
|
@ -146,23 +147,18 @@ class TravelCountryController extends Controller
|
|||
$general_file->delete();
|
||||
\Session()->flash('alert-success', 'Datei gelöscht');
|
||||
return redirect(route('admin_settings_travel_country_detail', [$travel_country->id, 'data']));
|
||||
|
||||
}
|
||||
if($del === 'country_service'){
|
||||
if ($del === 'country_service') {
|
||||
$travel_country_service = TravelCountryService::findOrFail($id);
|
||||
$travel_country = $travel_country_service->travel_country;
|
||||
//check as entry
|
||||
if($travel_country_service->booking_country_services->count() > 0){
|
||||
if ($travel_country_service->booking_country_services->count() > 0) {
|
||||
\Session()->flash('alert-error', 'Die Leistung kann nicht gelöscht werden, diese hat Einträge bei den Buchungen');
|
||||
return redirect(route('admin_settings_travel_country_detail', [$travel_country->id, 'services']));
|
||||
}
|
||||
$travel_country_service->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect(route('admin_settings_travel_country_detail', [$travel_country->id, 'services']));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use App\Models\TravelGerneralNote;
|
||||
use Request;
|
||||
|
||||
class TravelGerneralNotesController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['superadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
{
|
||||
$data = [
|
||||
'gerneral_notes' => TravelGerneralNote::all(),
|
||||
];
|
||||
return view('settings.gerneral_notes.index', $data);
|
||||
}
|
||||
|
||||
public function update(){
|
||||
$data = Request::all();
|
||||
if($data['id'] === "new"){
|
||||
$model = TravelGerneralNote::create([
|
||||
'name' => $data['name'],
|
||||
'text' => $data['text']
|
||||
]);
|
||||
}else{
|
||||
$model = TravelGerneralNote::find($data['id']);
|
||||
$model->name = $data['name'];
|
||||
$model->text = $data['text'];
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_settings_gerneral_notes'));
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
$model = TravelGerneralNote::findOrFail($id);
|
||||
if($model->travel_programs->count() > 0){
|
||||
\Session()->flash('alert-error', 'Eintrag wird bei Reiseprogrammen verwendet');
|
||||
return redirect()->back();
|
||||
}
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
65
app/Http/Controllers/SyS/SysController.php
Normal file
65
app/Http/Controllers/SyS/SysController.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\SyS;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\SyS\Import;
|
||||
use App\Services\SyS\ReCalcu;
|
||||
use App\Services\SyS\ReImport;
|
||||
|
||||
class SysController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['sysadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('sys.index');
|
||||
}
|
||||
|
||||
public function tool($serve)
|
||||
{
|
||||
switch ($serve) {
|
||||
case 'reimport':
|
||||
return ReImport::show();
|
||||
break;
|
||||
case 'calcu':
|
||||
dd('check App\Services\SyS\ReCalcu');
|
||||
break;
|
||||
case 'tree':
|
||||
dd('check App\Services\SyS\Import');
|
||||
break;
|
||||
case 'clean_tree_code':
|
||||
dd('check App\Services\SyS\Import');
|
||||
break;
|
||||
case 'media_insert':
|
||||
dd('check App\Services\SyS\Import');
|
||||
break;
|
||||
case 'import':
|
||||
dd('check App\Services\SyS\Import');
|
||||
break;
|
||||
}
|
||||
abort(403, 'not found tool');
|
||||
}
|
||||
|
||||
|
||||
public function store($serve)
|
||||
{
|
||||
switch ($serve) {
|
||||
case 'reimport':
|
||||
return ReImport::store();
|
||||
break;
|
||||
|
||||
}
|
||||
abort(403, 'not found tool');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,731 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\SyS\Tools;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Booking;
|
||||
use App\Models\IQContentSite;
|
||||
use App\Models\IQContentSiteField;
|
||||
use App\Models\IQContentTree;
|
||||
use App\Models\IQContentTreeNode;
|
||||
use App\Models\TravelCountry;
|
||||
use App\Models\TravelGuide;
|
||||
use App\Models\TravelNationality;
|
||||
use App\Models\TravelBooking;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use IqContent\LaravelFilemanager\Controllers\FileController;
|
||||
use IqContent\LaravelFilemanager\Controllers\FolderController;
|
||||
use IqContent\LaravelFilemanager\Models\IQContentFile;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
class ContentLinkController extends Controller
|
||||
{
|
||||
|
||||
private $tree = [];
|
||||
/**
|
||||
* ContentSiteController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['sysadmin', '2fa']);
|
||||
}
|
||||
|
||||
public function filterHTML(){
|
||||
|
||||
}
|
||||
//content_links
|
||||
public function index()
|
||||
{
|
||||
/*$query = Booking::with('booking_draft_items')->select('booking.*')->where('new_drafts', true);
|
||||
|
||||
$query->whereHas('booking_draft_items', function ($q) {
|
||||
$q->where('comfort', true);
|
||||
});
|
||||
$bookings = $query->get();
|
||||
foreach ($bookings as $booking){
|
||||
$booking->comfort = true;
|
||||
$booking->save();
|
||||
}
|
||||
*/
|
||||
dd("nothing");
|
||||
$val = [];
|
||||
$text = "";
|
||||
/* $travelGuides = TravelGuide::all();
|
||||
foreach ($travelGuides as $travelGuide){
|
||||
if(strpos($travelGuide->full_text, "<h1><br></h1>") !== false){
|
||||
$val[$travelGuide->id] = "<h1><br></h1>";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($travelGuides as $travelGuide){
|
||||
if(strpos($travelGuide->full_text, "<h1") !== false){
|
||||
$val[$travelGuide->id] = "<h1";
|
||||
}
|
||||
}
|
||||
|
||||
$travelGuide = TravelGuide::find(203);
|
||||
$text = $travelGuide->full_text;
|
||||
|
||||
// $new_text = preg_replace('/<h1[^>]*>([\s\S]*?)<\/h1[^>]*>/', '', $TravelGuide->full_text);
|
||||
|
||||
*/
|
||||
$data = [
|
||||
'text' => $text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.links', $data);
|
||||
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
//tree
|
||||
public function tree()
|
||||
{
|
||||
$text = "";
|
||||
$val = [];
|
||||
$trees = IQContentTree::all();
|
||||
foreach ($trees as $tree){
|
||||
foreach ($tree->iq_content_tree_nodes as $tree_node){
|
||||
|
||||
$text .= $tree_node->id." -- ".$tree_node->title."\n";
|
||||
foreach ($tree_node->iq_content_sites as $site){
|
||||
if($site->travel_guide && $site->identifier === null){
|
||||
$identifier = $site->travel_guide->scope === 1 ? 'long' : 'short';
|
||||
//$site->identifier = $site->travel_guide->scope === 1 ? 'long' : 'short';
|
||||
$text .= "-- ".$site->id." -- ".$identifier."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'text' => $text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.trees', $data);
|
||||
}
|
||||
|
||||
public function treeStore()
|
||||
{
|
||||
$trees = IQContentTree::all();
|
||||
foreach ($trees as $tree){
|
||||
foreach ($tree->iq_content_tree_nodes as $tree_node){
|
||||
|
||||
foreach ($tree_node->iq_content_sites as $site){
|
||||
if($site->travel_guide){
|
||||
$site->identifier = $site->travel_guide->scope === 1 ? 'long' : 'short';
|
||||
$site->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
//clean_tree_code
|
||||
public function cleanTreeCode(){
|
||||
$val = [];
|
||||
$text = "";
|
||||
|
||||
$travelGuide = TravelGuide::find(166);
|
||||
$text = $travelGuide->full_text;
|
||||
|
||||
$data = [
|
||||
'new_text' => \App\Services\Util::cleanHTML($text),
|
||||
'full_text' => $travelGuide->full_text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.clean', $data);
|
||||
}
|
||||
|
||||
public function cleanTreeCodeStore(){
|
||||
$this->cleanTextTravelGuide();
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function cleanTextTravelGuide()
|
||||
{
|
||||
$TravelGuides = TravelGuide::all();
|
||||
foreach ($TravelGuides as $travelGuide){
|
||||
$new_text = \App\Services\Util::cleanHTML($travelGuide->full_text);
|
||||
if(strcmp($travelGuide->full_text, $new_text) != 0){
|
||||
$travelGuide->full_text = $new_text;
|
||||
$travelGuide->save();
|
||||
var_dump($travelGuide->id);
|
||||
echo "<br>";
|
||||
}
|
||||
}
|
||||
die("done");
|
||||
}
|
||||
|
||||
//media_insert
|
||||
public function mediaInsert(){
|
||||
$val = [];
|
||||
$text = "";
|
||||
$data = [
|
||||
'text' => $text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.insert', $data);
|
||||
}
|
||||
|
||||
public function mediaInsertStore(){
|
||||
$val = [];
|
||||
|
||||
$data = Request::all();
|
||||
$text = $data['text'];
|
||||
|
||||
if($data['action'] === 'insert'){
|
||||
$lines = explode(PHP_EOL, $text);
|
||||
$FolderC = new FolderController();
|
||||
$FileC = new FileController();
|
||||
|
||||
foreach ($lines as $line){
|
||||
$sep = explode(';', $line);
|
||||
if(isset($sep[0]) && isset($sep[1]) && isset($sep[2])){
|
||||
//youtube //main dir
|
||||
$working_dir = "/shares/youtube/".$sep[0];
|
||||
$folder_name = $sep[1];
|
||||
|
||||
$folder = $FolderC->makeFolder($working_dir, $folder_name);
|
||||
$working_dir = $working_dir."/".$folder_name;
|
||||
$file = $FileC->makeYoutube($working_dir, $sep[2]);
|
||||
$val[] = $file.' - '.$sep[2]." | ".$working_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($data['action'] === 'youtube_ids'){
|
||||
$TravelGuides = TravelGuide::all();
|
||||
foreach ($TravelGuides as $travelGuide){
|
||||
$this->findYoutubeLinks($val, $travelGuide);
|
||||
|
||||
/* <iframe allowfullscreen="" frameborder="0" height="500" src="https://www.youtube-nocookie.com/embed/9zs9RKOFCIs?rel=0" width="100%"></iframe> */
|
||||
}
|
||||
}
|
||||
if($data['action'] === 'replace_youtube_links') {
|
||||
$TravelGuides = TravelGuide::all();
|
||||
foreach ($TravelGuides as $travelGuide){
|
||||
$this->replaceYoutubeLinks($val, $travelGuide);
|
||||
|
||||
/* <iframe allowfullscreen="" frameborder="0" height="500" src="https://www.youtube-nocookie.com/embed/9zs9RKOFCIs?rel=0" width="100%"></iframe> */
|
||||
}
|
||||
}
|
||||
|
||||
if($data['action'] === 'replace_youtube_div') {
|
||||
$this->replaceYoutubeDiv($val, TravelGuide::find(335));
|
||||
$TravelGuides = TravelGuide::all();
|
||||
foreach ($TravelGuides as $travelGuide){
|
||||
$this->replaceYoutubeDiv($val, $travelGuide);
|
||||
|
||||
/* <iframe allowfullscreen="" frameborder="0" height="500" src="https://www.youtube-nocookie.com/embed/9zs9RKOFCIs?rel=0" width="100%"></iframe> */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$data = [
|
||||
'text' => $text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.insert', $data);
|
||||
|
||||
}
|
||||
|
||||
//import
|
||||
public function import()
|
||||
{
|
||||
$text = "";
|
||||
$val = [];
|
||||
|
||||
$data = [
|
||||
'text' => $text,
|
||||
'values' => $val,
|
||||
];
|
||||
return view('sys.tools.import', $data);
|
||||
}
|
||||
|
||||
public function importStore()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
$lines = explode(PHP_EOL, $data['text']);
|
||||
|
||||
if($data['action'] === 'import_TN'){
|
||||
foreach ($lines as $line){
|
||||
$ex = explode(';', $line);
|
||||
$t_n = TravelNationality::whereName(trim($ex[1]))->first();
|
||||
if($t_n){
|
||||
$t_n->nat = $ex[0];
|
||||
$t_n->save();
|
||||
}else{
|
||||
TravelNationality::create([
|
||||
'name' => trim($ex[1]),
|
||||
'nat' => $ex[0],
|
||||
'active' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($data['action'] === 'import_CT') {
|
||||
foreach ($lines as $line){
|
||||
$ex = explode(';', $line);
|
||||
$t_c = TravelCountry::whereName(trim($ex[1]))->first();
|
||||
if($t_c){
|
||||
dump($t_c->name);
|
||||
$t_c->destco = $ex[0];
|
||||
$t_c->save();
|
||||
|
||||
$tc = \App\Models\Sym\TravelCountry::find($t_c->crm_id);
|
||||
$tc->destco = $ex[0];
|
||||
$tc->save();
|
||||
}
|
||||
}
|
||||
dd("");
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
private function replaceYoutubeDiv(&$val, $travelGuide)
|
||||
{
|
||||
$ret = [];
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@$dom->loadHTML(mb_convert_encoding($travelGuide->full_text, 'HTML-ENTITIES', 'UTF-8'));
|
||||
$links = $dom->getElementsByTagName('iframe');
|
||||
foreach ($links as $link) {
|
||||
if($link->parentNode->parentNode->nodeName === 'div'){
|
||||
if($link->parentNode->parentNode->getAttribute('itemprop') === 'video'){
|
||||
if($link->parentNode->parentNode->getAttribute('class') === 'mediaA'){
|
||||
if($link->parentNode->parentNode->parentNode->getAttribute('itemprop') === 'video'){
|
||||
|
||||
$need = $link->parentNode->parentNode;
|
||||
$replace = $link->parentNode->parentNode->parentNode;
|
||||
$replace->parentNode->insertBefore($dom->importNode($need, true), $replace->nextSibling);
|
||||
$replace->parentNode->removeChild($replace);
|
||||
$html = $dom->saveHTML();
|
||||
|
||||
$travelGuide->full_text = $html;
|
||||
$travelGuide->save();
|
||||
$val[] = 'replace - '.$travelGuide->id;
|
||||
|
||||
}else{
|
||||
// dump("notfound itemprop over class mediaA".$travelGuide->id);
|
||||
$val[] = 'notfound - itemprop over class mediaA - '.$travelGuide->id;
|
||||
|
||||
//in
|
||||
|
||||
foreach ($link->parentNode->parentNode->childNodes as $node){
|
||||
if($node->nodeName === 'h2'){
|
||||
|
||||
if($node->firstChild->nodeName === '#text'){
|
||||
|
||||
$span = $dom->createElement('span', htmlspecialchars($node->nodeValue));
|
||||
|
||||
$span->setAttribute('itemprop', 'name');
|
||||
$h2 = $dom->createElement('h2');
|
||||
$h2->appendChild($span);
|
||||
|
||||
$node->parentNode->replaceChild($h2, $node);
|
||||
$html = $dom->saveHTML();
|
||||
|
||||
$travelGuide->full_text = $html;
|
||||
$travelGuide->save();
|
||||
$val[] = 'replace h2 - '.$travelGuide->id;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
//<span itemprop="name">
|
||||
|
||||
}
|
||||
//dump("found M div ".$travelGuide->id);
|
||||
}else{
|
||||
// dump("notfound class mediaA".$travelGuide->id);
|
||||
$val[] = 'notfound - class mediaA - '.$travelGuide->id;
|
||||
}
|
||||
}else{
|
||||
// dump("notfound div ".$travelGuide->id);
|
||||
$val[] = 'notfound - video - '.$travelGuide->id;
|
||||
|
||||
|
||||
}
|
||||
// dump($travelGuide->id);
|
||||
}else{
|
||||
//dump("notfound".$travelGuide->id);
|
||||
$val[] = 'notfound - div - '.$travelGuide->id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function replaceYoutubeLinks(&$val, $travelGuide)
|
||||
{
|
||||
$ret = [];
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@$dom->loadHTML(mb_convert_encoding($travelGuide->full_text, 'HTML-ENTITIES', 'UTF-8'));
|
||||
$links = $dom->getElementsByTagName('iframe');
|
||||
foreach ($links as $link) {
|
||||
|
||||
$src = $link->getAttribute('src');
|
||||
|
||||
|
||||
//
|
||||
$replace = false;
|
||||
$reLink = false;
|
||||
if($link->parentNode->nodeName === 'div'){
|
||||
if($link->parentNode->getAttribute('class') === 'video-container'){
|
||||
if($link->parentNode->parentNode->getAttribute('class') === 'mediaA' && $link->parentNode->parentNode->getAttribute('itemprop') !== 'video'){
|
||||
$replace = $link->parentNode->parentNode;
|
||||
$reLink = $link->parentNode;
|
||||
}else{
|
||||
$val[] = 'found - manual - '.$travelGuide->id;
|
||||
}
|
||||
}else{
|
||||
$val[] = 'first div - manual - '.$travelGuide->id;
|
||||
|
||||
}
|
||||
|
||||
}elseif ($link->parentNode->nodeName === 'p'){
|
||||
if($link->parentNode->parentNode->nodeName === 'div'){
|
||||
if($link->parentNode->parentNode->getAttribute('itemprop') === 'video'){
|
||||
//replace div
|
||||
$replace = $link->parentNode->parentNode;
|
||||
$reLink = $link->parentNode;
|
||||
}else{
|
||||
//replace p
|
||||
$replace = $link->parentNode;
|
||||
$reLink = $link;
|
||||
}
|
||||
}else{
|
||||
$replace = $link->parentNode;
|
||||
$reLink = $link;
|
||||
}
|
||||
|
||||
}else{
|
||||
$val[] = 'else div - manual - '.$travelGuide->id;
|
||||
}
|
||||
if($replace){
|
||||
|
||||
$id = preg_replace('/http.*?embed\//i', '', $src);
|
||||
$videoID = preg_replace('#[&\?].+$#', '', $id);
|
||||
$identifier = Str::slug(pre_slug($videoID), '-');
|
||||
$IQContentFile = IQContentFile::whereIdentifier($identifier)->first();
|
||||
if($IQContentFile) {
|
||||
|
||||
$video = new \DOMDocument('1.0', 'utf-8');
|
||||
$makeText = '<?xml encoding="utf-8" ?><div class="mediaA" itemprop="video" itemscope itemtype="http://schema.org/VideoObject">';
|
||||
$makeText .= '<h2><span itemprop="name">' . $IQContentFile->content['title'] . '</span></h2>';
|
||||
$makeText .= '<meta itemprop="duration" content="' . $IQContentFile->content['duration'] . '" />';
|
||||
$makeText .= '<meta itemprop="uploadDate" content="' . $IQContentFile->content['uploadDate'] . '"/>';
|
||||
$makeText .= '<meta itemprop="thumbnailURL" content="' . $IQContentFile->content['thumbnailURL'] . '" />';
|
||||
$makeText .= '<meta itemprop="embedURL" content="https://youtube.googleapis.com/v/' . $IQContentFile->content['id'] . '" />';
|
||||
$makeText .= '<div class="video-container"><iframe src="https://www.youtube.com/embed/' . $IQContentFile->content['id'] . '?rel=0&controls=0&showinfo=0" data-identifier="' . $IQContentFile->identifier . '" data-slug="' . $IQContentFile->slug . '" frameborder="0" allowfullscreen></iframe></div>';
|
||||
$makeText .= '<div class="mediaInfo"><p class="infotext" itemprop="description">'.$IQContentFile->content['description'].'</p></div></div>';
|
||||
$makeText = str_replace('&', '&', $makeText);
|
||||
$video->loadHTML($makeText);
|
||||
$replace->insertBefore($dom->importNode($video->documentElement, true), $reLink->nextSibling);
|
||||
$replace->removeChild($reLink);
|
||||
$html = $dom->saveHTML();
|
||||
|
||||
$travelGuide->full_text = $html;
|
||||
$travelGuide->save();
|
||||
|
||||
$val[] = 'replace - '.$travelGuide->id;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function findYoutubeLinks(&$val, $travelGuide)
|
||||
{
|
||||
$ret = [];
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@$dom->loadHTML(mb_convert_encoding($travelGuide->full_text, 'HTML-ENTITIES', 'UTF-8'));
|
||||
|
||||
$links = $dom->getElementsByTagName('iframe');
|
||||
foreach ($links as $link) {
|
||||
|
||||
$src = $link->getAttribute('src');
|
||||
|
||||
$id = preg_replace('/http.*?embed\//i', '', $src);
|
||||
$videoID = preg_replace('#[&\?].+$#', '', $id);
|
||||
|
||||
$identifier = Str::slug(pre_slug($videoID), '-');
|
||||
$count = IQContentFile::whereIdentifier($identifier)->count();
|
||||
|
||||
if($count === 0){
|
||||
$ret[$videoID] = $count;
|
||||
$val[] = "weitere;Travel-Guide;".$videoID.";";
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
//private?
|
||||
public function h1ToTitleTravelGuide()
|
||||
{
|
||||
$TravelGuides = TravelGuide::all();
|
||||
foreach ($TravelGuides as $travelGuide){
|
||||
if(strpos($travelGuide->full_text,'<html><body><h1>' )){
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@$dom->loadHTML(mb_convert_encoding($travelGuide->full_text, 'HTML-ENTITIES', 'UTF-8'));
|
||||
$elements = $dom->getElementsByTagName('h1');
|
||||
|
||||
foreach ($elements as $element) {
|
||||
if($element->nodeValue != ""){
|
||||
var_dump($travelGuide->id);
|
||||
var_dump($element->nodeValue);
|
||||
echo "<br>";
|
||||
var_dump($travelGuide->name);
|
||||
echo "<br>";
|
||||
echo "--";
|
||||
echo "<br>";
|
||||
|
||||
$new_text = preg_replace('/<h1[^>]*>([\s\S]*?)<\/h1[^>]*>/', '', $travelGuide->full_text);
|
||||
|
||||
$travelGuide->name = $element->nodeValue;
|
||||
$travelGuide->full_text = $new_text;
|
||||
$travelGuide->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
die("done");
|
||||
}
|
||||
|
||||
public function readNodeAndSaveToTree(){
|
||||
$input = Request::all();
|
||||
$ret = [];
|
||||
if(isset($input['text'])){
|
||||
$out = $this->ul_to_array($input['text']);
|
||||
$this->array_to_nodes($out);
|
||||
}
|
||||
die("done");
|
||||
$data = [
|
||||
'text' => $input['text'],
|
||||
'values' => $ret,
|
||||
];
|
||||
return view('iq.tools.links', $data);
|
||||
}
|
||||
|
||||
public function array_to_nodes($array, $lvl = 1, $parent_id = 1, $pos=100){
|
||||
|
||||
|
||||
if(is_array($array)){
|
||||
foreach ($array as $node){
|
||||
if(isset($node['slug'])){
|
||||
|
||||
$slug = substr($node['slug'], 0, 80);
|
||||
// $slug = substr($node['slug'], 0, strrpos($slug, " "));
|
||||
|
||||
$name = substr($node['name'], 0, 255);
|
||||
// $name = substr($node['name'], 0, strrpos($name, " "));
|
||||
|
||||
|
||||
$data = [
|
||||
'tree_id' => 1,
|
||||
'parent_id' => $parent_id,
|
||||
'lvl' => $lvl,
|
||||
'name' => $name,
|
||||
'identifier' => $slug,
|
||||
'active' => false,
|
||||
'pos' => $pos++,
|
||||
];
|
||||
$tree_node = IQContentTreeNode::create($data);
|
||||
|
||||
|
||||
$travel_guides = TravelGuide::whereSlug($node['slug'])->get();
|
||||
foreach ($travel_guides as $travel_guide){
|
||||
if(IQContentSite::whereTreeNodeId($tree_node->id)->whereTravelGuideId($travel_guide->id)->count() == 0) {
|
||||
IQContentSite::create(['tree_node_id' => $tree_node->id, 'travel_guide_id' => $travel_guide->id]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(isset($node['children']) && is_array($node['children'])){
|
||||
$this->array_to_nodes($node['children'], $lvl + 1, $tree_node->id, $pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function ul_to_array($ol){
|
||||
if(is_string($ol)){
|
||||
if(!$ol = simplexml_load_string($ol)) {
|
||||
trigger_error("Syntax error in UL/LI structure");
|
||||
return FALSE;
|
||||
}
|
||||
return $this->ul_to_array($ol);
|
||||
} else if(is_object($ol)){
|
||||
$output = array();
|
||||
foreach($ol->li as $li){
|
||||
|
||||
$tmp = false;
|
||||
if(isset($li->ol)){
|
||||
$tmp = $this->ul_to_array($li->ol);
|
||||
}
|
||||
|
||||
if($li->count()){
|
||||
|
||||
$str = (string) $li;
|
||||
|
||||
$a = new \SimpleXMLElement($li->children()->asXML());
|
||||
$str = (string) $a[0]." ".$str;
|
||||
$str = str_replace("\n", "", $str);
|
||||
$str = str_replace("\r", "", $str);
|
||||
$str = str_replace("\t", "", $str);
|
||||
$str = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $str);
|
||||
|
||||
if(trim($str) !== "" && $str !== null){
|
||||
$slug = (string) $a['href'];
|
||||
$link = explode("/", $slug);
|
||||
|
||||
$link1 = array_pop($link);
|
||||
$link1 = str_replace('.htm', '',$link1);
|
||||
$output[] = ['slug'=> $link1, 'name'=>$str, 'children'=>$tmp];
|
||||
}
|
||||
}else{
|
||||
$str = (string) $li;
|
||||
$str = str_replace("\n", "", $str);
|
||||
$str = str_replace("\r", "", $str);
|
||||
$str = str_replace("\t", "", $str);
|
||||
if(trim($str) !== "" && $str !== null){
|
||||
|
||||
$output[] = ['slug'=>'', 'name'=>$str, 'children'=>$tmp];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $output;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function rindex()
|
||||
{
|
||||
$data = [
|
||||
'text' => "",
|
||||
'values' => [],
|
||||
];
|
||||
return view('iq.content.tools.redirects', $data);
|
||||
}
|
||||
|
||||
public function rstore()
|
||||
{
|
||||
|
||||
$iqContentTree = IQContentTree::find(2);
|
||||
$this->makeTree($iqContentTree);
|
||||
$input = Request::all();
|
||||
$ret = [];
|
||||
|
||||
if(isset($input['text'])){
|
||||
|
||||
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@$dom->loadHTML(mb_convert_encoding($input['text'], 'HTML-ENTITIES', 'UTF-8'));
|
||||
|
||||
$tags = ['ol'];
|
||||
foreach ($tags as $tag){
|
||||
$domElements = [];
|
||||
$elements = $dom->getElementsByTagName($tag)->item(0);
|
||||
|
||||
foreach($elements as $node){
|
||||
foreach($node->childNodes as $child) {
|
||||
$ret[] = array($child->nodeName => $child->nodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* $tags = ['a']; foreach ($tags as $tag){
|
||||
$domElements = [];
|
||||
$elements = $dom->getElementsByTagName($tag);
|
||||
foreach ($elements as $element) {
|
||||
$domElements[] = $element;
|
||||
|
||||
}
|
||||
foreach ($domElements as $domElement) {
|
||||
$r = "-----";
|
||||
$href = $domElement->getAttribute('href');
|
||||
$link = explode("/", $href);
|
||||
|
||||
$link1 = array_pop($link);
|
||||
$link1 = str_replace('.html', '',$link1);
|
||||
$link1 = str_replace('-', '',$link1);
|
||||
if(isset($this->tree[$link1])){
|
||||
$r = $this->tree[$link1];
|
||||
}else{
|
||||
$link1 = array_pop($link);
|
||||
$link1 = str_replace('.html', '',$link1);
|
||||
$link1 = str_replace('-', '',$link1);
|
||||
if(isset($this->tree[$link1])){
|
||||
$r = $this->tree[$link1];
|
||||
}
|
||||
}
|
||||
|
||||
$ret[] = "Redirect 301 /".$href." ".$r;
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
$data = [
|
||||
'text' => $input['text'],
|
||||
'values' => $ret,
|
||||
];
|
||||
|
||||
return view('iq.content.tools.redirects', $data);
|
||||
|
||||
}
|
||||
|
||||
public function makeTree(IQContentTree $iq_content_tree, $lvl = 0, $parent_id = false, $url = "")
|
||||
{
|
||||
|
||||
if ($parent_id) {
|
||||
//where('active', true)
|
||||
$tree_nodes = IQContentTreeNode::where('tree_id', $iq_content_tree->id)->where('lvl', $lvl)->where('active', true)->where('parent_id', $parent_id)->orderBy('pos', 'ASC')->get();
|
||||
} else {
|
||||
|
||||
$url = "/" . $iq_content_tree->identifier . "/";
|
||||
$tree_nodes = IQContentTreeNode::where('tree_id', $iq_content_tree->id)->where('lvl', $lvl)->where('active', true)->orderBy('pos', 'ASC')->get();
|
||||
}
|
||||
|
||||
foreach ($tree_nodes as $node) {
|
||||
$children = IQContentTreeNode::where('tree_id', $iq_content_tree->id)->where('lvl', $lvl + 1)->where('active', true)->where('parent_id', $node->id)->count();
|
||||
$this->tree[str_replace('-', '', $node->identifier)] = url($url . $node->identifier);
|
||||
|
||||
if ($children) {
|
||||
$this->makeTree($iq_content_tree, $lvl + 1, $node->id, $url . $node->identifier . "/");
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
154
app/Http/Controllers/TravelContentController.php
Normal file
154
app/Http/Controllers/TravelContentController.php
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Request;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Page;
|
||||
|
||||
class TravelContentController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['admin', '2fa']);
|
||||
}
|
||||
|
||||
public function index($step = false)
|
||||
{
|
||||
$data = [
|
||||
'travelProgramOverviews' => Page::whereTemplate('travelProgramOverview')->get(),
|
||||
'step' => $step
|
||||
];
|
||||
return view('travel.content.index', $data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
if($id === "new") {
|
||||
$id = 'new';
|
||||
|
||||
}else{
|
||||
$page = Page::findOrFail($id);
|
||||
$id = $page->id;
|
||||
}
|
||||
$data = [
|
||||
'model' => $page,
|
||||
'id' => $id,
|
||||
];
|
||||
return view('travel.content.detail', $data);
|
||||
}
|
||||
|
||||
public function store($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if($id === "new") {
|
||||
//$draft = new Draft();
|
||||
}else{
|
||||
$page = Page::findOrFail($id);
|
||||
}
|
||||
|
||||
if(Page::whereSlug($data['slug'])->where('id', '!=', $page->id)->count() > 0){
|
||||
$data['slug'] = "";
|
||||
}
|
||||
|
||||
$page->title = $data['title'];
|
||||
$page->title_short = $data['title_short'];
|
||||
$page->pagetitle = $data['pagetitle'];
|
||||
$page->slug = $data['slug'];
|
||||
$page->description = $data['description'];
|
||||
$page->content_new = $data['content_new'];
|
||||
$page->status = $data['status'];
|
||||
$page->show_in_navi = $data['show_in_navi'];
|
||||
$page->save();
|
||||
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('travel_content_detail', [$page->id]));
|
||||
}
|
||||
|
||||
public function subDetail($id)
|
||||
{
|
||||
if($id === "new") {
|
||||
$id = 'new';
|
||||
|
||||
}else{
|
||||
$page = Page::findOrFail($id);
|
||||
$id = $page->id;
|
||||
}
|
||||
$data = [
|
||||
'model' => $page,
|
||||
'id' => $id,
|
||||
];
|
||||
return view('travel.content.sub_detail', $data);
|
||||
}
|
||||
|
||||
public function subStore($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if($id === "new") {
|
||||
//$draft = new Draft();
|
||||
}else{
|
||||
$page = Page::findOrFail($id);
|
||||
}
|
||||
|
||||
if(Page::whereSlug($data['slug'])->where('id', '!=', $page->id)->count() > 0){
|
||||
$data['slug'] = "";
|
||||
}
|
||||
$page->title = $data['title'];
|
||||
$page->pagetitle = $data['pagetitle'];
|
||||
$page->slug = $data['slug'];
|
||||
$page->description = $data['description'];
|
||||
$page->status = $data['status'];
|
||||
$page->show_in_navi = $data['show_in_navi'];
|
||||
$page->order = $data['order'];
|
||||
|
||||
$page->travel_program = $data['travel_program'] > 0 ? $data['travel_program'] : null;
|
||||
|
||||
$page->save();
|
||||
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('travel_content_sub_detail', [$page->id]));
|
||||
}
|
||||
|
||||
|
||||
public function load(){
|
||||
$data = Request::all();
|
||||
$ret = "";
|
||||
if(Request::ajax()) {
|
||||
if($data['action'] === "modal-copy-page") {
|
||||
if($data['id'] > 0){
|
||||
$value = Page::findOrFail($data['id']);
|
||||
$ret = view('travel.content.modal_copy', compact('value'))->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
return response()->json(['response' => $data, 'html'=>$ret]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function update(){
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if($data['action'] === 'page-copy'){
|
||||
if($data['page_copy_id'] > 0){
|
||||
$model = Page::findOrFail($data['page_copy_id']);
|
||||
$newModel = $model->replicate();
|
||||
$newModel->date = null;
|
||||
//slug unique
|
||||
// $newModel->slug
|
||||
$newModel->created_at = now();
|
||||
$newModel->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('travel_content_detail', [$data['id']]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -48,11 +48,29 @@ class TravelProgramController extends Controller
|
|||
|
||||
public function store($id)
|
||||
{
|
||||
//TODO new must have an extra funtction!
|
||||
$data = Request::all();
|
||||
$program = $this->travelProgramRepo->update($data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('travel_program_detail', [$program->id]));
|
||||
if(!isset($data['action'])){
|
||||
abort(403, 'keine Action');
|
||||
}
|
||||
//save
|
||||
$program = $this->travelProgramRepo->updateGeneral($id, $data);
|
||||
$program = $this->travelProgramRepo->updateDetail($id, $data);
|
||||
$program = $this->travelProgramRepo->updatePage($id, $data);
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
||||
|
||||
if($data['action'] === 'saveGeneral'){
|
||||
return redirect(route('travel_program_detail', [$program->id])."#collapseBookingNotice");
|
||||
}
|
||||
if($data['action'] === 'saveDetails'){
|
||||
return redirect(route('travel_program_detail', [$program->id])."#collapseTravelProgramDetails");
|
||||
}
|
||||
if($data['action'] === 'savePage'){
|
||||
return redirect(route('travel_program_detail', [$program->id])."#collapseTravelProgramPage");
|
||||
}
|
||||
return redirect(route('travel_program_detail', [$id]));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -68,6 +86,7 @@ class TravelProgramController extends Controller
|
|||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('travel_program_detail', [$data['program_id']]));
|
||||
}
|
||||
|
||||
public function classDelete($id){
|
||||
$travel_class = TravelClass::findOrFail($id);
|
||||
$pId = $travel_class->program_id;
|
||||
|
|
|
|||
|
|
@ -3,21 +3,23 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
use App\Mail\MailSendFeWoInvoice;
|
||||
use App\Mail\MailSendFeWoService;
|
||||
use App\Mail\MailSendFeWoInfo;
|
||||
use Request;
|
||||
use App\Services\Util;
|
||||
use App\Models\CMSContent;
|
||||
use App\Models\FewoLodging;
|
||||
use App\Mail\MailSendFeWoInfo;
|
||||
use App\Models\FewoReservation;
|
||||
use App\Models\TravelBookingFewoChannel;
|
||||
use App\Models\TravelUserBookingFewo;
|
||||
use App\Models\TravelUserBookingFewoNotice;
|
||||
use App\Models\TravelUserBookingFile;
|
||||
use App\Repositories\BookingFewoFileRepository;
|
||||
use App\Repositories\TravelUserBookingFewoRepository;
|
||||
use App\Services\Util;
|
||||
use App\Models\CustomerFewoFile;
|
||||
use App\Mail\MailSendFeWoInvoice;
|
||||
use App\Mail\MailSendFeWoService;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Request;
|
||||
use App\Models\TravelUserBookingFewo;
|
||||
use App\Models\TravelUserBookingFile;
|
||||
use App\Models\TravelBookingFewoChannel;
|
||||
use App\Models\TravelUserBookingFewoNotice;
|
||||
use App\Repositories\BookingFewoFileRepository;
|
||||
use App\Repositories\CustomerFewoFileRepository;
|
||||
use App\Repositories\TravelUserBookingFewoRepository;
|
||||
|
||||
class TravelUserBookingFewoController extends Controller
|
||||
{
|
||||
|
|
@ -82,6 +84,10 @@ class TravelUserBookingFewoController extends Controller
|
|||
public function store($id)
|
||||
{
|
||||
$data = Request::all();
|
||||
if(!isset($data['action'])){
|
||||
abort(403, 'keine Action');
|
||||
}
|
||||
|
||||
if($data['action'] === 'save_notice'){
|
||||
$travel_user_booking_fewo = $this->userBookingFewoRepo->updateNotice($id, $data);
|
||||
\Session()->flash('alert-save', '1');
|
||||
|
|
@ -93,7 +99,6 @@ class TravelUserBookingFewoController extends Controller
|
|||
return redirect(route('travel_user_booking_fewo_detail', [$travel_user_booking_fewo->id])."#collapseBookingNotice");
|
||||
}
|
||||
|
||||
|
||||
if($data['action'] === 'saveAll'){
|
||||
return $this->userBookingFewoRepo->update($id, $data);
|
||||
}
|
||||
|
|
@ -147,8 +152,12 @@ class TravelUserBookingFewoController extends Controller
|
|||
if($data['action'] === 'sendInfosMailtoUser') {
|
||||
$travel_user_booking_fewo = TravelUserBookingFewo::findOrFail($id);
|
||||
if($travel_user_booking_fewo->travel_user_id && $travel_user_booking_fewo->travel_user->email){
|
||||
$mail_files = [];
|
||||
if(isset($data['info_mail_files'])){
|
||||
$mail_files = $this->setMailInfoFiles($data['info_mail_files'], $travel_user_booking_fewo);
|
||||
}
|
||||
$mail_bbc = config('mail.mail_bbc');
|
||||
Mail::to($travel_user_booking_fewo->travel_user->email)->bcc($mail_bbc)->send(new MailSendFeWoInfo($travel_user_booking_fewo));
|
||||
Mail::to($travel_user_booking_fewo->travel_user->email)->bcc($mail_bbc)->send(new MailSendFeWoInfo($travel_user_booking_fewo, $mail_files));
|
||||
$send_info_mail = $travel_user_booking_fewo->send_info_mail;
|
||||
$send_info_mail[] = [date('H:i d.m.Y') => $travel_user_booking_fewo->travel_user->email];
|
||||
$travel_user_booking_fewo->send_info_mail = $send_info_mail;
|
||||
|
|
@ -195,6 +204,51 @@ class TravelUserBookingFewoController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
private function setMailInfoFiles($info_mail_files, $travel_user_booking_fewo)
|
||||
{
|
||||
$files = [];
|
||||
$ret = [];
|
||||
//read files
|
||||
foreach($info_mail_files as $mail_file){
|
||||
if($mail_file === 'fewo_instruction_pdf'){
|
||||
$files[] = [
|
||||
'target' => route('customer_file_show', ['fewo_instruction_pdf', $travel_user_booking_fewo->fewo_lodging->id, 'stream']),
|
||||
'name' => \App\Services\BookingFewo::getFeWoInstructionPDFName($travel_user_booking_fewo->fewo_lodging)
|
||||
];
|
||||
}else{
|
||||
if($file = \App\Models\CMSContent::getModelBySlug($mail_file)){
|
||||
$files[] = [
|
||||
'target' => $file->getURL(),
|
||||
'name' => $file->name
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
//store files
|
||||
foreach($files as $file){
|
||||
$arrContextOptions=array(
|
||||
"ssl"=>array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
),
|
||||
);
|
||||
$contents = file_get_contents($file['target'], false, stream_context_create($arrContextOptions));
|
||||
$mine = Util::getMimeFromHeader($http_response_header);
|
||||
$extension = Util::getExtensionFromMime($mine);
|
||||
$fileRepo = new CustomerFewoFileRepository(new CustomerFewoFile());
|
||||
$fileRepo->_set('disk', 'travel_user');
|
||||
$fileRepo->_set('dir', '/attachment/'.date('Y/m').'/');
|
||||
$fileRepo->_set('travel_user_id', $travel_user_booking_fewo->travel_user_id);
|
||||
$fileRepo->_set('customer_fewo_mail_id', NULL);
|
||||
$fileRepo->_set('identifier', 'fewo_info_mail_user');
|
||||
$fileRepo->_set('originalName', $file['name']);
|
||||
$fileRepo->_set('mine', $mine);
|
||||
$fileRepo->_set('extension', $extension);
|
||||
$ret[] = $fileRepo->storeReturnFile($contents);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public function getAjaxRequests(){
|
||||
|
||||
|
|
@ -301,6 +355,7 @@ class TravelUserBookingFewoController extends Controller
|
|||
})
|
||||
->addColumn('is_calendar', function (TravelUserBookingFewo $travel_user_booking_fewo) {
|
||||
$back = "<div class='no-break'>";
|
||||
$back .= get_active_badge($travel_user_booking_fewo->is_calendar_traum_fewo, "Traum Direkt")." ";
|
||||
$back .= get_active_badge($travel_user_booking_fewo->is_calendar_fewo_direct, "FEWO Direkt")." ";
|
||||
$back .= get_active_badge($travel_user_booking_fewo->is_calendar_hrs, "HRS")." ";
|
||||
$back .= get_active_badge($travel_user_booking_fewo->is_calendar_stern_tours, "STERN TOURS");
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class Kernel extends HttpKernel
|
|||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
|
|
@ -39,19 +39,17 @@ class Kernel extends HttpKernel
|
|||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
'bindings',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'throttle:api',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
* The application's route middleware aliases.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'2fa' => \App\Http\Middleware\MiddleGoogle2FA::class,
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Auth;
|
||||
use Closure;
|
||||
use App\Services\AuthGoogle2FA;
|
||||
|
||||
class AuthGoogle2FA
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$AuthGoogle2FA = app(AuthGoogle2FA::class)->init($request);
|
||||
|
||||
if(!Auth::user()->isGoogle2Fa()){
|
||||
return $AuthGoogle2FA->makeActiveOneTimePasswordResponse();
|
||||
}
|
||||
if ($AuthGoogle2FA->isAuthenticated()) {
|
||||
return $next($request);
|
||||
}
|
||||
return $AuthGoogle2FA->makeRequestOneTimePasswordResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Auth;
|
||||
use Closure;
|
||||
use App\Services\AuthGoogle2FA;
|
||||
|
||||
class Google2FA
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$AuthGoogle2FA = app(AuthGoogle2FA::class)->init($request);
|
||||
|
||||
if(!Auth::user()->isGoogle2Fa()){
|
||||
return $AuthGoogle2FA->makeActiveOneTimePasswordResponse();
|
||||
}
|
||||
if ($AuthGoogle2FA->isAuthenticated()) {
|
||||
return $next($request);
|
||||
}
|
||||
return $AuthGoogle2FA->makeRequestOneTimePasswordResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use PragmaRX\Google2FALaravel\Support\Authenticator;
|
||||
use Auth;
|
||||
|
||||
class Google2FA
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$authenticator = app(Authenticator::class)->boot($request);
|
||||
dd(Auth::user()->isGoogle2Fa());
|
||||
if(Auth::user()->isGoogle2Fa()){
|
||||
|
||||
}
|
||||
if ($authenticator->isAuthenticated()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return $authenticator->makeRequestOneTimePasswordResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11,7 +11,6 @@ class MiddleGoogle2FA
|
|||
public function handle($request, Closure $next)
|
||||
{
|
||||
$AuthGoogle2FA = app(AuthGoogle2FA::class)->init($request);
|
||||
|
||||
if(!Auth::user()->isGoogle2Fa()){
|
||||
\App\Services\MyGoogle2FA::logout();
|
||||
return $AuthGoogle2FA->makeActiveOneTimePasswordResponse();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
|
|
@ -19,5 +19,11 @@ class TrustProxies extends Middleware
|
|||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_PREFIX |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
namespace App\Libraries;
|
||||
|
||||
use App\Libraries\CouponPDF;
|
||||
use App\Models\Coupon;
|
||||
use App\Services\Util;
|
||||
use App\Libraries\CouponPDF;
|
||||
|
||||
class CreateCouponPDF {
|
||||
|
||||
63
app/Libraries/CreatePDF.php
Normal file
63
app/Libraries/CreatePDF.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
namespace App\Libraries;
|
||||
|
||||
use App\Libraries\CouponPDF;
|
||||
use App\Models\Coupon;
|
||||
use Storage;
|
||||
|
||||
class CreatePDF{
|
||||
|
||||
protected $view;
|
||||
protected $pdf;
|
||||
protected $prepath;
|
||||
protected $disk;
|
||||
|
||||
|
||||
public function __construct($view, $disk = 'public')
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->disk = $disk;
|
||||
$this->prepath = Storage::disk($disk)->path('');
|
||||
|
||||
}
|
||||
|
||||
public function create($data, $name='test.pdf', $output='stream', $path = false){
|
||||
|
||||
header('Content-type: text/html; charset=UTF-8') ;//chrome
|
||||
//dd($data);
|
||||
|
||||
$pdf = app('dompdf.wrapper');
|
||||
$pdf->getDomPDF()->set_option("enable_php", true);
|
||||
$pdf->loadView($this->view, $data);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
|
||||
if($output === 'stream'){
|
||||
//file???
|
||||
return $pdf->stream($name);
|
||||
}
|
||||
if($output === 'download'){
|
||||
//download
|
||||
return $pdf->download($name);
|
||||
}
|
||||
|
||||
if($output === 'save'){
|
||||
if($path){
|
||||
$pdf->save($path.$name);
|
||||
return $path.$name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function merger($dir, $filename, $template){
|
||||
$pdfMerger = new MyPDFMerger();
|
||||
$pdfMerger->addPDF($this->prepath.$dir.$filename);
|
||||
$file = $pdfMerger->myMerge('string', $filename, $template);
|
||||
Storage::disk($this->disk)->put($dir.$filename, $file);
|
||||
}
|
||||
|
||||
public function setPrePath($path){
|
||||
$this->prepath = $path;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
namespace App\Libraries;
|
||||
|
||||
use App\Libraries\CouponPDF;
|
||||
use App\Models\Coupon;
|
||||
use Storage;
|
||||
|
||||
class CreatePDF{
|
||||
class CreatePDFCoupon{
|
||||
|
||||
protected $view;
|
||||
protected $pdf;
|
||||
|
|
@ -24,7 +24,9 @@ class CreatePDF{
|
|||
$pdf = app('dompdf.wrapper');
|
||||
$pdf->getDomPDF()->set_option("enable_php", true);
|
||||
$pdf->loadView($this->view, $data);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
$customPaper = array(0, 0, 595.28, 283,47);
|
||||
$pdf->setPaper($customPaper, 'portrait');
|
||||
// $pdf->setPaper('A4', 'portrait');
|
||||
|
||||
if($output === 'stream'){
|
||||
return $pdf->stream($name);
|
||||
190
app/Libraries/MyPDFMerger.php
Normal file
190
app/Libraries/MyPDFMerger.php
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
|
||||
namespace App\Libraries;
|
||||
|
||||
//use FPDI in myMerge v2
|
||||
//use FPDF;
|
||||
//use FPDI;
|
||||
|
||||
class MyPDFMerger
|
||||
{
|
||||
private $_files; //['form.pdf'] ["1,2,4, 5-19"]
|
||||
private $_fpdi;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
/* if(!class_exists("FPDF")) {
|
||||
require_once(__DIR__.'/fpdf/fpdf.php');
|
||||
}
|
||||
if(!class_exists("FPDI")) {
|
||||
require_once(__DIR__.'/fpdi/fpdi.php');
|
||||
}*/
|
||||
}
|
||||
|
||||
public function addPDF($filepath, $pages = 'all')
|
||||
{
|
||||
if (file_exists($filepath)) {
|
||||
if (strtolower($pages) != 'all') {
|
||||
$pages = $this->_rewritepages($pages);
|
||||
}
|
||||
|
||||
$this->_files[] = array($filepath, $pages);
|
||||
} else {
|
||||
throw new \exception("Could not locate PDF on '$filepath'");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function myMerge($outputmode = 'browser', $outputpath = 'newfile.pdf', $theme = false)
|
||||
{
|
||||
//$theme = false;
|
||||
if (!isset($this->_files) || !is_array($this->_files)): throw new \exception("No PDFs to merge.");
|
||||
endif;
|
||||
|
||||
$fpdi = new \setasign\Fpdi\Fpdi();
|
||||
$first = 1;
|
||||
|
||||
|
||||
//merger operations
|
||||
foreach ($this->_files as $file) {
|
||||
$filename = $file[0];
|
||||
$filepages = $file[1];
|
||||
|
||||
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
|
||||
//add the pages
|
||||
if ($filepages == 'all') {
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
$template = $fpdi->importPage($i);
|
||||
$size = $fpdi->getTemplateSize($template);
|
||||
$orientation = ($size['height'] > $size['width']) ? 'P' : 'L';
|
||||
$fpdi->AddPage($orientation, array($size['width'], $size['height']));
|
||||
if ($theme) {
|
||||
$fpdi->setSourceFile(__DIR__ . '/../../public/pdf/' . $theme . '-' . $first . '.pdf');
|
||||
if ($first == 1) {
|
||||
$first = 2;
|
||||
}
|
||||
$backId = $fpdi->importPage(1);
|
||||
$fpdi->useTemplate($backId);
|
||||
}
|
||||
$fpdi->useTemplate($template);
|
||||
}
|
||||
} else {
|
||||
foreach ($filepages as $page) {
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
if (!$template = $fpdi->importPage($page)): throw new \exception("Could not load page '$page' in PDF '$filename'. Check that the page exists.");
|
||||
endif;
|
||||
$size = $fpdi->getTemplateSize($template);
|
||||
$orientation = ($size['h'] > $size['w']) ? 'P' : 'L';
|
||||
|
||||
$fpdi->AddPage($orientation, array($size['w'], $size['h']));
|
||||
if ($theme) {
|
||||
$fpdi->setSourceFile(__DIR__ . '/../../public/pdf/' . $theme . '-' . $first . '.pdf');
|
||||
if ($first == 1) {
|
||||
$first = 2;
|
||||
}
|
||||
$backId = $fpdi->importPage(1);
|
||||
$fpdi->useTemplate($backId);
|
||||
}
|
||||
|
||||
$fpdi->useTemplate($template);
|
||||
}
|
||||
}
|
||||
//after first file (invoice) on bpaper
|
||||
$slug = false;
|
||||
}
|
||||
|
||||
//output operations
|
||||
$mode = $this->_switchmode($outputmode);
|
||||
|
||||
if ($mode == 'S') {
|
||||
return $fpdi->Output($outputpath, 'S');
|
||||
} else {
|
||||
if ($fpdi->Output($outputpath, $mode) == '') {
|
||||
return true;
|
||||
} else {
|
||||
throw new \exception("Error outputting PDF to '$outputmode'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FPDI uses single characters for specifying the output location. Change our more descriptive string into proper format.
|
||||
* @param $mode
|
||||
* @return Character
|
||||
*/
|
||||
private function _switchmode($mode)
|
||||
{
|
||||
switch (strtolower($mode)) {
|
||||
case 'download':
|
||||
return 'D';
|
||||
break;
|
||||
case 'browser':
|
||||
return 'I';
|
||||
break;
|
||||
case 'file':
|
||||
return 'F';
|
||||
break;
|
||||
case 'string':
|
||||
return 'S';
|
||||
break;
|
||||
default:
|
||||
return 'I';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes our provided pages in the form of 1,3,4,16-50 and creates an array of all pages
|
||||
* @param $pages
|
||||
* @return array
|
||||
* @throws exception
|
||||
*/
|
||||
private function _rewritepages($pages)
|
||||
{
|
||||
$pages = str_replace(' ', '', $pages);
|
||||
$part = explode(',', $pages);
|
||||
|
||||
//parse hyphens
|
||||
foreach ($part as $i) {
|
||||
$ind = explode('-', $i);
|
||||
|
||||
if (count($ind) == 2) {
|
||||
$x = $ind[0]; //start page
|
||||
$y = $ind[1]; //end page
|
||||
|
||||
if ($x > $y): throw new \exception("Starting page, '$x' is greater than ending page '$y'.");
|
||||
return false;
|
||||
endif;
|
||||
|
||||
//add middle pages
|
||||
while ($x <= $y): $newpages[] = (int)$x;
|
||||
$x++;
|
||||
endwhile;
|
||||
} else {
|
||||
$newpages[] = (int)$ind[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $newpages;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
$pdf = new PDFMerger;
|
||||
|
||||
$pdf->addPDF('samplepdfs/one.pdf', '1, 3, 4')
|
||||
->addPDF('samplepdfs/two.pdf', '1-2')
|
||||
->addPDF('samplepdfs/three.pdf', 'all')
|
||||
->merge('file', 'samplepdfs/TEST2.pdf');
|
||||
|
||||
//REPLACE 'file' WITH 'browser', 'download', 'string', or 'file' for output options
|
||||
//You do not need to give a file path for browser, string, or download - just the name.
|
||||
*/
|
||||
|
|
@ -14,12 +14,15 @@ class MailSendFeWoInfo extends Mailable
|
|||
|
||||
protected $travel_user_booking_fewo;
|
||||
public $subject;
|
||||
public $files;
|
||||
|
||||
|
||||
public function __construct(TravelUserBookingFewo $travel_user_booking_fewo)
|
||||
public function __construct(TravelUserBookingFewo $travel_user_booking_fewo, $files = [])
|
||||
{
|
||||
$this->travel_user_booking_fewo = $travel_user_booking_fewo;
|
||||
$this->subject = __('STERN TOURS Anreiseinfo FEWO');
|
||||
$this->files = $files;
|
||||
|
||||
}
|
||||
|
||||
public function build()
|
||||
|
|
@ -40,18 +43,33 @@ class MailSendFeWoInfo extends Mailable
|
|||
'mine' => 'application/pdf',
|
||||
);
|
||||
|
||||
return $this->view('emails.info')
|
||||
$message = $this->view('emails.info')
|
||||
->with([
|
||||
'salutation' => $salutation,
|
||||
'copy1line' => $this->travel_user_booking_fewo->info_mail_text,
|
||||
'copy2line' => "",
|
||||
'greetings' => __('Best regards'),
|
||||
'model' => $this->travel_user_booking_fewo,
|
||||
])
|
||||
->attach($file1['path'], [
|
||||
'as' => $file1['name'],
|
||||
'mime' => $file1['mine'],
|
||||
])
|
||||
;
|
||||
]);
|
||||
$message->attach($file1['path'], [
|
||||
'as' => $file1['name'],
|
||||
'mime' => $file1['mine'],
|
||||
]);
|
||||
|
||||
foreach ($this->files as $file) {
|
||||
$message->attach($file->getPath(),[
|
||||
'as' => $file->original_name,
|
||||
'mime' => $file->mine,
|
||||
]); // attach each file
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//path = \Storage::disk('lead')->path($this->dir.$this->filename);
|
||||
//name =
|
||||
//'mine' => 'application/pdf',
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||
* @method static bool|null restore()
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Account withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Account withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Account newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Account newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Account query()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Account extends Model
|
||||
{
|
||||
|
|
@ -32,7 +32,10 @@ class Account extends Model
|
|||
|
||||
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $casts = [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
|
||||
public function user()
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Airline whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Airline whereNameFull($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Airline whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string|null $flight_info
|
||||
* @property string|null $check_in
|
||||
* @property string|null $baggage
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airline whereBaggage($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airline whereCheckIn($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airline whereFlightInfo($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Airline extends Model
|
||||
{
|
||||
|
|
|
|||
54
app/Models/Airport.php
Normal file
54
app/Models/Airport.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Created by Reliese Model.
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class Airport
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $code
|
||||
* @property string $name
|
||||
* @property string $city
|
||||
* @property string $country
|
||||
* @property bool $active
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
* @package App\Models
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereActive($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereCity($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereCode($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereCountry($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Airport whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Airport extends Model
|
||||
{
|
||||
protected $connection = 'mysql';
|
||||
|
||||
protected $table = 'airports';
|
||||
|
||||
protected $casts = [
|
||||
'active' => 'bool'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'city',
|
||||
'country',
|
||||
'active'
|
||||
];
|
||||
}
|
||||
|
|
@ -32,12 +32,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\AnswerQuestion whereQuestion($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\AnswerQuestion whereQuestionText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\AnswerQuestion whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\IQContentFaq[] $iq_content_faq
|
||||
* @property-read int|null $iq_content_faq_count
|
||||
* @property int|null $i_q_content_category_id
|
||||
* @property-read \App\Models\IQContentCategory|null $iq_content_category
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\AnswerQuestion whereIQContentCategoryId($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class AnswerQuestion extends Model
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Arrangement whereTypeId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Arrangement whereTypeS($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Arrangement whereViewPosition($value)
|
||||
* @property-read \App\Models\ArrangementType|null $arrangement_type
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Arrangement extends Model
|
||||
|
|
@ -54,14 +55,12 @@ class Arrangement extends Model
|
|||
'view_position' => 'int',
|
||||
'booking_id' => 'int',
|
||||
'type_id' => 'int',
|
||||
'in_pdf' => 'bool'
|
||||
'in_pdf' => 'bool',
|
||||
'state' => 'datetime',
|
||||
'begin' => 'datetime',
|
||||
'end' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'state',
|
||||
'begin',
|
||||
'end'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'template_id',
|
||||
|
|
@ -85,4 +84,52 @@ class Arrangement extends Model
|
|||
{
|
||||
return $this->belongsTo(ArrangementTemplate::class, 'template_id');
|
||||
}
|
||||
|
||||
public function arrangement_type()
|
||||
{
|
||||
return $this->belongsTo(ArrangementType::class, 'type_id');
|
||||
}
|
||||
|
||||
public function getDataAsMap()
|
||||
{
|
||||
$rawData = $this->attributes['data_s'];
|
||||
$data = json_decode('{'. $rawData .'}', true);
|
||||
if (is_array($data))
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
$entries = preg_split("/[\r\n;]+\s*/", $rawData, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$ret = array();
|
||||
foreach ($entries as $entry)
|
||||
{
|
||||
$map = preg_split('/:\s*/', $entry, -1, PREG_SPLIT_NO_EMPTY);
|
||||
if (count($map) == 2)
|
||||
{
|
||||
$ret[$map[0]] = $map[1];
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getDataS()
|
||||
{
|
||||
$rawData = $this->attributes['data_s'];
|
||||
$data = json_decode('{'. $rawData .'}', true);
|
||||
if (is_array($data))
|
||||
{
|
||||
$str = '';
|
||||
$i = 0;
|
||||
foreach ($data as $k => $v)
|
||||
{
|
||||
if (++$i > 0)
|
||||
{
|
||||
$str .= '';
|
||||
}
|
||||
$str .= $k .' '. $v;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
return $rawData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -48,12 +48,10 @@ class BookingConfirmation extends Model
|
|||
'total' => 'float',
|
||||
'deposit' => 'float',
|
||||
'final_payment' => 'float',
|
||||
'deposit_payment_date' => 'datetime',
|
||||
'final_payment_date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'deposit_payment_date',
|
||||
'final_payment_date'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingCountryService whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingCountryService whereTravelCountryServiceId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingCountryService whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property int|null $status
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingCountryService whereStatus($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class BookingCountryService extends Model
|
||||
{
|
||||
|
|
|
|||
157
app/Models/BookingDocument.php
Normal file
157
app/Models/BookingDocument.php
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Created by Reliese Model.
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class BookingDocument
|
||||
*
|
||||
* @property int $id
|
||||
* @property int|null $booking_id
|
||||
* @property int|null $customer_id
|
||||
* @property int|null $lead_id
|
||||
* @property string $identifier
|
||||
* @property string $filename
|
||||
* @property string $dir
|
||||
* @property string $original_name
|
||||
* @property string $ext
|
||||
* @property string $mine
|
||||
* @property int $size
|
||||
* @property Carbon $date
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
* @property Booking|null $booking
|
||||
* @property Customer|null $customer
|
||||
* @property Lead|null $lead
|
||||
* @package App\Models
|
||||
* @property \App\Models\Coupon|null $coupon_id
|
||||
* @property int|null $booking_storno_id
|
||||
* @property object|null $data
|
||||
* @property int|null $status
|
||||
* @property-read \App\Models\BookingStorno|null $booking_storno
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereBookingId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereBookingStornoId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereCouponId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereCustomerId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereData($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereDate($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereDir($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereExt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereFilename($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereIdentifier($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereLeadId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereMine($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereOriginalName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereSize($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereStatus($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BookingDocument whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class BookingDocument extends Model
|
||||
{
|
||||
protected $table = 'booking_documents';
|
||||
|
||||
protected $casts = [
|
||||
'booking_id' => 'int',
|
||||
'customer_id' => 'int',
|
||||
'lead_id' => 'int',
|
||||
'size' => 'int',
|
||||
'data' => 'object',
|
||||
'status' => 'int',
|
||||
'booking_storno_id' => 'int',
|
||||
'coupon_id' => 'int',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
'customer_id',
|
||||
'lead_id',
|
||||
'coupon_id',
|
||||
'booking_storno_id', //
|
||||
'identifier',
|
||||
'filename',
|
||||
'dir',
|
||||
'original_name',
|
||||
'ext',
|
||||
'mine',
|
||||
'size',
|
||||
'date',
|
||||
'data',
|
||||
'status'
|
||||
];
|
||||
/* Je nach identifier können verschiebene stati gesetzt werden
|
||||
coupon 0 = nicht eingelöst 1 = eingelöst
|
||||
*/
|
||||
protected $status_type = [
|
||||
0 => 'offen',
|
||||
1 => 'erledigt',
|
||||
];
|
||||
|
||||
|
||||
public function booking()
|
||||
{
|
||||
return $this->belongsTo(Booking::class);
|
||||
}
|
||||
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
public function lead()
|
||||
{
|
||||
return $this->belongsTo(Lead::class);
|
||||
}
|
||||
|
||||
public function coupon_id()
|
||||
{
|
||||
return $this->belongsTo(Coupon::class);
|
||||
}
|
||||
|
||||
public function booking_storno()
|
||||
{
|
||||
return $this->belongsTo(BookingStorno::class);
|
||||
}
|
||||
|
||||
public function getURL($do=false){
|
||||
return route('storage_file', [$this->id, 'booking_document', $do]);
|
||||
}
|
||||
|
||||
public function getPath(){
|
||||
return \Storage::disk('public')->path($this->dir.$this->filename);
|
||||
|
||||
}
|
||||
|
||||
public function deleteFile(){
|
||||
if(\Storage::disk('public')->exists($this->dir.$this->filename)){
|
||||
\Storage::disk('public')->delete($this->dir.$this->filename);
|
||||
}
|
||||
}
|
||||
public function formatBytes($precision = 2)
|
||||
{
|
||||
$size = $this->size;
|
||||
|
||||
if ($size > 0) {
|
||||
$size = (int) $size;
|
||||
$base = log($size) / log(1024);
|
||||
$suffixes = array(' bytes', ' KB', ' MB', ' GB', ' TB');
|
||||
|
||||
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
|
||||
} else {
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,6 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem whereTravelClassId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem whereTravelProgramId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property int|null $fewo_lodging_id
|
||||
* @property float|null $price
|
||||
* @property-read \App\Models\Booking $booking
|
||||
|
|
@ -64,6 +63,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingDraftItem query()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class BookingDraftItem extends Model
|
||||
{
|
||||
|
|
@ -115,7 +115,7 @@ class BookingDraftItem extends Model
|
|||
return $this->belongsTo('App\Models\DraftType', 'draft_type_id');
|
||||
}
|
||||
|
||||
public function getItemPrice(){
|
||||
public function getItemPrice($return = false){
|
||||
$adult = 0;
|
||||
$children = 0;
|
||||
|
||||
|
|
@ -138,9 +138,20 @@ class BookingDraftItem extends Model
|
|||
$price = $this->price;
|
||||
}
|
||||
*/
|
||||
return ['adult'=>$adult, 'children'=>$children];
|
||||
}
|
||||
|
||||
if($return == 'adult'){
|
||||
return $adult;
|
||||
}
|
||||
if($return == 'children'){
|
||||
return $children;
|
||||
}
|
||||
if($return == 'total'){
|
||||
return $adult + $children;
|
||||
}
|
||||
return ['adult'=>$adult, 'children'=>$children];
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function getStartDateAttribute(){
|
||||
return isset($this->attributes['start_date']) ? Carbon::parse($this->attributes['start_date'])->format("d.m.Y") : '';
|
||||
|
|
|
|||
|
|
@ -48,12 +48,10 @@ class BookingInvoice extends Model
|
|||
'total' => 'float',
|
||||
'deposit' => 'float',
|
||||
'final_payment' => 'float',
|
||||
'deposit_payment_date' => 'datetime',
|
||||
'final_payment_date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'deposit_payment_date',
|
||||
'final_payment_date'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
|
|
|
|||
|
|
@ -52,12 +52,10 @@ class BookingNotice extends Model
|
|||
'from_user_id' => 'int',
|
||||
'to_user_id' => 'int',
|
||||
'show' => 'bool',
|
||||
'important' => 'bool'
|
||||
'important' => 'bool',
|
||||
'edit_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'edit_at',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
|
|
|
|||
|
|
@ -55,12 +55,10 @@ class BookingServiceItem extends Model
|
|||
'service_price' => 'float',
|
||||
'service_price_refund' => 'float',
|
||||
'commission' => 'float',
|
||||
'is_commission_locked' => 'bool'
|
||||
'is_commission_locked' => 'bool',
|
||||
'travel_date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'travel_date'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Services\Util;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
|
@ -35,9 +36,10 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingStorno whereStornoDate($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingStorno whereTotal($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingStorno whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property \Illuminate\Support\Carbon|null $storno_print
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingStorno whereStornoPrint($value)
|
||||
* @property-read \App\Models\BookingDocument|null $booking_document
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class BookingStorno extends Model
|
||||
{
|
||||
|
|
@ -47,13 +49,11 @@ class BookingStorno extends Model
|
|||
'booking_id' => 'int',
|
||||
'total' => 'float',
|
||||
'storno' => 'float',
|
||||
'done' => 'bool'
|
||||
'done' => 'bool',
|
||||
'storno_date' => 'datetime',
|
||||
'storno_print' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'storno_date',
|
||||
'storno_print'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
|
|
@ -69,4 +69,72 @@ class BookingStorno extends Model
|
|||
{
|
||||
return $this->belongsTo(Booking::class);
|
||||
}
|
||||
|
||||
public function booking_document()
|
||||
{
|
||||
return $this->hasOne(BookingDocument::class, 'booking_storno_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function getTotalFormatted()
|
||||
{
|
||||
return Util::_number_format($this->attributes['total']);
|
||||
}
|
||||
|
||||
public function getTotalRaw()
|
||||
{
|
||||
return $this->attributes['total'];
|
||||
}
|
||||
|
||||
public function setTotalAttribute($value)
|
||||
{
|
||||
$this->attributes['total'] = Util::_clean_float($value);
|
||||
}
|
||||
|
||||
|
||||
public function getStornoFormatted()
|
||||
{
|
||||
return Util::_number_format($this->attributes['storno']);
|
||||
}
|
||||
|
||||
public function getStornoRaw()
|
||||
{
|
||||
return $this->attributes['storno'];
|
||||
}
|
||||
|
||||
public function setStornoAttribute($value)
|
||||
{
|
||||
$this->attributes['storno'] = Util::_clean_float($value);
|
||||
}
|
||||
|
||||
|
||||
public function getStornoDateFormatted()
|
||||
{
|
||||
return isset($this->attributes['storno_date']) ? Carbon::parse($this->attributes['storno_date'])->format('d.m.Y') : '';
|
||||
}
|
||||
|
||||
public function setStornoDateAttribute($value)
|
||||
{
|
||||
if (!$value) {
|
||||
$this->attributes['storno_date'] = null;
|
||||
} else {
|
||||
$this->attributes['storno_date'] = Carbon::parse($value)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
public function getStornoPrintFormatted()
|
||||
{
|
||||
return isset($this->attributes['storno_print']) ? Carbon::parse($this->attributes['storno_print'])->format('d.m.Y') : '';
|
||||
}
|
||||
|
||||
public function setStornoPrintAttribute($value)
|
||||
{
|
||||
if (!$value) {
|
||||
$this->attributes['storno_print'] = null;
|
||||
} else {
|
||||
$this->attributes['storno_print'] = Carbon::parse($value)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
49
app/Models/BookingVoucherAgency.php
Normal file
49
app/Models/BookingVoucherAgency.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Created by Reliese Model.
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class BookingVoucherAgency
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $booking_id
|
||||
* @property boolean $binary_data
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Booking $booking
|
||||
* @package App\Models
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency whereBinaryData($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency whereBookingId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\BookingVoucherAgency whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class BookingVoucherAgency extends Model
|
||||
{
|
||||
protected $table = 'booking_voucher_agency';
|
||||
|
||||
protected $casts = [
|
||||
'booking_id' => 'int',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'booking_id',
|
||||
'binary_data'
|
||||
];
|
||||
|
||||
public function booking()
|
||||
{
|
||||
return $this->belongsTo(Booking::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +24,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSAuthor whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSAuthor whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSAuthor whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string|null $description
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSAuthor whereDescription($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class CMSAuthor extends Model
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,41 +4,42 @@ namespace App\Models;
|
|||
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* App\Models\CMSContent
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property string|null $identifier
|
||||
* @property string $field
|
||||
* @property string|null $text
|
||||
* @property string|null $full_text
|
||||
* @property array|null $object
|
||||
* @property int|null $integer
|
||||
* @property float|null $decimal
|
||||
* @property string|null $decimal
|
||||
* @property int|null $pos
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent findSimilarSlugs($attribute, $config, $slug)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereDecimal($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereField($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereFullText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereInteger($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent query()
|
||||
* @property string|null $identifier
|
||||
* @property array|null $object
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereIdentifier($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereObject($value)
|
||||
* @property int|null $pos
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent wherePos($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent findSimilarSlugs(string $attribute, array $config, string $slug)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereDecimal($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereField($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereFullText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereIdentifier($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereInteger($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereObject($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent wherePos($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSContent withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class CMSContent extends Model
|
||||
{
|
||||
|
|
@ -74,7 +75,7 @@ class CMSContent extends Model
|
|||
'pos' => 'int'
|
||||
];
|
||||
|
||||
public function sluggable()
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string $type
|
||||
* @property int $bool
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereBool($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|CMSInfo withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class CMSInfo extends Model
|
||||
{
|
||||
|
|
@ -61,7 +61,8 @@ class CMSInfo extends Model
|
|||
'name', 'slug', 'type', 'text', 'full_text', 'integer', 'decimal', 'bool'
|
||||
];
|
||||
|
||||
public function sluggable()
|
||||
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Helper\HTMLHelper;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
|
@ -26,13 +26,13 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereTo($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property int $wday
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereWday($value)
|
||||
* @property int|null $special
|
||||
* @property string|null $date
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereDate($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfoAvailable whereSpecial($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class CMSInfoAvailable extends Model
|
||||
{
|
||||
|
|
|
|||
164
app/Models/Contact.php
Normal file
164
app/Models/Contact.php
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Sym\TravelCountry;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Kontakt-Modell — saubere Neuimplementierung auf Basis der customer-Tabelle.
|
||||
*
|
||||
* Unterschiede zum alten Customer-Modell:
|
||||
* - Global Scope schließt zusammengeführte Duplikate (merged_into_id IS NOT NULL) aus
|
||||
* - merged_into_id + merged_at in $fillable
|
||||
* - mergedInto() / mergedContacts() Beziehungen
|
||||
*
|
||||
* Tabellen-Name: 'contacts' (nach Phase 2 — RENAME TABLE customer → contacts).
|
||||
*
|
||||
* @property int $id
|
||||
* @property int|null $salutation_id
|
||||
* @property string|null $title
|
||||
* @property string|null $name
|
||||
* @property string|null $firstname
|
||||
* @property Carbon|null $birthdate
|
||||
* @property string|null $company
|
||||
* @property string|null $street
|
||||
* @property string|null $zip
|
||||
* @property string|null $city
|
||||
* @property string|null $email
|
||||
* @property string|null $phone
|
||||
* @property string|null $phonebusiness
|
||||
* @property string|null $phonemobile
|
||||
* @property string|null $fax
|
||||
* @property int|null $merged_into_id
|
||||
* @property Carbon|null $merged_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property-read Contact|null $mergedInto
|
||||
* @property-read Collection|Contact[] $mergedContacts
|
||||
* @property-read Collection|Lead[] $leads
|
||||
* @property-read Collection|Booking[] $bookings
|
||||
*/
|
||||
class Contact extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $connection = 'mysql';
|
||||
|
||||
protected $table = 'contacts';
|
||||
|
||||
protected $casts = [
|
||||
'salutation_id' => 'int',
|
||||
'credit_card_type_id' => 'int',
|
||||
'country_id' => 'int',
|
||||
'merged_into_id' => 'int',
|
||||
'birthdate' => 'datetime',
|
||||
'credit_card_expiration_date' => 'datetime',
|
||||
'merged_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'salutation_id',
|
||||
'title',
|
||||
'name',
|
||||
'firstname',
|
||||
'birthdate',
|
||||
'company',
|
||||
'street',
|
||||
'zip',
|
||||
'city',
|
||||
'email',
|
||||
'phone',
|
||||
'phonebusiness',
|
||||
'phonemobile',
|
||||
'fax',
|
||||
'bank',
|
||||
'bank_code',
|
||||
'bank_account_number',
|
||||
'credit_card_type_id',
|
||||
'credit_card_number',
|
||||
'credit_card_expiration_date',
|
||||
'participants_remarks',
|
||||
'miscellaneous_remarks',
|
||||
'country_id',
|
||||
'merged_into_id',
|
||||
'merged_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Globaler Scope: zusammengeführte Duplikate werden standardmäßig ausgeblendet.
|
||||
* Für Zugriff auf alle inkl. Duplikate: Contact::withoutGlobalScope('not_merged')
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::addGlobalScope('not_merged', function (Builder $query) {
|
||||
$query->whereNull('merged_into_id');
|
||||
});
|
||||
}
|
||||
|
||||
// ── Beziehungen ──────────────────────────────────────────────────────────
|
||||
|
||||
public function mergedInto(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Contact::class, 'merged_into_id')
|
||||
->withoutGlobalScope('not_merged');
|
||||
}
|
||||
|
||||
public function mergedContacts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Contact::class, 'merged_into_id')
|
||||
->withoutGlobalScope('not_merged');
|
||||
}
|
||||
|
||||
public function leads(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Lead::class, 'customer_id')->orderByDesc('created_at');
|
||||
}
|
||||
|
||||
public function bookings(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Booking::class, 'customer_id')->orderByDesc('created_at');
|
||||
}
|
||||
|
||||
public function salutation(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Salutation::class);
|
||||
}
|
||||
|
||||
public function travel_country(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TravelCountry::class, 'country_id');
|
||||
}
|
||||
|
||||
// ── Hilfsmethoden ────────────────────────────────────────────────────────
|
||||
|
||||
public function fullName(): string
|
||||
{
|
||||
if ($this->firstname) {
|
||||
return $this->firstname . ' ' . $this->name;
|
||||
}
|
||||
return (string) $this->name;
|
||||
}
|
||||
|
||||
public function isMerged(): bool
|
||||
{
|
||||
return $this->merged_into_id !== null;
|
||||
}
|
||||
|
||||
public static function getCountriesArray(): \Illuminate\Support\Collection
|
||||
{
|
||||
return TravelCountry::where('is_customer_country', 1)->get()->pluck('name', 'id');
|
||||
}
|
||||
|
||||
public static $salutationType = [
|
||||
1 => 'Herr',
|
||||
2 => 'Frau',
|
||||
3 => 'Divers/keine Anrede',
|
||||
4 => 'Firma',
|
||||
];
|
||||
}
|
||||
|
|
@ -26,10 +26,10 @@ use PHPUnit\Framework\Constraint\Count;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country whereIt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country wherePhone($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country whereRu($value)
|
||||
* @mixin \Eloquent
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Country query()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Country extends Model
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Services\Util;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
/**
|
||||
* Class Coupon
|
||||
|
|
@ -43,9 +44,10 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereValidDate($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereValue($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string|null $text
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereText($value)
|
||||
* @property-read \App\Models\BookingDocument|null $booking_document
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Coupon extends Model
|
||||
{
|
||||
|
|
@ -57,14 +59,12 @@ class Coupon extends Model
|
|||
'customer_id' => 'int',
|
||||
'booking_id' => 'int',
|
||||
'value' => 'float',
|
||||
'is_redeemed' => 'bool'
|
||||
'is_redeemed' => 'bool',
|
||||
'issue_date' => 'datetime',
|
||||
'valid_date' => 'datetime',
|
||||
'redeem_date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'issue_date',
|
||||
'valid_date',
|
||||
'redeem_date'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'number',
|
||||
|
|
@ -78,6 +78,32 @@ class Coupon extends Model
|
|||
'text'
|
||||
];
|
||||
|
||||
/**
|
||||
* The "booted" method of the model.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::created(function ($model) {
|
||||
$model->number = sprintf(
|
||||
'%02u-%05u-%05u-%02u%02u',
|
||||
date('y'),
|
||||
$model->customer_id,
|
||||
$model->id,
|
||||
date('H'),
|
||||
date('i')
|
||||
);
|
||||
$model->save();
|
||||
});
|
||||
}
|
||||
|
||||
public function create($product)
|
||||
{
|
||||
logger($product->id);
|
||||
}
|
||||
|
||||
public function booking()
|
||||
{
|
||||
return $this->belongsTo(Booking::class);
|
||||
|
|
@ -88,6 +114,12 @@ class Coupon extends Model
|
|||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
public function booking_document()
|
||||
{
|
||||
return $this->hasOne(BookingDocument::class, 'coupon_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function bookings()
|
||||
{
|
||||
return $this->hasMany(Booking::class);
|
||||
|
|
@ -95,6 +127,67 @@ class Coupon extends Model
|
|||
|
||||
public function isLegal(){
|
||||
//TODO
|
||||
// return strtotime(date('Y-m-d')) <= strtotime($this->getValidDate());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getValueFormatted()
|
||||
{
|
||||
return Util::_number_format($this->attributes['value']);
|
||||
}
|
||||
|
||||
public function getValueRaw()
|
||||
{
|
||||
return $this->attributes['value'];
|
||||
}
|
||||
|
||||
public function setValueAttribute($value)
|
||||
{
|
||||
$this->attributes['value'] = Util::_clean_float($value);
|
||||
}
|
||||
|
||||
public function getIssueDateFormatted()
|
||||
{
|
||||
return isset($this->attributes['issue_date']) ? Carbon::parse($this->attributes['issue_date'])->format('d.m.Y') : '';
|
||||
}
|
||||
|
||||
public function setIssueDateAttribute($value)
|
||||
{
|
||||
if (!$value) {
|
||||
$this->attributes['issue_date'] = null;
|
||||
} else {
|
||||
$this->attributes['issue_date'] = Carbon::parse($value)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
public function getValidDateFormatted()
|
||||
{
|
||||
return isset($this->attributes['valid_date']) ? Carbon::parse($this->attributes['valid_date'])->format('d.m.Y') : '';
|
||||
}
|
||||
|
||||
public function setValidDateAttribute($value)
|
||||
{
|
||||
if (!$value) {
|
||||
$this->attributes['valid_date'] = null;
|
||||
} else {
|
||||
$this->attributes['valid_date'] = Carbon::parse($value)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
public function getRedeemDateFormatted()
|
||||
{
|
||||
return isset($this->attributes['redeem_date']) ? Carbon::parse($this->attributes['redeem_date'])->format('d.m.Y') : '';
|
||||
}
|
||||
|
||||
public function setRedeemDateAttribute($value)
|
||||
{
|
||||
if (!$value) {
|
||||
$this->attributes['redeem_date'] = null;
|
||||
} else {
|
||||
$this->attributes['redeem_date'] = Carbon::parse($value)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue