update 20.10.2025
This commit is contained in:
parent
8c11130b5d
commit
a939cd51ef
616 changed files with 84821 additions and 4121 deletions
2
.devcontainer.env
Normal file
2
.devcontainer.env
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
WWWUSER=501
|
||||||
|
WWWGROUP=20
|
||||||
2
.devcontainer/.env
Normal file
2
.devcontainer/.env
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
WWWUSER=501
|
||||||
|
WWWGROUP=20
|
||||||
231
.devcontainer/Readme.md
Normal file
231
.devcontainer/Readme.md
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
# Laravel Sail DevContainer Setup
|
||||||
|
|
||||||
|
Diese Dokumentation beschreibt die Einrichtung und Verwendung des DevContainers für das Laravel Sail-Projekt.
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Der DevContainer ermöglicht es, das Laravel-Projekt in einer vollständig konfigurierten Docker-Umgebung zu entwickeln, ohne dass lokale PHP-, Node.js- oder andere Abhängigkeiten installiert werden müssen.
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Docker Desktop installiert und laufend
|
||||||
|
- Cursor.ai oder VS Code mit DevContainer-Erweiterung
|
||||||
|
- Git (für Repository-Zugriff)
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
### 1. DevContainer-Konfiguration (`devcontainer.json`)
|
||||||
|
|
||||||
|
Die Hauptkonfiguration befindet sich in `.devcontainer/devcontainer.json`:
|
||||||
|
|
||||||
|
- **Eigenständiges Docker-Image**: Verwendet `sail-8.4/app` direkt ohne Docker Compose
|
||||||
|
- **Build-Konfiguration**: Definiert Build-Argumente für `WWWUSER` und `WWWGROUP`
|
||||||
|
- **Workspace**: `/var/www/html` (Standard-Laravel-Verzeichnis)
|
||||||
|
- **Benutzer**: `sail` (Laravel Sail Standard-Benutzer)
|
||||||
|
- **Features**: Leer (Tools werden über postCreateCommand installiert)
|
||||||
|
- **Extensions**: PHP, Laravel Blade, Tailwind CSS Extensions
|
||||||
|
- **Port-Forwarding**: Automatisch für wichtige Services (5173, 33061, 6380, 8025)
|
||||||
|
|
||||||
|
### 2. Dockerfile-Anpassungen (`docker/8.4/Dockerfile`)
|
||||||
|
|
||||||
|
Das Dockerfile wurde angepasst um:
|
||||||
|
|
||||||
|
- `ARG WWWUSER` hinzugefügt für korrekte Benutzer-ID
|
||||||
|
- Benutzererstellung mit dynamischen IDs (`$WWWUSER` statt feste `1337`)
|
||||||
|
- Vollständige Laravel-Umgebung mit PHP 8.4, Composer, NPM, Git
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Automatische Installation (Empfohlen)
|
||||||
|
|
||||||
|
1. Öffnen Sie das Projekt in Cursor.ai oder VS Code
|
||||||
|
2. Klicken Sie auf "Reopen in Container" wenn die DevContainer-Benachrichtigung erscheint
|
||||||
|
3. Warten Sie bis der Container gebaut und gestartet ist
|
||||||
|
|
||||||
|
### Manuelle Installation
|
||||||
|
|
||||||
|
Falls die automatische Installation fehlschlägt, können Sie den Container manuell bauen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/pandora/Sites/mivita.care
|
||||||
|
docker build --build-arg WWWUSER=501 --build-arg WWWGROUP=20 -f docker/8.4/Dockerfile -t sail-8.4/app docker/8.4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verfügbare Tools
|
||||||
|
|
||||||
|
Nach der Installation sind folgende Tools verfügbar:
|
||||||
|
|
||||||
|
- **PHP 8.4.12**: Mit Xdebug für Debugging
|
||||||
|
- **Composer**: Für Laravel-Abhängigkeiten
|
||||||
|
- **NPM**: Für Frontend-Assets
|
||||||
|
- **Git**: Für Versionskontrolle
|
||||||
|
- **Node.js**: Für JavaScript-Entwicklung
|
||||||
|
|
||||||
|
Überprüfen Sie die Installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
which git
|
||||||
|
which npm
|
||||||
|
which composer
|
||||||
|
php --version
|
||||||
|
```
|
||||||
|
|
||||||
|
## Post-Create-Befehle
|
||||||
|
|
||||||
|
Nach dem Erstellen des Containers werden automatisch ausgeführt:
|
||||||
|
|
||||||
|
1. Composer-Abhängigkeiten (`composer install`)
|
||||||
|
|
||||||
|
## Entwicklung
|
||||||
|
|
||||||
|
### Erste Schritte
|
||||||
|
|
||||||
|
1. **Composer-Abhängigkeiten**: Werden automatisch installiert
|
||||||
|
2. **Laravel-Konfiguration**: `.env` Datei muss manuell erstellt werden (siehe Laravel-Dokumentation)
|
||||||
|
3. **Datenbank-Migrationen**: `php artisan migrate`
|
||||||
|
4. **Asset-Kompilierung**: `npm install && npm run dev`
|
||||||
|
|
||||||
|
### Häufige Befehle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Laravel-Befehle
|
||||||
|
php artisan migrate
|
||||||
|
php artisan serve
|
||||||
|
php artisan tinker
|
||||||
|
|
||||||
|
# Composer
|
||||||
|
composer install
|
||||||
|
composer update
|
||||||
|
|
||||||
|
# NPM/Node
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Sail-Befehle (falls verfügbar)
|
||||||
|
./vendor/bin/sail up
|
||||||
|
./vendor/bin/sail artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Container startet nicht
|
||||||
|
|
||||||
|
1. Überprüfen Sie ob Docker Desktop läuft
|
||||||
|
2. Stellen Sie sicher, dass keine anderen Container die benötigten Ports blockieren
|
||||||
|
3. Versuchen Sie einen Clean-Build: `docker build --no-cache ...`
|
||||||
|
|
||||||
|
### Berechtigungsprobleme
|
||||||
|
|
||||||
|
Die Container sind so konfiguriert, dass sie mit Ihrer lokalen Benutzer-ID (`501`) laufen, um Berechtigungsprobleme zu vermeiden.
|
||||||
|
|
||||||
|
### NPM Global Install Probleme
|
||||||
|
|
||||||
|
Falls Sie globale NPM-Pakete installieren möchten, verwenden Sie lokale Installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lokale Installation (empfohlen)
|
||||||
|
npm install package-name
|
||||||
|
|
||||||
|
# Oder NPM-Prefix ändern
|
||||||
|
mkdir ~/.npm-global
|
||||||
|
npm config set prefix '~/.npm-global'
|
||||||
|
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
|
||||||
|
source ~/.bashrc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Claude CLI Kompatibilitätsprobleme
|
||||||
|
|
||||||
|
**Problem**: Das `@anthropic-ai/claude-code` Paket ist nicht mit modernen Node.js-Versionen kompatibel.
|
||||||
|
|
||||||
|
**Symptome**:
|
||||||
|
|
||||||
|
- Viele veraltete Abhängigkeiten (deprecated packages)
|
||||||
|
- PhantomJS ARM64 Kompatibilitätsprobleme
|
||||||
|
- Engine-Konflikte mit Node.js v22
|
||||||
|
|
||||||
|
**Lösung**:
|
||||||
|
|
||||||
|
- Verwenden Sie die Cursor.ai-Integration direkt (empfohlen)
|
||||||
|
- Oder verwenden Sie alternative CLI-Tools
|
||||||
|
- Das Paket ist für die Laravel-Entwicklung nicht notwendig
|
||||||
|
|
||||||
|
### Port-Konflikte
|
||||||
|
|
||||||
|
Falls Ports bereits belegt sind, können Sie die Port-Mapping in der DevContainer-Konfiguration anpassen.
|
||||||
|
|
||||||
|
## Erweiterte Konfiguration
|
||||||
|
|
||||||
|
### Zusätzliche Extensions hinzufügen
|
||||||
|
|
||||||
|
Bearbeiten Sie `devcontainer.json` und fügen Sie Extensions zum `extensions` Array hinzu:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"extensions": [
|
||||||
|
"bmewburn.vscode-intelephense-client",
|
||||||
|
"onecentlin.laravel-blade",
|
||||||
|
"shufo.vscode-blade-formatter",
|
||||||
|
"bradlc.vscode-tailwindcss",
|
||||||
|
"ihrc.vscode-php-cs-fixer"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zusätzliche Tools installieren
|
||||||
|
|
||||||
|
Fügen Sie Tools zum `postCreateCommand` hinzu:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"postCreateCommand": "composer install --no-interaction --prefer-dist --optimize-autoloader && npm install -g your-tool"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Bei Problemen mit dem DevContainer:
|
||||||
|
|
||||||
|
1. Überprüfen Sie die Docker-Logs: `docker logs <container-name>`
|
||||||
|
2. Stellen Sie sicher, dass alle Umgebungsvariablen korrekt gesetzt sind
|
||||||
|
3. Versuchen Sie einen Neustart des DevContainers
|
||||||
|
|
||||||
|
## Bekannte Probleme und Lösungen
|
||||||
|
|
||||||
|
### DevContainer-CLI Kompatibilität
|
||||||
|
|
||||||
|
**Problem**: DevContainer-CLI erstellt temporäre Docker-Compose-Dateien die mit der Konfiguration kollidieren.
|
||||||
|
|
||||||
|
**Lösung**: Verwendung eines eigenständigen Docker-Images ohne Docker Compose-Abhängigkeit.
|
||||||
|
|
||||||
|
### Features-Installation
|
||||||
|
|
||||||
|
**Problem**: DevContainer Features können zu Build-Fehlern führen.
|
||||||
|
|
||||||
|
**Lösung**: Tools werden über `postCreateCommand` installiert statt über Features.
|
||||||
|
|
||||||
|
### Root-Berechtigungen
|
||||||
|
|
||||||
|
**Problem**: Der `sail`-Benutzer hat keine Root-Rechte für Paket-Installation.
|
||||||
|
|
||||||
|
**Lösung**: Alle notwendigen Tools sind bereits im Docker-Image installiert.
|
||||||
|
|
||||||
|
### Claude CLI Kompatibilität
|
||||||
|
|
||||||
|
**Problem**: Das `@anthropic-ai/claude-code` Paket ist veraltet und nicht mit Node.js v22 kompatibel.
|
||||||
|
|
||||||
|
**Symptome**:
|
||||||
|
|
||||||
|
- Hunderte von deprecated package warnings
|
||||||
|
- PhantomJS ARM64 Kompatibilitätsprobleme
|
||||||
|
- Engine-Konflikte mit modernen Node.js-Versionen
|
||||||
|
|
||||||
|
**Lösung**:
|
||||||
|
|
||||||
|
- **Verwenden Sie Cursor.ai direkt** (empfohlen) - keine CLI nötig
|
||||||
|
- Das Paket ist für Laravel-Entwicklung nicht notwendig
|
||||||
|
- Alle wichtigen Tools (PHP, Composer, NPM, Git) sind bereits verfügbar
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Letzte Aktualisierung**: September 2025
|
||||||
|
**Laravel Version**: 11.x
|
||||||
|
**PHP Version**: 8.4.12
|
||||||
|
**Docker Version**: 2.x
|
||||||
|
**Status**: ✅ Vollständig funktionsfähig
|
||||||
78
.devcontainer/devcontainer.json
Normal file
78
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"name": "Mivita Care (Dev Container)",
|
||||||
|
// 1. DIES IST DER WICHTIGSTE TEIL:
|
||||||
|
// Wir verwenden Docker Compose für alle Services
|
||||||
|
"dockerComposeFile": [
|
||||||
|
"../docker-compose.yml"
|
||||||
|
],
|
||||||
|
"service": "laravel.test",
|
||||||
|
// 3. WIR DEFINIEREN DEN ARBEITSBEREICH:
|
||||||
|
// Das ist der Pfad, in dem Ihr Code *innerhalb* des Containers liegt.
|
||||||
|
"workspaceFolder": "/var/www/html",
|
||||||
|
// 4. WIR LEGEN DEN BENUTZER FEST:
|
||||||
|
// Laravel Sail führt Befehle standardmäßig als 'sail'-Benutzer aus, um Berechtigungsprobleme zu vermeiden.
|
||||||
|
"remoteUser": "sail",
|
||||||
|
// 5. ZUSÄTZLICHE ENTWICKLER-TOOLS (FEATURES):
|
||||||
|
// Features werden über postCreateCommand installiert um Kompatibilitätsprobleme zu vermeiden
|
||||||
|
"features": {},
|
||||||
|
// 6. BEFEHLE NACH DEM ERSTELLEN:
|
||||||
|
// Installiert nur die Tools die ohne Root-Rechte funktionieren
|
||||||
|
//"postCreateCommand": "composer install --no-interaction --prefer-dist --optimize-autoloader",
|
||||||
|
// 7. EDITOR-ANPASSUNGEN (Optional, aber sehr empfohlen):
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"bmewburn.vscode-intelephense-client",
|
||||||
|
"onecentlin.laravel-blade",
|
||||||
|
"shufo.vscode-blade-formatter",
|
||||||
|
"bradlc.vscode-tailwindcss"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 8. ZU STARTENDE DIENSTE:
|
||||||
|
// Legt fest, welche Dienste aus der docker-compose.yml gestartet werden sollen.
|
||||||
|
"runServices": [
|
||||||
|
"laravel.test",
|
||||||
|
"mysql",
|
||||||
|
"redis",
|
||||||
|
"mailpit"
|
||||||
|
],
|
||||||
|
// 9. ZUSÄTZLICHE KONFIGURATION:
|
||||||
|
// Umgebungsvariablen für den DevContainer
|
||||||
|
"containerEnv": {
|
||||||
|
"WWWUSER": "501",
|
||||||
|
"WWWGROUP": "20",
|
||||||
|
"LARAVEL_SAIL": "1"
|
||||||
|
},
|
||||||
|
// 10. MOUNT-KONFIGURATION:
|
||||||
|
// Stellt sicher, dass der Code korrekt gemountet wird
|
||||||
|
"mounts": [
|
||||||
|
"source=${localWorkspaceFolder},target=/var/www/html,type=bind,consistency=cached"
|
||||||
|
],
|
||||||
|
// 11. FORWARD PORTS:
|
||||||
|
// Ports die automatisch weitergeleitet werden sollen
|
||||||
|
"forwardPorts": [
|
||||||
|
5173,
|
||||||
|
33061,
|
||||||
|
6380,
|
||||||
|
8025
|
||||||
|
],
|
||||||
|
"portsAttributes": {
|
||||||
|
"5173": {
|
||||||
|
"label": "Vite Dev Server",
|
||||||
|
"onAutoForward": "notify"
|
||||||
|
},
|
||||||
|
"33061": {
|
||||||
|
"label": "MySQL",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"6380": {
|
||||||
|
"label": "Redis",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"8025": {
|
||||||
|
"label": "Mailpit Dashboard",
|
||||||
|
"onAutoForward": "notify"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
125
.devcontainer/docker-compose.dev.yml
Normal file
125
.devcontainer/docker-compose.dev.yml
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
services:
|
||||||
|
laravel.test:
|
||||||
|
build:
|
||||||
|
context: '../docker/8.4'
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
# Führen Sie in Ihrem normalen Terminal `id -u` aus und tragen Sie die Zahl hier ein.
|
||||||
|
WWWUSER: '501'
|
||||||
|
# Führen Sie in Ihrem normalen Terminal `id -g` aus und tragen Sie die Zahl hier ein.
|
||||||
|
WWWGROUP: '20'
|
||||||
|
image: 'sail-8.4/app'
|
||||||
|
extra_hosts:
|
||||||
|
- 'host.docker.internal:host-gateway'
|
||||||
|
ports:
|
||||||
|
- '5173:5173'
|
||||||
|
environment:
|
||||||
|
# Laravel Sail Environment Variables
|
||||||
|
WWWUSER: '501'
|
||||||
|
WWWGROUP: '20'
|
||||||
|
LARAVEL_SAIL: 1
|
||||||
|
XDEBUG_MODE: 'develop,debug'
|
||||||
|
XDEBUG_CONFIG: 'client_host=host.docker.internal'
|
||||||
|
IGNITION_LOCAL_SITES_PATH: '/var/www/html'
|
||||||
|
# Database Configuration
|
||||||
|
DB_CONNECTION: mysql
|
||||||
|
DB_HOST: mysql
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_DATABASE: mivita
|
||||||
|
DB_USERNAME: sail
|
||||||
|
DB_PASSWORD: password
|
||||||
|
# Application Configuration
|
||||||
|
APP_NAME: Mivita
|
||||||
|
APP_ENV: local
|
||||||
|
APP_DEBUG: true
|
||||||
|
APP_URL: http://localhost
|
||||||
|
# Mail Configuration
|
||||||
|
MAIL_MAILER: smtp
|
||||||
|
MAIL_HOST: mailpit
|
||||||
|
MAIL_PORT: 1025
|
||||||
|
MAIL_USERNAME: null
|
||||||
|
MAIL_PASSWORD: null
|
||||||
|
MAIL_ENCRYPTION: null
|
||||||
|
MAIL_FROM_ADDRESS: hello@example.com
|
||||||
|
MAIL_FROM_NAME: Mivita
|
||||||
|
# Redis Configuration
|
||||||
|
REDIS_HOST: redis
|
||||||
|
REDIS_PASSWORD: null
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
# Vite Configuration
|
||||||
|
VITE_PORT: 5173
|
||||||
|
# Forward Ports
|
||||||
|
FORWARD_DB_PORT: 33061
|
||||||
|
FORWARD_REDIS_PORT: 6380
|
||||||
|
FORWARD_MAILPIT_PORT: 1025
|
||||||
|
FORWARD_MAILPIT_DASHBOARD_PORT: 8025
|
||||||
|
# MySQL Extra Options
|
||||||
|
MYSQL_EXTRA_OPTIONS: --default-authentication-plugin=mysql_native_password
|
||||||
|
volumes:
|
||||||
|
- '../:/var/www/html'
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- mailpit
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: 'mysql/mysql-server:8.0'
|
||||||
|
ports:
|
||||||
|
- '33061:3306'
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: password
|
||||||
|
MYSQL_ROOT_HOST: '%'
|
||||||
|
MYSQL_DATABASE: mivita
|
||||||
|
MYSQL_USER: sail
|
||||||
|
MYSQL_PASSWORD: password
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: 1
|
||||||
|
MYSQL_EXTRA_OPTIONS: --default-authentication-plugin=mysql_native_password
|
||||||
|
volumes:
|
||||||
|
- 'sail-mysql:/var/lib/mysql'
|
||||||
|
- '../docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- mysqladmin
|
||||||
|
- ping
|
||||||
|
- '-ppassword'
|
||||||
|
retries: 3
|
||||||
|
timeout: 5s
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: 'redis:alpine'
|
||||||
|
ports:
|
||||||
|
- '6380:6379'
|
||||||
|
volumes:
|
||||||
|
- 'sail-redis:/data'
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- redis-cli
|
||||||
|
- ping
|
||||||
|
retries: 3
|
||||||
|
timeout: 5s
|
||||||
|
|
||||||
|
mailpit:
|
||||||
|
image: 'axllent/mailpit:latest'
|
||||||
|
ports:
|
||||||
|
- '1025:1025'
|
||||||
|
- '8025:8025'
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
|
||||||
|
networks:
|
||||||
|
sail:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
sail-mysql:
|
||||||
|
driver: local
|
||||||
|
sail-redis:
|
||||||
|
driver: local
|
||||||
8
.env
8
.env
|
|
@ -73,7 +73,7 @@ QUEUE_DRIVER=redis
|
||||||
QUEUE_CONNECTION=redis
|
QUEUE_CONNECTION=redis
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PASSWORD=null
|
REDIS_PASSWORD=null
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6380
|
||||||
|
|
||||||
MAIL_DRIVER=smtp
|
MAIL_DRIVER=smtp
|
||||||
MAIL_HOST=mailpit
|
MAIL_HOST=mailpit
|
||||||
|
|
@ -91,6 +91,7 @@ PUSHER_APP_CLUSTER=mt1
|
||||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
|
|
||||||
MIVITA_RENEWAL_DAYS=29
|
MIVITA_RENEWAL_DAYS=29
|
||||||
MIVITA_REMIND_FIRST_DAYS=21
|
MIVITA_REMIND_FIRST_DAYS=21
|
||||||
MIVITA_REMIND_SEC_DAYS=14
|
MIVITA_REMIND_SEC_DAYS=14
|
||||||
|
|
@ -106,6 +107,8 @@ MIVITA_ADD_NUMBER_ID=946
|
||||||
|
|
||||||
# DHL API Zugangsdaten (konsolidiert)
|
# DHL API Zugangsdaten (konsolidiert)
|
||||||
DHL_BASE_URL=https://api-eu.dhl.com
|
DHL_BASE_URL=https://api-eu.dhl.com
|
||||||
|
DHL_SANDBOX_URL=https://api-sandbox.dhl.com
|
||||||
|
|
||||||
DHL_API_KEY=AxGBdF8DBdIAmuhqvG0ASBRKFvyV7ypX
|
DHL_API_KEY=AxGBdF8DBdIAmuhqvG0ASBRKFvyV7ypX
|
||||||
DHL_USERNAME=riwa-tec
|
DHL_USERNAME=riwa-tec
|
||||||
DHL_PASSWORD=MivitaCare!!2025
|
DHL_PASSWORD=MivitaCare!!2025
|
||||||
|
|
@ -130,6 +133,9 @@ DHL_ACCOUNT_NUMBER_V62WP=63144073556201 # Warenpost National
|
||||||
DHL_ACCOUNT_NUMBER_V53PAK=63144073555301 # DHL Paket International
|
DHL_ACCOUNT_NUMBER_V53PAK=63144073555301 # DHL Paket International
|
||||||
DHL_ACCOUNT_NUMBER_V07PAK=63144073550701 # DHL Retoure Online
|
DHL_ACCOUNT_NUMBER_V07PAK=63144073550701 # DHL Retoure Online
|
||||||
#sandbox
|
#sandbox
|
||||||
|
DHL_USERNAME=user-valid
|
||||||
|
DHL_PASSWORD=SandboxPasswort2023!
|
||||||
|
DHL_BILLING_NUMBER=33333333330101
|
||||||
DHL_ACCOUNT_NUMBER_DEFAULT=33333333330101
|
DHL_ACCOUNT_NUMBER_DEFAULT=33333333330101
|
||||||
DHL_ACCOUNT_NUMBER_V01PAK=33333333330102 # DHL Paket National
|
DHL_ACCOUNT_NUMBER_V01PAK=33333333330102 # DHL Paket National
|
||||||
DHL_ACCOUNT_NUMBER_V62WP=33333333336601 # Warenpost National
|
DHL_ACCOUNT_NUMBER_V62WP=33333333336601 # Warenpost National
|
||||||
|
|
|
||||||
187
CLAUDE.md
Normal file
187
CLAUDE.md
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a Laravel 11 business e-commerce application called "mivita.care" that handles multi-level marketing structures, product sales, payments, and DHL shipping integration. The application supports multi-tenancy through domain resolution and includes comprehensive business analytics and commission calculations.
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
### Core Laravel Commands
|
||||||
|
```bash
|
||||||
|
# Run development server
|
||||||
|
php artisan serve
|
||||||
|
|
||||||
|
# Run scheduled tasks
|
||||||
|
php artisan schedule:run
|
||||||
|
|
||||||
|
# Clear application cache
|
||||||
|
php artisan cache:clear
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan route:clear
|
||||||
|
php artisan view:clear
|
||||||
|
|
||||||
|
# Generate IDE helper files
|
||||||
|
php artisan ide-helper:generate
|
||||||
|
php artisan ide-helper:models
|
||||||
|
php artisan ide-helper:meta
|
||||||
|
|
||||||
|
# Database migrations
|
||||||
|
php artisan migrate
|
||||||
|
php artisan migrate:rollback
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
```bash
|
||||||
|
# Run tests using Pest
|
||||||
|
./vendor/bin/pest
|
||||||
|
|
||||||
|
# Run specific test
|
||||||
|
./vendor/bin/pest --filter=TestName
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Quality
|
||||||
|
```bash
|
||||||
|
# Format code using Laravel Pint
|
||||||
|
./vendor/bin/pint
|
||||||
|
composer run format
|
||||||
|
```
|
||||||
|
|
||||||
|
### Asset Compilation
|
||||||
|
```bash
|
||||||
|
# Install node dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Development build
|
||||||
|
npm run dev
|
||||||
|
npm run watch
|
||||||
|
|
||||||
|
# Production build
|
||||||
|
npm run production
|
||||||
|
|
||||||
|
# Asset postinstall (rebuilds node-sass)
|
||||||
|
npm run postinstall
|
||||||
|
```
|
||||||
|
|
||||||
|
### Business-Specific Commands
|
||||||
|
```bash
|
||||||
|
# Business structure calculations (optimized version - recommended)
|
||||||
|
php artisan business:store-optimized {month} {year}
|
||||||
|
php artisan business:store-optimized {month} {year} --clear
|
||||||
|
|
||||||
|
# Legacy business structure command
|
||||||
|
php artisan business:store {month} {year}
|
||||||
|
|
||||||
|
# Clear business data
|
||||||
|
php artisan business:clear-data {month} {year}
|
||||||
|
php artisan business:clear-data {month} {year} --force
|
||||||
|
|
||||||
|
# User management
|
||||||
|
php artisan user:cleanup
|
||||||
|
php artisan user:make_abo_order
|
||||||
|
|
||||||
|
# Payment processing
|
||||||
|
php artisan payments:check-accounts
|
||||||
|
|
||||||
|
# Level reports (new feature)
|
||||||
|
php artisan business:level-reports {month} {year}
|
||||||
|
|
||||||
|
# Test account management
|
||||||
|
php artisan business:test-account
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
### Multi-Level Marketing Structure
|
||||||
|
- **TreeCalcBot/TreeCalcBotOptimized**: Core business logic for calculating commission structures and multi-level hierarchies
|
||||||
|
- **BusinessPlan Services**: Handle commission calculations, sales volumes, and business structure management
|
||||||
|
- **BusinessController/BusinessControllerOptimized**: Handle business administration and analytics
|
||||||
|
|
||||||
|
### Domain Architecture
|
||||||
|
- **Multi-tenant setup** using domain resolution
|
||||||
|
- **DomainService**: Manages domain-specific configurations and routing
|
||||||
|
- **DomainResolver Middleware**: Routes requests based on domain
|
||||||
|
|
||||||
|
### Key Service Classes
|
||||||
|
- **Payment Services**: Handle various payment methods (Payone, credit systems, invoices)
|
||||||
|
- **DHL Integration**: Complete shipping solution with label generation and tracking
|
||||||
|
- **Shopping Cart Systems**: Multiple cart implementations (AboOrderCart, HomepartyCart, ShopApiOrderCart)
|
||||||
|
- **User Management**: Comprehensive user hierarchy and team management
|
||||||
|
|
||||||
|
### Database Structure
|
||||||
|
- Business users with hierarchical relationships
|
||||||
|
- Product catalog with categories and ingredients
|
||||||
|
- Order and payment tracking
|
||||||
|
- Commission and sales volume calculations
|
||||||
|
- Multi-domain configurations
|
||||||
|
|
||||||
|
### Custom Packages
|
||||||
|
- **Gloudemans\Shoppingcart**: Custom shopping cart implementation
|
||||||
|
- **Acme\Dhl**: DHL shipping integration package
|
||||||
|
- **Alban\LaravelCollectiveSpatieHtmlParser**: HTML parsing utilities
|
||||||
|
|
||||||
|
## Scheduled Tasks (Cron Jobs)
|
||||||
|
The application runs several daily scheduled tasks (defined in `app/Console/Kernel.php`):
|
||||||
|
- `02:00` - Payment account checks (`payments:check-accounts`)
|
||||||
|
- `03:00` - Business structure optimization (`store-optimized 0 0`)
|
||||||
|
- `03:30` - User cleanup (`user:cleanup`)
|
||||||
|
- `04:00` - Automated subscription orders (`user:make_abo_order`)
|
||||||
|
|
||||||
|
## Important File Locations
|
||||||
|
- **Business Commands**: `app/Console/Commands/Business*.php`
|
||||||
|
- **Service Classes**: `app/Services/` (extensive service layer)
|
||||||
|
- **Controllers**: `app/Http/Controllers/` (40+ controllers)
|
||||||
|
- **Custom Packages**: `packages/` directory
|
||||||
|
- **Dev Documentation**: `dev/code/Services/*.md` (contains optimization guides)
|
||||||
|
|
||||||
|
## Development Notes
|
||||||
|
|
||||||
|
### Business Optimization Features
|
||||||
|
- Use `TreeCalcBotOptimized` for all new business calculation features
|
||||||
|
- Memory monitoring and automatic garbage collection built into optimized commands
|
||||||
|
- Comprehensive error handling with graceful degradation
|
||||||
|
- Performance logging and monitoring capabilities
|
||||||
|
|
||||||
|
### DHL Shipping Integration
|
||||||
|
- Full DHL API integration with both Developer API and Business Customer API support
|
||||||
|
- Automatic label generation and tracking
|
||||||
|
- Sandbox/production mode switching
|
||||||
|
- Complete shipping workflow integration
|
||||||
|
|
||||||
|
### Multi-Domain Support
|
||||||
|
- Each domain can have different configurations
|
||||||
|
- Domain-specific routing and middleware
|
||||||
|
- Subdomain management through console commands
|
||||||
|
|
||||||
|
### Asset Management
|
||||||
|
- Laravel Mix for asset compilation
|
||||||
|
- Appwork theme integration with Bootstrap 4
|
||||||
|
- Vendor assets management with SASS compilation
|
||||||
|
- Custom node-sass rebuild process for compatibility
|
||||||
|
|
||||||
|
## Docker Development Environment
|
||||||
|
The project uses Laravel Sail with Docker Compose:
|
||||||
|
```bash
|
||||||
|
# Start services
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Execute artisan commands in container
|
||||||
|
./vendor/bin/sail artisan [command]
|
||||||
|
|
||||||
|
# Access container shell
|
||||||
|
./vendor/bin/sail shell
|
||||||
|
```
|
||||||
|
|
||||||
|
### Services:
|
||||||
|
- **laravel.test**: Main application (Traefik-enabled with SSL)
|
||||||
|
- **horizon**: Laravel Horizon queue worker
|
||||||
|
- **mysql**: MySQL 8.0 database server
|
||||||
|
- **redis**: Redis cache/session store
|
||||||
|
- **mailpit**: Email testing interface (accessible at mivita-mail.test)
|
||||||
|
|
||||||
|
### Domain Configuration:
|
||||||
|
- Main domain: `mivita.test`
|
||||||
|
- Wildcard subdomain support: `*.mivita.test`
|
||||||
|
- Mail interface: `mivita-mail.test`
|
||||||
|
- Uses Traefik reverse proxy with SSL
|
||||||
|
|
@ -189,8 +189,6 @@ namespace App\Models{
|
||||||
|
|
||||||
namespace App\Models{
|
namespace App\Models{
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $name
|
* @property string|null $name
|
||||||
* @property string $email
|
* @property string $email
|
||||||
|
|
@ -221,6 +219,8 @@ namespace App\Models{
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|Customer whereShoppingUserId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Customer whereShoppingUserId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|Customer whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Customer whereUpdatedAt($value)
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
|
* @property string|null $user_shop_domain
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Customer whereUserShopDomain($value)
|
||||||
*/
|
*/
|
||||||
class Customer extends \Eloquent {}
|
class Customer extends \Eloquent {}
|
||||||
}
|
}
|
||||||
|
|
@ -412,111 +412,6 @@ namespace App\Models{
|
||||||
class DcTag extends \Eloquent {}
|
class DcTag extends \Eloquent {}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace App\Models{
|
|
||||||
/**
|
|
||||||
* DHL Shipment Model
|
|
||||||
*
|
|
||||||
* Represents a DHL shipment for a shopping order, including both outbound and return shipments.
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int $shopping_order_id
|
|
||||||
* @property string|null $shipment_number DHL shipment number
|
|
||||||
* @property string|null $tracking_number DHL tracking number
|
|
||||||
* @property string $type Type: 'outbound' or 'return'
|
|
||||||
* @property int|null $related_shipment_id For returns: reference to original shipment
|
|
||||||
* @property float $weight Package weight in kg
|
|
||||||
* @property int|null $length Package length in cm
|
|
||||||
* @property int|null $width Package width in cm
|
|
||||||
* @property int|null $height Package height in cm
|
|
||||||
* @property string $product_code DHL product code (e.g., V01PAK)
|
|
||||||
* @property array|null $services Additional DHL services
|
|
||||||
* @property string|null $label_path Path to generated label file
|
|
||||||
* @property string $label_format Label format (PDF or ZPL)
|
|
||||||
* @property bool $label_printed Whether label has been printed
|
|
||||||
* @property string $status Shipment status
|
|
||||||
* @property string|null $tracking_status Current tracking status from DHL
|
|
||||||
* @property string|null $tracking_details Detailed tracking information (JSON)
|
|
||||||
* @property Carbon|null $last_tracked_at Last tracking update
|
|
||||||
* @property string $recipient_name Recipient name
|
|
||||||
* @property string|null $recipient_company Recipient company
|
|
||||||
* @property string $recipient_street Recipient street
|
|
||||||
* @property string $recipient_street_number Recipient street number
|
|
||||||
* @property string $recipient_postal_code Recipient postal code
|
|
||||||
* @property string $recipient_city Recipient city
|
|
||||||
* @property string|null $recipient_state Recipient state
|
|
||||||
* @property string $recipient_country Recipient country code
|
|
||||||
* @property string|null $recipient_email Recipient email
|
|
||||||
* @property string|null $recipient_phone Recipient phone
|
|
||||||
* @property array|null $api_request_data API request data for debugging
|
|
||||||
* @property array|null $api_response_data API response data for debugging
|
|
||||||
* @property string|null $api_errors API error messages
|
|
||||||
* @property float|null $shipping_cost Shipping cost
|
|
||||||
* @property string $currency Currency code
|
|
||||||
* @property string|null $notes Internal notes
|
|
||||||
* @property array|null $metadata Additional metadata
|
|
||||||
* @property Carbon|null $shipped_at When the package was shipped
|
|
||||||
* @property Carbon|null $delivered_at When the package was delivered
|
|
||||||
* @property Carbon|null $created_at
|
|
||||||
* @property Carbon|null $updated_at
|
|
||||||
* @property-read ShoppingOrder $shoppingOrder
|
|
||||||
* @property-read DhlShipment|null $relatedShipment
|
|
||||||
* @property-read DhlShipment|null $returnShipment
|
|
||||||
* @property-read string|null $dimensions
|
|
||||||
* @property-read string|null $label_url
|
|
||||||
* @property-read string $recipient_address
|
|
||||||
* @property-read string $status_label
|
|
||||||
* @property-read string $type_label
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment active()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment outbound()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment returns()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment trackable()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereApiErrors($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereApiRequestData($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereApiResponseData($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereCurrency($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereDeliveredAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereHeight($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereLabelFormat($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereLabelPath($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereLabelPrinted($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereLastTrackedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereLength($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereMetadata($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereNotes($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereProductCode($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientCity($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientCompany($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientCountry($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientEmail($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientPhone($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientPostalCode($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientState($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientStreet($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRecipientStreetNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereRelatedShipmentId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereServices($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereShipmentNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereShippedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereShippingCost($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereShoppingOrderId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereStatus($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereTrackingDetails($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereTrackingNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereTrackingStatus($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereType($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereWeight($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|DhlShipment whereWidth($value)
|
|
||||||
*/
|
|
||||||
class DhlShipment extends \Eloquent {}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace App\Models{
|
namespace App\Models{
|
||||||
/**
|
/**
|
||||||
* Class File
|
* Class File
|
||||||
|
|
@ -1614,13 +1509,13 @@ namespace App\Models{
|
||||||
* @property int|null $abo_interval
|
* @property int|null $abo_interval
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereAboInterval($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereAboInterval($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereIsAbo($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereIsAbo($value)
|
||||||
* @mixin \Eloquent
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlOutboundShipments
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlOutboundShipments
|
|
||||||
* @property-read int|null $dhl_outbound_shipments_count
|
* @property-read int|null $dhl_outbound_shipments_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlReturnShipments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlReturnShipments
|
||||||
* @property-read int|null $dhl_return_shipments_count
|
* @property-read int|null $dhl_return_shipments_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlShipments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlShipments
|
||||||
* @property-read int|null $dhl_shipments_count
|
* @property-read int|null $dhl_shipments_count
|
||||||
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class ShoppingOrder extends \Eloquent {}
|
class ShoppingOrder extends \Eloquent {}
|
||||||
}
|
}
|
||||||
|
|
@ -3100,9 +2995,9 @@ namespace App{
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User wherePreSponsor($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User wherePreSponsor($value)
|
||||||
* @property \Illuminate\Support\Carbon|null $pre_deleted_at
|
* @property \Illuminate\Support\Carbon|null $pre_deleted_at
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder<static>|User wherePreDeletedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|User wherePreDeletedAt($value)
|
||||||
* @mixin \Eloquent
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\UserBusiness> $userBusiness
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\UserBusiness> $userBusiness
|
||||||
* @property-read int|null $user_business_count
|
* @property-read int|null $user_business_count
|
||||||
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class User extends \Eloquent {}
|
class User extends \Eloquent {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
136
app/Console/Commands/BusinessClearData.php
Normal file
136
app/Console/Commands/BusinessClearData.php
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\UserBusinessStructure;
|
||||||
|
use App\Models\UserBusiness;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class BusinessClearData extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* php artisan business:clear-data {month} {year}
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'business:clear-data {month} {year} {--force : Force deletion without confirmation}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Clear stored business structure data for a specific month/year';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$month = (int) $this->argument('month');
|
||||||
|
$year = (int) $this->argument('year');
|
||||||
|
|
||||||
|
// Validierung
|
||||||
|
if ($month < 1 || $month > 12) {
|
||||||
|
$this->error('Invalid month. Must be between 1 and 12.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentYear = (int) date('Y');
|
||||||
|
if ($year < 2020 || $year > $currentYear + 1) {
|
||||||
|
$this->error('Invalid year. Must be between 2020 and ' . ($currentYear + 1));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Preparing to clear business data for month: {$month} | year: {$year}");
|
||||||
|
|
||||||
|
// Finde bestehende Struktur
|
||||||
|
$existingStructure = UserBusinessStructure::where('year', $year)
|
||||||
|
->where('month', $month)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$existingStructure) {
|
||||||
|
$this->info('No stored business structure found for the specified month/year');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$structureId = $existingStructure->id;
|
||||||
|
$userBusinessCount = UserBusiness::where('b_structure_id', $structureId)->count();
|
||||||
|
$userCount = is_array($existingStructure->users) ? count($existingStructure->users) : 0;
|
||||||
|
|
||||||
|
$this->info("Found structure ID: {$structureId}");
|
||||||
|
$this->info("- UserBusiness records: {$userBusinessCount}");
|
||||||
|
$this->info("- Users in structure: {$userCount}");
|
||||||
|
$this->info("- Completed: " . ($existingStructure->completed ? 'Yes' : 'No'));
|
||||||
|
|
||||||
|
// Bestätigung (außer bei --force)
|
||||||
|
if (!$this->option('force')) {
|
||||||
|
if (!$this->confirm('Are you sure you want to delete this business structure data?')) {
|
||||||
|
$this->info('Operation cancelled by user');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$startTime = microtime(true);
|
||||||
|
|
||||||
|
// Lösche UserBusiness Einträge
|
||||||
|
if ($userBusinessCount > 0) {
|
||||||
|
$this->info("Deleting {$userBusinessCount} UserBusiness records...");
|
||||||
|
UserBusiness::where('b_structure_id', $structureId)->delete();
|
||||||
|
$this->info('✓ UserBusiness records deleted');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lösche UserBusinessStructure
|
||||||
|
$this->info('Deleting UserBusinessStructure...');
|
||||||
|
$existingStructure->delete();
|
||||||
|
$this->info('✓ UserBusinessStructure deleted');
|
||||||
|
|
||||||
|
// Garbage Collection
|
||||||
|
gc_collect_cycles();
|
||||||
|
|
||||||
|
$endTime = microtime(true);
|
||||||
|
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||||
|
|
||||||
|
$this->info("✅ Successfully cleared all business data in {$duration}ms");
|
||||||
|
$this->logMemoryUsage();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error clearing business data: ' . $e->getMessage());
|
||||||
|
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loggt aktuelle Memory-Nutzung
|
||||||
|
*/
|
||||||
|
private function logMemoryUsage(): void
|
||||||
|
{
|
||||||
|
$currentMemory = memory_get_usage();
|
||||||
|
$peakMemory = memory_get_peak_usage();
|
||||||
|
|
||||||
|
$currentFormatted = $this->formatBytes($currentMemory);
|
||||||
|
$peakFormatted = $this->formatBytes($peakMemory);
|
||||||
|
|
||||||
|
$this->info("Memory - Current: {$currentFormatted} | Peak: {$peakFormatted}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatiert Bytes in lesbare Einheiten
|
||||||
|
*/
|
||||||
|
private function formatBytes(int $bytes, int $precision = 2): string
|
||||||
|
{
|
||||||
|
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||||
|
|
||||||
|
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||||
|
$bytes /= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return round($bytes, $precision) . ' ' . $units[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
149
app/Console/Commands/BusinessLevelReports.php
Normal file
149
app/Console/Commands/BusinessLevelReports.php
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Services\LevelReportService;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class BusinessLevelReports extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'business:level-reports {--month= : Filter by specific month} {--year= : Filter by specific year} {--user-id= : Filter by specific user ID} {--csv : Export as CSV file} {--not-updated : Show only users not yet updated to their new level}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Generate reports showing who achieved new career levels and when';
|
||||||
|
|
||||||
|
private $levelReportService;
|
||||||
|
|
||||||
|
public function __construct(LevelReportService $levelReportService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->levelReportService = $levelReportService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->info('Generiere Level-Aufstieg-Report...');
|
||||||
|
|
||||||
|
// Filter Parameter
|
||||||
|
$filters = [
|
||||||
|
'month' => $this->option('month'),
|
||||||
|
'year' => $this->option('year'),
|
||||||
|
'user_id' => $this->option('user-id'),
|
||||||
|
'only_not_updated' => $this->option('not-updated')
|
||||||
|
];
|
||||||
|
|
||||||
|
$exportCsv = $this->option('csv');
|
||||||
|
|
||||||
|
// Lade Level-Aufstiege über Service
|
||||||
|
$levelPromotions = $this->levelReportService->getLevelPromotions($filters);
|
||||||
|
|
||||||
|
if ($levelPromotions->isEmpty()) {
|
||||||
|
$this->info('Keine Level-Aufstiege gefunden.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exportCsv) {
|
||||||
|
$filepath = $this->levelReportService->exportToCsv($levelPromotions);
|
||||||
|
$this->info('');
|
||||||
|
$this->info('CSV-Export erstellt: ' . $filepath);
|
||||||
|
$this->info('Anzahl Datensätze: ' . $levelPromotions->count());
|
||||||
|
} else {
|
||||||
|
$this->displayReport($levelPromotions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Report erfolgreich generiert.');
|
||||||
|
return 0;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Fehler beim Generieren des Reports: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function displayReport($promotions)
|
||||||
|
{
|
||||||
|
$statistics = $this->levelReportService->getStatistics($promotions);
|
||||||
|
|
||||||
|
$this->info('');
|
||||||
|
$this->info('=== LEVEL-AUFSTIEG REPORT ===');
|
||||||
|
$this->info('');
|
||||||
|
|
||||||
|
if ($promotions->isEmpty()) {
|
||||||
|
$this->info('Keine Level-Aufstiege gefunden.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Datum',
|
||||||
|
'User ID',
|
||||||
|
'Name',
|
||||||
|
'E-Mail',
|
||||||
|
'Von Level',
|
||||||
|
'Zu Level',
|
||||||
|
'Aktueller Level',
|
||||||
|
'Margin',
|
||||||
|
'KP Req',
|
||||||
|
'PP Req',
|
||||||
|
'Growth Bonus',
|
||||||
|
'User PP',
|
||||||
|
'User KP',
|
||||||
|
'Level Update',
|
||||||
|
'Aktiv'
|
||||||
|
];
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
foreach ($promotions->toArray() as $promotion) {
|
||||||
|
$rows[] = [
|
||||||
|
$promotion['date'],
|
||||||
|
$promotion['user_id'],
|
||||||
|
$promotion['first_name'] . ' ' . $promotion['last_name'],
|
||||||
|
$promotion['email'],
|
||||||
|
$promotion['from_level_name'] . ' (ID:' . $promotion['from_level_id'] . ')',
|
||||||
|
$promotion['to_level_name'] . ' (ID:' . $promotion['to_level_id'] . ')',
|
||||||
|
$promotion['current_user_level_name'] . ' (ID:' . ($promotion['current_user_level_id'] ?? 'N/A') . ')',
|
||||||
|
$promotion['to_level_margin'] . '%',
|
||||||
|
number_format($promotion['to_level_qual_kp'], 0, ',', '.'),
|
||||||
|
number_format($promotion['to_level_qual_pp'], 0, ',', '.'),
|
||||||
|
$promotion['to_level_growth_bonus'] . '%',
|
||||||
|
number_format($promotion['total_pp'], 0, ',', '.'),
|
||||||
|
number_format($promotion['sales_volume_points_sum'], 0, ',', '.'),
|
||||||
|
$promotion['level_updated'],
|
||||||
|
$promotion['active_account'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->table($headers, $rows);
|
||||||
|
|
||||||
|
// Zusammenfassung
|
||||||
|
$this->info('');
|
||||||
|
$this->info('=== ZUSAMMENFASSUNG ===');
|
||||||
|
$this->info('Anzahl Level-Aufstiege: ' . $statistics['total_count']);
|
||||||
|
|
||||||
|
$this->info('');
|
||||||
|
$this->info('Aufstiege nach Ziel-Level:');
|
||||||
|
foreach ($statistics['level_stats'] as $level => $count) {
|
||||||
|
$this->info(" - {$level}: {$count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('');
|
||||||
|
$this->info('Aufstiege nach Zeitraum:');
|
||||||
|
foreach ($statistics['period_stats'] as $period => $count) {
|
||||||
|
$this->info(" - {$period}: {$count}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ class BusinessStore extends Command
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $description = 'Create Business Structur and UserDetails';
|
protected $description = 'Create Business Structure and UserDetails with optimized performance';
|
||||||
|
|
||||||
private $timeStart;
|
private $timeStart;
|
||||||
private $month;
|
private $month;
|
||||||
|
|
@ -52,15 +52,19 @@ class BusinessStore extends Command
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
||||||
$presentDay = (int) date('d');
|
$presentDay = (int) date('d');
|
||||||
|
|
||||||
$this->info('RUN Command BusinessStore on Day: '. $executeDay);
|
$this->info('RUN Command BusinessStore on Day: ' . $executeDay);
|
||||||
$this->info('RUN Command BusinessStore present Day: '. $presentDay);
|
$this->info('RUN Command BusinessStore present Day: ' . $presentDay);
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStore on Day: ' . $executeDay);
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStore present Day: ' . $presentDay);
|
||||||
|
$this->logMemoryUsage('Command Start');
|
||||||
|
|
||||||
if($executeDay !== $presentDay){
|
if ($executeDay !== $presentDay) {
|
||||||
$this->info('NOT RUN Command BusinessStore is not present Day: '. $presentDay);
|
$this->info('NOT RUN Command BusinessStore is not present Day: ' . $presentDay);
|
||||||
|
\Log::channel('cron')->info('NOT RUN Command BusinessStore is not present Day: ' . $presentDay);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,93 +74,109 @@ class BusinessStore extends Command
|
||||||
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
||||||
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
||||||
|
|
||||||
$this->info('RUN Command BusinessStore on month: '.$this->month.' | year: '.$this->year);
|
$this->info('RUN Command BusinessStore on month: ' . $this->month . ' | year: ' . $this->year);
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStore on month: ' . $this->month . ' | year: ' . $this->year);
|
||||||
|
$this->logMemoryUsage('Parameters initialized');
|
||||||
|
|
||||||
// Prozesse ausführen
|
// Prozesse ausführen mit Fehlerbehandlung
|
||||||
|
$this->executeWithErrorHandling('Business Structure Storage', function () {
|
||||||
$this->storeBusinessStructureUsersDetailMonth();
|
$this->storeBusinessStructureUsersDetailMonth();
|
||||||
$this->userBusinessCommissionsToCredit();
|
});
|
||||||
|
|
||||||
// Auskommentierte Prozesse
|
$this->executeWithErrorHandling('Commission Calculation', function () {
|
||||||
|
$this->userBusinessCommissionsToCredit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auskommentierte Prozesse bleiben inaktiv
|
||||||
// $this->userCreatePaymentCreditsPDF();
|
// $this->userCreatePaymentCreditsPDF();
|
||||||
// $this->userLevelUpdate();
|
// $this->userLevelUpdate();
|
||||||
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
||||||
|
|
||||||
|
$this->logExecutionTime('COMMAND COMPLETED SUCCESSFULLY');
|
||||||
|
$this->logMemoryUsage('Command End');
|
||||||
|
\Log::channel('cron')->info('COMMAND COMPLETED SUCCESSFULLY');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Command failed with error: ' . $e->getMessage());
|
||||||
|
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||||
|
$this->logExecutionTime('COMMAND FAILED');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function storeBusinessStructureUsersDetailMonth(){
|
private function storeBusinessStructureUsersDetailMonth()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('storeBusinessStructureUsersDetailMonth month: '.$this->month.' year:'.$this->year);
|
$this->info('storeBusinessStructureUsersDetailMonth month: ' . $this->month . ' year:' . $this->year);
|
||||||
$businessUsersStore = new BusinessUsersStore($this->month, $this->year);
|
$businessUsersStore = new BusinessUsersStore($this->month, $this->year);
|
||||||
$businessUsersStore->storeUserBusinessStructure();
|
$businessUsersStore->storeUserBusinessStructure();
|
||||||
$businessUsersStore->storeBusinessUsersDetail();
|
$businessUsersStore->storeBusinessUsersDetail();
|
||||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||||
|
|
||||||
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: '.$bool);
|
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: ' . $bool);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function userBusinessCommissionsToCredit(){
|
private function userBusinessCommissionsToCredit()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('userBusinessCommissionsToCredit month: '.$this->month.' year:'.$this->year);
|
$this->info('userBusinessCommissionsToCredit month: ' . $this->month . ' year:' . $this->year);
|
||||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||||
$userBusinesses = $userPaymentCredits->getUserBusinessByMonthYear();
|
$userBusinesses = $userPaymentCredits->getUserBusinessByMonthYear();
|
||||||
|
|
||||||
foreach($userBusinesses as $userBusiness){
|
foreach ($userBusinesses as $userBusiness) {
|
||||||
$ret = $userPaymentCredits->addUserCreditItem($userBusiness);
|
$ret = $userPaymentCredits->addUserCreditItem($userBusiness);
|
||||||
$this->info('userBusinessCredit: '.$ret->user_id.' : Team: '.$ret->commission_pp_total.' | Shop: '.$ret->commission_shop_sales);
|
$this->info('userBusinessCredit: ' . $ret->user_id . ' : Team: ' . $ret->commission_pp_total . ' | Shop: ' . $ret->commission_shop_sales);
|
||||||
}
|
}
|
||||||
$this->logExecutionTime('END Command userBusinessCommissionsToCredit:');
|
$this->logExecutionTime('END Command userBusinessCommissionsToCredit:');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function userCreatePaymentCreditsPDF(){
|
private function userCreatePaymentCreditsPDF()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('userCreatePaymentCreditsPDF month: '.$this->month.' year:'.$this->year);
|
$this->info('userCreatePaymentCreditsPDF month: ' . $this->month . ' year:' . $this->year);
|
||||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||||
$creditItemUsers = $userPaymentCredits->getUserCreditItemUsersByMonthYear();
|
$creditItemUsers = $userPaymentCredits->getUserCreditItemUsersByMonthYear();
|
||||||
|
|
||||||
foreach($creditItemUsers as $creditItemUser){
|
foreach ($creditItemUsers as $creditItemUser) {
|
||||||
$bool = $userPaymentCredits->makeCreditPaymentPDF($creditItemUser->user_id, $this->sendCreditMail);
|
$bool = $userPaymentCredits->makeCreditPaymentPDF($creditItemUser->user_id, $this->sendCreditMail);
|
||||||
$this->info('creditsPDF: '.$bool.' user_id: '.$creditItemUser->user_id);
|
$this->info('creditsPDF: ' . $bool . ' user_id: ' . $creditItemUser->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function userLevelUpdate(){
|
private function userLevelUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('userLevelUpdate month: '.$this->month.' year:'.$this->year);
|
$this->info('userLevelUpdate month: ' . $this->month . ' year:' . $this->year);
|
||||||
|
|
||||||
$userLevelUpdate = new UserLevelUpdate($this->month, $this->year);
|
$userLevelUpdate = new UserLevelUpdate($this->month, $this->year);
|
||||||
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
|
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
|
||||||
|
|
||||||
foreach($levelUpdateUsers as $userBusiness){
|
foreach ($levelUpdateUsers as $userBusiness) {
|
||||||
$ret = $userLevelUpdate->makeUserLevelUpdate($userBusiness, $this->sendUpdateMail);
|
$ret = $userLevelUpdate->makeUserLevelUpdate($userBusiness, $this->sendUpdateMail);
|
||||||
if($ret){
|
if ($ret) {
|
||||||
$this->info('updateLevel: '.$userBusiness->user->id.' | '.$userBusiness->user->email.' | '.
|
$this->info('updateLevel: ' . $userBusiness->user->id . ' | ' . $userBusiness->user->email . ' | ' .
|
||||||
'from: '.$userBusiness->m_level_id.' '.$userBusiness->user_level_name.' | '.
|
'from: ' . $userBusiness->m_level_id . ' ' . $userBusiness->user_level_name . ' | ' .
|
||||||
'to: '.$ret);
|
'to: ' . $ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
$this->logExecutionTime('END Command userLevelUpdate:');
|
$this->logExecutionTime('END Command userLevelUpdate:');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
||||||
{
|
{
|
||||||
for($i = $from; $i <= $to; $i++){
|
for ($i = $from; $i <= $to; $i++) {
|
||||||
$this->info('Store Business Structure Users Detail month: '.$i.' year:'.$this->year);
|
$this->info('Store Business Structure Users Detail month: ' . $i . ' year:' . $this->year);
|
||||||
$businessUsersStore = new BusinessUsersStore($i, $this->year);
|
$businessUsersStore = new BusinessUsersStore($i, $this->year);
|
||||||
$businessUsersStore->storeUserBusinessStructure();
|
$businessUsersStore->storeUserBusinessStructure();
|
||||||
$businessUsersStore->storeBusinessUsersDetail();
|
$businessUsersStore->storeBusinessUsersDetail();
|
||||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||||
|
|
||||||
$this->logExecutionTime('Period BusinessStore: '.$bool);
|
$this->logExecutionTime('Period BusinessStore: ' . $bool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +186,6 @@ class BusinessStore extends Command
|
||||||
$sec = intval($diff);
|
$sec = intval($diff);
|
||||||
$micro = $diff - $sec;
|
$micro = $diff - $sec;
|
||||||
|
|
||||||
$this->info($message. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
$this->info($message . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
368
app/Console/Commands/BusinessStoreOptimized.php
Normal file
368
app/Console/Commands/BusinessStoreOptimized.php
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\UserBusinessStructure;
|
||||||
|
use App\Models\UserBusiness;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Cron\BusinessUsersStoreOptimized;
|
||||||
|
use App\Cron\UserLevelUpdate;
|
||||||
|
use App\Cron\UserPaymentCredits;
|
||||||
|
|
||||||
|
class BusinessStoreOptimized extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ln -sfv /usr/bin/php73 /usr/bin/php
|
||||||
|
* php artisan business:store-optimized month year
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'business:store-optimized {month} {year} {--clear : Clear stored data before processing}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Create Business Structure and UserDetails with optimized performance and monitoring';
|
||||||
|
|
||||||
|
private $timeStart;
|
||||||
|
private $month;
|
||||||
|
private $year;
|
||||||
|
|
||||||
|
private $sendCreditMail = false;
|
||||||
|
private $sendUpdateMail = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
||||||
|
$presentDay = (int) date('d');
|
||||||
|
|
||||||
|
$this->info('RUN Command BusinessStoreOptimized on Day: ' . $executeDay);
|
||||||
|
$this->info('RUN Command BusinessStoreOptimized present Day: ' . $presentDay);
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized on Day: ' . $executeDay);
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized present Day: ' . $presentDay);
|
||||||
|
$this->logMemoryUsage('Command Start');
|
||||||
|
|
||||||
|
if ($executeDay !== $presentDay) {
|
||||||
|
$this->info('NOT RUN Command BusinessStoreOptimized is not present Day: ' . $presentDay);
|
||||||
|
\Log::channel('cron')->info('NOT RUN Command BusinessStoreOptimized is not present Day: ' . $presentDay);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->timeStart = microtime(true);
|
||||||
|
|
||||||
|
// Argumente mit Standardwerten für den Vormonat
|
||||||
|
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
||||||
|
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
||||||
|
|
||||||
|
$this->info('RUN Command BusinessStoreOptimized on month: ' . $this->month . ' | year: ' . $this->year);
|
||||||
|
$this->logMemoryUsage('Parameters initialized');
|
||||||
|
|
||||||
|
// Prüfe --clear Option und lösche gespeicherte Daten falls gewünscht
|
||||||
|
if ($this->option('clear')) {
|
||||||
|
$this->executeWithErrorHandling('Clear Stored Data', function () {
|
||||||
|
$this->clearStoredData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prozesse ausführen mit optimierter Fehlerbehandlung
|
||||||
|
$this->executeWithErrorHandling('Business Structure Storage', function () {
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized Business Structure Storage');
|
||||||
|
$this->storeBusinessStructureUsersDetailMonth();
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->executeWithErrorHandling('Commission Calculation', function () {
|
||||||
|
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized Commission Calculation');
|
||||||
|
$this->userBusinessCommissionsToCredit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auskommentierte Prozesse bleiben inaktiv
|
||||||
|
// $this->userCreatePaymentCreditsPDF();
|
||||||
|
// $this->userLevelUpdate();
|
||||||
|
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
||||||
|
|
||||||
|
$this->logExecutionTime('COMMAND COMPLETED SUCCESSFULLY');
|
||||||
|
$this->logMemoryUsage('Command End');
|
||||||
|
\Log::channel('cron')->info('COMMAND COMPLETED SUCCESSFULLY');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Command failed with error: ' . $e->getMessage());
|
||||||
|
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||||
|
$this->logExecutionTime('COMMAND FAILED');
|
||||||
|
\Log::channel('cron')->info('COMMAND FAILED');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function storeBusinessStructureUsersDetailMonth()
|
||||||
|
{
|
||||||
|
$this->info('storeBusinessStructureUsersDetailMonth month: ' . $this->month . ' year:' . $this->year);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$businessUsersStore = new BusinessUsersStoreOptimized($this->month, $this->year);
|
||||||
|
$businessUsersStore->storeUserBusinessStructure();
|
||||||
|
$businessUsersStore->storeBusinessUsersDetail();
|
||||||
|
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||||
|
|
||||||
|
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: ' . $bool);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error in storeBusinessStructureUsersDetailMonth: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function userBusinessCommissionsToCredit()
|
||||||
|
{
|
||||||
|
$this->info('userBusinessCommissionsToCredit month: ' . $this->month . ' year:' . $this->year);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||||
|
$userBusinesses = $userPaymentCredits->getUserBusinessByMonthYear();
|
||||||
|
|
||||||
|
$processedCount = 0;
|
||||||
|
foreach ($userBusinesses as $userBusiness) {
|
||||||
|
$ret = $userPaymentCredits->addUserCreditItem($userBusiness);
|
||||||
|
$this->info('userBusinessCredit: ' . $ret->user_id . ' : Team: ' . $ret->commission_pp_total . ' | Shop: ' . $ret->commission_shop_sales);
|
||||||
|
$processedCount++;
|
||||||
|
|
||||||
|
// Memory-Check alle 100 User
|
||||||
|
if ($processedCount % 100 === 0) {
|
||||||
|
$this->logMemoryUsage("After processing {$processedCount} users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Processed {$processedCount} user businesses total");
|
||||||
|
$this->logExecutionTime('END Command userBusinessCommissionsToCredit:');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error in userBusinessCommissionsToCredit: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function userCreatePaymentCreditsPDF()
|
||||||
|
{
|
||||||
|
$this->info('userCreatePaymentCreditsPDF month: ' . $this->month . ' year:' . $this->year);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||||
|
$creditItemUsers = $userPaymentCredits->getUserCreditItemUsersByMonthYear();
|
||||||
|
|
||||||
|
$processedCount = 0;
|
||||||
|
foreach ($creditItemUsers as $creditItemUser) {
|
||||||
|
$bool = $userPaymentCredits->makeCreditPaymentPDF($creditItemUser->user_id, $this->sendCreditMail);
|
||||||
|
$this->info('creditsPDF: ' . $bool . ' user_id: ' . $creditItemUser->user_id);
|
||||||
|
$processedCount++;
|
||||||
|
|
||||||
|
// Memory-Check alle 50 PDFs
|
||||||
|
if ($processedCount % 50 === 0) {
|
||||||
|
$this->logMemoryUsage("After processing {$processedCount} PDFs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Created {$processedCount} PDF files total");
|
||||||
|
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error in userCreatePaymentCreditsPDF: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function userLevelUpdate()
|
||||||
|
{
|
||||||
|
$this->info('userLevelUpdate month: ' . $this->month . ' year:' . $this->year);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userLevelUpdate = new UserLevelUpdate($this->month, $this->year);
|
||||||
|
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
|
||||||
|
|
||||||
|
$updatedCount = 0;
|
||||||
|
foreach ($levelUpdateUsers as $userBusiness) {
|
||||||
|
$ret = $userLevelUpdate->makeUserLevelUpdate($userBusiness, $this->sendUpdateMail);
|
||||||
|
if ($ret) {
|
||||||
|
$this->info('updateLevel: ' . $userBusiness->user->id . ' | ' . $userBusiness->user->email . ' | ' .
|
||||||
|
'from: ' . $userBusiness->m_level_id . ' ' . $userBusiness->user_level_name . ' | ' .
|
||||||
|
'to: ' . $ret);
|
||||||
|
$updatedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Updated {$updatedCount} user levels total");
|
||||||
|
$this->logExecutionTime('END Command userLevelUpdate:');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error in userLevelUpdate: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
for ($i = $from; $i <= $to; $i++) {
|
||||||
|
$this->info('Store Business Structure Users Detail month: ' . $i . ' year:' . $this->year);
|
||||||
|
$this->logMemoryUsage("Before month {$i}");
|
||||||
|
|
||||||
|
$businessUsersStore = new BusinessUsersStoreOptimized($i, $this->year);
|
||||||
|
$businessUsersStore->storeUserBusinessStructure();
|
||||||
|
$businessUsersStore->storeBusinessUsersDetail();
|
||||||
|
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||||
|
|
||||||
|
$this->logExecutionTime('Period BusinessStore: ' . $bool);
|
||||||
|
$this->logMemoryUsage("After month {$i}");
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error in storeBusinessStructureUsersDetailPeriod: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht gespeicherte Business Structure Daten für den angegebenen Monat/Jahr
|
||||||
|
*/
|
||||||
|
private function clearStoredData()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->info("Clearing stored business data for month: {$this->month} | year: {$this->year}");
|
||||||
|
|
||||||
|
// Finde bestehende UserBusinessStructure
|
||||||
|
$existingStructure = UserBusinessStructure::where('year', $this->year)
|
||||||
|
->where('month', $this->month)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$existingStructure) {
|
||||||
|
$this->info('No stored business structure found to clear');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$structureId = $existingStructure->id;
|
||||||
|
$this->info("Found existing structure with ID: {$structureId}");
|
||||||
|
|
||||||
|
// Lösche zugehörige UserBusiness Einträge
|
||||||
|
$deletedUserBusinesses = UserBusiness::where('b_structure_id', $structureId)->count();
|
||||||
|
if ($deletedUserBusinesses > 0) {
|
||||||
|
UserBusiness::where('b_structure_id', $structureId)->delete();
|
||||||
|
$this->info("Deleted {$deletedUserBusinesses} UserBusiness records");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lösche die UserBusinessStructure
|
||||||
|
$existingStructure->delete();
|
||||||
|
$this->info("Deleted UserBusinessStructure with ID: {$structureId}");
|
||||||
|
|
||||||
|
// Garbage Collection nach dem Löschen
|
||||||
|
gc_collect_cycles();
|
||||||
|
|
||||||
|
$this->info('Successfully cleared all stored business data');
|
||||||
|
$this->logMemoryUsage('After clearing data');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error clearing stored data: ' . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function logExecutionTime($message)
|
||||||
|
{
|
||||||
|
$diff = microtime(true) - $this->timeStart;
|
||||||
|
$sec = intval($diff);
|
||||||
|
$micro = $diff - $sec;
|
||||||
|
|
||||||
|
$this->info($message . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Führt eine Funktion mit Fehlerbehandlung aus
|
||||||
|
*/
|
||||||
|
private function executeWithErrorHandling(string $processName, callable $callback): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$startTime = microtime(true);
|
||||||
|
$this->info("Starting: {$processName}");
|
||||||
|
$this->logMemoryUsage("Before {$processName}");
|
||||||
|
|
||||||
|
$callback();
|
||||||
|
|
||||||
|
$endTime = microtime(true);
|
||||||
|
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||||
|
$this->info("Completed: {$processName} in {$duration}ms");
|
||||||
|
$this->logMemoryUsage("After {$processName}");
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error("Error in {$processName}: " . $e->getMessage());
|
||||||
|
$this->error("Stack trace: " . $e->getTraceAsString());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loggt aktuelle Memory-Nutzung
|
||||||
|
*/
|
||||||
|
private function logMemoryUsage(string $checkpoint): void
|
||||||
|
{
|
||||||
|
$currentMemory = memory_get_usage();
|
||||||
|
$peakMemory = memory_get_peak_usage();
|
||||||
|
$memoryLimit = $this->parseMemoryLimit(ini_get('memory_limit'));
|
||||||
|
|
||||||
|
$currentFormatted = $this->formatBytes($currentMemory);
|
||||||
|
$peakFormatted = $this->formatBytes($peakMemory);
|
||||||
|
$limitFormatted = $this->formatBytes($memoryLimit);
|
||||||
|
$usagePercent = round(($currentMemory / $memoryLimit) * 100, 2);
|
||||||
|
|
||||||
|
$this->info("[{$checkpoint}] Memory: {$currentFormatted} / {$limitFormatted} ({$usagePercent}%) | Peak: {$peakFormatted}");
|
||||||
|
|
||||||
|
if ($usagePercent > 80) {
|
||||||
|
$this->warn("High memory usage detected at {$checkpoint}: {$usagePercent}%");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konvertiert Memory-Limit String zu Bytes
|
||||||
|
*/
|
||||||
|
private function parseMemoryLimit(string $limit): int
|
||||||
|
{
|
||||||
|
$limit = trim($limit);
|
||||||
|
$last = strtolower($limit[strlen($limit) - 1]);
|
||||||
|
$number = (int) $limit;
|
||||||
|
|
||||||
|
switch ($last) {
|
||||||
|
case 'g':
|
||||||
|
$number *= 1024;
|
||||||
|
case 'm':
|
||||||
|
$number *= 1024;
|
||||||
|
case 'k':
|
||||||
|
$number *= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatiert Bytes in lesbare Einheiten
|
||||||
|
*/
|
||||||
|
private function formatBytes(int $bytes, int $precision = 2): string
|
||||||
|
{
|
||||||
|
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||||
|
|
||||||
|
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||||
|
$bytes /= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return round($bytes, $precision) . ' ' . $units[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
182
app/Console/Commands/BusinessTestAccount.php
Normal file
182
app/Console/Commands/BusinessTestAccount.php
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\User;
|
||||||
|
use App\Models\UserBusiness;
|
||||||
|
use App\Services\BusinessPlan\BusinessUserItemOptimized;
|
||||||
|
use App\Cron\UserPaymentCredits;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class BusinessTestAccount extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* php artisan business:test-account {user_id} {month} {year}
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'business:test-account {user_id} {month} {year} {--commissions : Calculate and show user commissions}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Test account data loading for a specific user in business calculations, with optional commission calculation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$userId = (int) $this->argument('user_id');
|
||||||
|
$month = (int) $this->argument('month');
|
||||||
|
$year = (int) $this->argument('year');
|
||||||
|
|
||||||
|
$this->info("Testing account data for User ID: {$userId}, Month: {$month}, Year: {$year}");
|
||||||
|
$this->line('');
|
||||||
|
|
||||||
|
// Lade User mit Account
|
||||||
|
$user = User::with('account', 'user_level')->find($userId);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$this->error("User {$userId} not found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("User found: {$user->email}");
|
||||||
|
$this->info("Account ID: " . ($user->account_id ?? 'NULL'));
|
||||||
|
|
||||||
|
if ($user->account) {
|
||||||
|
$this->info("Account loaded: YES");
|
||||||
|
$this->info("Account m_account: " . ($user->account->m_account ?? 'NULL'));
|
||||||
|
$this->info("Account first_name: " . ($user->account->first_name ?? 'NULL'));
|
||||||
|
$this->info("Account last_name: " . ($user->account->last_name ?? 'NULL'));
|
||||||
|
$this->info("Account birthday: " . ($user->account->birthday ?? 'NULL'));
|
||||||
|
$this->info("Account phone: " . ($user->account->getPhoneNumber() ?? 'NULL'));
|
||||||
|
} else {
|
||||||
|
$this->warn("Account loaded: NO");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Testing BusinessUserItemOptimized...');
|
||||||
|
|
||||||
|
// Erstelle Date Object
|
||||||
|
$date = new stdClass();
|
||||||
|
$date->month = $month;
|
||||||
|
$date->year = $year;
|
||||||
|
$date->start_date = "{$year}-{$month}-01 00:00:00";
|
||||||
|
$date->end_date = date('Y-m-t 23:59:59', strtotime("{$year}-{$month}-01"));
|
||||||
|
|
||||||
|
// Teste BusinessUserItemOptimized
|
||||||
|
$businessUserItem = new BusinessUserItemOptimized($date);
|
||||||
|
$businessUserItem->makeUserFromModel($user, true);
|
||||||
|
|
||||||
|
$bUser = $businessUserItem->getBUser();
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Results from BusinessUserItemOptimized:');
|
||||||
|
$this->info("m_account: " . ($bUser->m_account ?? 'NULL'));
|
||||||
|
$this->info("first_name: " . ($bUser->first_name ?? 'NULL'));
|
||||||
|
$this->info("last_name: " . ($bUser->last_name ?? 'NULL'));
|
||||||
|
$this->info("user_birthday: " . ($bUser->user_birthday ?? 'NULL'));
|
||||||
|
$this->info("user_phone: " . ($bUser->user_phone ?? 'NULL'));
|
||||||
|
$this->info("email: " . ($bUser->email ?? 'NULL'));
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Sales Volume Fields:');
|
||||||
|
$this->info("sales_volume_KP_points: " . ($bUser->sales_volume_KP_points ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_TP_points: " . ($bUser->sales_volume_TP_points ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_points_shop: " . ($bUser->sales_volume_points_shop ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_points_KP_sum: " . ($bUser->sales_volume_points_KP_sum ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_points_TP_sum: " . ($bUser->sales_volume_points_TP_sum ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_total: " . ($bUser->sales_volume_total ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_total_shop: " . ($bUser->sales_volume_total_shop ?? 'NULL'));
|
||||||
|
$this->info("sales_volume_total_sum: " . ($bUser->sales_volume_total_sum ?? 'NULL'));
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Commission Fields:');
|
||||||
|
$this->info("payline_points: " . ($bUser->payline_points ?? 'NULL'));
|
||||||
|
$this->info("commission_pp_total: " . ($bUser->commission_pp_total ?? 'NULL'));
|
||||||
|
$this->info("commission_shop_sales: " . ($bUser->commission_shop_sales ?? 'NULL'));
|
||||||
|
$this->info("commission_growth_total: " . ($bUser->commission_growth_total ?? 'NULL'));
|
||||||
|
|
||||||
|
// Test UserSalesVolume directly
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Testing UserSalesVolume data directly:');
|
||||||
|
$userSalesVolume = $user->getUserSalesVolume($month, $year, 'first');
|
||||||
|
if ($userSalesVolume) {
|
||||||
|
$this->info("UserSalesVolume found: ID {$userSalesVolume->id}");
|
||||||
|
$this->info("month_KP_points: " . ($userSalesVolume->month_KP_points ?? 'NULL'));
|
||||||
|
$this->info("month_TP_points: " . ($userSalesVolume->month_TP_points ?? 'NULL'));
|
||||||
|
$this->info("month_shop_points: " . ($userSalesVolume->month_shop_points ?? 'NULL'));
|
||||||
|
$this->info("month_total_net: " . ($userSalesVolume->month_total_net ?? 'NULL'));
|
||||||
|
$this->info("month_shop_total_net: " . ($userSalesVolume->month_shop_total_net ?? 'NULL'));
|
||||||
|
} else {
|
||||||
|
$this->warn("No UserSalesVolume found for month {$month}/{$year}");
|
||||||
|
|
||||||
|
// Check if any UserSalesVolume exists for this user
|
||||||
|
$anyVolume = \App\Models\UserSalesVolume::where('user_id', $userId)->orderBy('year', 'desc')->orderBy('month', 'desc')->first();
|
||||||
|
if ($anyVolume) {
|
||||||
|
$this->info("Latest UserSalesVolume found: {$anyVolume->month}/{$anyVolume->year}");
|
||||||
|
} else {
|
||||||
|
$this->warn("No UserSalesVolume records found for this user at all");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
|
||||||
|
// Prüfe ob UserBusiness bereits gespeichert ist
|
||||||
|
$existingUserBusiness = UserBusiness::where('user_id', $userId)
|
||||||
|
->where('month', $month)
|
||||||
|
->where('year', $year)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($existingUserBusiness) {
|
||||||
|
$this->info('Existing UserBusiness found:');
|
||||||
|
$this->info("m_account: " . ($existingUserBusiness->m_account ?? 'NULL'));
|
||||||
|
$this->info("first_name: " . ($existingUserBusiness->first_name ?? 'NULL'));
|
||||||
|
$this->info("last_name: " . ($existingUserBusiness->last_name ?? 'NULL'));
|
||||||
|
$this->info("user_birthday: " . ($existingUserBusiness->user_birthday ?? 'NULL'));
|
||||||
|
$this->info("user_phone: " . ($existingUserBusiness->user_phone ?? 'NULL'));
|
||||||
|
$this->info("email: " . ($existingUserBusiness->email ?? 'NULL'));
|
||||||
|
} else {
|
||||||
|
$this->info('No existing UserBusiness found for this period');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('commissions')) {
|
||||||
|
$this->line('');
|
||||||
|
$this->info('Testing UserBusiness Commissions to Credit...');
|
||||||
|
|
||||||
|
if ($existingUserBusiness) {
|
||||||
|
try {
|
||||||
|
$userPaymentCredits = new UserPaymentCredits($month, $year);
|
||||||
|
$ret = $userPaymentCredits->addUserCreditItem($existingUserBusiness);
|
||||||
|
$this->info('UserBusinessCredit calculated:');
|
||||||
|
$this->info('User ID: ' . $ret->user_id);
|
||||||
|
$this->info('Team Commission: ' . $ret->commission_pp_total);
|
||||||
|
$this->info('Shop Commission: ' . $ret->commission_shop_sales);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Error calculating commissions: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->warn('No UserBusiness record found, cannot calculate commissions.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
$this->info('✅ Test completed successfully');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Test failed with error: ' . $e->getMessage());
|
||||||
|
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -46,6 +46,7 @@ class UserCleanUp extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->info('RUN Command user:cleanup');
|
$this->info('RUN Command user:cleanup');
|
||||||
|
\Log::channel('cleanup')->info('COMMAND [user:cleanup] started.');
|
||||||
|
|
||||||
$this->timeStart = microtime(true);
|
$this->timeStart = microtime(true);
|
||||||
|
|
||||||
|
|
@ -55,13 +56,14 @@ class UserCleanUp extends Command
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//\Log::info('Cron is running');
|
\Log::channel('cleanup')->info('COMMAND [user:cleanup] finished.');
|
||||||
//return 0;
|
//return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//gibt es gelöschte Berater mit Kunden und childs???
|
//gibt es gelöschte Berater mit Kunden und childs???
|
||||||
|
|
||||||
private function deleteInavtiveUsers(){
|
private function deleteInavtiveUsers()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('START Command deleteInavtiveUsers');
|
$this->info('START Command deleteInavtiveUsers');
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
@ -69,7 +71,7 @@ class UserCleanUp extends Command
|
||||||
$date = Carbon::now()->modify('-2 month');
|
$date = Carbon::now()->modify('-2 month');
|
||||||
$delete_users = User::where('admin', 0)->where('payment_account', '<', $date)->get();
|
$delete_users = User::where('admin', 0)->where('payment_account', '<', $date)->get();
|
||||||
|
|
||||||
foreach($delete_users as $delete_user){
|
foreach ($delete_users as $delete_user) {
|
||||||
/*
|
/*
|
||||||
dump('delete_users ---------- ');
|
dump('delete_users ---------- ');
|
||||||
dump($delete_user->id);
|
dump($delete_user->id);
|
||||||
|
|
@ -77,12 +79,12 @@ class UserCleanUp extends Command
|
||||||
*/
|
*/
|
||||||
//finde nächsten aktiven Sponsor $delete_user->id kann sponsor oder pre sponsor sein
|
//finde nächsten aktiven Sponsor $delete_user->id kann sponsor oder pre sponsor sein
|
||||||
$active_sponsor = UserUtil::findNextActiveSponsor($delete_user->id);
|
$active_sponsor = UserUtil::findNextActiveSponsor($delete_user->id);
|
||||||
if($active_sponsor){
|
if ($active_sponsor) {
|
||||||
//setze alle Berater vom Sponsor für alle childs
|
//setze alle Berater vom Sponsor für alle childs
|
||||||
UserUtil::setNewSponsorToChilds($delete_user->id, $active_sponsor->id);
|
UserUtil::setNewSponsorToChilds($delete_user->id, $active_sponsor->id);
|
||||||
UserUtil::setShoppingUserToNewMember($delete_user->id, $active_sponsor->id);
|
UserUtil::setShoppingUserToNewMember($delete_user->id, $active_sponsor->id);
|
||||||
}else{
|
} else {
|
||||||
\Log::channel('cleanup')->error('deleteInavtiveUsers find no active_sponsor by delete_user_id:'.$delete_user->id);
|
\Log::channel('cleanup')->error('deleteInavtiveUsers find no active_sponsor by delete_user_id:' . $delete_user->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -99,8 +101,8 @@ class UserCleanUp extends Command
|
||||||
'm_first_name' => $delete_user->account ? $delete_user->account->m_first_name : '',
|
'm_first_name' => $delete_user->account ? $delete_user->account->m_first_name : '',
|
||||||
'm_last_name' => $delete_user->account ? $delete_user->account->m_last_name : '',
|
'm_last_name' => $delete_user->account ? $delete_user->account->m_last_name : '',
|
||||||
];
|
];
|
||||||
$count ++;
|
$count++;
|
||||||
\Log::channel('cleanup')->info('deleteUser: '.json_encode($data));
|
\Log::channel('cleanup')->info('deleteUser: ' . json_encode($data));
|
||||||
UserUtil::deleteUser($delete_user);
|
UserUtil::deleteUser($delete_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,11 +110,11 @@ class UserCleanUp extends Command
|
||||||
$sec = intval($diff);
|
$sec = intval($diff);
|
||||||
$micro = $diff - $sec;
|
$micro = $diff - $sec;
|
||||||
|
|
||||||
$this->info('END Command deleteInavtiveUsers: '.$count. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
$this->info('END Command deleteInavtiveUsers: ' . $count . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function cleanUpInActiveUser(){
|
private function cleanUpInActiveUser()
|
||||||
|
{
|
||||||
|
|
||||||
$this->info('START Command cleanUpInActiveUser');
|
$this->info('START Command cleanUpInActiveUser');
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
@ -121,17 +123,17 @@ class UserCleanUp extends Command
|
||||||
$date = Carbon::now()->modify('-2 weeks');
|
$date = Carbon::now()->modify('-2 weeks');
|
||||||
|
|
||||||
$inactive_users = User::where('active', true)->where('m_sponsor', '!=', null)->where('payment_account', '<', $date)->get();
|
$inactive_users = User::where('active', true)->where('m_sponsor', '!=', null)->where('payment_account', '<', $date)->get();
|
||||||
foreach($inactive_users as $inactive_user){
|
foreach ($inactive_users as $inactive_user) {
|
||||||
/*
|
/*
|
||||||
dump('inactive_user ---------- ');
|
dump('inactive_user ---------- ');
|
||||||
dump($inactive_user->id);
|
dump($inactive_user->id);
|
||||||
dump($inactive_user->email);
|
dump($inactive_user->email);
|
||||||
*/
|
*/
|
||||||
$active_sponsor = UserUtil::findNextActiveSponsor($inactive_user->m_sponsor);
|
$active_sponsor = UserUtil::findNextActiveSponsor($inactive_user->m_sponsor);
|
||||||
if($active_sponsor){
|
if ($active_sponsor) {
|
||||||
UserUtil::setNewSponsorToChilds($inactive_user->id, $active_sponsor->id);
|
UserUtil::setNewSponsorToChilds($inactive_user->id, $active_sponsor->id);
|
||||||
}else{
|
} else {
|
||||||
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:'.$inactive_user->id);
|
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:' . $inactive_user->id);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
dump('findNextActiveSponsor');
|
dump('findNextActiveSponsor');
|
||||||
|
|
@ -144,9 +146,9 @@ class UserCleanUp extends Command
|
||||||
'm_first_name' => $inactive_user->account ? $inactive_user->account->m_first_name : '',
|
'm_first_name' => $inactive_user->account ? $inactive_user->account->m_first_name : '',
|
||||||
'm_last_name' => $inactive_user->account ? $inactive_user->account->m_last_name : '',
|
'm_last_name' => $inactive_user->account ? $inactive_user->account->m_last_name : '',
|
||||||
];
|
];
|
||||||
$count ++;
|
$count++;
|
||||||
|
|
||||||
\Log::channel('cleanup')->info('inactive_user: '.json_encode($data));
|
\Log::channel('cleanup')->info('inactive_user: ' . json_encode($data));
|
||||||
UserUtil::deactiveUser($inactive_user);
|
UserUtil::deactiveUser($inactive_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,6 +156,6 @@ class UserCleanUp extends Command
|
||||||
$sec = intval($diff);
|
$sec = intval($diff);
|
||||||
$micro = $diff - $sec;
|
$micro = $diff - $sec;
|
||||||
|
|
||||||
$this->info('END Command cleanUpInActiveUser: '.$count. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
$this->info('END Command cleanUpInActiveUser: ' . $count . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,18 +56,18 @@ class UserMakeAboOrder extends Command
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$this->timeStart = microtime(true);
|
$this->timeStart = microtime(true);
|
||||||
Log::info('UserMakeAboOrder: Befehl gestartet');
|
\Log::channel('cron')->info('UserMakeAboOrder: Befehl gestartet');
|
||||||
$this->info('RUN Command user:make_abo_order');
|
$this->info('RUN Command user:make_abo_order');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->checkAbosToOrder();
|
$this->checkAbosToOrder();
|
||||||
$executionTime = $this->getExecutionTime();
|
$executionTime = $this->getExecutionTime();
|
||||||
Log::info("UserMakeAboOrder: Befehl erfolgreich abgeschlossen in {$executionTime}");
|
\Log::channel('cron')->info("UserMakeAboOrder: Befehl erfolgreich abgeschlossen in {$executionTime}");
|
||||||
$this->info("Befehl erfolgreich abgeschlossen in {$executionTime}");
|
$this->info("Befehl erfolgreich abgeschlossen in {$executionTime}");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('UserMakeAboOrder: Fehler beim Ausführen des Befehls', [
|
\Log::channel('cron')->error('UserMakeAboOrder: Fehler beim Ausführen des Befehls', [
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
'trace' => $e->getTraceAsString()
|
'trace' => $e->getTraceAsString()
|
||||||
]);
|
]);
|
||||||
|
|
@ -85,18 +85,18 @@ class UserMakeAboOrder extends Command
|
||||||
{
|
{
|
||||||
$dateNow = Carbon::now()->format('Y-m-d');
|
$dateNow = Carbon::now()->format('Y-m-d');
|
||||||
|
|
||||||
Log::info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', ['date' => $dateNow]);
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', ['date' => $dateNow]);
|
||||||
|
|
||||||
$userAbos = UserAbo::where('next_date', '=', $dateNow)
|
$userAbos = UserAbo::where('next_date', '=', $dateNow)
|
||||||
->where('active', true)
|
->where('active', true)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$count = $userAbos->count();
|
$count = $userAbos->count();
|
||||||
Log::info("UserMakeAboOrder: {$count} fällige Abos gefunden");
|
\Log::channel('abo_order')->info("UserMakeAboOrder: {$count} fällige Abos gefunden");
|
||||||
$this->info("Gefundene fällige Abos: {$count}");
|
$this->info("Gefundene fällige Abos: {$count}");
|
||||||
|
|
||||||
foreach ($userAbos as $userAbo) {
|
foreach ($userAbos as $userAbo) {
|
||||||
Log::info('UserMakeAboOrder: Verarbeite Abo', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Verarbeite Abo', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'payone_userid' => $userAbo->payone_userid
|
'payone_userid' => $userAbo->payone_userid
|
||||||
]);
|
]);
|
||||||
|
|
@ -107,17 +107,17 @@ class UserMakeAboOrder extends Command
|
||||||
$shoppingOrder = $this->makeOrder($userAbo);
|
$shoppingOrder = $this->makeOrder($userAbo);
|
||||||
|
|
||||||
if ($shoppingOrder) {
|
if ($shoppingOrder) {
|
||||||
Log::info('UserMakeAboOrder: Bestellung erstellt', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Bestellung erstellt', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id
|
'order_id' => $shoppingOrder->id
|
||||||
]);
|
]);
|
||||||
$this->info("Bestellung erstellt: {$shoppingOrder->id}");
|
$this->info("Bestellung erstellt: {$shoppingOrder->id}");
|
||||||
} else {
|
} else {
|
||||||
Log::warning('UserMakeAboOrder: Keine Bestellung erstellt für Abo', ['abo_id' => $userAbo->id]);
|
\Log::channel('abo_order')->warning('UserMakeAboOrder: Keine Bestellung erstellt für Abo', ['abo_id' => $userAbo->id]);
|
||||||
$this->warn("Keine Bestellung erstellt für Abo: {$userAbo->id}");
|
$this->warn("Keine Bestellung erstellt für Abo: {$userAbo->id}");
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('UserMakeAboOrder: Fehler bei der Verarbeitung des Abos', [
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Fehler bei der Verarbeitung des Abos', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
'trace' => $e->getTraceAsString()
|
'trace' => $e->getTraceAsString()
|
||||||
|
|
@ -135,7 +135,7 @@ class UserMakeAboOrder extends Command
|
||||||
*/
|
*/
|
||||||
private function makeOrder($userAbo)
|
private function makeOrder($userAbo)
|
||||||
{
|
{
|
||||||
Log::info('UserMakeAboOrder: Starte Bestellungserstellung', ['abo_id' => $userAbo->id]);
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Starte Bestellungserstellung', ['abo_id' => $userAbo->id]);
|
||||||
$this->info('Starte Bestellungserstellung für Abo: ' . $userAbo->id);
|
$this->info('Starte Bestellungserstellung für Abo: ' . $userAbo->id);
|
||||||
|
|
||||||
$shoppingOrder = null;
|
$shoppingOrder = null;
|
||||||
|
|
@ -143,19 +143,19 @@ class UserMakeAboOrder extends Command
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$userOrder->createShoppingUser()) {
|
if (!$userOrder->createShoppingUser()) {
|
||||||
Log::error('UserMakeAboOrder: Konnte Shopping-User nicht erstellen', ['abo_id' => $userAbo->id]);
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Konnte Shopping-User nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||||
$this->error("Konnte Shopping-User für Abo {$userAbo->id} nicht erstellen");
|
$this->error("Konnte Shopping-User für Abo {$userAbo->id} nicht erstellen");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$shoppingOrder = $userOrder->makeShoppingOrder();
|
$shoppingOrder = $userOrder->makeShoppingOrder();
|
||||||
if (!$shoppingOrder) {
|
if (!$shoppingOrder) {
|
||||||
Log::error('UserMakeAboOrder: Konnte Bestellung nicht erstellen', ['abo_id' => $userAbo->id]);
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Konnte Bestellung nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||||
$this->error("Konnte Bestellung für Abo {$userAbo->id} nicht erstellen");
|
$this->error("Konnte Bestellung für Abo {$userAbo->id} nicht erstellen");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::info('UserMakeAboOrder: Bestellung erstellt, starte Zahlungsvorgang', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Bestellung erstellt, starte Zahlungsvorgang', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id
|
'order_id' => $shoppingOrder->id
|
||||||
]);
|
]);
|
||||||
|
|
@ -164,7 +164,7 @@ class UserMakeAboOrder extends Command
|
||||||
$this->info('makePayment response: ' . json_encode($response));
|
$this->info('makePayment response: ' . json_encode($response));
|
||||||
|
|
||||||
if (!isset($response['status'])) {
|
if (!isset($response['status'])) {
|
||||||
Log::error('UserMakeAboOrder: Ungültige Zahlungsantwort', [
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Ungültige Zahlungsantwort', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id,
|
'order_id' => $shoppingOrder->id,
|
||||||
'response' => $response
|
'response' => $response
|
||||||
|
|
@ -174,7 +174,7 @@ class UserMakeAboOrder extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($response['status'] === 'APPROVED') {
|
if ($response['status'] === 'APPROVED') {
|
||||||
Log::info('UserMakeAboOrder: Zahlung erfolgreich', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Zahlung erfolgreich', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id,
|
'order_id' => $shoppingOrder->id,
|
||||||
'response' => $response
|
'response' => $response
|
||||||
|
|
@ -182,7 +182,7 @@ class UserMakeAboOrder extends Command
|
||||||
$this->info("Zahlung erfolgreich für Abo {$userAbo->id}");
|
$this->info("Zahlung erfolgreich für Abo {$userAbo->id}");
|
||||||
$this->updateAbo($userAbo, $shoppingOrder, 1);
|
$this->updateAbo($userAbo, $shoppingOrder, 1);
|
||||||
} elseif ($response['status'] === 'ERROR') {
|
} elseif ($response['status'] === 'ERROR') {
|
||||||
Log::error('UserMakeAboOrder: Zahlungsfehler', [
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Zahlungsfehler', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id,
|
'order_id' => $shoppingOrder->id,
|
||||||
'error' => $response
|
'error' => $response
|
||||||
|
|
@ -208,7 +208,7 @@ class UserMakeAboOrder extends Command
|
||||||
|
|
||||||
Payment::paymentStatusSendMail($shoppingOrder, $shoppingPayment, $data);
|
Payment::paymentStatusSendMail($shoppingOrder, $shoppingPayment, $data);
|
||||||
} else {
|
} else {
|
||||||
Log::warning('UserMakeAboOrder: Unbekannter Zahlungsstatus', [
|
\Log::channel('abo_order')->warning('UserMakeAboOrder: Unbekannter Zahlungsstatus', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id,
|
'order_id' => $shoppingOrder->id,
|
||||||
'status' => $response['status']
|
'status' => $response['status']
|
||||||
|
|
@ -216,7 +216,7 @@ class UserMakeAboOrder extends Command
|
||||||
$this->warn("Unbekannter Zahlungsstatus für Abo {$userAbo->id}: {$response['status']}");
|
$this->warn("Unbekannter Zahlungsstatus für Abo {$userAbo->id}: {$response['status']}");
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('UserMakeAboOrder: Ausnahme bei der Bestellungserstellung', [
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Ausnahme bei der Bestellungserstellung', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
'trace' => $e->getTraceAsString()
|
'trace' => $e->getTraceAsString()
|
||||||
|
|
@ -237,7 +237,7 @@ class UserMakeAboOrder extends Command
|
||||||
*/
|
*/
|
||||||
private function updateAbo($userAbo, $shoppingOrder, $status = 1)
|
private function updateAbo($userAbo, $shoppingOrder, $status = 1)
|
||||||
{
|
{
|
||||||
Log::info('UserMakeAboOrder: Aktualisiere Abo', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Aktualisiere Abo', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'order_id' => $shoppingOrder->id,
|
'order_id' => $shoppingOrder->id,
|
||||||
'status' => $status
|
'status' => $status
|
||||||
|
|
@ -263,12 +263,12 @@ class UserMakeAboOrder extends Command
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Log::info('UserMakeAboOrder: Abo erfolgreich aktualisiert', [
|
\Log::channel('abo_order')->info('UserMakeAboOrder: Abo erfolgreich aktualisiert', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'next_date' => $updateData['next_date']
|
'next_date' => $updateData['next_date']
|
||||||
]);
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('UserMakeAboOrder: Fehler beim Aktualisieren des Abos', [
|
\Log::channel('abo_order')->error('UserMakeAboOrder: Fehler beim Aktualisieren des Abos', [
|
||||||
'abo_id' => $userAbo->id,
|
'abo_id' => $userAbo->id,
|
||||||
'error' => $e->getMessage()
|
'error' => $e->getMessage()
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
6
app/Console/Kernel.php
Executable file → Normal file
6
app/Console/Kernel.php
Executable file → Normal file
|
|
@ -33,11 +33,11 @@ class Kernel extends ConsoleKernel
|
||||||
{
|
{
|
||||||
// Job 1: Überprüft täglich um 02:00 Uhr die Zahlungskonten.
|
// Job 1: Überprüft täglich um 02:00 Uhr die Zahlungskonten.
|
||||||
$schedule->command('payments:check-accounts')->dailyAt('02:00');
|
$schedule->command('payments:check-accounts')->dailyAt('02:00');
|
||||||
|
|
||||||
// Jobs 2, 3, 4: Die Befehle aus deinem alten Shell-Skript.
|
// Jobs 2, 3, 4: Die Befehle aus deinem alten Shell-Skript.
|
||||||
// Werden nacheinander täglich zu unterschiedlichen Zeiten ausgeführt,
|
// Werden nacheinander täglich zu unterschiedlichen Zeiten ausgeführt,
|
||||||
// um die Serverlast zu verteilen.
|
// um die Serverlast zu verteilen.
|
||||||
$schedule->command('business:store 0 0')->dailyAt('03:00');
|
$schedule->command('store-optimized 0 0')->dailyAt('03:00');
|
||||||
|
|
||||||
$schedule->command('user:cleanup')->dailyAt('03:30');
|
$schedule->command('user:cleanup')->dailyAt('03:30');
|
||||||
$schedule->command('user:make_abo_order')->dailyAt('04:00');
|
$schedule->command('user:make_abo_order')->dailyAt('04:00');
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ class Kernel extends ConsoleKernel
|
||||||
*/
|
*/
|
||||||
protected function commands()
|
protected function commands()
|
||||||
{
|
{
|
||||||
$this->load(__DIR__.'/Commands');
|
$this->load(__DIR__ . '/Commands');
|
||||||
|
|
||||||
require base_path('routes/console.php');
|
require base_path('routes/console.php');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Cron;
|
namespace App\Cron;
|
||||||
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use App\Models\UserBusinessStructure;
|
use App\Models\UserBusinessStructure;
|
||||||
use App\Services\BusinessPlan\TreeCalcBot;
|
use App\Services\BusinessPlan\TreeCalcBotOptimized;
|
||||||
|
|
||||||
class BusinessUsersStore
|
class BusinessUsersStore
|
||||||
{
|
{
|
||||||
|
|
@ -22,16 +23,17 @@ class BusinessUsersStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getStoreUserBusinessStructure(){
|
public function getStoreUserBusinessStructure()
|
||||||
|
{
|
||||||
return UserBusinessStructure::where('year', $this->year)->where('month', $this->month)->first();
|
return UserBusinessStructure::where('year', $this->year)->where('month', $this->month)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeUserBusinessStructure()
|
public function storeUserBusinessStructure()
|
||||||
{
|
{
|
||||||
if($this->user_business_structure = $this->getStoreUserBusinessStructure()){
|
if ($this->user_business_structure = $this->getStoreUserBusinessStructure()) {
|
||||||
return $this->user_business_structure;
|
return $this->user_business_structure;
|
||||||
}
|
}
|
||||||
$treeCalcBot = new TreeCalcBot($this->month, $this->year, 'admin');
|
$treeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'admin');
|
||||||
//only load, when no structur is save
|
//only load, when no structur is save
|
||||||
$treeCalcBot->initStructureAdmin(false);
|
$treeCalcBot->initStructureAdmin(false);
|
||||||
$this->storeStructure($treeCalcBot);
|
$this->storeStructure($treeCalcBot);
|
||||||
|
|
@ -39,19 +41,19 @@ class BusinessUsersStore
|
||||||
|
|
||||||
public function storeBusinessUsersDetail()
|
public function storeBusinessUsersDetail()
|
||||||
{
|
{
|
||||||
if(!$this->user_business_structure){
|
if (!$this->user_business_structure) {
|
||||||
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
||||||
if(!$this->user_business_structure){
|
if (!$this->user_business_structure) {
|
||||||
abort(403, 'not found UserBusinessStructure');
|
abort(403, 'not found UserBusinessStructure');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($this->user_business_structure->users as $user_id=>$completed){
|
foreach ($this->user_business_structure->users as $user_id => $completed) {
|
||||||
if($completed === 0){
|
if ($completed === 0) {
|
||||||
$user = User::find($user_id);
|
$user = User::find($user_id);
|
||||||
if($user){
|
if ($user) {
|
||||||
$TreeCalcBot = new TreeCalcBot($this->month, $this->year, 'admin');
|
$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'admin');
|
||||||
$TreeCalcBot->initBusinesslUserDetail($user);
|
$TreeCalcBot->initBusinesslUserDetail($user);
|
||||||
if(!$TreeCalcBot->business_user){
|
if (!$TreeCalcBot->business_user) {
|
||||||
abort(403, 'not found TreeCalcBot->business_user');
|
abort(403, 'not found TreeCalcBot->business_user');
|
||||||
}
|
}
|
||||||
$this->storeBusinesslUser($TreeCalcBot->business_user);
|
$this->storeBusinesslUser($TreeCalcBot->business_user);
|
||||||
|
|
@ -60,13 +62,13 @@ class BusinessUsersStore
|
||||||
$this->user_business_structure->users = $users;
|
$this->user_business_structure->users = $users;
|
||||||
$this->user_business_structure->save();
|
$this->user_business_structure->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function storeBusinesslUser($business_user){
|
public function storeBusinesslUser($business_user)
|
||||||
|
{
|
||||||
$b_user = $business_user->getBUser();
|
$b_user = $business_user->getBUser();
|
||||||
$b_user->user_items = $this->storeUserItems($business_user->businessUserItems, 1);
|
$b_user->user_items = $this->storeUserItems($business_user->businessUserItems, 1);
|
||||||
$b_user->b_structure_id = $this->user_business_structure->id;
|
$b_user->b_structure_id = $this->user_business_structure->id;
|
||||||
|
|
@ -74,12 +76,13 @@ class BusinessUsersStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function storeBusinessCompleted(){
|
public function storeBusinessCompleted()
|
||||||
if(!$this->user_business_structure){
|
{
|
||||||
|
if (!$this->user_business_structure) {
|
||||||
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
||||||
}
|
}
|
||||||
foreach($this->user_business_structure->users as $user_id=>$completed){
|
foreach ($this->user_business_structure->users as $user_id => $completed) {
|
||||||
if($completed === 0){
|
if ($completed === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->user_business_structure->completed = 1;
|
$this->user_business_structure->completed = 1;
|
||||||
|
|
@ -89,12 +92,13 @@ class BusinessUsersStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function storeUserItems($userItems, $line){
|
private function storeUserItems($userItems, $line)
|
||||||
|
{
|
||||||
$ret = [];
|
$ret = [];
|
||||||
foreach($userItems as $userItem){
|
foreach ($userItems as $userItem) {
|
||||||
$temp = null;
|
$temp = null;
|
||||||
if(count($userItem->businessUserItems) > 0){
|
if (count($userItem->businessUserItems) > 0) {
|
||||||
$temp = $this->storeUserItems($userItem->businessUserItems, $line+1);
|
$temp = $this->storeUserItems($userItem->businessUserItems, $line + 1);
|
||||||
}
|
}
|
||||||
$obj = new stdClass();
|
$obj = new stdClass();
|
||||||
$obj->user_id = $userItem->user_id;
|
$obj->user_id = $userItem->user_id;
|
||||||
|
|
@ -114,13 +118,13 @@ class BusinessUsersStore
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
$structure = [];
|
$structure = [];
|
||||||
foreach($treeCalcBot->business_users as $business_user){
|
foreach ($treeCalcBot->business_users as $business_user) {
|
||||||
$structure[] = $this->storeStructureItem($business_user, 0);
|
$structure[] = $this->storeStructureItem($business_user, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$parentless = [];
|
$parentless = [];
|
||||||
if($treeCalcBot->parentless){
|
if ($treeCalcBot->parentless) {
|
||||||
foreach($treeCalcBot->parentless as $pless){
|
foreach ($treeCalcBot->parentless as $pless) {
|
||||||
$parentless[] = $this->storeStructureItem($pless, 0);
|
$parentless[] = $this->storeStructureItem($pless, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -139,11 +143,12 @@ class BusinessUsersStore
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private function storeStructureItem($item, $deep){
|
private function storeStructureItem($item, $deep)
|
||||||
|
{
|
||||||
$temp = null;
|
$temp = null;
|
||||||
if($item->businessUserItems){
|
if ($item->businessUserItems) {
|
||||||
foreach($item->businessUserItems as $parent){
|
foreach ($item->businessUserItems as $parent) {
|
||||||
$temp[] = $this->storeStructureItem($parent, $deep+1);
|
$temp[] = $this->storeStructureItem($parent, $deep + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->users_structure[$item->user_id] = 0;
|
$this->users_structure[$item->user_id] = 0;
|
||||||
|
|
@ -156,7 +161,4 @@ class BusinessUsersStore
|
||||||
$obj->parents = $temp;
|
$obj->parents = $temp;
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
263
app/Cron/BusinessUsersStoreOptimized.php
Normal file
263
app/Cron/BusinessUsersStoreOptimized.php
Normal file
|
|
@ -0,0 +1,263 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cron;
|
||||||
|
|
||||||
|
use App\User;
|
||||||
|
use stdClass;
|
||||||
|
use App\Models\UserBusinessStructure;
|
||||||
|
use App\Services\BusinessPlan\TreeCalcBotOptimized;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
class BusinessUsersStoreOptimized
|
||||||
|
{
|
||||||
|
private $month;
|
||||||
|
private $year;
|
||||||
|
private $user_business_structure;
|
||||||
|
private $users_structure = [];
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
public function __construct($month, $year, ?LoggerInterface $logger = null)
|
||||||
|
{
|
||||||
|
$this->month = $month;
|
||||||
|
$this->year = $year;
|
||||||
|
$this->logger = $logger ?? app(LoggerInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStoreUserBusinessStructure()
|
||||||
|
{
|
||||||
|
return UserBusinessStructure::where('year', $this->year)
|
||||||
|
->where('month', $this->month)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeUserBusinessStructure()
|
||||||
|
{
|
||||||
|
if ($this->user_business_structure = $this->getStoreUserBusinessStructure()) {
|
||||||
|
$this->logger->info("Found existing business structure for {$this->month}/{$this->year}");
|
||||||
|
return $this->user_business_structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->logger->info("Creating new business structure for {$this->month}/{$this->year}");
|
||||||
|
$startTime = microtime(true);
|
||||||
|
|
||||||
|
// Verwende TreeCalcBotOptimized mit Live-Berechnung für aktuelle Daten
|
||||||
|
$treeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'admin', true);
|
||||||
|
$treeCalcBot->initStructureAdmin(false, true); // forceLiveCalculation = true
|
||||||
|
|
||||||
|
$this->storeStructure($treeCalcBot);
|
||||||
|
|
||||||
|
$endTime = microtime(true);
|
||||||
|
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||||
|
$this->logger->info("Business structure created in {$duration}ms with " . count($this->users_structure) . " users");
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error creating business structure: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeBusinessUsersDetail()
|
||||||
|
{
|
||||||
|
if (!$this->user_business_structure) {
|
||||||
|
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
||||||
|
if (!$this->user_business_structure) {
|
||||||
|
throw new \Exception('UserBusinessStructure not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalUsers = count($this->user_business_structure->users);
|
||||||
|
$processedUsers = 0;
|
||||||
|
|
||||||
|
$this->logger->info("Processing {$totalUsers} business user details");
|
||||||
|
|
||||||
|
foreach ($this->user_business_structure->users as $user_id => $completed) {
|
||||||
|
if ($completed === 0) {
|
||||||
|
try {
|
||||||
|
$user = User::find($user_id);
|
||||||
|
if ($user) {
|
||||||
|
$this->processBusinessUser($user, $user_id);
|
||||||
|
$processedUsers++;
|
||||||
|
|
||||||
|
// Log progress every 50 users
|
||||||
|
if ($processedUsers % 50 === 0) {
|
||||||
|
$this->logger->info("Processed {$processedUsers}/{$totalUsers} business users");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->logger->warning("User {$user_id} not found, skipping");
|
||||||
|
$this->markUserCompleted($user_id);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error processing user {$user_id}: " . $e->getMessage());
|
||||||
|
// Mark as completed to avoid infinite retry loops
|
||||||
|
$this->markUserCompleted($user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info("Completed processing {$processedUsers} business user details");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processBusinessUser(User $user, int $user_id): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$startTime = microtime(true);
|
||||||
|
|
||||||
|
// Verwende TreeCalcBotOptimized für detaillierte Benutzerberechnung
|
||||||
|
$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'admin', true);
|
||||||
|
$TreeCalcBot->initBusinesslUserDetail($user, true); // forceLiveCalculation = true
|
||||||
|
|
||||||
|
if (!$TreeCalcBot->business_user) {
|
||||||
|
throw new \Exception("business_user not found for user {$user_id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->storeBusinesslUser($TreeCalcBot->business_user);
|
||||||
|
$this->markUserCompleted($user_id);
|
||||||
|
|
||||||
|
$endTime = microtime(true);
|
||||||
|
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||||
|
$this->logger->debug("Processed user {$user_id} in {$duration}ms");
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error in processBusinessUser for {$user_id}: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function markUserCompleted(int $user_id): void
|
||||||
|
{
|
||||||
|
$users = $this->user_business_structure->users;
|
||||||
|
$users[$user_id] = 1;
|
||||||
|
$this->user_business_structure->users = $users;
|
||||||
|
$this->user_business_structure->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeBusinesslUser($business_user)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$b_user = $business_user->getBUser();
|
||||||
|
$b_user->user_items = $this->storeUserItems($business_user->businessUserItems, 1);
|
||||||
|
$b_user->b_structure_id = $this->user_business_structure->id;
|
||||||
|
$b_user->save();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error storing business user: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeBusinessCompleted()
|
||||||
|
{
|
||||||
|
if (!$this->user_business_structure) {
|
||||||
|
$this->user_business_structure = $this->getStoreUserBusinessStructure();
|
||||||
|
}
|
||||||
|
|
||||||
|
$incompleteCount = 0;
|
||||||
|
foreach ($this->user_business_structure->users as $user_id => $completed) {
|
||||||
|
if ($completed === 0) {
|
||||||
|
$incompleteCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($incompleteCount === 0) {
|
||||||
|
$this->user_business_structure->completed = 1;
|
||||||
|
$this->user_business_structure->save();
|
||||||
|
$this->logger->info("Business structure marked as completed");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info("{$incompleteCount} users still incomplete");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function storeUserItems($userItems, $line)
|
||||||
|
{
|
||||||
|
$ret = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
foreach ($userItems as $userItem) {
|
||||||
|
$temp = null;
|
||||||
|
if (count($userItem->businessUserItems) > 0) {
|
||||||
|
$temp = $this->storeUserItems($userItem->businessUserItems, $line + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->user_id = $userItem->user_id;
|
||||||
|
$obj->line = $line;
|
||||||
|
$obj->points = $userItem->sales_volume_points_sum ?? 0;
|
||||||
|
$obj->parents = $temp;
|
||||||
|
$ret[] = $obj;
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error storing user items at line {$line}: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function storeStructure($treeCalcBot)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$structure = [];
|
||||||
|
$businessUsers = $treeCalcBot->business_users;
|
||||||
|
|
||||||
|
if (!is_array($businessUsers)) {
|
||||||
|
throw new \Exception("business_users is not an array");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($businessUsers as $business_user) {
|
||||||
|
$structure[] = $this->storeStructureItem($business_user, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentless = [];
|
||||||
|
$parentlessUsers = $treeCalcBot->parentless;
|
||||||
|
|
||||||
|
if ($parentlessUsers && is_array($parentlessUsers)) {
|
||||||
|
foreach ($parentlessUsers as $pless) {
|
||||||
|
$parentless[] = $this->storeStructureItem($pless, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fill = [
|
||||||
|
'month' => $this->month,
|
||||||
|
'year' => $this->year,
|
||||||
|
'structure' => $structure,
|
||||||
|
'parentless' => $parentless,
|
||||||
|
'users' => $this->users_structure,
|
||||||
|
'completed' => false,
|
||||||
|
'status' => 0
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->user_business_structure = UserBusinessStructure::create($fill);
|
||||||
|
$this->logger->info("Stored structure with " . count($structure) . " root users and " . count($parentless) . " parentless users");
|
||||||
|
|
||||||
|
return $this->user_business_structure;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error storing structure: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function storeStructureItem($item, $deep)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$temp = null;
|
||||||
|
if (isset($item->businessUserItems) && is_array($item->businessUserItems)) {
|
||||||
|
foreach ($item->businessUserItems as $parent) {
|
||||||
|
$temp[] = $this->storeStructureItem($parent, $deep + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->users_structure[$item->user_id] = 0;
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->user_id = $item->user_id;
|
||||||
|
$obj->email = $item->email ?? 'unknown';
|
||||||
|
$obj->deep = $deep;
|
||||||
|
$obj->parents = $temp;
|
||||||
|
|
||||||
|
return $obj;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error("Error storing structure item for user {$item->user_id}: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
277
app/Domain/EarlyDomainParser.php
Normal file
277
app/Domain/EarlyDomainParser.php
Normal file
|
|
@ -0,0 +1,277 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Early Domain Parser Service
|
||||||
|
*
|
||||||
|
* Provides domain parsing functionality that can be used during
|
||||||
|
* bootstrap phase (RouteServiceProvider) and runtime (Middleware).
|
||||||
|
*
|
||||||
|
* This service caches parsing results per request to avoid duplicate work.
|
||||||
|
*/
|
||||||
|
class EarlyDomainParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cache for parsed domain information per request
|
||||||
|
* @var array|null
|
||||||
|
*/
|
||||||
|
private static ?array $cachedDomainInfo = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache key (host) for cache invalidation
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private static ?string $cachedHost = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse domain information from config/domains.php
|
||||||
|
*
|
||||||
|
* Results are cached per request to avoid duplicate parsing.
|
||||||
|
*
|
||||||
|
* @param string|null $host If null, uses HTTP_HOST or SERVER_NAME
|
||||||
|
* @return array Domain information array
|
||||||
|
*/
|
||||||
|
public static function parseDomain(?string $host = null): array
|
||||||
|
{
|
||||||
|
// Get host from request if not provided
|
||||||
|
if ($host === null) {
|
||||||
|
$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove protocol if present
|
||||||
|
$host = preg_replace('/^https?:\/\//', '', $host);
|
||||||
|
|
||||||
|
// Return cached result if available for same host
|
||||||
|
if (self::$cachedHost === $host && self::$cachedDomainInfo !== null) {
|
||||||
|
return self::$cachedDomainInfo;
|
||||||
|
}
|
||||||
|
// Load domains configuration
|
||||||
|
$domains = self::getDomainsConfig();
|
||||||
|
$reservedSubdomains = self::getReservedSubdomains();
|
||||||
|
|
||||||
|
// Check exact matches first (main, shop, crm, portal, checkout)
|
||||||
|
foreach ($domains as $key => $domainConfig) {
|
||||||
|
if ($key === 'user-shop') {
|
||||||
|
continue; // Handle user-shop separately
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($host === $domainConfig['host']) {
|
||||||
|
$domainInfo = [
|
||||||
|
'type' => $domainConfig['type'],
|
||||||
|
'host' => $host,
|
||||||
|
'subdomain' => null,
|
||||||
|
'config_key' => $key,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Cache the result for this request
|
||||||
|
self::$cachedHost = $host;
|
||||||
|
self::$cachedDomainInfo = $domainInfo;
|
||||||
|
|
||||||
|
return $domainInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for user-shop pattern (dynamic subdomains)
|
||||||
|
if (isset($domains['user-shop'])) {
|
||||||
|
$userShopPattern = $domains['user-shop']['host'];
|
||||||
|
$baseDomain = str_replace('{subdomain}.', '', $userShopPattern);
|
||||||
|
|
||||||
|
if (str_ends_with($host, '.' . $baseDomain)) {
|
||||||
|
$subdomain = str_replace('.' . $baseDomain, '', $host);
|
||||||
|
|
||||||
|
// Check if subdomain is not reserved
|
||||||
|
if (!empty($subdomain) && !in_array($subdomain, $reservedSubdomains)) {
|
||||||
|
$domainInfo = [
|
||||||
|
'type' => 'user-shop',
|
||||||
|
'host' => $host,
|
||||||
|
'subdomain' => $subdomain,
|
||||||
|
'config_key' => 'user-shop',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Cache the result for this request
|
||||||
|
self::$cachedHost = $host;
|
||||||
|
self::$cachedDomainInfo = $domainInfo;
|
||||||
|
|
||||||
|
return $domainInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown domain
|
||||||
|
$domainInfo = [
|
||||||
|
'type' => 'unknown',
|
||||||
|
'host' => $host,
|
||||||
|
'subdomain' => null,
|
||||||
|
'config_key' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Cache the result for this request
|
||||||
|
self::$cachedHost = $host;
|
||||||
|
self::$cachedDomainInfo = $domainInfo;
|
||||||
|
|
||||||
|
return $domainInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current domain type quickly (for RouteServiceProvider)
|
||||||
|
*/
|
||||||
|
public static function getCurrentDomainType(): string
|
||||||
|
{
|
||||||
|
$domainInfo = self::parseDomain();
|
||||||
|
return $domainInfo['type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if current domain is a user shop
|
||||||
|
*/
|
||||||
|
public static function isUserShop(): bool
|
||||||
|
{
|
||||||
|
return self::getCurrentDomainType() === 'user-shop';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get subdomain for user shops
|
||||||
|
*/
|
||||||
|
public static function getSubdomain(): ?string
|
||||||
|
{
|
||||||
|
$domainInfo = self::parseDomain();
|
||||||
|
return $domainInfo['subdomain'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get domains configuration (early bootstrap safe)
|
||||||
|
*/
|
||||||
|
private static function getDomainsConfig(): array
|
||||||
|
{
|
||||||
|
// Try Laravel config first (if available)
|
||||||
|
if (function_exists('config')) {
|
||||||
|
$config = config('domains.domains');
|
||||||
|
if ($config) {
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Read config file directly
|
||||||
|
$configPath = __DIR__ . '/../../../../config/domains.php';
|
||||||
|
if (file_exists($configPath)) {
|
||||||
|
$config = include $configPath;
|
||||||
|
return $config['domains'] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last resort: Build from environment variables
|
||||||
|
return self::buildConfigFromEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reserved subdomains configuration
|
||||||
|
*/
|
||||||
|
private static function getReservedSubdomains(): array
|
||||||
|
{
|
||||||
|
// Try Laravel config first (if available)
|
||||||
|
if (function_exists('config')) {
|
||||||
|
$reserved = config('domains.reserved_subdomains');
|
||||||
|
if ($reserved) {
|
||||||
|
return $reserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Read config file directly
|
||||||
|
$configPath = __DIR__ . '/../../../../config/domains.php';
|
||||||
|
if (file_exists($configPath)) {
|
||||||
|
$config = include $configPath;
|
||||||
|
return $config['reserved_subdomains'] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default reserved subdomains
|
||||||
|
return ['my', 'in', 'checkout', 'www', 'api', 'mail'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build basic domain configuration from environment variables
|
||||||
|
* Used as fallback when config file is not available
|
||||||
|
*/
|
||||||
|
private static function buildConfigFromEnv(): array
|
||||||
|
{
|
||||||
|
$domain = $_ENV['APP_DOMAIN'] ?? 'mivita';
|
||||||
|
$tldCare = $_ENV['APP_TLD_CARE'] ?? '.care';
|
||||||
|
$tldShop = $_ENV['APP_TLD_SHOP'] ?? '.shop';
|
||||||
|
$crmPrefix = $_ENV['APP_PRE_URL_CRM'] ?? 'my.';
|
||||||
|
$portalPrefix = $_ENV['APP_PRE_URL_PORTAL'] ?? 'in.';
|
||||||
|
$checkoutPrefix = $_ENV['APP_URL_CHECKOUT'] ?? 'checkout.';
|
||||||
|
|
||||||
|
return [
|
||||||
|
'main' => [
|
||||||
|
'host' => $domain . $tldCare,
|
||||||
|
'type' => 'main',
|
||||||
|
],
|
||||||
|
'shop' => [
|
||||||
|
'host' => $domain . $tldShop,
|
||||||
|
'type' => 'main-shop',
|
||||||
|
'default_user_shop' => 'aloevera',
|
||||||
|
],
|
||||||
|
'crm' => [
|
||||||
|
'host' => $crmPrefix . $domain . $tldCare,
|
||||||
|
'type' => 'crm',
|
||||||
|
],
|
||||||
|
'portal' => [
|
||||||
|
'host' => $portalPrefix . $domain . $tldCare,
|
||||||
|
'type' => 'portal',
|
||||||
|
],
|
||||||
|
'checkout' => [
|
||||||
|
'host' => $checkoutPrefix . $domain . $tldCare,
|
||||||
|
'type' => 'checkout',
|
||||||
|
],
|
||||||
|
'user-shop' => [
|
||||||
|
'host' => '{subdomain}.' . $domain . $tldCare,
|
||||||
|
'type' => 'user-shop',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get protocol from configuration
|
||||||
|
*/
|
||||||
|
public static function getProtocol(): string
|
||||||
|
{
|
||||||
|
if (function_exists('config')) {
|
||||||
|
return config('domains.protocol', 'https://');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $_ENV['APP_PROTOCOL'] ?? 'https://';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get main domain URL for redirects
|
||||||
|
*/
|
||||||
|
public static function getMainUrl(): string
|
||||||
|
{
|
||||||
|
$domains = self::getDomainsConfig();
|
||||||
|
$mainHost = $domains['main']['host'] ?? 'localhost';
|
||||||
|
$protocol = self::getProtocol();
|
||||||
|
|
||||||
|
return $protocol . $mainHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the internal cache (useful for testing or special cases)
|
||||||
|
*/
|
||||||
|
public static function clearCache(): void
|
||||||
|
{
|
||||||
|
self::$cachedDomainInfo = null;
|
||||||
|
self::$cachedHost = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if result is cached for current/given host
|
||||||
|
*/
|
||||||
|
public static function isCached(?string $host = null): bool
|
||||||
|
{
|
||||||
|
if ($host === null) {
|
||||||
|
$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';
|
||||||
|
$host = preg_replace('/^https?:\/\//', '', $host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$cachedHost === $host && self::$cachedDomainInfo !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
app/Exceptions/Handler.php
Executable file → Normal file
18
app/Exceptions/Handler.php
Executable file → Normal file
|
|
@ -75,15 +75,17 @@ class Handler extends ExceptionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Versuche domain-spezifische Login-Route
|
// HOTFIX: DomainContext temporär deaktiviert
|
||||||
$context = app(\App\Domain\DomainContext::class);
|
// TODO: Nach Claude v2 Implementation wieder aktivieren
|
||||||
$loginRoute = match($context->type) {
|
// $context = app(\App\Domain\DomainContext::class);
|
||||||
'portal' => 'portal.login.form',
|
// $loginRoute = match($context->type) {
|
||||||
'crm' => 'login', // CRM hat eine eigene login route
|
// 'portal' => 'portal.login.form',
|
||||||
default => 'login'
|
// 'crm' => 'login', // CRM hat eine eigene login route
|
||||||
};
|
// default => 'login'
|
||||||
|
// };
|
||||||
|
|
||||||
return redirect()->guest(route($loginRoute));
|
// Temporär: Verwende Standard-Login-Route
|
||||||
|
return redirect()->guest(route('login'));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// Fallback: Weiterleitung zur Hauptdomain
|
// Fallback: Weiterleitung zur Hauptdomain
|
||||||
return redirect()->guest('https://' . config('app.domain') . config('app.tld_care') . '/login');
|
return redirect()->guest('https://' . config('app.domain') . config('app.tld_care') . '/login');
|
||||||
|
|
|
||||||
146
app/Http/Controllers/AdminUserController.php
Executable file → Normal file
146
app/Http/Controllers/AdminUserController.php
Executable file → Normal file
|
|
@ -26,7 +26,6 @@ class AdminUserController extends Controller
|
||||||
{
|
{
|
||||||
$this->middleware('superadmin');
|
$this->middleware('superadmin');
|
||||||
$this->userRepo = $userRepo;
|
$this->userRepo = $userRepo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -44,7 +43,7 @@ class AdminUserController extends Controller
|
||||||
public function edit($user_id)
|
public function edit($user_id)
|
||||||
{
|
{
|
||||||
$user = User::findOrFail($user_id);
|
$user = User::findOrFail($user_id);
|
||||||
if(!$user->account){
|
if (!$user->account) {
|
||||||
$user->account = new UserAccount();
|
$user->account = new UserAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,8 +51,6 @@ class AdminUserController extends Controller
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
];
|
];
|
||||||
return view('admin.user.edit', $data);
|
return view('admin.user.edit', $data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -70,71 +67,71 @@ class AdminUserController extends Controller
|
||||||
return redirect(route('admin_user_delete', [$user->id]));
|
return redirect(route('admin_user_delete', [$user->id]));
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
if(isset($data['save-admin'])){
|
if (isset($data['save-admin'])) {
|
||||||
$user->admin = $data['admin'];
|
$user->admin = $data['admin'];
|
||||||
SysLog::action('save-admin', 'admin_user', 3)
|
SysLog::action('save-admin', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user admin value: '.HTMLHelper::getLabel($user->admin))
|
->setMessage('Set user admin value: ' . HTMLHelper::getLabel($user->admin))
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-confirmed'])){
|
if (isset($data['save-confirmed'])) {
|
||||||
$data['confirmed'] = isset($data['confirmed']) ? true : false;
|
$data['confirmed'] = isset($data['confirmed']) ? true : false;
|
||||||
$user->confirmed = $data['confirmed'];
|
$user->confirmed = $data['confirmed'];
|
||||||
if($data['confirmed']){
|
if ($data['confirmed']) {
|
||||||
if(!isset($data['confirmation_date']) || $data['confirmation_date'] == ""){
|
if (!isset($data['confirmation_date']) || $data['confirmation_date'] == "") {
|
||||||
$user->confirmation_date = now();
|
$user->confirmation_date = now();
|
||||||
}else{
|
} else {
|
||||||
$user->confirmation_date = \Carbon::parse(str_replace("- ", "", $data['confirmation_date']));
|
$user->confirmation_date = \Carbon::parse(str_replace("- ", "", $data['confirmation_date']));
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
$user->confirmation_date = null;
|
$user->confirmation_date = null;
|
||||||
}
|
}
|
||||||
SysLog::action('save-confirmed', 'admin_user', 3)
|
SysLog::action('save-confirmed', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user confirmed value: '.$user->confirmed." to date: ".$data['confirmation_date'])
|
->setMessage('Set user confirmed value: ' . $user->confirmed . " to date: " . $data['confirmation_date'])
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-active'])){
|
if (isset($data['save-active'])) {
|
||||||
$data['active'] = isset($data['active']) ? true : false;
|
$data['active'] = isset($data['active']) ? true : false;
|
||||||
$user->active = $data['active'];
|
$user->active = $data['active'];
|
||||||
if($data['active'] === true && $user->wizard < 20){
|
if ($data['active'] === true && $user->wizard < 20) {
|
||||||
$user->wizard = 20;
|
$user->wizard = 20;
|
||||||
}
|
}
|
||||||
if($data['active']){
|
if ($data['active']) {
|
||||||
if(!isset($data['active_date']) || $data['active_date'] == ""){
|
if (!isset($data['active_date']) || $data['active_date'] == "") {
|
||||||
$user->active_date = now();
|
$user->active_date = now();
|
||||||
}else{
|
} else {
|
||||||
$user->active_date = \Carbon::parse(str_replace("- ", "", $data['active_date']));
|
$user->active_date = \Carbon::parse(str_replace("- ", "", $data['active_date']));
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
$user->active_date = null;
|
$user->active_date = null;
|
||||||
}
|
}
|
||||||
SysLog::action('save-active', 'admin_user', 3)
|
SysLog::action('save-active', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user active value: '.$user->active." to date: ".$data['active_date'])
|
->setMessage('Set user active value: ' . $user->active . " to date: " . $data['active_date'])
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-account'])){
|
if (isset($data['save-account'])) {
|
||||||
$old = $user->getPaymentAccountDateFormat(true);
|
$old = $user->getPaymentAccountDateFormat(true);
|
||||||
if(!isset($data['payment_account']) || $data['payment_account'] == ""){
|
if (!isset($data['payment_account']) || $data['payment_account'] == "") {
|
||||||
$user->payment_account = null;
|
$user->payment_account = null;
|
||||||
}else{
|
} else {
|
||||||
$user->wizard = 100;
|
$user->wizard = 100;
|
||||||
$payment_account = \Carbon::parse(str_replace("- ", "", $data['payment_account']));
|
$payment_account = \Carbon::parse(str_replace("- ", "", $data['payment_account']));
|
||||||
$user->payment_account = $payment_account;
|
$user->payment_account = $payment_account;
|
||||||
if($payment_account > Carbon::now()){
|
if ($payment_account > Carbon::now()) {
|
||||||
if($user->active === 0){
|
if ($user->active === 0) {
|
||||||
$user->active = true;
|
$user->active = true;
|
||||||
UserUtil::reactiveUserResetChilds($user->id, 'on save-account AdminUserController');
|
UserUtil::reactiveUserResetChilds($user->id, 'on save-account AdminUserController');
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if($user->active === 1){
|
if ($user->active === 1) {
|
||||||
$user->active = false;
|
$user->active = false;
|
||||||
UserUtil::deactiveUserNewSponsorChilds($user->id, 'on save-account AdminUserController');
|
UserUtil::deactiveUserNewSponsorChilds($user->id, 'on save-account AdminUserController');
|
||||||
}
|
}
|
||||||
|
|
@ -144,40 +141,40 @@ class AdminUserController extends Controller
|
||||||
SysLog::action('save-account', 'admin_user', 3)
|
SysLog::action('save-account', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user payment_account from date: '.$old." to date: ".$data['payment_account'])
|
->setMessage('Set user payment_account from date: ' . $old . " to date: " . $data['payment_account'])
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-shop'])){
|
if (isset($data['save-shop'])) {
|
||||||
$old = $user->getPaymentShopDateFormat(true);
|
$old = $user->getPaymentShopDateFormat(true);
|
||||||
if(!isset($data['payment_shop']) || $data['payment_shop'] == ""){
|
if (!isset($data['payment_shop']) || $data['payment_shop'] == "") {
|
||||||
$user->payment_shop = null;
|
$user->payment_shop = null;
|
||||||
}else{
|
} else {
|
||||||
$user->wizard = 100;
|
$user->wizard = 100;
|
||||||
$user->payment_shop = \Carbon::parse(str_replace("- ", "", $data['payment_shop']));
|
$user->payment_shop = \Carbon::parse(str_replace("- ", "", $data['payment_shop']));
|
||||||
}
|
}
|
||||||
SysLog::action('save-shop', 'admin_user', 3)
|
SysLog::action('save-shop', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user payment_shop from date: '.$old." to date: ".$data['payment_shop'])
|
->setMessage('Set user payment_shop from date: ' . $old . " to date: " . $data['payment_shop'])
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-test_mode'])){
|
if (isset($data['save-test_mode'])) {
|
||||||
$user->test_mode = isset($data['test_mode']) ? true : false;
|
$user->test_mode = isset($data['test_mode']) ? true : false;
|
||||||
SysLog::action('save-test_mode', 'admin_user', 3)
|
SysLog::action('save-test_mode', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user test_mode value: '.$user->test_mode)
|
->setMessage('Set user test_mode value: ' . $user->test_mode)
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['save-payment_methods'])){
|
if (isset($data['save-payment_methods'])) {
|
||||||
$user->payment_methods = isset($data['payment_methods']) ? array_map('intval', $data['payment_methods']) : null;
|
$user->payment_methods = isset($data['payment_methods']) ? array_map('intval', $data['payment_methods']) : null;
|
||||||
SysLog::action('save-payment_methods', 'admin_user', 3)
|
SysLog::action('save-payment_methods', 'admin_user', 3)
|
||||||
->setUserId(Auth::user()->id)
|
->setUserId(Auth::user()->id)
|
||||||
->setModel($user->id, User::class)
|
->setModel($user->id, User::class)
|
||||||
->setMessage('Set user payment_methods value: '.$user->getPaymentMethodsShort())
|
->setMessage('Set user payment_methods value: ' . $user->getPaymentMethodsShort())
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,22 +188,22 @@ class AdminUserController extends Controller
|
||||||
{
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
$user = User::withTrashed()->findOrFail($data['id']);
|
$user = User::withTrashed()->findOrFail($data['id']);
|
||||||
if(isset($data['realy_delete_user'])){
|
if (isset($data['realy_delete_user'])) {
|
||||||
$this->userRepo->deleteUser($user);
|
$this->userRepo->deleteUser($user);
|
||||||
\Session()->flash('alert-success', __('msg.contact_delete'));
|
\Session()->flash('alert-success', __('msg.contact_delete'));
|
||||||
}
|
}
|
||||||
if(isset($data['realy_delete_user_complete'])){
|
if (isset($data['realy_delete_user_complete'])) {
|
||||||
// $this->userRepo->deleteUserComplete($user);
|
// $this->userRepo->deleteUserComplete($user);
|
||||||
$this->userRepo->deleteUser($user, true);
|
$this->userRepo->deleteUser($user, true);
|
||||||
\Session()->flash('alert-success', __('msg.contact_delete'));
|
\Session()->flash('alert-success', __('msg.contact_delete'));
|
||||||
}
|
}
|
||||||
return redirect('/admin/users');
|
return redirect('/admin/users');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function userLoginAs($userId){
|
public function userLoginAs($userId)
|
||||||
if(Auth::user()->isSuperAdmin()){
|
{
|
||||||
|
if (Auth::user()->isSuperAdmin()) {
|
||||||
$user = User::find($userId);
|
$user = User::find($userId);
|
||||||
Auth::login($user);
|
Auth::login($user);
|
||||||
return redirect('/home');
|
return redirect('/home');
|
||||||
|
|
@ -216,9 +213,9 @@ class AdminUserController extends Controller
|
||||||
public function getUsers()
|
public function getUsers()
|
||||||
{
|
{
|
||||||
$query = User::withTrashed()
|
$query = User::withTrashed()
|
||||||
->where(function($q) {
|
->where(function ($q) {
|
||||||
$q->where('pre_deleted_at', '!=', null)
|
$q->where('pre_deleted_at', '!=', null)
|
||||||
->orWhere(function($query) {
|
->orWhere(function ($query) {
|
||||||
$query->whereNull('deleted_at')
|
$query->whereNull('deleted_at')
|
||||||
->whereNull('pre_deleted_at');
|
->whereNull('pre_deleted_at');
|
||||||
});
|
});
|
||||||
|
|
@ -232,8 +229,8 @@ class AdminUserController extends Controller
|
||||||
return $user->account ? $user->account->first_name : '';
|
return $user->account ? $user->account->first_name : '';
|
||||||
})
|
})
|
||||||
->addColumn('email', function (User $user) {
|
->addColumn('email', function (User $user) {
|
||||||
if($user->pre_deleted_at){
|
if ($user->pre_deleted_at) {
|
||||||
return '<span class="badge badge-pill badge-danger">'.$user->email.'</span>';
|
return '<span class="badge badge-pill badge-danger">' . $user->email . '</span>';
|
||||||
}
|
}
|
||||||
return $user->email;
|
return $user->email;
|
||||||
})
|
})
|
||||||
|
|
@ -244,43 +241,46 @@ class AdminUserController extends Controller
|
||||||
return '<a href="' . route('admin_lead_edit', [$user->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
return '<a href="' . route('admin_lead_edit', [$user->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('admin', function (User $user) {
|
->addColumn('admin', function (User $user) {
|
||||||
return '<a href="#" data-toggle="modal" data-target="#modals-admin" data-id="'.$user->id.'" data-email="'.$user->email.'" data-admin="'.$user->admin.'">'.HTMLHelper::getRoleLabel($user->admin).'</a>';
|
return '<a href="#" data-toggle="modal" data-target="#modals-admin" data-id="' . $user->id . '" data-email="' . $user->email . '" data-admin="' . $user->admin . '">' . HTMLHelper::getRoleLabel($user->admin) . '</a>';
|
||||||
})
|
})
|
||||||
->addColumn('confirmed', function (User $user) {
|
->addColumn('confirmed', function (User $user) {
|
||||||
$date = $user->getConfirmationDateFormat();
|
$date = $user->getConfirmationDateFormat();
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-confirmed" data-id="'.$user->id.'" data-email="'.$user->email.'" data-confirmed="'.$user->confirmed.'" data-confirmation_date="'.$date.'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-confirmed" data-id="' . $user->id . '" data-email="' . $user->email . '" data-confirmed="' . $user->confirmed . '" data-confirmation_date="' . $date . '">';
|
||||||
return $user->confirmed ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $user->confirmed ? $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $date . '</span></a>' : $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('active', function (User $user) {
|
->addColumn('active', function (User $user) {
|
||||||
$date = $user->getActiveDateFormat();
|
$date = $user->getActiveDateFormat();
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-active" data-id="'.$user->id.'" data-email="'.$user->email.'" data-active="'.$user->active.'" data-active_date="'.$date.'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-active" data-id="' . $user->id . '" data-email="' . $user->email . '" data-active="' . $user->active . '" data-active_date="' . $date . '">';
|
||||||
return $user->active ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $user->active ? $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $date . '</span></a>' : $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('account', function (User $user) {
|
->addColumn('account', function (User $user) {
|
||||||
$date = $user->getPaymentAccountDateFormat();
|
$date = $user->getPaymentAccountDateFormat();
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-account" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_account="'.$date.'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-account" data-id="' . $user->id . '" data-email="' . $user->email . '" data-payment_account="' . $date . '">';
|
||||||
if($user->payment_account){
|
if ($user->payment_account) {
|
||||||
if($user->isActiveAccount()){
|
if ($user->isActiveAccount()) {
|
||||||
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>';
|
return $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $date . '</span></a>';
|
||||||
}
|
}
|
||||||
return $link.'<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> '.$date.'</span></a>';
|
return $link . '<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> ' . $date . '</span></a>';
|
||||||
}
|
}
|
||||||
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('shop', function (User $user) {
|
->addColumn('shop', function (User $user) {
|
||||||
$date = $user->getPaymentShopDateFormat();
|
$date = $user->getPaymentShopDateFormat();
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-shop" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_shop="'.$date.'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-shop" data-id="' . $user->id . '" data-email="' . $user->email . '" data-payment_shop="' . $date . '">';
|
||||||
if($user->payment_shop){
|
if ($user->payment_shop) {
|
||||||
if($user->isActiveShop()){
|
if ($user->isActiveShop()) {
|
||||||
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>';
|
return $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $date . '</span></a>';
|
||||||
}
|
}
|
||||||
return $link.'<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> '.$date.'</span></a>';
|
return $link . '<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> ' . $date . '</span></a>';
|
||||||
}
|
}
|
||||||
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
|
})
|
||||||
|
->addColumn('shop_domain', function (User $user) {
|
||||||
|
return $user->shop ? '<a href="' . $user->shop->getSubdomain(false) . '" target="_blank">' . $user->shop->getSubdomain(false) . '</a>' : '';
|
||||||
})
|
})
|
||||||
->addColumn('since', function (User $user) {
|
->addColumn('since', function (User $user) {
|
||||||
if($user->shop){
|
if ($user->shop) {
|
||||||
if($user->shop->active){
|
if ($user->shop->active) {
|
||||||
return $user->shop->getActiveDateFormatSmall();
|
return $user->shop->getActiveDateFormatSmall();
|
||||||
}
|
}
|
||||||
return $user->shop->getActiveDateFormatSmall();
|
return $user->shop->getActiveDateFormatSmall();
|
||||||
|
|
@ -292,23 +292,21 @@ class AdminUserController extends Controller
|
||||||
})
|
})
|
||||||
->addColumn('my_payment_methods', function (User $user) {
|
->addColumn('my_payment_methods', function (User $user) {
|
||||||
$payment_methods = json_encode($user->payment_methods);
|
$payment_methods = json_encode($user->payment_methods);
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-payment_methods" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_methods="'.htmlspecialchars($payment_methods).'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-payment_methods" data-id="' . $user->id . '" data-email="' . $user->email . '" data-payment_methods="' . htmlspecialchars($payment_methods) . '">';
|
||||||
if(!$user->payment_methods){
|
if (!$user->payment_methods) {
|
||||||
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
}
|
}
|
||||||
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$user->getPaymentMethodsShort().'</span></a>';
|
return $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> ' . $user->getPaymentMethodsShort() . '</span></a>';
|
||||||
|
|
||||||
})
|
})
|
||||||
->addColumn('action_login', function (User $user) {
|
->addColumn('action_login', function (User $user) {
|
||||||
return '<a href="' . route('admin_user_login_as', [$user->id]) . '" class="btn icon-btn btn-sm btn-warning" onclick="return confirm(\''.__('Login as User?').'\');"><span class="fa fa-sign-in-alt"></span></a>';
|
return '<a href="' . route('admin_user_login_as', [$user->id]) . '" class="btn icon-btn btn-sm btn-warning" onclick="return confirm(\'' . __('Login as User?') . '\');"><span class="fa fa-sign-in-alt"></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('action_delete', function (User $user) {
|
->addColumn('action_delete', function (User $user) {
|
||||||
return '<a class="btn icon-btn btn-sm btn-danger" href="#" data-toggle="modal" data-target="#modals-user-delete" data-id="'.$user->id.'" data-email="'.$user->email.'"><span class="fa fa-trash"></span></a>';
|
return '<a class="btn icon-btn btn-sm btn-danger" href="#" data-toggle="modal" data-target="#modals-user-delete" data-id="' . $user->id . '" data-email="' . $user->email . '"><span class="fa fa-trash"></span></a>';
|
||||||
})
|
})
|
||||||
->addColumn('test_mode', function (User $user) {
|
->addColumn('test_mode', function (User $user) {
|
||||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-test_mode" data-id="'.$user->id.'" data-email="'.$user->email.'" data-test_mode="'.$user->test_mode.'">';
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-test_mode" data-id="' . $user->id . '" data-email="' . $user->email . '" data-test_mode="' . $user->test_mode . '">';
|
||||||
return $user->test_mode ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
return $user->test_mode ? $link . '<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span></a>' : $link . '<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
||||||
|
|
||||||
})
|
})
|
||||||
->orderColumn('id', 'id $1')
|
->orderColumn('id', 'id $1')
|
||||||
->orderColumn('email', 'email $1')
|
->orderColumn('email', 'email $1')
|
||||||
|
|
@ -316,7 +314,7 @@ class AdminUserController extends Controller
|
||||||
->orderColumn('active', 'active $1')
|
->orderColumn('active', 'active $1')
|
||||||
->orderColumn('shop', 'shop $1')
|
->orderColumn('shop', 'shop $1')
|
||||||
->orderColumn('admin', 'active $1')
|
->orderColumn('admin', 'active $1')
|
||||||
->rawColumns(['id', 'email', 'admin', 'confirmed', 'active', 'account', 'shop', 'my_payment_methods', 'test_mode', 'action_login', 'action_delete'])
|
->rawColumns(['id', 'email', 'admin', 'confirmed', 'active', 'account', 'shop', 'shop_domain', 'my_payment_methods', 'test_mode', 'action_login', 'action_delete'])
|
||||||
->make(true);
|
->make(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
app/Http/Controllers/Api/AuthController.php
Executable file → Normal file
0
app/Http/Controllers/Api/AuthController.php
Executable file → Normal file
0
app/Http/Controllers/Api/KasController.php
Executable file → Normal file
0
app/Http/Controllers/Api/KasController.php
Executable file → Normal file
0
app/Http/Controllers/Api/KasSLLController.php
Executable file → Normal file
0
app/Http/Controllers/Api/KasSLLController.php
Executable file → Normal file
0
app/Http/Controllers/Api/PayoneController.php
Executable file → Normal file
0
app/Http/Controllers/Api/PayoneController.php
Executable file → Normal file
0
app/Http/Controllers/Api/ShoppingUserController.php
Executable file → Normal file
0
app/Http/Controllers/Api/ShoppingUserController.php
Executable file → Normal file
0
app/Http/Controllers/AttributeController.php
Executable file → Normal file
0
app/Http/Controllers/AttributeController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ForgotPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ForgotPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/LoginController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/LoginController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/RegisterController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/RegisterController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ResetPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ResetPasswordController.php
Executable file → Normal file
|
|
@ -25,6 +25,7 @@ class BusinessController extends Controller
|
||||||
|
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
|
abort(403, 'This page is removed');
|
||||||
$this->setFilterVars();
|
$this->setFilterVars();
|
||||||
$data = [
|
$data = [
|
||||||
'filter_months' => HTMLHelper::getTransMonths(),
|
'filter_months' => HTMLHelper::getTransMonths(),
|
||||||
|
|
@ -36,6 +37,7 @@ class BusinessController extends Controller
|
||||||
|
|
||||||
public function structure()
|
public function structure()
|
||||||
{
|
{
|
||||||
|
//abort(403, 'This page is removed');
|
||||||
$this->setFilterVars();
|
$this->setFilterVars();
|
||||||
$this->month = session('business_user_filter_month');
|
$this->month = session('business_user_filter_month');
|
||||||
$this->year = session('business_user_filter_year');
|
$this->year = session('business_user_filter_year');
|
||||||
|
|
@ -53,6 +55,7 @@ class BusinessController extends Controller
|
||||||
|
|
||||||
public function userDetail($user_id)
|
public function userDetail($user_id)
|
||||||
{
|
{
|
||||||
|
abort(403, 'This page is removed');
|
||||||
$user = User::findOrFail($user_id);
|
$user = User::findOrFail($user_id);
|
||||||
$this->setFilterVars();
|
$this->setFilterVars();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ class BusinessControllerOptimized extends Controller
|
||||||
Log::info("BusinessControllerOptimized: Force live calculation requested");
|
Log::info("BusinessControllerOptimized: Force live calculation requested");
|
||||||
$TreeCalcBot->initStructureAdmin(true, $forceLiveCalculation); // check=true, forceLiveCalculation=true
|
$TreeCalcBot->initStructureAdmin(true, $forceLiveCalculation); // check=true, forceLiveCalculation=true
|
||||||
} else {
|
} else {
|
||||||
|
Log::info("BusinessControllerOptimized: Force live calculation not requested");
|
||||||
$TreeCalcBot->initStructureAdmin(); // Standard: verwende gespeicherte wenn verfügbar
|
$TreeCalcBot->initStructureAdmin(); // Standard: verwende gespeicherte wenn verfügbar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +118,6 @@ class BusinessControllerOptimized extends Controller
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('admin.business_optimized.structure', $data);
|
return view('admin.business_optimized.structure', $data);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("BusinessControllerOptimized: Error in structure: " . $e->getMessage());
|
Log::error("BusinessControllerOptimized: Error in structure: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -179,7 +179,6 @@ class BusinessControllerOptimized extends Controller
|
||||||
Log::info("BusinessControllerOptimized: User detail built in {$executionTime}ms{$calculationType}");
|
Log::info("BusinessControllerOptimized: User detail built in {$executionTime}ms{$calculationType}");
|
||||||
|
|
||||||
return view('admin.business_optimized.user_detail', compact('TreeCalcBot', 'user', 'data'));
|
return view('admin.business_optimized.user_detail', compact('TreeCalcBot', 'user', 'data'));
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("BusinessControllerOptimized: Error in userDetail for {$user_id}: " . $e->getMessage());
|
Log::error("BusinessControllerOptimized: Error in userDetail for {$user_id}: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -215,7 +214,6 @@ class BusinessControllerOptimized extends Controller
|
||||||
} else {
|
} else {
|
||||||
return $this->userCurrentlyDatatableOptimized();
|
return $this->userCurrentlyDatatableOptimized();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("BusinessControllerOptimized: Error in userDatatable: " . $e->getMessage());
|
Log::error("BusinessControllerOptimized: Error in userDatatable: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -364,28 +362,28 @@ class BusinessControllerOptimized extends Controller
|
||||||
})
|
})
|
||||||
->filterColumn('m_account', function ($query, $keyword) {
|
->filterColumn('m_account', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereRaw("user_businesses.m_account LIKE ?", '%' . $keyword . '%');
|
$query->whereRaw("user_accounts.m_account LIKE ?", '%' . $keyword . '%');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->filterColumn('first_name', function ($query, $keyword) {
|
->filterColumn('first_name', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereRaw("user_businesses.first_name LIKE ?", '%' . $keyword . '%');
|
$query->whereRaw("user_accounts.first_name LIKE ?", '%' . $keyword . '%');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->filterColumn('last_name', function ($query, $keyword) {
|
->filterColumn('last_name', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereRaw("user_businesses.last_name LIKE ?", '%' . $keyword . '%');
|
$query->whereRaw("user_accounts.last_name LIKE ?", '%' . $keyword . '%');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->filterColumn('email', function ($query, $keyword) {
|
->filterColumn('email', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereRaw("user_businesses.email LIKE ?", '%' . $keyword . '%');
|
$query->whereRaw("users.email LIKE ?", '%' . $keyword . '%');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->orderColumn('id', 'users.id $1')
|
->orderColumn('id', 'users.id $1')
|
||||||
->orderColumn('m_account', 'user_accounts.m_account $1')
|
->orderColumn('m_account', 'user_accounts.m_account $1')
|
||||||
->orderColumn('first_name', 'first_name $1')
|
->orderColumn('first_name', 'user_accounts.first_name $1')
|
||||||
->orderColumn('last_name', 'last_name $1')
|
->orderColumn('last_name', 'user_accounts.last_name $1')
|
||||||
->orderColumn('email', 'users.email $1')
|
->orderColumn('email', 'users.email $1')
|
||||||
->orderColumn('active_account', 'users.payment_account $1')
|
->orderColumn('active_account', 'users.payment_account $1')
|
||||||
->rawColumns(['id', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total', 'sponsor', 'active_account', 'next_level_qualified'])
|
->rawColumns(['id', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total', 'sponsor', 'active_account', 'next_level_qualified'])
|
||||||
|
|
@ -426,7 +424,7 @@ class BusinessControllerOptimized extends Controller
|
||||||
->where('user_businesses.next_qual_user_level', '!=', '[]');
|
->where('user_businesses.next_qual_user_level', '!=', '[]');
|
||||||
break;
|
break;
|
||||||
case 2: // In Arbeit (gelb) - hat next_can_user_level aber kein next_qual_user_level
|
case 2: // In Arbeit (gelb) - hat next_can_user_level aber kein next_qual_user_level
|
||||||
$query->where(function($q) {
|
$query->where(function ($q) {
|
||||||
$q->whereNull('user_businesses.next_qual_user_level')
|
$q->whereNull('user_businesses.next_qual_user_level')
|
||||||
->orWhere('user_businesses.next_qual_user_level', '=', '[]');
|
->orWhere('user_businesses.next_qual_user_level', '=', '[]');
|
||||||
})
|
})
|
||||||
|
|
@ -434,12 +432,12 @@ class BusinessControllerOptimized extends Controller
|
||||||
->where('user_businesses.next_can_user_level', '!=', '[]');
|
->where('user_businesses.next_can_user_level', '!=', '[]');
|
||||||
break;
|
break;
|
||||||
case 3: // Kein Level (rot) - hat weder next_qual noch next_can
|
case 3: // Kein Level (rot) - hat weder next_qual noch next_can
|
||||||
$query->where(function($q) {
|
$query->where(function ($q) {
|
||||||
$q->where(function($q1) {
|
$q->where(function ($q1) {
|
||||||
$q1->whereNull('user_businesses.next_qual_user_level')
|
$q1->whereNull('user_businesses.next_qual_user_level')
|
||||||
->orWhere('user_businesses.next_qual_user_level', '=', '[]');
|
->orWhere('user_businesses.next_qual_user_level', '=', '[]');
|
||||||
})
|
})
|
||||||
->where(function($q2) {
|
->where(function ($q2) {
|
||||||
$q2->whereNull('user_businesses.next_can_user_level')
|
$q2->whereNull('user_businesses.next_can_user_level')
|
||||||
->orWhere('user_businesses.next_can_user_level', '=', '[]');
|
->orWhere('user_businesses.next_can_user_level', '=', '[]');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
0
app/Http/Controllers/CategoryController.php
Executable file → Normal file
0
app/Http/Controllers/CategoryController.php
Executable file → Normal file
0
app/Http/Controllers/Controller.php
Executable file → Normal file
0
app/Http/Controllers/Controller.php
Executable file → Normal file
0
app/Http/Controllers/CountryController.php
Executable file → Normal file
0
app/Http/Controllers/CountryController.php
Executable file → Normal file
0
app/Http/Controllers/CustomerController.php
Executable file → Normal file
0
app/Http/Controllers/CustomerController.php
Executable file → Normal file
|
|
@ -11,16 +11,19 @@ use Acme\Dhl\Models\DhlShipment;
|
||||||
use App\Models\ShoppingOrder;
|
use App\Models\ShoppingOrder;
|
||||||
use App\Services\DhlModalService;
|
use App\Services\DhlModalService;
|
||||||
use App\Services\DhlShipmentService;
|
use App\Services\DhlShipmentService;
|
||||||
|
use App\Services\DhlTrackingService;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Yajra\DataTables\Facades\DataTables;
|
use Yajra\DataTables\Facades\DataTables;
|
||||||
|
use ZipArchive;
|
||||||
|
|
||||||
// Import new DHL package and SettingController
|
// Import new DHL package and SettingController
|
||||||
use Acme\Dhl\DhlManager;
|
use Acme\Dhl\DhlManager;
|
||||||
|
|
@ -141,11 +144,15 @@ class DhlShipmentController extends Controller
|
||||||
if ($request->filled('search')) {
|
if ($request->filled('search')) {
|
||||||
$search = $request->get('search');
|
$search = $request->get('search');
|
||||||
$query->where(function ($q) use ($search) {
|
$query->where(function ($q) use ($search) {
|
||||||
$q->where('dhl_shipment_no', 'LIKE', "%{$search}%")
|
// Search in shipment fields
|
||||||
->orWhere('id', 'LIKE', "%{$search}%")
|
$q->where('order_id', 'LIKE', "%{$search}%")
|
||||||
->orWhereHas('shoppingOrder', function ($orderQuery) use ($search) {
|
->orWhere('dhl_shipment_no', 'LIKE', "%{$search}%")
|
||||||
$orderQuery->where('id', $search);
|
->orWhere('routing_code', 'LIKE', "%{$search}%")
|
||||||
});
|
->orWhere('related_shipment_id', 'LIKE', "%{$search}%")
|
||||||
|
->orWhere('billing_number', 'LIKE', "%{$search}%")
|
||||||
|
->orWhere('firstname', 'LIKE', "%{$search}%")
|
||||||
|
->orWhere('lastname', 'LIKE', "%{$search}%")
|
||||||
|
->orWhere('company', 'LIKE', "%{$search}%");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,11 +177,7 @@ class DhlShipmentController extends Controller
|
||||||
return '<span class="text-muted">N/A</span>';
|
return '<span class="text-muted">N/A</span>';
|
||||||
})
|
})
|
||||||
->addColumn('customer', function ($shipment) {
|
->addColumn('customer', function ($shipment) {
|
||||||
if ($shipment->shoppingOrder && $shipment->shoppingOrder->shopping_user) {
|
return $shipment->firstname . ' ' . $shipment->lastname;
|
||||||
return e($shipment->shoppingOrder->shopping_user->billing_firstname) . ' ' . e($shipment->shoppingOrder->shopping_user->billing_lastname) .
|
|
||||||
'<br><small class="text-muted">' . e($shipment->shoppingOrder->shopping_user->billing_email) . '</small>';
|
|
||||||
}
|
|
||||||
return '<span class="text-muted">Unbekannt</span>';
|
|
||||||
})
|
})
|
||||||
->editColumn('dhl_shipment_no', function ($shipment) {
|
->editColumn('dhl_shipment_no', function ($shipment) {
|
||||||
return $shipment->dhl_shipment_no ? '<code class="text-success">' . e($shipment->dhl_shipment_no) . '</code>' : '<span class="text-muted">-</span>';
|
return $shipment->dhl_shipment_no ? '<code class="text-success">' . e($shipment->dhl_shipment_no) . '</code>' : '<span class="text-muted">-</span>';
|
||||||
|
|
@ -210,12 +213,14 @@ class DhlShipmentController extends Controller
|
||||||
if ($shipment->label_path) {
|
if ($shipment->label_path) {
|
||||||
$buttons .= '<a href="' . route('admin.dhl.download-label', $shipment) . '" class="btn btn-sm btn-outline-success" data-toggle="tooltip" title="Label herunterladen"><i class="fas fa-download"></i></a>';
|
$buttons .= '<a href="' . route('admin.dhl.download-label', $shipment) . '" class="btn btn-sm btn-outline-success" data-toggle="tooltip" title="Label herunterladen"><i class="fas fa-download"></i></a>';
|
||||||
}
|
}
|
||||||
|
/* Todo: Add tracking button
|
||||||
if ($shipment->canCancel()) {
|
if ($shipment->canCancel()) {
|
||||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-warning cancel-shipment-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Sendung stornieren"><i class="fas fa-ban"></i></button>';
|
$buttons .= '<button type="button" class="btn btn-sm btn-outline-warning cancel-shipment-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Sendung stornieren"><i class="fas fa-ban"></i></button>';
|
||||||
}
|
}
|
||||||
if ($shipment->type == 'outbound' && !$shipment->returns()->count()) {
|
if ($shipment->type == 'outbound' && !$shipment->returns()->count()) {
|
||||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-info create-return-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Retourenlabel erstellen"><i class="fas fa-undo"></i></button>';
|
$buttons .= '<button type="button" class="btn btn-sm btn-outline-info create-return-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Retourenlabel erstellen"><i class="fas fa-undo"></i></button>';
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
$buttons .= '</div>';
|
$buttons .= '</div>';
|
||||||
return $buttons;
|
return $buttons;
|
||||||
})
|
})
|
||||||
|
|
@ -465,27 +470,27 @@ class DhlShipmentController extends Controller
|
||||||
public function updateTracking(DhlShipment $shipment): JsonResponse
|
public function updateTracking(DhlShipment $shipment): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!$shipment->tracking_number) {
|
if (!$shipment->dhl_shipment_no) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'Keine Tracking-Nummer verfügbar.'
|
'message' => 'Keine DHL-Sendungsnummer verfügbar.'
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch tracking update job
|
// Use DhlTrackingService (handles queue/sync automatically based on config)
|
||||||
TrackShipmentJob::dispatch($shipment, ['auto_retrack' => false]);
|
$dhlTrackingService = new DhlTrackingService();
|
||||||
|
$result = $dhlTrackingService->updateTracking($shipment, ['auto_retrack' => false]);
|
||||||
|
|
||||||
Log::info('[DHL Controller] Tracking update job dispatched', [
|
Log::info('[DHL Controller] Tracking update processed', [
|
||||||
'shipment_id' => $shipment->id,
|
'shipment_id' => $shipment->id,
|
||||||
'tracking_number' => $shipment->tracking_number,
|
'dhl_shipment_no' => $shipment->dhl_shipment_no,
|
||||||
|
'queued' => $result['queued'] ?? false,
|
||||||
|
'success' => $result['success'] ?? false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json($result);
|
||||||
'success' => true,
|
|
||||||
'message' => 'Tracking-Informationen werden aktualisiert...'
|
|
||||||
]);
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Log::error('[DHL Controller] Failed to dispatch tracking update', [
|
Log::error('[DHL Controller] Failed to process tracking update', [
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
'shipment_id' => $shipment->id,
|
'shipment_id' => $shipment->id,
|
||||||
]);
|
]);
|
||||||
|
|
@ -511,11 +516,9 @@ class DhlShipmentController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$labelContent = Storage::get($shipment->label_path);
|
$labelContent = Storage::get($shipment->label_path);
|
||||||
$filename = sprintf(
|
|
||||||
'dhl-label-%s-%s.pdf',
|
// Generate descriptive filename
|
||||||
$shipment->type,
|
$filename = $this->generateLabelFilename($shipment);
|
||||||
$shipment->shipment_number ?: $shipment->id
|
|
||||||
);
|
|
||||||
|
|
||||||
return response($labelContent, 200)
|
return response($labelContent, 200)
|
||||||
->header('Content-Type', 'application/pdf')
|
->header('Content-Type', 'application/pdf')
|
||||||
|
|
@ -531,13 +534,63 @@ class DhlShipmentController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate descriptive filename for DHL label
|
||||||
|
* Format: DHL-Kundenname-Sendungsnummer-Datum.pdf
|
||||||
|
* Example: DHL-Geraldine-Seebacher-0034043333301020015589177-15092025.pdf
|
||||||
|
*
|
||||||
|
* @param DhlShipment $shipment
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function generateLabelFilename(DhlShipment $shipment): string
|
||||||
|
{
|
||||||
|
// Load order with customer data
|
||||||
|
$customerName = $shipment->firstname . '_' . $shipment->lastname;
|
||||||
|
if ($shipment->company) {
|
||||||
|
$customerName = $shipment->company;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean customer name for filename (remove special characters)
|
||||||
|
$customerName = preg_replace('/[^a-zA-Z0-9\-]/', '', $customerName);
|
||||||
|
$customerName = preg_replace('/-+/', '-', $customerName); // Remove multiple dashes
|
||||||
|
$customerName = trim($customerName, '-'); // Remove leading/trailing dashes
|
||||||
|
|
||||||
|
// Get shipment number
|
||||||
|
$shipmentNumber = $shipment->dhl_shipment_no ?: $shipment->id;
|
||||||
|
|
||||||
|
// Get creation date
|
||||||
|
$date = $shipment->created_at->format('d_m_Y');
|
||||||
|
|
||||||
|
// Build filename
|
||||||
|
$filename = sprintf(
|
||||||
|
'DHL-%s-%s-%s.pdf',
|
||||||
|
$customerName,
|
||||||
|
$shipmentNumber,
|
||||||
|
$date
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure filename is not too long (max 255 characters)
|
||||||
|
if (strlen($filename) > 255) {
|
||||||
|
$maxCustomerLength = 255 - strlen('DHL--' . $shipmentNumber . '-' . $date . '.pdf');
|
||||||
|
$customerName = substr($customerName, 0, max(10, $maxCustomerLength));
|
||||||
|
$filename = sprintf(
|
||||||
|
'DHL-%s-%s-%s.pdf',
|
||||||
|
$customerName,
|
||||||
|
$shipmentNumber,
|
||||||
|
$date
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batch operations (multiple shipments)
|
* Batch operations (multiple shipments)
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return JsonResponse
|
* @return JsonResponse|BinaryFileResponse
|
||||||
*/
|
*/
|
||||||
public function batchAction(Request $request): JsonResponse
|
public function batchAction(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$request->validate([
|
$request->validate([
|
||||||
|
|
@ -550,6 +603,7 @@ class DhlShipmentController extends Controller
|
||||||
$action = $request->action;
|
$action = $request->action;
|
||||||
$processed = 0;
|
$processed = 0;
|
||||||
$errors = [];
|
$errors = [];
|
||||||
|
$labels = []; // For batch label download
|
||||||
|
|
||||||
foreach ($shipmentIds as $shipmentId) {
|
foreach ($shipmentIds as $shipmentId) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -566,17 +620,31 @@ class DhlShipmentController extends Controller
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'update_tracking':
|
case 'update_tracking':
|
||||||
if ($shipment->tracking_number) {
|
if ($shipment->dhl_shipment_no) {
|
||||||
TrackShipmentJob::dispatch($shipment, ['auto_retrack' => false]);
|
$dhlTrackingService = new DhlTrackingService();
|
||||||
|
$trackingResult = $dhlTrackingService->updateTracking($shipment, ['auto_retrack' => false]);
|
||||||
|
|
||||||
|
if ($trackingResult['success']) {
|
||||||
$processed++;
|
$processed++;
|
||||||
} else {
|
} else {
|
||||||
$errors[] = "Sendung {$shipment->shipment_number} hat keine Tracking-Nummer.";
|
$errors[] = "Sendung #{$shipment->id}: " . $trackingResult['message'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$errors[] = "Sendung #{$shipment->id} hat keine DHL-Sendungsnummer.";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'download_labels':
|
case 'download_labels':
|
||||||
// This would require ZIP creation - implement if needed
|
if ($shipment->label_path && Storage::exists($shipment->label_path)) {
|
||||||
$errors[] = "Stapel-Download noch nicht implementiert.";
|
$labels[] = [
|
||||||
|
'shipment' => $shipment,
|
||||||
|
'filename' => $this->generateLabelFilename($shipment),
|
||||||
|
'path' => $shipment->label_path
|
||||||
|
];
|
||||||
|
$processed++;
|
||||||
|
} else {
|
||||||
|
$errors[] = "Sendung #{$shipment->id} hat kein verfügbares Label.";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
@ -584,6 +652,11 @@ class DhlShipmentController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle batch label download
|
||||||
|
if ($action === 'download_labels' && !empty($labels)) {
|
||||||
|
return $this->createLabelsZip($labels);
|
||||||
|
}
|
||||||
|
|
||||||
Log::info('[DHL Controller] Batch action executed', [
|
Log::info('[DHL Controller] Batch action executed', [
|
||||||
'action' => $action,
|
'action' => $action,
|
||||||
'processed' => $processed,
|
'processed' => $processed,
|
||||||
|
|
@ -623,7 +696,7 @@ class DhlShipmentController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$shipment = DhlShipment::where('tracking_number', $request->tracking_number)->first();
|
$shipment = DhlShipment::where('dhl_shipment_no', $request->tracking_number)->first();
|
||||||
|
|
||||||
if (!$shipment) {
|
if (!$shipment) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
@ -632,13 +705,15 @@ class DhlShipmentController extends Controller
|
||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch tracking update
|
// Use DhlTrackingService for tracking update
|
||||||
TrackShipmentJob::dispatch($shipment, ['auto_retrack' => false]);
|
$dhlTrackingService = new DhlTrackingService();
|
||||||
|
$trackingResult = $dhlTrackingService->updateTracking($shipment, ['auto_retrack' => false]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => $trackingResult['success'],
|
||||||
|
'message' => $trackingResult['message'],
|
||||||
'data' => [
|
'data' => [
|
||||||
'tracking_number' => $shipment->tracking_number,
|
'dhl_shipment_no' => $shipment->dhl_shipment_no,
|
||||||
'status' => $shipment->status,
|
'status' => $shipment->status,
|
||||||
'tracking_status' => $shipment->tracking_status,
|
'tracking_status' => $shipment->tracking_status,
|
||||||
'last_tracked_at' => $shipment->last_tracked_at?->format('d.m.Y H:i'),
|
'last_tracked_at' => $shipment->last_tracked_at?->format('d.m.Y H:i'),
|
||||||
|
|
@ -659,4 +734,65 @@ class DhlShipmentController extends Controller
|
||||||
|
|
||||||
return view('public.tracking');
|
return view('public.tracking');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create ZIP file with multiple labels
|
||||||
|
*
|
||||||
|
* @param array $labels Array of label data
|
||||||
|
* @return Response|BinaryFileResponse
|
||||||
|
*/
|
||||||
|
private function createLabelsZip(array $labels)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$zip = new ZipArchive();
|
||||||
|
$zipFilename = 'dhl_labels_' . date('Y-m-d_H-i-s') . '.zip';
|
||||||
|
$zipPath = storage_path('app/temp/' . $zipFilename);
|
||||||
|
|
||||||
|
// Ensure temp directory exists
|
||||||
|
if (!file_exists(storage_path('app/temp'))) {
|
||||||
|
mkdir(storage_path('app/temp'), 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($zip->open($zipPath, ZipArchive::CREATE) !== TRUE) {
|
||||||
|
throw new Exception('ZIP-Datei konnte nicht erstellt werden.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$addedFiles = 0;
|
||||||
|
foreach ($labels as $labelData) {
|
||||||
|
$shipment = $labelData['shipment'];
|
||||||
|
$filename = $labelData['filename'];
|
||||||
|
$filePath = $labelData['path'];
|
||||||
|
|
||||||
|
if (Storage::exists($filePath)) {
|
||||||
|
$content = Storage::get($filePath);
|
||||||
|
$zip->addFromString($filename, $content);
|
||||||
|
$addedFiles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
if ($addedFiles === 0) {
|
||||||
|
throw new Exception('Keine Labels konnten zur ZIP-Datei hinzugefügt werden.');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('[DHL Controller] Labels ZIP created', [
|
||||||
|
'zip_file' => $zipFilename,
|
||||||
|
'files_count' => $addedFiles,
|
||||||
|
'total_labels' => count($labels)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->download($zipPath, $zipFilename)->deleteFileAfterSend(true);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('[DHL Controller] Failed to create labels ZIP', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'labels_count' => count($labels)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Fehler beim Erstellen der ZIP-Datei: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,33 +15,34 @@ class FileController extends Controller
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct() {}
|
||||||
|
|
||||||
|
private function isPermissionShoppingOrder($shopping_order)
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
private function isPermissionShoppingOrder($shopping_order){
|
|
||||||
$user_id = $shopping_order->auth_user_id ? $shopping_order->auth_user_id : $shopping_order->member_id;
|
$user_id = $shopping_order->auth_user_id ? $shopping_order->auth_user_id : $shopping_order->member_id;
|
||||||
if(Auth::user()->isAdmin() || $user_id == Auth::user()->id){
|
if (Auth::user()->isAdmin() || $user_id == Auth::user()->id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isPermissionUserCredit($user_credit){
|
private function isPermissionUserCredit($user_credit)
|
||||||
if(Auth::user()->isAdmin() || $user_credit->user_id == Auth::user()->id){
|
{
|
||||||
|
if (Auth::user()->isAdmin() || $user_credit->user_id == Auth::user()->id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isPermissionAuth(){
|
private function isPermissionAuth()
|
||||||
if(Auth::check()){
|
{
|
||||||
|
if (Auth::check()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
abort(404);
|
abort(403, "Nicht autorisiert");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show($id = null, $from = null, $do='file')
|
public function show($id = null, $from = null, $do = 'file')
|
||||||
{
|
{
|
||||||
|
|
||||||
$path = "";
|
$path = "";
|
||||||
|
|
@ -56,21 +57,20 @@ class FileController extends Controller
|
||||||
return Response::file($path);
|
return Response::file($path);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
if ($from === 'invoice'){
|
if ($from === 'invoice') {
|
||||||
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
|
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
|
||||||
if($shopping_order->user_invoice){
|
if ($shopping_order->user_invoice) {
|
||||||
$this->isPermissionShoppingOrder($shopping_order);
|
$this->isPermissionShoppingOrder($shopping_order);
|
||||||
$user_invoice = $shopping_order->user_invoice;
|
$user_invoice = $shopping_order->user_invoice;
|
||||||
$filename = $user_invoice->filename;
|
$filename = $user_invoice->filename;
|
||||||
$disk = $user_invoice->disk;
|
$disk = $user_invoice->disk;
|
||||||
$path = $user_invoice->getDownloadPath();
|
$path = $user_invoice->getDownloadPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($from === 'delivery'){
|
if ($from === 'delivery') {
|
||||||
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
|
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
|
||||||
if($shopping_order->user_invoice){
|
if ($shopping_order->user_invoice) {
|
||||||
$this->isPermissionShoppingOrder($shopping_order);
|
$this->isPermissionShoppingOrder($shopping_order);
|
||||||
$user_invoice = $shopping_order->user_invoice;
|
$user_invoice = $shopping_order->user_invoice;
|
||||||
$filename = $user_invoice->delivery_filename;
|
$filename = $user_invoice->delivery_filename;
|
||||||
|
|
@ -79,7 +79,7 @@ class FileController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($from === 'credit'){
|
if ($from === 'credit') {
|
||||||
$user_credit = \App\Models\UserCredit::findOrFail($id);
|
$user_credit = \App\Models\UserCredit::findOrFail($id);
|
||||||
$this->isPermissionUserCredit($user_credit);
|
$this->isPermissionUserCredit($user_credit);
|
||||||
$filename = $user_credit->filename;
|
$filename = $user_credit->filename;
|
||||||
|
|
@ -87,7 +87,7 @@ class FileController extends Controller
|
||||||
$path = $user_credit->getDownloadPath();
|
$path = $user_credit->getDownloadPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($from === 'credit_detail'){
|
if ($from === 'credit_detail') {
|
||||||
$user_credit = \App\Models\UserCredit::findOrFail($id);
|
$user_credit = \App\Models\UserCredit::findOrFail($id);
|
||||||
$this->isPermissionUserCredit($user_credit);
|
$this->isPermissionUserCredit($user_credit);
|
||||||
|
|
||||||
|
|
@ -102,23 +102,23 @@ class FileController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($from === 'dc_file'){
|
if ($from === 'dc_file') {
|
||||||
$this->isPermissionAuth();
|
// $this->isPermissionAuth();
|
||||||
$dc_file = \App\Models\DcFile::findOrFail($id);
|
$dc_file = \App\Models\DcFile::findOrFail($id);
|
||||||
$filename = $dc_file->filename;
|
$filename = $dc_file->filename;
|
||||||
$disk = 'public';
|
$disk = 'public';
|
||||||
$path = $dc_file->getFile();
|
$path = $dc_file->getFile();
|
||||||
}
|
}
|
||||||
if ($from === 'dc_thumb'){
|
if ($from === 'dc_thumb') {
|
||||||
$this->isPermissionAuth();
|
// $this->isPermissionAuth();
|
||||||
$dc_file = \App\Models\DcFile::findOrFail($id);
|
$dc_file = \App\Models\DcFile::findOrFail($id);
|
||||||
$filename = $dc_file->filename;
|
$filename = $dc_file->filename;
|
||||||
$disk = 'public';
|
$disk = 'public';
|
||||||
$path = $dc_file->getThumb();
|
$path = $dc_file->getThumb();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($from === 'dc_big'){
|
if ($from === 'dc_big') {
|
||||||
$this->isPermissionAuth();
|
// $this->isPermissionAuth();
|
||||||
$dc_file = \App\Models\DcFile::findOrFail($id);
|
$dc_file = \App\Models\DcFile::findOrFail($id);
|
||||||
$filename = $dc_file->filename;
|
$filename = $dc_file->filename;
|
||||||
$disk = 'public';
|
$disk = 'public';
|
||||||
|
|
@ -127,7 +127,7 @@ class FileController extends Controller
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!Storage::disk($disk)->exists($path)){
|
if (!Storage::disk($disk)->exists($path)) {
|
||||||
return Response::make('Datei nicht gefunden.', 404);
|
return Response::make('Datei nicht gefunden.', 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,26 +138,26 @@ class FileController extends Controller
|
||||||
$file = Storage::disk($disk)->get($path);
|
$file = Storage::disk($disk)->get($path);
|
||||||
$mime = Storage::disk($disk)->mimeType($path);
|
$mime = Storage::disk($disk)->mimeType($path);
|
||||||
|
|
||||||
if(isset($file)){
|
if (isset($file)) {
|
||||||
if($do === 'stream'){
|
if ($do === 'stream') {
|
||||||
return Storage::disk($disk)->response($path, $filename);
|
return Storage::disk($disk)->response($path, $filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($do === 'file'){
|
if ($do === 'file') {
|
||||||
return Response::make($file, 200)
|
return Response::make($file, 200)
|
||||||
->header("Content-Type", $mime)
|
->header("Content-Type", $mime)
|
||||||
->header("Content-Length", strlen($file))
|
->header("Content-Length", strlen($file))
|
||||||
->header('Content-disposition', 'filename="'.$filename.'"');
|
->header('Content-disposition', 'filename="' . $filename . '"');
|
||||||
}
|
}
|
||||||
if($do === 'image'){
|
if ($do === 'image') {
|
||||||
return Response::make($file, 200)
|
return Response::make($file, 200)
|
||||||
->header("Content-Type", $mime);
|
->header("Content-Type", $mime);
|
||||||
}
|
}
|
||||||
if($do === 'pdf'){
|
if ($do === 'pdf') {
|
||||||
$path = storage_path().'/app/public/' . $path;
|
$path = storage_path() . '/app/public/' . $path;
|
||||||
|
|
||||||
$headers = array(
|
$headers = array(
|
||||||
'Content-Type:'. $mime,
|
'Content-Type:' . $mime,
|
||||||
// 'Content-Length: ' . $file->size
|
// 'Content-Length: ' . $file->size
|
||||||
// 'Content-Disposition: ' . $stream . '; filename=' . $file->original_name
|
// 'Content-Disposition: ' . $stream . '; filename=' . $file->original_name
|
||||||
);
|
);
|
||||||
|
|
@ -167,7 +167,8 @@ class FileController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function create_credit_detail(UserCredit $user_credit, $do){
|
private function create_credit_detail(UserCredit $user_credit, $do)
|
||||||
|
{
|
||||||
|
|
||||||
$credit_repo = new CreditRepository($user_credit->user);
|
$credit_repo = new CreditRepository($user_credit->user);
|
||||||
return $credit_repo->create_report($user_credit, $do);
|
return $credit_repo->create_report($user_credit, $do);
|
||||||
|
|
|
||||||
97
app/Http/Controllers/HomeController.php
Executable file → Normal file
97
app/Http/Controllers/HomeController.php
Executable file → Normal file
|
|
@ -4,7 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\ShoppingPayment;
|
use App\Models\ShoppingPayment;
|
||||||
use App\User;
|
use App\User;
|
||||||
use Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Config;
|
use Config;
|
||||||
use Request;
|
use Request;
|
||||||
|
|
@ -17,25 +17,22 @@ class HomeController extends Controller
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
return redirect('home');
|
return redirect('home');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//login / Dashboard
|
//login / Dashboard
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,12 +44,13 @@ class HomeController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function loadingModal(){
|
public function loadingModal()
|
||||||
|
{
|
||||||
|
|
||||||
$data = Request::get('data');
|
$data = Request::get('data');
|
||||||
$target = Request::get('target');
|
$target = Request::get('target');
|
||||||
$response = "";
|
$response = "";
|
||||||
if($data === "data_protection"){
|
if ($data === "data_protection") {
|
||||||
$data = [
|
$data = [
|
||||||
'modal' => true,
|
'modal' => true,
|
||||||
'user_shop' => true,
|
'user_shop' => true,
|
||||||
|
|
@ -60,29 +58,29 @@ class HomeController extends Controller
|
||||||
];
|
];
|
||||||
$response = view('legal.data_protect_de', $data)->render();
|
$response = view('legal.data_protect_de', $data)->render();
|
||||||
}
|
}
|
||||||
if($data === "imprint"){
|
if ($data === "imprint") {
|
||||||
$data = [
|
$data = [
|
||||||
'modal' => true,
|
'modal' => true,
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
];
|
];
|
||||||
$response = view('legal.imprint_de', $data)->render();
|
$response = view('legal.imprint_de', $data)->render();
|
||||||
}
|
}
|
||||||
if($data === "shop_term_of_use"){
|
if ($data === "shop_term_of_use") {
|
||||||
$data = [
|
$data = [
|
||||||
'modal' => true,
|
'modal' => true,
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
];
|
];
|
||||||
$response = view('legal.shop_term_of_use_de', $data)->render();
|
$response = view('legal.shop_term_of_use_de', $data)->render();
|
||||||
}
|
}
|
||||||
if($data === "agb"){
|
if ($data === "agb") {
|
||||||
$data = [
|
$data = [
|
||||||
'modal' => true,
|
'modal' => true,
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
];
|
];
|
||||||
$response = view('legal.agb_de', $data)->render();
|
$response = view('legal.agb_de', $data)->render();
|
||||||
}
|
}
|
||||||
if(Request::ajax()) {
|
if (Request::ajax()) {
|
||||||
return response()->json(['response' => $response, 'target'=>$target]);
|
return response()->json(['response' => $response, 'target' => $target]);
|
||||||
}
|
}
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +127,8 @@ class HomeController extends Controller
|
||||||
return abort(404);
|
return abort(404);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
public function zahlungsarten(){
|
public function zahlungsarten()
|
||||||
|
{
|
||||||
return view('web.templates.zahlungsarten', [
|
return view('web.templates.zahlungsarten', [
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
'isMivitaShop' => Util::isMivitaShop(),
|
'isMivitaShop' => Util::isMivitaShop(),
|
||||||
|
|
@ -137,7 +136,8 @@ class HomeController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function versandkosten(){
|
public function versandkosten()
|
||||||
|
{
|
||||||
return view('web.templates.versandkosten', [
|
return view('web.templates.versandkosten', [
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
'isMivitaShop' => Util::isMivitaShop(),
|
'isMivitaShop' => Util::isMivitaShop(),
|
||||||
|
|
@ -179,44 +179,51 @@ class HomeController extends Controller
|
||||||
return view('legal.imprint', $data);
|
return view('legal.imprint', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verify($confirmation_code){
|
public function verify($confirmation_code)
|
||||||
if( ! $confirmation_code)
|
|
||||||
{
|
{
|
||||||
|
if (! $confirmation_code) {
|
||||||
return redirect('/status/error');
|
return redirect('/status/error');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::whereConfirmationCode($confirmation_code)->first();
|
$user = User::whereConfirmationCode($confirmation_code)->first();
|
||||||
|
if (! $user) {
|
||||||
if ( ! $user)
|
|
||||||
{
|
|
||||||
return redirect('/status/not/found');
|
return redirect('/status/not/found');
|
||||||
}
|
}
|
||||||
if($user->confirmed === 0){
|
$user_auto_login = false;
|
||||||
|
if ($user->confirmed === 0) {
|
||||||
$user->confirmed = 1;
|
$user->confirmed = 1;
|
||||||
$user->confirmation_date = now();
|
$user->confirmation_date = now();
|
||||||
|
$user_auto_login = true;
|
||||||
|
//nur bei der ersten Verifizierung den user auto login
|
||||||
}
|
}
|
||||||
|
//wird nun in WizardController::releaseAccount() auf null gesetzt
|
||||||
// $user->confirmation_code = null;
|
//$user->confirmation_code = null;
|
||||||
// $user->confirmation_code_to = null;
|
//$user->confirmation_code_to = null;
|
||||||
// $user->confirmation_code_remider = 0;
|
//$user->confirmation_code_remider = 0;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
//Login!
|
//Login!
|
||||||
|
if ($user_auto_login) {
|
||||||
Auth::login($user);
|
Auth::login($user);
|
||||||
|
}
|
||||||
return redirect('/home');
|
$url = Util::getMyMivitaUrl();
|
||||||
|
return redirect($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function statusRegister(){
|
public function statusRegister()
|
||||||
|
{
|
||||||
return view('status.status_register');
|
return view('status.status_register');
|
||||||
}
|
}
|
||||||
public function statusVerify(){
|
public function statusVerify()
|
||||||
|
{
|
||||||
return view('status.status_verify');
|
return view('status.status_verify');
|
||||||
}
|
}
|
||||||
public function statusError(){
|
public function statusError()
|
||||||
|
{
|
||||||
return view('status.status_error');
|
return view('status.status_error');
|
||||||
}
|
}
|
||||||
public function notFound(){
|
public function notFound()
|
||||||
|
{
|
||||||
return view('status.not_found');
|
return view('status.not_found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,15 +231,16 @@ class HomeController extends Controller
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function checkMail(){
|
public function checkMail()
|
||||||
|
{
|
||||||
|
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if($data['user_id'] === "new"){
|
if ($data['user_id'] === "new") {
|
||||||
if(User::where('email', $data['email'])->count()){
|
if (User::where('email', $data['email'])->count()) {
|
||||||
return json_encode(false);
|
return json_encode(false);
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if(User::where('email', $data['email'])->where('id', '!=', $data['user_id'])->count()){
|
if (User::where('email', $data['email'])->where('id', '!=', $data['user_id'])->count()) {
|
||||||
return json_encode(false);
|
return json_encode(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -244,24 +252,23 @@ class HomeController extends Controller
|
||||||
return view('status.user_blocked');
|
return view('status.user_blocked');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function backToShop($reference = ""){
|
public function backToShop($reference = "")
|
||||||
|
{
|
||||||
|
|
||||||
if($reference){
|
if ($reference) {
|
||||||
$ShoppingPayment = ShoppingPayment::where('reference', $reference)->first();
|
$ShoppingPayment = ShoppingPayment::where('reference', $reference)->first();
|
||||||
if($ShoppingPayment && $ShoppingPayment->status === 'success'){
|
if ($ShoppingPayment && $ShoppingPayment->status === 'success') {
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
//is form wizard create payment
|
//is form wizard create payment
|
||||||
if($user && ($user->wizard == 13 || $user->wizard == 20)){
|
if ($user && ($user->wizard == 13 || $user->wizard == 20)) {
|
||||||
$user->wizard = 15; //realese Payments
|
$user->wizard = 15; //realese Payments
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect(route('wizard_create', [15]));
|
return redirect(route('wizard_create', [15]));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
\Session()->flash('alert-error', __('msg.error_occurred_with_order'));
|
\Session()->flash('alert-error', __('msg.error_occurred_with_order'));
|
||||||
return redirect(route('/'));
|
return redirect(url('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
app/Http/Controllers/ImportProductController.php
Executable file → Normal file
0
app/Http/Controllers/ImportProductController.php
Executable file → Normal file
0
app/Http/Controllers/IngredientController.php
Executable file → Normal file
0
app/Http/Controllers/IngredientController.php
Executable file → Normal file
0
app/Http/Controllers/LeadController.php
Executable file → Normal file
0
app/Http/Controllers/LeadController.php
Executable file → Normal file
88
app/Http/Controllers/LevelReportsController.php
Normal file
88
app/Http/Controllers/LevelReportsController.php
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Services\LevelReportService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
|
class LevelReportsController extends Controller
|
||||||
|
{
|
||||||
|
private $levelReportService;
|
||||||
|
|
||||||
|
public function __construct(LevelReportService $levelReportService)
|
||||||
|
{
|
||||||
|
$this->levelReportService = $levelReportService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeige Level-Aufstieg Reports
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
// Filter aus Request extrahieren
|
||||||
|
$filters = [
|
||||||
|
'month' => $request->get('month'),
|
||||||
|
'year' => $request->get('year'),
|
||||||
|
'user_id' => $request->get('user_id'),
|
||||||
|
'only_not_updated' => $request->boolean('not_updated')
|
||||||
|
];
|
||||||
|
|
||||||
|
// Lade Level-Aufstiege
|
||||||
|
$promotions = $this->levelReportService->getLevelPromotions($filters);
|
||||||
|
$statistics = $this->levelReportService->getStatistics($promotions);
|
||||||
|
|
||||||
|
// Verfügbare Jahre für Filter
|
||||||
|
$availableYears = range(date('Y'), date('Y') - 5);
|
||||||
|
$availableMonths = [
|
||||||
|
1 => 'Januar',
|
||||||
|
2 => 'Februar',
|
||||||
|
3 => 'März',
|
||||||
|
4 => 'April',
|
||||||
|
5 => 'Mai',
|
||||||
|
6 => 'Juni',
|
||||||
|
7 => 'Juli',
|
||||||
|
8 => 'August',
|
||||||
|
9 => 'September',
|
||||||
|
10 => 'Oktober',
|
||||||
|
11 => 'November',
|
||||||
|
12 => 'Dezember'
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin.level-reports.index', compact(
|
||||||
|
'promotions',
|
||||||
|
'statistics',
|
||||||
|
'filters',
|
||||||
|
'availableYears',
|
||||||
|
'availableMonths'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSV Export
|
||||||
|
*/
|
||||||
|
public function export(Request $request)
|
||||||
|
{
|
||||||
|
// Filter aus Request extrahieren
|
||||||
|
$filters = [
|
||||||
|
'month' => $request->get('month'),
|
||||||
|
'year' => $request->get('year'),
|
||||||
|
'user_id' => $request->get('user_id'),
|
||||||
|
'only_not_updated' => $request->boolean('not_updated')
|
||||||
|
];
|
||||||
|
|
||||||
|
// Lade Level-Aufstiege
|
||||||
|
$promotions = $this->levelReportService->getLevelPromotions($filters);
|
||||||
|
|
||||||
|
if ($promotions->isEmpty()) {
|
||||||
|
return redirect()->back()->with('error', 'Keine Daten für Export gefunden.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erstelle CSV
|
||||||
|
$filename = 'level_promotions_' . date('Y-m-d_H-i-s') . '.csv';
|
||||||
|
$filepath = $this->levelReportService->exportToCsv($promotions, $filename);
|
||||||
|
|
||||||
|
// Download CSV
|
||||||
|
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,100 +27,101 @@ class ModalController extends Controller
|
||||||
$this->middleware('auth');
|
$this->middleware('auth');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function load(){
|
public function load()
|
||||||
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
$ret = "";
|
$ret = "";
|
||||||
$status = false;
|
$status = false;
|
||||||
if(Request::ajax()){
|
if (Request::ajax()) {
|
||||||
if($data['action'] === 'shopping-order-change-member'){
|
if ($data['action'] === 'shopping-order-change-member') {
|
||||||
$value = ShoppingOrder::find($data['id']);
|
$value = ShoppingOrder::find($data['id']);
|
||||||
$route = route('admin_sales_customers_detail', [$value->id]);
|
$route = route('admin_sales_customers_detail', [$value->id]);
|
||||||
$ret = view("admin.modal.member", compact('value', 'data', 'route'))->render();
|
$ret = view("admin.modal.member", compact('value', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'shopping-user-change-member'){
|
if ($data['action'] === 'shopping-user-change-member') {
|
||||||
$value = ShoppingUser::find($data['id']);
|
$value = ShoppingUser::find($data['id']);
|
||||||
$route = route('admin_customer_edit', [$value->id]);
|
$route = route('admin_customer_edit', [$value->id]);
|
||||||
$ret = view("admin.modal.member", compact('value', 'data', 'route'))->render();
|
$ret = view("admin.modal.member", compact('value', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'shopping-user-is-like-member'){
|
if ($data['action'] === 'shopping-user-is-like-member') {
|
||||||
$current = ShoppingUser::find($data['id']); //current user form order
|
$current = ShoppingUser::find($data['id']); //current user form order
|
||||||
$possibles = [];
|
$possibles = [];
|
||||||
if($current->is_like){
|
if ($current->is_like) {
|
||||||
$likes = $current->getNotice('like');
|
$likes = $current->getNotice('like');
|
||||||
foreach ($likes as $like_id=>$number){
|
foreach ($likes as $like_id => $number) {
|
||||||
$possibles[] = ShoppingUser::find($like_id);
|
$possibles[] = ShoppingUser::find($like_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$ret = view("admin.modal.is_like_member", compact('current', 'possibles', 'data'))->render();
|
$ret = view("admin.modal.is_like_member", compact('current', 'possibles', 'data'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'shopping-order-change-points'){
|
if ($data['action'] === 'shopping-order-change-points') {
|
||||||
$value = ShoppingOrder::find($data['id']);
|
$value = ShoppingOrder::find($data['id']);
|
||||||
$route = route('admin_sales_customers_detail', [$value->id]);
|
$route = route('admin_sales_customers_detail', [$value->id]);
|
||||||
$ret = view("admin.modal.change_points", compact('value', 'data', 'route'))->render();
|
$ret = view("admin.modal.change_points", compact('value', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'user-order-show-product'){
|
if ($data['action'] === 'user-order-show-product') {
|
||||||
$product = Product::find($data['id']); //current user form order
|
$product = Product::find($data['id']); //current user form order
|
||||||
$ret = view("admin.modal.show_product", compact('product', 'data'))->render();
|
$ret = view("admin.modal.show_product", compact('product', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'user-order-show-product'){
|
if ($data['action'] === 'user-order-show-product') {
|
||||||
$product = Product::find($data['id']); //current user form order
|
$product = Product::find($data['id']); //current user form order
|
||||||
$ret = view("admin.modal.show_product", compact('product', 'data'))->render();
|
$ret = view("admin.modal.show_product", compact('product', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'shop-user-order-detail'){
|
if ($data['action'] === 'shop-user-order-detail') {
|
||||||
$user = \Auth::user();
|
$user = \Auth::user();
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
if(!$user->isAdmin() && $shopping_order->member_id !== $user->id){
|
if (!$user->isAdmin() && $shopping_order->member_id !== $user->id) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
$isAdmin = false ;
|
$isAdmin = false;
|
||||||
$ret = view("user.shop.sales.modal_api_order_detail", compact('shopping_order', 'isAdmin', 'data'))->render();
|
$ret = view("user.shop.sales.modal_api_order_detail", compact('shopping_order', 'isAdmin', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'shop-user-order-shipping-detail'){
|
if ($data['action'] === 'shop-user-order-shipping-detail') {
|
||||||
$user = \Auth::user();
|
$user = \Auth::user();
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
if(!$user->isAdmin() && $shopping_order->auth_user_id !== $user->id){
|
if (!$user->isAdmin() && $shopping_order->auth_user_id !== $user->id) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
$isAdmin = false ;
|
$isAdmin = false;
|
||||||
$ret = view("user.shop.sales.modal_api_order_shipping_detail", compact('shopping_order', 'isAdmin', 'data'))->render();
|
$ret = view("user.shop.sales.modal_api_order_shipping_detail", compact('shopping_order', 'isAdmin', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'user-order-my-delivery-show'){
|
if ($data['action'] === 'user-order-my-delivery-show') {
|
||||||
$user = \Auth::user();
|
$user = \Auth::user();
|
||||||
$ret = view("admin.modal.show_user_customers", compact('user', 'data'))->render();
|
$ret = view("admin.modal.show_user_customers", compact('user', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'user-order-my-delivery-add'){
|
if ($data['action'] === 'user-order-my-delivery-add') {
|
||||||
$user = \Auth::user();
|
$user = \Auth::user();
|
||||||
/* $product = Product::find($data['id']); //current user form order
|
/* $product = Product::find($data['id']); //current user form order
|
||||||
$ret = view("admin.modal.show_product", compact('product', 'data'))->render(); */
|
$ret = view("admin.modal.show_product", compact('product', 'data'))->render(); */
|
||||||
}
|
}
|
||||||
if($data['action'] === 'homeparty-add-product') {
|
if ($data['action'] === 'homeparty-add-product') {
|
||||||
$homeparty = Homeparty::find($data['id']);
|
$homeparty = Homeparty::find($data['id']);
|
||||||
$homeparty_user = HomepartyUser::find($data['user_id']);
|
$homeparty_user = HomepartyUser::find($data['user_id']);
|
||||||
$data['homeparty'] = $homeparty;
|
$data['homeparty'] = $homeparty;
|
||||||
$ret = view("user.homeparty.modal_hp_show_products", compact( 'data', 'homeparty', 'homeparty_user'))->render();
|
$ret = view("user.homeparty.modal_hp_show_products", compact('data', 'homeparty', 'homeparty_user'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'user-level-edit'){
|
if ($data['action'] === 'user-level-edit') {
|
||||||
$value = UserLevel::find($data['id']);
|
$value = UserLevel::find($data['id']);
|
||||||
$route = route('admin_level_store', [$value->id]);
|
$route = route('admin_level_store', [$value->id]);
|
||||||
$ret = view("admin.modal.user_level_edit", compact('value', 'data', 'route'))->render();
|
$ret = view("admin.modal.user_level_edit", compact('value', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'user-level-add'){
|
if ($data['action'] === 'user-level-add') {
|
||||||
$value = new UserLevel();
|
$value = new UserLevel();
|
||||||
$route = route('admin_level_store', ['new']);
|
$route = route('admin_level_store', ['new']);
|
||||||
$ret = view("admin.modal.user_level_edit", compact('value', 'data', 'route'))->render();
|
$ret = view("admin.modal.user_level_edit", compact('value', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'business-user-detail'){
|
if ($data['action'] === 'business-user-detail') {
|
||||||
$user = User::findOrFail($data['id']);
|
$user = User::findOrFail($data['id']);
|
||||||
if($data['init_from'] === 'admin'){
|
if ($data['init_from'] === 'admin') {
|
||||||
$data['month'] = session('business_user_filter_month');
|
$data['month'] = session('business_user_filter_month');
|
||||||
$data['year'] = session('business_user_filter_year');
|
$data['year'] = session('business_user_filter_year');
|
||||||
}else{
|
} else {
|
||||||
$data['month'] = session('team_user_filter_month');
|
$data['month'] = session('team_user_filter_month');
|
||||||
$data['year'] = session('team_user_filter_year');
|
$data['year'] = session('team_user_filter_year');
|
||||||
}
|
}
|
||||||
|
|
@ -131,74 +132,72 @@ class ModalController extends Controller
|
||||||
$ret = view("admin.modal.business_user_detail", compact('TreeCalcBot', 'user', 'data'))->render();
|
$ret = view("admin.modal.business_user_detail", compact('TreeCalcBot', 'user', 'data'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'business-user-show'){
|
if ($data['action'] === 'business-user-show') {
|
||||||
$user = User::find($data['id']);
|
$user = User::find($data['id']);
|
||||||
if($user && $user->account){
|
if ($user && $user->account) {
|
||||||
$route = "";
|
$route = "";
|
||||||
$ret = view("admin.modal.business_user_show", compact('user', 'data'))->render();
|
$ret = view("admin.modal.business_user_show", compact('user', 'data'))->render();
|
||||||
}
|
}
|
||||||
$ret = view("admin.modal.business_user_notfound", compact('data'))->render();
|
$ret = view("admin.modal.business_user_notfound", compact('data'))->render();
|
||||||
|
|
||||||
}
|
}
|
||||||
if($data['action'] === 'edit_user_sales_volume'){
|
if ($data['action'] === 'edit_user_sales_volume') {
|
||||||
$userSalesVolume = UserSalesVolume::findOrFail($data['id']);
|
$userSalesVolume = UserSalesVolume::findOrFail($data['id']);
|
||||||
$route = route('admin_business_points_store', );
|
$route = route('admin_business_points_store',);
|
||||||
$ret = view("admin.business.modal_edit_points", compact('userSalesVolume', 'data', 'route'))->render();
|
$ret = view("admin.business.modal_edit_points", compact('userSalesVolume', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'add_user_sales_volume'){
|
if ($data['action'] === 'add_user_sales_volume') {
|
||||||
$userSalesVolume = new UserSalesVolume();
|
$userSalesVolume = new UserSalesVolume();
|
||||||
$route = route('admin_business_points_store', );
|
$route = route('admin_business_points_store',);
|
||||||
$ret = view("admin.business.modal_add_points", compact('userSalesVolume', 'data', 'route'))->render();
|
$ret = view("admin.business.modal_add_points", compact('userSalesVolume', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'add-user-credit'){
|
if ($data['action'] === 'add-user-credit') {
|
||||||
$value = [];
|
$value = [];
|
||||||
$ret = view("admin.payment.modal_add_credit", compact('value', 'data'))->render();
|
$ret = view("admin.payment.modal_add_credit", compact('value', 'data'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'user-credit-status'){
|
if ($data['action'] === 'user-credit-status') {
|
||||||
$UserCredit = UserCredit::find($data['id']); //current user form order
|
$UserCredit = UserCredit::find($data['id']); //current user form order
|
||||||
$ret = view("admin.payment.modal_credit_status", compact('UserCredit', 'data'))->render();
|
$ret = view("admin.payment.modal_credit_status", compact('UserCredit', 'data'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'abo_update_settings'){
|
if ($data['action'] === 'abo_update_settings') {
|
||||||
$user_abo = UserAbo::find($data['id']);
|
$user_abo = UserAbo::find($data['id']);
|
||||||
if($data['view'] === 'admin'){
|
if ($data['view'] === 'admin') {
|
||||||
$route = route('admin_abos_update', [$user_abo->id]);
|
$route = route('admin_abos_update', [$user_abo->id]);
|
||||||
}else{
|
} else {
|
||||||
$route = route('user_abos_update', [$data['view'], $user_abo->id]);
|
$route = route('user_abos_update', [$data['view'], $user_abo->id]);
|
||||||
}
|
}
|
||||||
$ret = view("admin.abo.modal_abo_update", compact('user_abo', 'data', 'route'))->render();
|
$ret = view("admin.abo.modal_abo_update", compact('user_abo', 'data', 'route'))->render();
|
||||||
}
|
}
|
||||||
if($data['action'] === 'abo-add-product') {
|
if ($data['action'] === 'abo-add-product') {
|
||||||
$user_abo = UserAbo::find($data['id']);
|
$user_abo = UserAbo::find($data['id']);
|
||||||
$ret = view("user.abo.modal_abo_show_products", compact( 'data', 'user_abo'))->render();
|
$ret = view("user.abo.modal_abo_show_products", compact('data', 'user_abo'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'create-dhl-shipment') {
|
if ($data['action'] === 'create-dhl-shipment') {
|
||||||
$id = $data['id'] ?? null;
|
$id = $data['id'] ?? null;
|
||||||
$ret = $this->handleDhlShipmentModal($id, $data);
|
$ret = $this->handleDhlShipmentModal($id, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return response()->json(['response' => $data, 'html'=>$ret, 'status'=>$status]);
|
return response()->json(['response' => $data, 'html' => $ret, 'status' => $status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getForBusinessUserDetail(User $user, $data){
|
private function getForBusinessUserDetail(User $user, $data)
|
||||||
|
{
|
||||||
|
|
||||||
//$auth_user = \Auth::user();
|
//$auth_user = \Auth::user();
|
||||||
//if($auth_user->isAdmin() || $auth_user->id === $user->id){
|
//if($auth_user->isAdmin() || $auth_user->id === $user->id){
|
||||||
if($data['optimized']){
|
if ($data['optimized']) {
|
||||||
$TreeCalcBot = new TreeCalcBotOptimized($data['month'], $data['year'], $data['init_from'], $data['live']);
|
$TreeCalcBot = new TreeCalcBotOptimized($data['month'], $data['year'], $data['init_from'], $data['live']);
|
||||||
}else{
|
} else {
|
||||||
$TreeCalcBot = new TreeCalcBot($data['month'], $data['year'], $data['init_from']);
|
$TreeCalcBot = new TreeCalcBot($data['month'], $data['year'], $data['init_from']);
|
||||||
}
|
}
|
||||||
$TreeCalcBot->initBusinesslUserDetail($user, $data['live']);
|
$TreeCalcBot->initBusinesslUserDetail($user, $data['live']);
|
||||||
//TODO is not Admin, read is user in Parent tree ...
|
//TODO is not Admin, read is user in Parent tree ...
|
||||||
if(!$TreeCalcBot->business_user){
|
if (!$TreeCalcBot->business_user) {
|
||||||
abort(403, 'no user found');
|
abort(403, 'no user found');
|
||||||
}
|
}
|
||||||
return $TreeCalcBot;
|
return $TreeCalcBot;
|
||||||
//}
|
//}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -221,7 +220,6 @@ class ModalController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return view("admin.dhl.modal_create_shipment", $viewData)->render();
|
return view("admin.dhl.modal_create_shipment", $viewData)->render();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error('[ModalController] Error in DHL shipment modal', [
|
\Log::error('[ModalController] Error in DHL shipment modal', [
|
||||||
'order_id' => $id,
|
'order_id' => $id,
|
||||||
|
|
@ -240,7 +238,6 @@ class ModalController extends Controller
|
||||||
'productCodes' => [
|
'productCodes' => [
|
||||||
'V01PAK' => 'DHL Paket (National)',
|
'V01PAK' => 'DHL Paket (National)',
|
||||||
'V53WPAK' => 'DHL Paket International',
|
'V53WPAK' => 'DHL Paket International',
|
||||||
'V54EPAK' => 'DHL Express'
|
|
||||||
],
|
],
|
||||||
'errors' => ['Fehler beim Laden der Daten: ' . $e->getMessage()],
|
'errors' => ['Fehler beim Laden der Daten: ' . $e->getMessage()],
|
||||||
'warnings' => []
|
'warnings' => []
|
||||||
|
|
@ -249,7 +246,6 @@ class ModalController extends Controller
|
||||||
return view("admin.dhl.modal_create_shipment", $errorData)->render();
|
return view("admin.dhl.modal_create_shipment", $errorData)->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
0
app/Http/Controllers/PaymentMethodController.php
Executable file → Normal file
0
app/Http/Controllers/PaymentMethodController.php
Executable file → Normal file
15
app/Http/Controllers/Portal/Auth/LoginController.php
Executable file → Normal file
15
app/Http/Controllers/Portal/Auth/LoginController.php
Executable file → Normal file
|
|
@ -23,7 +23,7 @@ class LoginController extends Controller
|
||||||
public function showLoginForm()
|
public function showLoginForm()
|
||||||
{
|
{
|
||||||
//wenn als Berater eingeloggt, dann zum Login wechseln
|
//wenn als Berater eingeloggt, dann zum Login wechseln
|
||||||
if(Auth::guard('user')->check()){
|
if (Auth::guard('user')->check()) {
|
||||||
return redirect()->route('portal.change_login');
|
return redirect()->route('portal.change_login');
|
||||||
}
|
}
|
||||||
//wenn als Kunde eingeloggt, dann direkt zum Dashboard
|
//wenn als Kunde eingeloggt, dann direkt zum Dashboard
|
||||||
|
|
@ -41,9 +41,12 @@ class LoginController extends Controller
|
||||||
|
|
||||||
// 1. Prüfen, ob die E-Mail im System bekannt ist über Kunden-Tabelle)
|
// 1. Prüfen, ob die E-Mail im System bekannt ist über Kunden-Tabelle)
|
||||||
$customer = Customer::firstOrCreate(['email' => $email]); // Erstellt Kunden, wenn nicht vorhanden
|
$customer = Customer::firstOrCreate(['email' => $email]); // Erstellt Kunden, wenn nicht vorhanden
|
||||||
if($customer && $customer->language){
|
if ($customer && $customer->language) {
|
||||||
\App::setLocale($customer->language);
|
\App::setLocale($customer->language);
|
||||||
}
|
}
|
||||||
|
//add user_shop_domain for back
|
||||||
|
$customer->user_shop_domain = session('user_shop_domain');
|
||||||
|
$customer->save();
|
||||||
|
|
||||||
// if (!$customerExists && !$orderExists) { // Oder nur eine Prüfung, je nach Logik
|
// if (!$customerExists && !$orderExists) { // Oder nur eine Prüfung, je nach Logik
|
||||||
if (!$customer) { // Prüfung anhand des Customer-Models
|
if (!$customer) { // Prüfung anhand des Customer-Models
|
||||||
|
|
@ -86,7 +89,7 @@ class LoginController extends Controller
|
||||||
public function showOtpForm(Request $request, $email = null, $otp = null)
|
public function showOtpForm(Request $request, $email = null, $otp = null)
|
||||||
{
|
{
|
||||||
//wenn als Berater eingeloggt, dann zum Login wechseln
|
//wenn als Berater eingeloggt, dann zum Login wechseln
|
||||||
if(Auth::guard('user')->check()){
|
if (Auth::guard('user')->check()) {
|
||||||
return redirect()->route('portal.change_login');
|
return redirect()->route('portal.change_login');
|
||||||
}
|
}
|
||||||
//wenn als Kunde eingeloggt, dann zum Dashboard wechseln
|
//wenn als Kunde eingeloggt, dann zum Dashboard wechseln
|
||||||
|
|
@ -94,7 +97,7 @@ class LoginController extends Controller
|
||||||
return redirect()->route('portal.dashboard');
|
return redirect()->route('portal.dashboard');
|
||||||
}
|
}
|
||||||
// E-Mail aus der Session holen (oder als Request-Parameter erwarten)
|
// E-Mail aus der Session holen (oder als Request-Parameter erwarten)
|
||||||
if($email) {
|
if ($email) {
|
||||||
$email = $email;
|
$email = $email;
|
||||||
} else {
|
} else {
|
||||||
$email = session('otp_email', $request->query('email'));
|
$email = session('otp_email', $request->query('email'));
|
||||||
|
|
@ -152,7 +155,7 @@ class LoginController extends Controller
|
||||||
|
|
||||||
// 8. customer DB aktualisieren
|
// 8. customer DB aktualisieren
|
||||||
$shopping_user = ShoppingUser::where('billing_email', $email)->latest()->first();
|
$shopping_user = ShoppingUser::where('billing_email', $email)->latest()->first();
|
||||||
if($shopping_user){
|
if ($shopping_user) {
|
||||||
$data = [
|
$data = [
|
||||||
'name' => $shopping_user->billing_firstname . ' ' . $shopping_user->billing_lastname,
|
'name' => $shopping_user->billing_firstname . ' ' . $shopping_user->billing_lastname,
|
||||||
'shopping_user_id' => $shopping_user->id,
|
'shopping_user_id' => $shopping_user->id,
|
||||||
|
|
@ -161,7 +164,7 @@ class LoginController extends Controller
|
||||||
'language' => session('locale') ?? 'de',
|
'language' => session('locale') ?? 'de',
|
||||||
];
|
];
|
||||||
$customer->update($data);
|
$customer->update($data);
|
||||||
}else{
|
} else {
|
||||||
$data = [
|
$data = [
|
||||||
'name' => __('portal.guest'),
|
'name' => __('portal.guest'),
|
||||||
'shopping_user_id' => null,
|
'shopping_user_id' => null,
|
||||||
|
|
|
||||||
0
app/Http/Controllers/Portal/InController.php
Executable file → Normal file
0
app/Http/Controllers/Portal/InController.php
Executable file → Normal file
0
app/Http/Controllers/ProductController.php
Executable file → Normal file
0
app/Http/Controllers/ProductController.php
Executable file → Normal file
153
app/Http/Controllers/SalesController.php
Executable file → Normal file
153
app/Http/Controllers/SalesController.php
Executable file → Normal file
|
|
@ -16,25 +16,25 @@ use App\Services\BusinessPlan\SalesPointsVolume;
|
||||||
class SalesController extends Controller
|
class SalesController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct()
|
||||||
|
{
|
||||||
$this->middleware('admin');
|
$this->middleware('admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function users(){
|
public function users()
|
||||||
|
{
|
||||||
|
|
||||||
if(Request::get('reset') === 'filter'){
|
if (Request::get('reset') === 'filter') {
|
||||||
return redirect(route('admin_sales_users'));
|
return redirect(route('admin_sales_users'));
|
||||||
}
|
}
|
||||||
$data = [
|
$data = [];
|
||||||
|
|
||||||
];
|
|
||||||
return view('admin.sales.users', $data);
|
return view('admin.sales.users', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function usersDetail($id)
|
public function usersDetail($id)
|
||||||
{
|
{
|
||||||
$ShoppingOrder = ShoppingOrder::find($id);
|
$ShoppingOrder = ShoppingOrder::find($id);
|
||||||
if( $ShoppingOrder->payment_for === 6 || $ShoppingOrder->payment_for === 7){
|
if ($ShoppingOrder->payment_for === 6 || $ShoppingOrder->payment_for === 7) {
|
||||||
return redirect(route('admin_sales_customers_detail', [$ShoppingOrder->id]));
|
return redirect(route('admin_sales_customers_detail', [$ShoppingOrder->id]));
|
||||||
abort(403, 'Kundenbestellung');
|
abort(403, 'Kundenbestellung');
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,8 @@ class SalesController extends Controller
|
||||||
return view('admin.sales.user_detail', $data);
|
return view('admin.sales.user_detail', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function usersDatatable(){
|
public function usersDatatable()
|
||||||
|
{
|
||||||
|
|
||||||
$query = ShoppingOrder::with('shopping_user', 'user_shop', 'shopping_payments')->select('shopping_orders.*')->where('shopping_orders.auth_user_id', '!=', NULL);
|
$query = ShoppingOrder::with('shopping_user', 'user_shop', 'shopping_payments')->select('shopping_orders.*')->where('shopping_orders.auth_user_id', '!=', NULL);
|
||||||
|
|
||||||
|
|
@ -76,29 +77,35 @@ class SalesController extends Controller
|
||||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||||
})
|
})
|
||||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return '<span class="no-line-break">'.$ShoppingOrder->getFormattedTotalShipping()." €</span>";
|
return '<span class="no-line-break">' . $ShoppingOrder->getFormattedTotalShipping() . " €</span>";
|
||||||
})
|
})
|
||||||
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
||||||
})
|
})
|
||||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||||
if($ShoppingOrder->payment_for === 8){
|
if ($ShoppingOrder->payment_for === 8) {
|
||||||
return '<button type="button" class="btn btn-xs btn-info btn-round" data-toggle="modal" data-target="#modals-load-content"
|
return '<button type="button" class="btn btn-xs btn-info btn-round" data-toggle="modal" data-target="#modals-load-content"
|
||||||
data-id="'.$ShoppingOrder->id.'"
|
data-id="' . $ShoppingOrder->id . '"
|
||||||
data-action="shop-user-order-shipping-detail"
|
data-action="shop-user-order-shipping-detail"
|
||||||
data-back=""
|
data-back=""
|
||||||
data-modal="modal-xl"
|
data-modal="modal-xl"
|
||||||
data-init_from="user"
|
data-init_from="user"
|
||||||
data-route="'.route('modal_load').'"><span class="fa fa-eye"></span></button>';
|
data-route="' . route('modal_load') . '"><span class="fa fa-eye"></span></button>';
|
||||||
}
|
}
|
||||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
return '<span class="badge badge-pill badge-' . $ShoppingOrder->getShippedColor() . '">' . $ShoppingOrder->getShippedType() . '</span>';
|
||||||
|
})
|
||||||
|
->addColumn('dhl_button', function (ShoppingOrder $ShoppingOrder) {
|
||||||
|
return '<button type="button" class="btn btn-xs btn-' . ($ShoppingOrder->hasDhlShipments() ? 'primary' : 'secondary') . '" data-toggle="modal" data-target="#modals-load-content"
|
||||||
|
data-id="' . $ShoppingOrder->id . '"
|
||||||
|
data-action="create-dhl-shipment"
|
||||||
|
data-route="' . route('modal_load') . '"><span class="fa fa-shipping-fast"></span></button>';
|
||||||
})
|
})
|
||||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return Payment::getPaymentForBadge($ShoppingOrder);
|
return Payment::getPaymentForBadge($ShoppingOrder);
|
||||||
})
|
})
|
||||||
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->isInvoice() ? '<span class="no-line-break"><a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'download']).'" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a>
|
return $ShoppingOrder->isInvoice() ? '<span class="no-line-break"><a href="' . route('storage_file', [$ShoppingOrder->id, 'invoice', 'download']) . '" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a>
|
||||||
<a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'stream']).'" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a></span>' : '-';
|
<a href="' . route('storage_file', [$ShoppingOrder->id, 'invoice', 'stream']) . '" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a></span>' : '-';
|
||||||
})
|
})
|
||||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||||
|
|
@ -107,11 +114,11 @@ class SalesController extends Controller
|
||||||
return $ShoppingOrder->shopping_user ? $ShoppingOrder->shopping_user->orders : '';
|
return $ShoppingOrder->shopping_user ? $ShoppingOrder->shopping_user->orders : '';
|
||||||
})
|
})
|
||||||
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->user_shop ? '<a href="'.$ShoppingOrder->user_shop->getSubdomain(false).'" target="_blank">'.$ShoppingOrder->user_shop->getSubdomain(false).'</span>' : '';
|
return $ShoppingOrder->user_shop ? '<a href="' . $ShoppingOrder->user_shop->getSubdomain(false) . '" target="_blank">' . $ShoppingOrder->user_shop->getSubdomain(false) . '</span>' : '';
|
||||||
})
|
})
|
||||||
->addColumn('auth_user_shop', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('auth_user_shop', function (ShoppingOrder $ShoppingOrder) {
|
||||||
$auth_user_shop = UserShop::whereUserId($ShoppingOrder->auth_user_id)->first();
|
$auth_user_shop = UserShop::whereUserId($ShoppingOrder->auth_user_id)->first();
|
||||||
return $auth_user_shop ? '<a href="'.$auth_user_shop->getSubdomain(false).'" target="_blank">'.$auth_user_shop->getSubdomain(false).'</span>' : '-';
|
return $auth_user_shop ? '<a href="' . $auth_user_shop->getSubdomain(false) . '" target="_blank">' . $auth_user_shop->getSubdomain(false) . '</span>' : '-';
|
||||||
})
|
})
|
||||||
->orderColumn('id', 'id $1')
|
->orderColumn('id', 'id $1')
|
||||||
->orderColumn('txaction', 'txaction $1')
|
->orderColumn('txaction', 'txaction $1')
|
||||||
|
|
@ -120,13 +127,13 @@ class SalesController extends Controller
|
||||||
->orderColumn('total_shipping', 'total_shipping $1')
|
->orderColumn('total_shipping', 'total_shipping $1')
|
||||||
->orderColumn('payment_for', 'payment_for $1')
|
->orderColumn('payment_for', 'payment_for $1')
|
||||||
|
|
||||||
->rawColumns(['id', 'txaction', 'user_shop_id', 'auth_user_shop', 'payment_for', 'total_shipping', 'invoice', 'shipped'])
|
->rawColumns(['id', 'dhl_button', 'txaction', 'user_shop_id', 'auth_user_shop', 'payment_for', 'total_shipping', 'invoice', 'shipped'])
|
||||||
->make(true);
|
->make(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function customers()
|
public function customers()
|
||||||
{
|
{
|
||||||
if(Request::get('reset') === 'filter'){
|
if (Request::get('reset') === 'filter') {
|
||||||
set_user_attr('filter_user_shop_id', null);
|
set_user_attr('filter_user_shop_id', null);
|
||||||
set_user_attr('filter_txaction', null);
|
set_user_attr('filter_txaction', null);
|
||||||
set_user_attr('filter_member_id', null);
|
set_user_attr('filter_member_id', null);
|
||||||
|
|
@ -153,10 +160,10 @@ class SalesController extends Controller
|
||||||
public function customersDetail($id)
|
public function customersDetail($id)
|
||||||
{
|
{
|
||||||
$ShoppingOrder = ShoppingOrder::find($id);
|
$ShoppingOrder = ShoppingOrder::find($id);
|
||||||
if(!$ShoppingOrder){
|
if (!$ShoppingOrder) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
if( $ShoppingOrder->payment_for !== 6 && $ShoppingOrder->payment_for !== 7){
|
if ($ShoppingOrder->payment_for !== 6 && $ShoppingOrder->payment_for !== 7) {
|
||||||
return redirect(route('admin_sales_users_detail', [$ShoppingOrder->id]));
|
return redirect(route('admin_sales_users_detail', [$ShoppingOrder->id]));
|
||||||
abort(403, 'Beraterbestellung');
|
abort(403, 'Beraterbestellung');
|
||||||
}
|
}
|
||||||
|
|
@ -178,10 +185,10 @@ class SalesController extends Controller
|
||||||
{
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
$change_member_error = false;
|
$change_member_error = false;
|
||||||
if($data['action']==='shopping-order-change-member'){
|
if ($data['action'] === 'shopping-order-change-member') {
|
||||||
if(!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')){
|
if (!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')) {
|
||||||
$change_member_error = "Das Passwort ist falsch.";
|
$change_member_error = "Das Passwort ist falsch.";
|
||||||
}else{
|
} else {
|
||||||
//change
|
//change
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
CustomerPriority::newMemberForOrder($shopping_order, $data['change_member_id'], $data['customer_set_member_for']);
|
CustomerPriority::newMemberForOrder($shopping_order, $data['change_member_id'], $data['customer_set_member_for']);
|
||||||
|
|
@ -189,12 +196,12 @@ class SalesController extends Controller
|
||||||
return redirect(route('admin_sales_customers_detail', [$shopping_order->id]));
|
return redirect(route('admin_sales_customers_detail', [$shopping_order->id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($data['action']==='shopping-user-is-like-member'){
|
if ($data['action'] === 'shopping-user-is-like-member') {
|
||||||
if(!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')){
|
if (!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')) {
|
||||||
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
|
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
|
||||||
return redirect($data['back']);
|
return redirect($data['back']);
|
||||||
}else{
|
} else {
|
||||||
if(!isset($data['is_like_shopping_user_id'])){
|
if (!isset($data['is_like_shopping_user_id'])) {
|
||||||
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
|
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
|
||||||
return redirect($data['back']);
|
return redirect($data['back']);
|
||||||
}
|
}
|
||||||
|
|
@ -208,12 +215,12 @@ class SalesController extends Controller
|
||||||
return redirect($data['back']);
|
return redirect($data['back']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($data['action']==='shopping-order-change-points'){
|
if ($data['action'] === 'shopping-order-change-points') {
|
||||||
if(!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')){
|
if (!isset($data['change_member_key']) || $data['change_member_key'] !== config('mivita.edit_data_pass')) {
|
||||||
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
|
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
|
||||||
return back();
|
return back();
|
||||||
}else{
|
} else {
|
||||||
if(!isset($data['change_points'])){
|
if (!isset($data['change_points'])) {
|
||||||
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
|
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
|
||||||
return back();
|
return back();
|
||||||
}
|
}
|
||||||
|
|
@ -231,24 +238,24 @@ class SalesController extends Controller
|
||||||
return view('admin.sales.customer_detail', $data);
|
return view('admin.sales.customer_detail', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function customersDatatable(){
|
public function customersDatatable()
|
||||||
|
{
|
||||||
|
|
||||||
$query = ShoppingOrder::with('shopping_user')->select('shopping_orders.*')->where('shopping_orders.auth_user_id', NULL);
|
$query = ShoppingOrder::with('shopping_user')->select('shopping_orders.*')->where('shopping_orders.auth_user_id', NULL);
|
||||||
set_user_attr('filter_user_shop_id', Request::get('filter_user_shop_id'));
|
set_user_attr('filter_user_shop_id', Request::get('filter_user_shop_id'));
|
||||||
if(Request::get('filter_user_shop_id') != ""){
|
if (Request::get('filter_user_shop_id') != "") {
|
||||||
$query->where('user_shop_id', '=', Request::get('filter_user_shop_id'));
|
$query->where('user_shop_id', '=', Request::get('filter_user_shop_id'));
|
||||||
}
|
}
|
||||||
set_user_attr('filter_txaction', Request::get('filter_txaction'));
|
set_user_attr('filter_txaction', Request::get('filter_txaction'));
|
||||||
if(Request::get('filter_txaction') != ""){
|
if (Request::get('filter_txaction') != "") {
|
||||||
if(Request::get('filter_txaction') === 'NULL'){
|
if (Request::get('filter_txaction') === 'NULL') {
|
||||||
$query->where('txaction', '=', NULL);
|
$query->where('txaction', '=', NULL);
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
$query->where('txaction', '=', Request::get('filter_txaction'));
|
$query->where('txaction', '=', Request::get('filter_txaction'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_user_attr('filter_member_id', Request::get('filter_member_id'));
|
set_user_attr('filter_member_id', Request::get('filter_member_id'));
|
||||||
if(Request::get('filter_member_id') != ""){
|
if (Request::get('filter_member_id') != "") {
|
||||||
$query->where('member_id', '=', Request::get('filter_member_id'));
|
$query->where('member_id', '=', Request::get('filter_member_id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,49 +270,55 @@ class SalesController extends Controller
|
||||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||||
})
|
})
|
||||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return '<span class="no-line-break">'.$ShoppingOrder->getFormattedTotalShipping()." €</span>";
|
return '<span class="no-line-break">' . $ShoppingOrder->getFormattedTotalShipping() . " €</span>";
|
||||||
})
|
})
|
||||||
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
||||||
if($ShoppingOrder->txaction === 'extern_paid'){
|
if ($ShoppingOrder->txaction === 'extern_paid') {
|
||||||
$shopping_oder_id = isset($ShoppingOrder->api_notice['shopping_order_id']) ? $ShoppingOrder->api_notice['shopping_order_id'] : null;
|
$shopping_oder_id = isset($ShoppingOrder->api_notice['shopping_order_id']) ? $ShoppingOrder->api_notice['shopping_order_id'] : null;
|
||||||
if($shopping_oder_id){
|
if ($shopping_oder_id) {
|
||||||
return '<a class="btn btn-xs btn-default btn-round" href="'.route('admin_sales_users_detail', [$shopping_oder_id]).'"><i class="fa fa-check fa-check-circle-o"> '.$shopping_oder_id.'</a>';
|
return '<a class="btn btn-xs btn-default btn-round" href="' . route('admin_sales_users_detail', [$shopping_oder_id]) . '"><i class="fa fa-check fa-check-circle-o"> ' . $shopping_oder_id . '</a>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
||||||
})
|
})
|
||||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
return '<span class="badge badge-pill badge-' . $ShoppingOrder->getShippedColor() . '">' . $ShoppingOrder->getShippedType() . '</span>';
|
||||||
|
})
|
||||||
|
->addColumn('dhl_button', function (ShoppingOrder $ShoppingOrder) {
|
||||||
|
return '<button type="button" class="btn btn-xs btn-' . ($ShoppingOrder->hasDhlShipments() ? 'primary' : 'secondary') . '" data-toggle="modal" data-target="#modals-load-content"
|
||||||
|
data-id="' . $ShoppingOrder->id . '"
|
||||||
|
data-action="create-dhl-shipment"
|
||||||
|
data-route="' . route('modal_load') . '"><span class="fa fa-shipping-fast"></span></button>';
|
||||||
})
|
})
|
||||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return Payment::getPaymentForBadge($ShoppingOrder);
|
return Payment::getPaymentForBadge($ShoppingOrder);
|
||||||
})
|
})
|
||||||
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
||||||
if(($ShoppingOrder->txaction === 'extern' || $ShoppingOrder->txaction === 'extern_paid') && $ShoppingOrder->wp_invoice_path){
|
if (($ShoppingOrder->txaction === 'extern' || $ShoppingOrder->txaction === 'extern_paid') && $ShoppingOrder->wp_invoice_path) {
|
||||||
return '<span class="no-line-break"><a href="'.$ShoppingOrder->wp_invoice_path.'" class="btn btn-secondary btn-xs"><i class="fa fa-external-link-alt"></i> <i class="fa fa-download"></i></a> </div>';
|
return '<span class="no-line-break"><a href="' . $ShoppingOrder->wp_invoice_path . '" class="btn btn-secondary btn-xs"><i class="fa fa-external-link-alt"></i> <i class="fa fa-download"></i></a> </div>';
|
||||||
}
|
}
|
||||||
return $ShoppingOrder->isInvoice() ? '<span class="no-line-break"><a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'download']).'" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a>
|
return $ShoppingOrder->isInvoice() ? '<span class="no-line-break"><a href="' . route('storage_file', [$ShoppingOrder->id, 'invoice', 'download']) . '" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a>
|
||||||
<a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'stream']).'" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a></span>' : '-';
|
<a href="' . route('storage_file', [$ShoppingOrder->id, 'invoice', 'stream']) . '" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a></span>' : '-';
|
||||||
})
|
})
|
||||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||||
})
|
})
|
||||||
->addColumn('member_id', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('member_id', function (ShoppingOrder $ShoppingOrder) {
|
||||||
if($ShoppingOrder->member_id && $ShoppingOrder->member) {
|
if ($ShoppingOrder->member_id && $ShoppingOrder->member) {
|
||||||
return $ShoppingOrder->member ? '<a href="' . route('admin_lead_edit', [$ShoppingOrder->member_id]) . '">' . $ShoppingOrder->member->getFullName() . '</a>' : 'gelöscht';
|
return $ShoppingOrder->member ? '<a href="' . route('admin_lead_edit', [$ShoppingOrder->member_id]) . '">' . $ShoppingOrder->member->getFullName() . '</a>' : 'gelöscht';
|
||||||
}
|
}
|
||||||
if($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like){
|
if ($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like) {
|
||||||
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
|
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
|
||||||
data-id="'.$ShoppingOrder->shopping_user->id.'"
|
data-id="' . $ShoppingOrder->shopping_user->id . '"
|
||||||
data-action="shopping-user-is-like-member"
|
data-action="shopping-user-is-like-member"
|
||||||
data-back="'.route('admin_sales_customers').'"
|
data-back="' . route('admin_sales_customers') . '"
|
||||||
data-modal="modal-xl"
|
data-modal="modal-xl"
|
||||||
data-route="'.route('modal_load').'"><span class="fa fa-edit"></span> Berater zuordnen</button>';
|
data-route="' . route('modal_load') . '"><span class="fa fa-edit"></span> Berater zuordnen</button>';
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
})
|
})
|
||||||
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
||||||
return $ShoppingOrder->user_shop ? '<a href="'.$ShoppingOrder->user_shop->getSubdomain(false).'" target="_blank">'.$ShoppingOrder->user_shop->getSubdomain(false).'</span>' : '';
|
return $ShoppingOrder->user_shop ? '<a href="' . $ShoppingOrder->user_shop->getSubdomain(false) . '" target="_blank">' . $ShoppingOrder->user_shop->getSubdomain(false) . '</span>' : '';
|
||||||
})
|
})
|
||||||
->orderColumn('id', 'id $1')
|
->orderColumn('id', 'id $1')
|
||||||
->orderColumn('txaction', 'txaction $1')
|
->orderColumn('txaction', 'txaction $1')
|
||||||
|
|
@ -314,23 +327,24 @@ class SalesController extends Controller
|
||||||
->orderColumn('shipped', 'shipped $1')
|
->orderColumn('shipped', 'shipped $1')
|
||||||
->orderColumn('payment_for', 'payment_for $1')
|
->orderColumn('payment_for', 'payment_for $1')
|
||||||
->orderColumn('total_shipping', 'total_shipping $1')
|
->orderColumn('total_shipping', 'total_shipping $1')
|
||||||
->rawColumns(['id', 'member_id', 'txaction', 'user_shop_id', 'payment_for', 'payment', 'total_shipping', 'invoice', 'shipped'])
|
->rawColumns(['id', 'dhl_button', 'member_id', 'txaction', 'user_shop_id', 'payment_for', 'payment', 'total_shipping', 'invoice', 'shipped'])
|
||||||
->make(true);
|
->make(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(){
|
public function store()
|
||||||
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if(!isset($data['id'])){
|
if (!isset($data['id'])) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
if(isset($data['action'])){
|
if (isset($data['action'])) {
|
||||||
if($data['action'] === 'store_shipped' && isset($data['shipped'])){
|
if ($data['action'] === 'store_shipped' && isset($data['shipped'])) {
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
$shopping_order->shipped = $data['shipped'];
|
$shopping_order->shipped = $data['shipped'];
|
||||||
$shopping_order->save();
|
$shopping_order->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])){
|
if ($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])) {
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
$shopping_payment = ShoppingPayment::findOrFail($data['payment_id']);
|
$shopping_payment = ShoppingPayment::findOrFail($data['payment_id']);
|
||||||
|
|
||||||
|
|
@ -356,37 +370,36 @@ class SalesController extends Controller
|
||||||
//wenn muss hier die Storno erstellt werden
|
//wenn muss hier die Storno erstellt werden
|
||||||
//Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
//Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if(isset($data['back'])){
|
if (isset($data['back'])) {
|
||||||
return redirect($data['back']);
|
return redirect($data['back']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Manuelle Rechnung erstellen.*/
|
Manuelle Rechnung erstellen.*/
|
||||||
public function invoice(){
|
public function invoice()
|
||||||
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if(!isset($data['id'])){
|
if (!isset($data['id'])) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
if(isset($data['action'])){
|
if (isset($data['action'])) {
|
||||||
if($data['action'] === 'create_invoice'){
|
if ($data['action'] === 'create_invoice') {
|
||||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||||
|
|
||||||
$invoice_repo = new InvoiceRepository($shopping_order);
|
$invoice_repo = new InvoiceRepository($shopping_order);
|
||||||
if($shopping_order->isInvoice()){
|
if ($shopping_order->isInvoice()) {
|
||||||
$invoice_repo->update($data);
|
$invoice_repo->update($data);
|
||||||
}else{
|
} else {
|
||||||
$invoice_repo->createAndSalesVolume($data);
|
$invoice_repo->createAndSalesVolume($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['view']) && $data['view'] === 'sales_customer'){
|
if (isset($data['view']) && $data['view'] === 'sales_customer') {
|
||||||
return redirect(route('admin_sales_customers_detail', [$shopping_order->id]));
|
return redirect(route('admin_sales_customers_detail', [$shopping_order->id]));
|
||||||
}
|
}
|
||||||
return redirect(route('admin_sales_users_detail', [$shopping_order->id]));
|
return redirect(route('admin_sales_users_detail', [$shopping_order->id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -54,9 +54,13 @@ class SettingController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getDhlConfig()
|
public function getDhlConfig()
|
||||||
{
|
{
|
||||||
|
// Check if we're in test/sandbox mode
|
||||||
|
$isTestMode = config('dhl.legacy.test_mode', false) || config('dhl.legacy.sandbox', false);
|
||||||
|
$baseUrl = $isTestMode ? config('dhl.sandbox_url') : config('dhl.base_url');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// API Settings
|
// API Settings
|
||||||
'base_url' => Setting::getContentBySlug('dhl_base_url') ?: config('dhl.base_url'),
|
'base_url' => $isTestMode ? $baseUrl : (Setting::getContentBySlug('dhl_base_url') ?: $baseUrl),
|
||||||
'api_key' => Setting::getContentBySlug('dhl_api_key') ?: config('dhl.api_key'),
|
'api_key' => Setting::getContentBySlug('dhl_api_key') ?: config('dhl.api_key'),
|
||||||
'username' => Setting::getContentBySlug('dhl_username') ?: config('dhl.username'),
|
'username' => Setting::getContentBySlug('dhl_username') ?: config('dhl.username'),
|
||||||
'password' => Setting::getContentBySlug('dhl_password') ?: config('dhl.password'),
|
'password' => Setting::getContentBySlug('dhl_password') ?: config('dhl.password'),
|
||||||
|
|
@ -91,6 +95,15 @@ class SettingController extends Controller
|
||||||
'default' => config('dhl.account_numbers.default'),
|
'default' => config('dhl.account_numbers.default'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
|
// Dimensions
|
||||||
|
'dimensions' => [
|
||||||
|
'V01PAK' => config('dhl.dimensions.V01PAK'),
|
||||||
|
'V62WP' => config('dhl.dimensions.V62WP'),
|
||||||
|
'V53PAK' => config('dhl.dimensions.V53PAK'),
|
||||||
|
'V07PAK' => config('dhl.dimensions.V07PAK'),
|
||||||
|
'default' => config('dhl.dimensions.default'),
|
||||||
|
],
|
||||||
// Static config values (webhook, profile, legacy)
|
// Static config values (webhook, profile, legacy)
|
||||||
'profile' => config('dhl.profile'),
|
'profile' => config('dhl.profile'),
|
||||||
'webhook' => config('dhl.webhook'),
|
'webhook' => config('dhl.webhook'),
|
||||||
|
|
|
||||||
0
app/Http/Controllers/ShippingController.php
Executable file → Normal file
0
app/Http/Controllers/ShippingController.php
Executable file → Normal file
0
app/Http/Controllers/SitesController.php
Executable file → Normal file
0
app/Http/Controllers/SitesController.php
Executable file → Normal file
0
app/Http/Controllers/SyS/SettingController.php
Executable file → Normal file
0
app/Http/Controllers/SyS/SettingController.php
Executable file → Normal file
0
app/Http/Controllers/TemplateController.php
Executable file → Normal file
0
app/Http/Controllers/TemplateController.php
Executable file → Normal file
0
app/Http/Controllers/TranslationController.php
Executable file → Normal file
0
app/Http/Controllers/TranslationController.php
Executable file → Normal file
0
app/Http/Controllers/TranslationFileController.php
Executable file → Normal file
0
app/Http/Controllers/TranslationFileController.php
Executable file → Normal file
0
app/Http/Controllers/User/CustomerController.php
Executable file → Normal file
0
app/Http/Controllers/User/CustomerController.php
Executable file → Normal file
0
app/Http/Controllers/User/HomepartyController.php
Executable file → Normal file
0
app/Http/Controllers/User/HomepartyController.php
Executable file → Normal file
0
app/Http/Controllers/User/MembershipController.php
Executable file → Normal file
0
app/Http/Controllers/User/MembershipController.php
Executable file → Normal file
0
app/Http/Controllers/User/OrderController.php
Executable file → Normal file
0
app/Http/Controllers/User/OrderController.php
Executable file → Normal file
0
app/Http/Controllers/User/ShopSalesController.php
Executable file → Normal file
0
app/Http/Controllers/User/ShopSalesController.php
Executable file → Normal file
243
app/Http/Controllers/User/TeamController.php
Executable file → Normal file
243
app/Http/Controllers/User/TeamController.php
Executable file → Normal file
|
|
@ -64,14 +64,14 @@ class TeamController extends Controller
|
||||||
|
|
||||||
// Prüfe ob Live-Berechnung erzwungen werden soll
|
// Prüfe ob Live-Berechnung erzwungen werden soll
|
||||||
$forceLiveCalculation = Request::get('force_live_calculation', false) || Request::get('live', false);
|
$forceLiveCalculation = Request::get('force_live_calculation', false) || Request::get('live', false);
|
||||||
|
$forceLiveCalculation = false;
|
||||||
|
|
||||||
\Log::info("TeamController: Building optimized team overview for user {$user->id} ({$this->month}/{$this->year})" .
|
\Log::info("TeamController: Building optimized team overview for user {$user->id} ({$this->month}/{$this->year})" .
|
||||||
($forceLiveCalculation ? " with forced live calculation" : ""));
|
($forceLiveCalculation === true ? " with forced live calculation" : "not live calculation"));
|
||||||
|
|
||||||
// Verwende TreeCalcBotOptimized für bessere Performance
|
// Verwende TreeCalcBotOptimized für bessere Performance
|
||||||
$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'member', $forceLiveCalculation);
|
//$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'member', $forceLiveCalculation);
|
||||||
$TreeCalcBot->initStructureUser($user->id);
|
//$TreeCalcBot->initStructureUser($user->id);
|
||||||
|
|
||||||
$endTime = microtime(true);
|
$endTime = microtime(true);
|
||||||
$endMemory = memory_get_usage();
|
$endMemory = memory_get_usage();
|
||||||
|
|
||||||
|
|
@ -87,21 +87,19 @@ class TeamController extends Controller
|
||||||
'filter_active' => $this->getFilterActive(),
|
'filter_active' => $this->getFilterActive(),
|
||||||
'filter_levels' => $this->getFilterLevels(),
|
'filter_levels' => $this->getFilterLevels(),
|
||||||
'filter_next_level' => $this->getFilterNextLevel(),
|
'filter_next_level' => $this->getFilterNextLevel(),
|
||||||
'TreeCalcBot' => $TreeCalcBot,
|
//'TreeCalcBot' => $TreeCalcBot,
|
||||||
'performance' => [
|
'performance' => [
|
||||||
'execution_time' => $executionTime,
|
'execution_time' => $executionTime,
|
||||||
'memory_used' => $memoryUsed,
|
'memory_used' => $memoryUsed,
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'user_count' => $TreeCalcBot->getTotalUserCount(),
|
'user_count' => 0, //$TreeCalcBot->getTotalUserCount(),
|
||||||
'version' => 'Optimized',
|
'version' => 'Optimized',
|
||||||
'calculation_type' => $forceLiveCalculation ? 'Live' : 'Cache'
|
'calculation_type' => $forceLiveCalculation ? 'Live' : 'Cache'
|
||||||
],
|
],
|
||||||
'optimized' => true,
|
'optimized' => true,
|
||||||
'forceLiveCalculation' => $forceLiveCalculation,
|
'forceLiveCalculation' => $forceLiveCalculation,
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('user.team.show', $data);
|
return view('user.team.show', $data);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("TeamController: Error in optimized show for user {$user->id}: " . $e->getMessage());
|
\Log::error("TeamController: Error in optimized show for user {$user->id}: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -135,7 +133,7 @@ class TeamController extends Controller
|
||||||
$startMemory = memory_get_usage();
|
$startMemory = memory_get_usage();
|
||||||
|
|
||||||
$user = User::find(\Auth::user()->id);
|
$user = User::find(\Auth::user()->id);
|
||||||
if(config('app.debug')){
|
if (config('app.debug')) {
|
||||||
$user = User::find(454);
|
$user = User::find(454);
|
||||||
}
|
}
|
||||||
$this->setFilterVars();
|
$this->setFilterVars();
|
||||||
|
|
@ -157,7 +155,6 @@ class TeamController extends Controller
|
||||||
);
|
);
|
||||||
$TreeCalcBot->initStructureUser($user->id, $forceLiveCalculation);
|
$TreeCalcBot->initStructureUser($user->id, $forceLiveCalculation);
|
||||||
$optimizedUsed = true;
|
$optimizedUsed = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Standard TreeCalcBot mit Performance-Monitoring
|
// Standard TreeCalcBot mit Performance-Monitoring
|
||||||
$TreeCalcBot = new TreeCalcBot(
|
$TreeCalcBot = new TreeCalcBot(
|
||||||
|
|
@ -200,7 +197,6 @@ class TeamController extends Controller
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('user.team.structure', $data);
|
return view('user.team.structure', $data);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("TeamController: Error in structure for user {$user->id}: " . $e->getMessage());
|
\Log::error("TeamController: Error in structure for user {$user->id}: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -232,8 +228,9 @@ class TeamController extends Controller
|
||||||
}
|
}
|
||||||
public function structureOld()
|
public function structureOld()
|
||||||
{
|
{
|
||||||
|
abort(403, 'This page is removed');
|
||||||
$user = User::find(\Auth::user()->id);
|
$user = User::find(\Auth::user()->id);
|
||||||
if(config('app.debug')){
|
if (config('app.debug')) {
|
||||||
$user = User::find(454);
|
$user = User::find(454);
|
||||||
}
|
}
|
||||||
$this->setFilterVars();
|
$this->setFilterVars();
|
||||||
|
|
@ -266,18 +263,20 @@ class TeamController extends Controller
|
||||||
|
|
||||||
// Prüfe ob Live-Berechnung erzwungen werden soll
|
// Prüfe ob Live-Berechnung erzwungen werden soll
|
||||||
$forceLiveCalculation = Request::get('force_live_calculation', false) || Request::get('live', false);
|
$forceLiveCalculation = Request::get('force_live_calculation', false) || Request::get('live', false);
|
||||||
|
$forceLiveCalculation = false;
|
||||||
\Log::info("TeamController: Building optimized datatable for user {$user->id} ({$this->month}/{$this->year})" .
|
\Log::info("TeamController: Building optimized datatable for user {$user->id} ({$this->month}/{$this->year})" .
|
||||||
($forceLiveCalculation == true ? " with forced live calculation" : ""));
|
($forceLiveCalculation == true ? " with forced live calculation" : ""));
|
||||||
|
|
||||||
// Lade TreeCalcBotOptimized-Daten
|
// Lade TreeCalcBotOptimized-Daten
|
||||||
$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'member', $forceLiveCalculation);
|
$TreeCalcBot = new TreeCalcBotOptimized($this->month, $this->year, 'member', $forceLiveCalculation);
|
||||||
$TreeCalcBot->initStructureUser($user->id, $forceLiveCalculation);
|
$TreeCalcBot->initStructureUser($user->id, $forceLiveCalculation);
|
||||||
|
|
||||||
// Extrahiere alle User aus der Struktur
|
// Extrahiere alle User aus der Struktur
|
||||||
$teamUsers = collect($this->getTeamUsersFromStructure($TreeCalcBot));
|
$teamUsersRaw = $this->getTeamUsersFromStructure($TreeCalcBot);
|
||||||
// \Log::info("TeamController: TeamUsers: " . $teamUsers->count());
|
|
||||||
|
|
||||||
|
// KRITISCH: Bereinige die Objekte für DataTables (entferne zirkuläre Referenzen)
|
||||||
|
$teamUsers = collect($this->cleanBusinessUserItemsForDataTable($teamUsersRaw));
|
||||||
|
|
||||||
|
\Log::info("TeamController: TeamUsers cleaned for DataTable: " . $teamUsers->count());
|
||||||
$endTime = microtime(true);
|
$endTime = microtime(true);
|
||||||
$executionTime = round(($endTime - $startTime) * 1000, 2);
|
$executionTime = round(($endTime - $startTime) * 1000, 2);
|
||||||
$this->forceLiveCalculation = $forceLiveCalculation;
|
$this->forceLiveCalculation = $forceLiveCalculation;
|
||||||
|
|
@ -310,7 +309,6 @@ class TeamController extends Controller
|
||||||
})
|
})
|
||||||
->addColumn('user_level', function ($teamUser) {
|
->addColumn('user_level', function ($teamUser) {
|
||||||
return $teamUser->user_level_name ? TranslationHelper::transUserLevelName($teamUser->user_level_name) : '';
|
return $teamUser->user_level_name ? TranslationHelper::transUserLevelName($teamUser->user_level_name) : '';
|
||||||
|
|
||||||
})
|
})
|
||||||
->addColumn('is_qual_kp', function ($teamUser) {
|
->addColumn('is_qual_kp', function ($teamUser) {
|
||||||
$user = User::find($teamUser->user_id);
|
$user = User::find($teamUser->user_id);
|
||||||
|
|
@ -322,7 +320,6 @@ class TeamController extends Controller
|
||||||
->addColumn('sales_volume_total', function ($teamUser) {
|
->addColumn('sales_volume_total', function ($teamUser) {
|
||||||
|
|
||||||
return formatNumber($teamUser->payline_points_qual_kp, 0);
|
return formatNumber($teamUser->payline_points_qual_kp, 0);
|
||||||
|
|
||||||
})
|
})
|
||||||
->addColumn('next_level_qualified', function ($teamUser) {
|
->addColumn('next_level_qualified', function ($teamUser) {
|
||||||
|
|
||||||
|
|
@ -334,7 +331,6 @@ class TeamController extends Controller
|
||||||
return NextLevelBadgeHelper::generateBadgeFromUserBusiness($userBusiness);
|
return NextLevelBadgeHelper::generateBadgeFromUserBusiness($userBusiness);
|
||||||
}
|
}
|
||||||
return NextLevelBadgeHelper::renderNoDataBadge();
|
return NextLevelBadgeHelper::renderNoDataBadge();
|
||||||
|
|
||||||
})
|
})
|
||||||
->addColumn('active_account', function ($teamUser) {
|
->addColumn('active_account', function ($teamUser) {
|
||||||
return get_active_badge($teamUser->active_account);
|
return get_active_badge($teamUser->active_account);
|
||||||
|
|
@ -344,7 +340,6 @@ class TeamController extends Controller
|
||||||
})
|
})
|
||||||
->rawColumns(['id', 'next_level_qualified', 'active_account', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total'])
|
->rawColumns(['id', 'next_level_qualified', 'active_account', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total'])
|
||||||
->make(true);
|
->make(true);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("TeamController: Error in optimized datatable: " . $e->getMessage());
|
\Log::error("TeamController: Error in optimized datatable: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -455,21 +450,21 @@ class TeamController extends Controller
|
||||||
})
|
})
|
||||||
->filterColumn('m_account', function ($query, $keyword) {
|
->filterColumn('m_account', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereHas('account', function($q) use ($keyword) {
|
$query->whereHas('account', function ($q) use ($keyword) {
|
||||||
$q->where('m_account', 'LIKE', '%' . $keyword . '%');
|
$q->where('m_account', 'LIKE', '%' . $keyword . '%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->filterColumn('first_name', function ($query, $keyword) {
|
->filterColumn('first_name', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereHas('account', function($q) use ($keyword) {
|
$query->whereHas('account', function ($q) use ($keyword) {
|
||||||
$q->where('first_name', 'LIKE', '%' . $keyword . '%');
|
$q->where('first_name', 'LIKE', '%' . $keyword . '%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->filterColumn('last_name', function ($query, $keyword) {
|
->filterColumn('last_name', function ($query, $keyword) {
|
||||||
if ($keyword != "") {
|
if ($keyword != "") {
|
||||||
$query->whereHas('account', function($q) use ($keyword) {
|
$query->whereHas('account', function ($q) use ($keyword) {
|
||||||
$q->where('last_name', 'LIKE', '%' . $keyword . '%');
|
$q->where('last_name', 'LIKE', '%' . $keyword . '%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -487,7 +482,6 @@ class TeamController extends Controller
|
||||||
->orderColumn('active_account', 'users.payment_account $1')
|
->orderColumn('active_account', 'users.payment_account $1')
|
||||||
->rawColumns(['id', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total', 'sponsor', 'active_account', 'next_level_qualified'])
|
->rawColumns(['id', 'is_qual_kp', 'sales_volume_KP_points', 'sales_volume_total', 'sponsor', 'active_account', 'next_level_qualified'])
|
||||||
->make(true);
|
->make(true);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("TeamController: Error in userDatatable: " . $e->getMessage());
|
\Log::error("TeamController: Error in userDatatable: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -529,7 +523,6 @@ class TeamController extends Controller
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('user.team.marketingplan', $data);
|
return view('user.team.marketingplan', $data);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("TeamController: Error loading marketingplan: " . $e->getMessage());
|
\Log::error("TeamController: Error loading marketingplan: " . $e->getMessage());
|
||||||
|
|
||||||
|
|
@ -718,12 +711,12 @@ class TeamController extends Controller
|
||||||
}
|
}
|
||||||
if (Request::get('team_user_filter_level')) {
|
if (Request::get('team_user_filter_level')) {
|
||||||
session(['team_user_filter_level' => Request::get('team_user_filter_level')]);
|
session(['team_user_filter_level' => Request::get('team_user_filter_level')]);
|
||||||
}else{
|
} else {
|
||||||
session(['team_user_filter_level' => 0]);
|
session(['team_user_filter_level' => 0]);
|
||||||
}
|
}
|
||||||
if (Request::get('team_user_filter_next_level')) {
|
if (Request::get('team_user_filter_next_level')) {
|
||||||
session(['team_user_filter_next_level' => Request::get('team_user_filter_next_level')]);
|
session(['team_user_filter_next_level' => Request::get('team_user_filter_next_level')]);
|
||||||
}else{
|
} else {
|
||||||
session(['team_user_filter_next_level' => 0]);
|
session(['team_user_filter_next_level' => 0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -857,44 +850,68 @@ class TeamController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extrahiert alle User aus TreeCalcBotOptimized-Struktur für DataTable-Anzeige
|
* Extrahiert alle User aus TreeCalcBotOptimized-Struktur für DataTable-Anzeige
|
||||||
* Sammelt rekursiv alle User aus der Struktur und macht sie als flache Liste verfügbar
|
* Sammelt rekursiv alle User aus der Struktur und macht sie als FLACHE Liste verfügbar
|
||||||
*/
|
*/
|
||||||
public function getTeamUsersFromStructure(TreeCalcBotOptimized $treeCalcBot): array
|
public function getTeamUsersFromStructure(TreeCalcBotOptimized $treeCalcBot): array
|
||||||
{
|
{
|
||||||
$allUsers = [];
|
$allUsers = [];
|
||||||
$deep = 0;
|
$processedIds = [];
|
||||||
|
|
||||||
// Debug: Prüfe TreeCalcBot-Inhalt
|
// Debug: Prüfe TreeCalcBot-Inhalt
|
||||||
$businessUsers = $treeCalcBot->getItems();
|
$businessUsers = $treeCalcBot->getItems();
|
||||||
\Log::info("TeamController: TreeCalcBot items count: " . count($businessUsers));
|
\Log::info("TeamController: TreeCalcBot root items count: " . count($businessUsers));
|
||||||
|
|
||||||
// Sammle alle Root-User
|
// Sammle alle Root-User UND deren verschachtelte businessUserItems
|
||||||
foreach ($businessUsers as $businessUser) {
|
foreach ($businessUsers as $businessUser) {
|
||||||
\Log::debug("TeamController: Processing businessUser", [
|
// WICHTIG: user_id korrekt über b_user abrufen (Magic Method Problem mit isset())
|
||||||
'user_id' => ($businessUser->user_id),
|
$userId = $businessUser->user_id; // Über __get() Method
|
||||||
|
|
||||||
|
\Log::debug("TeamController: Processing root businessUser", [
|
||||||
|
'user_id' => $userId,
|
||||||
|
'businessUserItems_count' => count($businessUser->businessUserItems ?? []),
|
||||||
]);
|
]);
|
||||||
$businessUser->deep = $deep;
|
// WICHTIG: Root-User selbst hinzufügen (korrigierte user_id Prüfung)
|
||||||
|
//nur User können auch children haben - businessUserItems
|
||||||
|
if ($userId && !isset($processedIds[$userId])) {
|
||||||
|
$processedIds[$userId] = true;
|
||||||
|
$businessUser->deep = 0;
|
||||||
$allUsers[] = $businessUser;
|
$allUsers[] = $businessUser;
|
||||||
$this->collectUserIdsFromBusinessUser($businessUser, $allUsers, $deep+1, false);
|
$this->collectAllBusinessUserItemsFlat($businessUser->businessUserItems ?? [], $allUsers, $processedIds, 1);
|
||||||
|
\Log::debug("TeamController: Root-User hinzugefügt: {$userId}");
|
||||||
}
|
}
|
||||||
// Sammle parentless User
|
}
|
||||||
|
// Sammle parentless User, kann bei usern eigenlich nicht vorkommen, da sie immer teil des baums sind
|
||||||
if ($treeCalcBot->isParentless()) {
|
if ($treeCalcBot->isParentless()) {
|
||||||
$parentless = $treeCalcBot->__get('parentless');
|
$parentless = $treeCalcBot->__get('parentless');
|
||||||
//\Log::info("TeamController: Found " . count($parentless) . " parentless users");
|
|
||||||
|
|
||||||
if (is_array($parentless)) {
|
if (is_array($parentless)) {
|
||||||
foreach ($parentless as $businessUser) {
|
foreach ($parentless as $businessUser) {
|
||||||
if ($businessUser) {
|
if ($businessUser) {
|
||||||
|
// WICHTIG: user_id korrekt über b_user abrufen (Magic Method Problem mit isset())
|
||||||
|
$userId = $businessUser->user_id; // Über __get() Method
|
||||||
|
|
||||||
|
if ($userId) {
|
||||||
|
// Prüfe ob dieser parentless User bereits gesammelt wurde
|
||||||
|
if (!isset($processedIds[$userId])) {
|
||||||
|
$processedIds[$userId] = true;
|
||||||
$businessUser->deep = 0;
|
$businessUser->deep = 0;
|
||||||
$allUsers[] = $businessUser;
|
$allUsers[] = $businessUser;
|
||||||
|
|
||||||
// Sammle rekursiv alle Unter-User
|
\Log::debug("TeamController: Parentless-User hinzugefügt: {$userId}");
|
||||||
$this->collectUserIdsFromBusinessUser($businessUser, $allUsers, 0, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
\Log::info("TeamController: AllUsers before filtering: " . count($allUsers));
|
|
||||||
|
|
||||||
|
// Sammle ALLE verschachtelten businessUserItems rekursiv
|
||||||
|
$this->collectAllBusinessUserItemsFlat($businessUser->businessUserItems ?? [], $allUsers, $processedIds, 1);
|
||||||
|
} else {
|
||||||
|
\Log::debug("TeamController: Parentless-User übersprungen: {$userId} (bereits verarbeitet)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
\Log::warning("TeamController: Parentless BusinessUser ohne user_id übersprungen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\Log::info("TeamController: AllUsers before filtering: " . count($allUsers));
|
||||||
// Filter anwenden
|
// Filter anwenden
|
||||||
$filteredUsers = $this->applyTeamFiltersToBusinessUsers($allUsers);
|
$filteredUsers = $this->applyTeamFiltersToBusinessUsers($allUsers);
|
||||||
\Log::info("TeamController: AllUsers after filtering: " . count($filteredUsers));
|
\Log::info("TeamController: AllUsers after filtering: " . count($filteredUsers));
|
||||||
|
|
@ -925,7 +942,7 @@ class TeamController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$filtered = array_filter($businessUsers, function($businessUser) use ($activeFilter, $levelFilter, $nextLevelFilter) {
|
$filtered = array_filter($businessUsers, function ($businessUser) use ($activeFilter, $levelFilter, $nextLevelFilter) {
|
||||||
// Active Filter anwenden
|
// Active Filter anwenden
|
||||||
if ($activeFilter == 1) { // Nur aktive
|
if ($activeFilter == 1) { // Nur aktive
|
||||||
if (!$businessUser->active_account) {
|
if (!$businessUser->active_account) {
|
||||||
|
|
@ -977,26 +994,144 @@ class TeamController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode zum rekursiven Sammeln von User-IDs aus BusinessUser-Struktur
|
* NEUE OPTIMIERTE Methode: Sammelt ALLE BusinessUserItems in einer flachen Liste
|
||||||
|
* Perfekt für DataTable-Verarbeitung - keine verschachtelte Struktur
|
||||||
*/
|
*/
|
||||||
private function collectUserIdsFromBusinessUser($businessUser, &$allUsers, $deep, $parentless): void
|
private function collectAllBusinessUserItemsFlat(array $businessUserItems, &$allUsers, &$processedIds, $depth = 1): void
|
||||||
{
|
{
|
||||||
|
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 20 Levels)
|
||||||
|
$maxDepth = 20;
|
||||||
|
if ($depth > $maxDepth) {
|
||||||
|
\Log::warning("TeamController: Maximale Sammlungstiefe ({$maxDepth}) erreicht bei Tiefe {$depth}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($businessUserItems as $businessUserItem) {
|
||||||
|
if ($businessUserItem) {
|
||||||
|
// WICHTIG: user_id korrekt über b_user abrufen (Magic Method Problem mit isset())
|
||||||
|
$userId = $businessUserItem->user_id; // Über __get() Method
|
||||||
|
if ($userId) {
|
||||||
|
// KRITISCHER SCHUTZ: Prüfe ob User bereits gesammelt wurde
|
||||||
|
if (isset($processedIds[$userId])) {
|
||||||
|
\Log::debug("TeamController: Überspringe bereits gesammelten User {$userId} (Duplikat verhindert)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User zu flacher Liste hinzufügen
|
||||||
|
$processedIds[$userId] = true;
|
||||||
|
$businessUserItem->deep = $depth;
|
||||||
|
$allUsers[] = $businessUserItem;
|
||||||
|
|
||||||
|
\Log::debug("TeamController: Flach gesammelt - User ID: {$userId} at depth {$depth}");
|
||||||
|
|
||||||
|
// Rekursiv ALLE verschachtelten businessUserItems sammeln
|
||||||
|
if (isset($businessUserItem->businessUserItems) && is_array($businessUserItem->businessUserItems) && !empty($businessUserItem->businessUserItems)) {
|
||||||
|
\Log::debug("TeamController: Sammle " . count($businessUserItem->businessUserItems) . " verschachtelte Items von User {$userId}");
|
||||||
|
$this->collectAllBusinessUserItemsFlat($businessUserItem->businessUserItems, $allUsers, $processedIds, $depth + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
\Log::warning("TeamController: BusinessUserItem ohne user_id bei Tiefe {$depth} übersprungen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Alte Methode zum rekursiven Sammeln von User-IDs aus BusinessUser-Struktur
|
||||||
|
* Wird durch collectAllBusinessUserItemsFlat() ersetzt
|
||||||
|
*/
|
||||||
|
private function collectUserIdsFromBusinessUser($businessUser, &$allUsers, $deep, $parentless, &$processedIds = []): void
|
||||||
|
{
|
||||||
|
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 20 Levels)
|
||||||
|
$maxDepth = 20;
|
||||||
|
if ($deep > $maxDepth) {
|
||||||
|
\Log::warning("TeamController: Maximale Sammlungstiefe ({$maxDepth}) erreicht");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($businessUser->businessUserItems) && is_array($businessUser->businessUserItems)) {
|
if (isset($businessUser->businessUserItems) && is_array($businessUser->businessUserItems)) {
|
||||||
\Log::debug("TeamController: Collecting from businessUser with " . count($businessUser->businessUserItems) . " sub-items");
|
\Log::debug("TeamController: Collecting from businessUser with " . count($businessUser->businessUserItems) . " sub-items at depth {$deep}");
|
||||||
|
|
||||||
foreach ($businessUser->businessUserItems as $subBusinessUser) {
|
foreach ($businessUser->businessUserItems as $subBusinessUser) {
|
||||||
if ($subBusinessUser) {
|
if ($subBusinessUser) {
|
||||||
|
// WICHTIG: user_id korrekt über b_user abrufen (Magic Method Problem mit isset())
|
||||||
|
$userId = $subBusinessUser->user_id; // Über __get() Method
|
||||||
|
|
||||||
|
if ($userId) {
|
||||||
|
// KRITISCHER BUGFIX: Prüfe ob User bereits gesammelt wurde
|
||||||
|
if (isset($processedIds[$userId])) {
|
||||||
|
\Log::debug("TeamController: Überspringe bereits gesammelten User {$userId} (zirkuläre Referenz verhindert)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$processedIds[$userId] = true;
|
||||||
$subBusinessUser->deep = $deep;
|
$subBusinessUser->deep = $deep;
|
||||||
$allUsers[] = $subBusinessUser;
|
$allUsers[] = $subBusinessUser;
|
||||||
if($subBusinessUser->user_id){
|
|
||||||
\Log::debug("TeamController: Collected user ID: " . $subBusinessUser->user_id);
|
\Log::debug("TeamController: Collected user ID: {$userId} at depth {$deep}");
|
||||||
|
|
||||||
|
// Rekursiver Aufruf für weitere Unter-User mit Schutz vor Zyklen
|
||||||
|
$newDeep = $parentless ? 0 : $deep + 1;
|
||||||
|
$this->collectUserIdsFromBusinessUser($subBusinessUser, $allUsers, $newDeep, $parentless, $processedIds);
|
||||||
|
} else {
|
||||||
|
\Log::warning("TeamController: SubBusinessUser ohne user_id bei Tiefe {$deep} übersprungen");
|
||||||
}
|
}
|
||||||
// Rekursiver Aufruf für weitere Unter-User
|
|
||||||
$newDeep = $parentless ? 0 : $deep+1;
|
|
||||||
$this->collectUserIdsFromBusinessUser($subBusinessUser, $allUsers, $newDeep, $parentless);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KRITISCHE METHODE: Bereinigt BusinessUserItemOptimized Objekte für DataTables
|
||||||
|
* Entfernt zirkuläre Referenzen und extrahiert nur nötige Properties
|
||||||
|
*/
|
||||||
|
private function cleanBusinessUserItemsForDataTable(array $businessUserItems): array
|
||||||
|
{
|
||||||
|
$cleanedUsers = [];
|
||||||
|
|
||||||
|
foreach ($businessUserItems as $businessUserItem) {
|
||||||
|
if (!$businessUserItem) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Extrahiere nur die Properties, die für DataTable benötigt werden
|
||||||
|
$cleanedUser = new \stdClass();
|
||||||
|
|
||||||
|
// Basis Properties (direkt über Magic Method __get)
|
||||||
|
$cleanedUser->user_id = $businessUserItem->user_id;
|
||||||
|
$cleanedUser->m_account = $businessUserItem->m_account;
|
||||||
|
$cleanedUser->email = $businessUserItem->email;
|
||||||
|
$cleanedUser->first_name = $businessUserItem->first_name;
|
||||||
|
$cleanedUser->last_name = $businessUserItem->last_name;
|
||||||
|
$cleanedUser->user_level_name = $businessUserItem->user_level_name;
|
||||||
|
$cleanedUser->active_account = $businessUserItem->active_account;
|
||||||
|
$cleanedUser->active_date = $businessUserItem->active_date;
|
||||||
|
|
||||||
|
// Sales Volume Properties
|
||||||
|
$cleanedUser->sales_volume_points_KP_sum = $businessUserItem->sales_volume_points_KP_sum ?? 0;
|
||||||
|
$cleanedUser->payline_points_qual_kp = $businessUserItem->payline_points_qual_kp ?? 0;
|
||||||
|
|
||||||
|
// Depth für Debug/Sortierung (falls gesetzt)
|
||||||
|
$cleanedUser->deep = $businessUserItem->deep ?? 0;
|
||||||
|
|
||||||
|
// Level-Informationen für Filter
|
||||||
|
$cleanedUser->m_level_id = $businessUserItem->m_level_id;
|
||||||
|
$cleanedUser->next_qual_user_level = $businessUserItem->next_qual_user_level;
|
||||||
|
$cleanedUser->next_can_user_level = $businessUserItem->next_can_user_level;
|
||||||
|
|
||||||
|
$cleanedUsers[] = $cleanedUser;
|
||||||
|
|
||||||
|
\Log::debug("TeamController: Cleaned user {$cleanedUser->user_id} for DataTable");
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("TeamController: Error cleaning BusinessUserItem for DataTable: " . $e->getMessage());
|
||||||
|
// Skip diesen User, statt alles abzubrechen
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\Log::info("TeamController: Cleaned " . count($cleanedUsers) . " users for DataTable (from " . count($businessUserItems) . " raw items)");
|
||||||
|
|
||||||
|
return $cleanedUsers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
app/Http/Controllers/UserDataController.php
Executable file → Normal file
0
app/Http/Controllers/UserDataController.php
Executable file → Normal file
0
app/Http/Controllers/UserDeleteController.php
Executable file → Normal file
0
app/Http/Controllers/UserDeleteController.php
Executable file → Normal file
0
app/Http/Controllers/UserLevelController.php
Executable file → Normal file
0
app/Http/Controllers/UserLevelController.php
Executable file → Normal file
0
app/Http/Controllers/UserShopController.php
Executable file → Normal file
0
app/Http/Controllers/UserShopController.php
Executable file → Normal file
0
app/Http/Controllers/UserUpdateEmailController.php
Executable file → Normal file
0
app/Http/Controllers/UserUpdateEmailController.php
Executable file → Normal file
0
app/Http/Controllers/UserUpdatePasswordController.php
Executable file → Normal file
0
app/Http/Controllers/UserUpdatePasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Web/CardController.php
Executable file → Normal file
0
app/Http/Controllers/Web/CardController.php
Executable file → Normal file
4
app/Http/Controllers/Web/CheckoutController.php
Executable file → Normal file
4
app/Http/Controllers/Web/CheckoutController.php
Executable file → Normal file
|
|
@ -243,7 +243,7 @@ class CheckoutController extends Controller
|
||||||
// Kreditkarte prüfen
|
// Kreditkarte prüfen
|
||||||
if ($payment_method === 'cc') {
|
if ($payment_method === 'cc') {
|
||||||
$result = $this->checkCreditCard($data, $shopping_user, $shopping_order);
|
$result = $this->checkCreditCard($data, $shopping_user, $shopping_order);
|
||||||
if (!isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
if (!is_array($result) || !isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +251,7 @@ class CheckoutController extends Controller
|
||||||
// SEPA prüfen
|
// SEPA prüfen
|
||||||
if ($payment_method === 'elv') {
|
if ($payment_method === 'elv') {
|
||||||
$result = $this->checkSepaAccount($data, $shopping_user, $shopping_order);
|
$result = $this->checkSepaAccount($data, $shopping_user, $shopping_order);
|
||||||
if (!isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
if (!is_array($result) || !isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
app/Http/Controllers/Web/ContactController.php
Executable file → Normal file
0
app/Http/Controllers/Web/ContactController.php
Executable file → Normal file
0
app/Http/Controllers/Web/HomepartyController.php
Executable file → Normal file
0
app/Http/Controllers/Web/HomepartyController.php
Executable file → Normal file
47
app/Http/Controllers/Web/RegisterController.php
Executable file → Normal file
47
app/Http/Controllers/Web/RegisterController.php
Executable file → Normal file
|
|
@ -39,6 +39,18 @@ class RegisterController extends Controller
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
if (config('app.debug')) {
|
||||||
|
\Log::channel('doamin')->debug('RegisterController: index - Session user_shop', [
|
||||||
|
'session_user_shop_id' => \Session::get('user_shop')?->id,
|
||||||
|
'session_user_shop_name' => \Session::get('user_shop')?->name,
|
||||||
|
'session_user_shop_user_id' => \Session::get('user_shop')?->user_id,
|
||||||
|
'session_id' => \Session::getId(),
|
||||||
|
'session_domain' => config('session.domain'),
|
||||||
|
'request_host' => request()->getHost(),
|
||||||
|
'all_session_keys' => array_keys(\Session::all())
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'GOOGLE_ReCAPTCHA_KEY' => $this->GOOGLE_ReCAPTCHA_KEY,
|
'GOOGLE_ReCAPTCHA_KEY' => $this->GOOGLE_ReCAPTCHA_KEY,
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
|
|
@ -49,12 +61,12 @@ class RegisterController extends Controller
|
||||||
|
|
||||||
public function member($member_id = false)
|
public function member($member_id = false)
|
||||||
{
|
{
|
||||||
if(!$member_id){
|
if (!$member_id) {
|
||||||
return redirect('/registrierung');
|
return redirect('/registrierung');
|
||||||
}
|
}
|
||||||
$user_id = (int) str_replace('m', '', $member_id) - config('mivita.add_number_id');
|
$user_id = (int) str_replace('m', '', $member_id) - config('mivita.add_number_id');
|
||||||
$user = User::find($user_id);
|
$user = User::find($user_id);
|
||||||
if(!$user || !$user->isActive() || !$user->isActiveAccount()){
|
if (!$user || !$user->isActive() || !$user->isActiveAccount()) {
|
||||||
return redirect('/registrierung');
|
return redirect('/registrierung');
|
||||||
}
|
}
|
||||||
$data = [
|
$data = [
|
||||||
|
|
@ -66,21 +78,22 @@ class RegisterController extends Controller
|
||||||
return view('web.templates.registrierung', $data);
|
return view('web.templates.registrierung', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(){
|
public function register()
|
||||||
|
{
|
||||||
|
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'salutation' => 'required',
|
'salutation' => 'required',
|
||||||
'first_name'=>'required',
|
'first_name' => 'required',
|
||||||
'last_name'=>'required',
|
'last_name' => 'required',
|
||||||
'email' => 'required|string|email|max:255|unique:users',
|
'email' => 'required|string|email|max:255|unique:users',
|
||||||
'email-confirm' => 'required|same:email',
|
'email-confirm' => 'required|same:email',
|
||||||
'password' => 'required|string|min:6|confirmed',
|
'password' => 'required|string|min:6|confirmed',
|
||||||
'password_confirmation' => 'required|string|min:6',
|
'password_confirmation' => 'required|string|min:6',
|
||||||
'g-recaptcha-response'=>'required|recaptcha',
|
'g-recaptcha-response' => 'required|recaptcha',
|
||||||
'accepted_data_protection' => 'required',
|
'accepted_data_protection' => 'required',
|
||||||
);
|
);
|
||||||
|
|
||||||
Validator::extend('recaptcha', function($attribute, $value, $parameters, $validator) {
|
Validator::extend('recaptcha', function ($attribute, $value, $parameters, $validator) {
|
||||||
return $this->reCaptcha_validate($attribute, $value, $parameters, $validator);
|
return $this->reCaptcha_validate($attribute, $value, $parameters, $validator);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -90,16 +103,15 @@ class RegisterController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_shop = Util::getUserShop();
|
$user_shop = Util::getUserShop();
|
||||||
|
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
$user = $this->userRepo->create($data);
|
$user = $this->userRepo->create($data);
|
||||||
|
|
||||||
$confirmation_code = UserService::createConfirmationCode();
|
$confirmation_code = UserService::createConfirmationCode();
|
||||||
$m_sponsor_id = 1;
|
$m_sponsor_id = 1;
|
||||||
if($user_shop){
|
if ($user_shop) {
|
||||||
$m_sponsor_id = $user_shop->user->id;
|
$m_sponsor_id = $user_shop->user->id;
|
||||||
}
|
}
|
||||||
if(isset($data['from_member_id'])){
|
if (isset($data['from_member_id'])) {
|
||||||
$m_sponsor_id = (int) str_replace('m', '', $data['from_member_id']) - config('mivita.add_number_id');
|
$m_sponsor_id = (int) str_replace('m', '', $data['from_member_id']) - config('mivita.add_number_id');
|
||||||
}
|
}
|
||||||
$user->lang = !empty(\App::getLocale()) ? \App::getLocale() : "de";
|
$user->lang = !empty(\App::getLocale()) ? \App::getLocale() : "de";
|
||||||
|
|
@ -109,11 +121,10 @@ class RegisterController extends Controller
|
||||||
$user->m_sponsor = $m_sponsor_id;
|
$user->m_sponsor = $m_sponsor_id;
|
||||||
|
|
||||||
$UserLevel = UserLevel::where('default', 1)->first();
|
$UserLevel = UserLevel::where('default', 1)->first();
|
||||||
if($UserLevel){
|
if ($UserLevel) {
|
||||||
$user->m_level = $UserLevel->id;
|
$user->m_level = $UserLevel->id;
|
||||||
}else{
|
} else {
|
||||||
$user->m_level = 10;
|
$user->m_level = 10;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
@ -121,10 +132,8 @@ class RegisterController extends Controller
|
||||||
$user->account->data_protection = now();
|
$user->account->data_protection = now();
|
||||||
$user->account->save();
|
$user->account->save();
|
||||||
|
|
||||||
Mail::to($user->email)->locale($user->getLocale())->send(new MailVerifyAccount($confirmation_code, $user));
|
Mail::to($user->email)->locale($user->getLocale())->send(new MailVerifyAccount($confirmation_code, User::find($user->id)));
|
||||||
return redirect('/registrierung/finish');
|
return redirect('/registrierung/finish');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function finish()
|
public function finish()
|
||||||
|
|
@ -143,7 +152,8 @@ class RegisterController extends Controller
|
||||||
|
|
||||||
$response = $client->post(
|
$response = $client->post(
|
||||||
'https://www.google.com/recaptcha/api/siteverify',
|
'https://www.google.com/recaptcha/api/siteverify',
|
||||||
['form_params' =>
|
[
|
||||||
|
'form_params' =>
|
||||||
[
|
[
|
||||||
'secret' => $this->GOOGLE_ReCAPTCHA_SECRET,
|
'secret' => $this->GOOGLE_ReCAPTCHA_SECRET,
|
||||||
'response' => $value
|
'response' => $value
|
||||||
|
|
@ -154,7 +164,4 @@ class RegisterController extends Controller
|
||||||
$body = json_decode((string)$response->getBody());
|
$body = json_decode((string)$response->getBody());
|
||||||
return $body->success;
|
return $body->success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
54
app/Http/Controllers/Web/SiteController.php
Executable file → Normal file
54
app/Http/Controllers/Web/SiteController.php
Executable file → Normal file
|
|
@ -34,16 +34,18 @@ class SiteController extends Controller
|
||||||
return view('web.index', $data);
|
return view('web.index', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function domainCheck(){
|
public function domainCheck()
|
||||||
|
{
|
||||||
die("checked");
|
die("checked");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeLang(){
|
public function changeLang()
|
||||||
|
{
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if(isset($data['change_country_id'])){
|
if (isset($data['change_country_id'])) {
|
||||||
$mylangs = Shop::getLangChange('webshop');
|
$mylangs = Shop::getLangChange('webshop');
|
||||||
foreach($mylangs as $code => $country){
|
foreach ($mylangs as $code => $country) {
|
||||||
if(strtolower($data['change_country_id']) === strtolower($code)){
|
if (strtolower($data['change_country_id']) === strtolower($code)) {
|
||||||
\Session::put('user_init_country', strtolower($code));
|
\Session::put('user_init_country', strtolower($code));
|
||||||
\Session::forget('user_init_country_options');
|
\Session::forget('user_init_country_options');
|
||||||
\Session::put('locale', strtolower($data['change_locale_id']));
|
\Session::put('locale', strtolower($data['change_locale_id']));
|
||||||
|
|
@ -58,19 +60,19 @@ class SiteController extends Controller
|
||||||
{
|
{
|
||||||
//wurde schon gesetzt //cache
|
//wurde schon gesetzt //cache
|
||||||
$country = strtolower(Shop::getIPDatabaseInfo());
|
$country = strtolower(Shop::getIPDatabaseInfo());
|
||||||
if(\Session::has('user_init_country')){
|
if (\Session::has('user_init_country')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(config('app.ipinfo')){
|
if (config('app.ipinfo')) {
|
||||||
$country = strtolower(Shop::getIPDatabaseInfo());
|
$country = strtolower(Shop::getIPDatabaseInfo());
|
||||||
if($country === 'de'){ //$locale de - init AT
|
if ($country === 'de') { //$locale de - init AT
|
||||||
\Session::put('user_init_country', $country);
|
\Session::put('user_init_country', $country);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if($country === 'error'){ //$locale at - init AT
|
if ($country === 'error') { //$locale at - init AT
|
||||||
$country = 'de';
|
$country = 'de';
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
$country = 'de';
|
$country = 'de';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,11 +80,11 @@ class SiteController extends Controller
|
||||||
//ist default
|
//ist default
|
||||||
|
|
||||||
//sprache
|
//sprache
|
||||||
if(array_key_exists($country, \App\Services\UserService::getTransChange())){
|
if (array_key_exists($country, \App\Services\UserService::getTransChange())) {
|
||||||
\Session::put('user_init_country', $country);
|
\Session::put('user_init_country', $country);
|
||||||
\Session::put('locale', $country);
|
\Session::put('locale', $country);
|
||||||
\App::setLocale($country);
|
\App::setLocale($country);
|
||||||
}else{
|
} else {
|
||||||
//default EN
|
//default EN
|
||||||
\Session::put('user_init_country', 'de');
|
\Session::put('user_init_country', 'de');
|
||||||
\Session::put('locale', 'de');
|
\Session::put('locale', 'de');
|
||||||
|
|
@ -90,9 +92,9 @@ class SiteController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
//bestelland / versandland
|
//bestelland / versandland
|
||||||
if(array_key_exists($country, Shop::getLangChange('webshop'))){
|
if (array_key_exists($country, Shop::getLangChange('webshop'))) {
|
||||||
\Session::put('user_init_country_options', $country);
|
\Session::put('user_init_country_options', $country);
|
||||||
}else{
|
} else {
|
||||||
\Session::put('user_init_country_options', 'de');
|
\Session::put('user_init_country_options', 'de');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,11 +103,10 @@ class SiteController extends Controller
|
||||||
|
|
||||||
public function site($site, $subsite = false, $product_slug = false)
|
public function site($site, $subsite = false, $product_slug = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->setIPInfo();
|
$this->setIPInfo();
|
||||||
$subsite = trim($subsite, '/');
|
$subsite = trim($subsite, '/');
|
||||||
$product_slug = trim($product_slug, '/');
|
$product_slug = trim($product_slug, '/');
|
||||||
if($product_slug){
|
if ($product_slug) {
|
||||||
$category = Category::where('slug', $subsite)->where('active', true)->first();
|
$category = Category::where('slug', $subsite)->where('active', true)->first();
|
||||||
$product = Product::where('slug', $product_slug)->where('active', true)->whereJsonContains('show_on', '1')->first();
|
$product = Product::where('slug', $product_slug)->where('active', true)->whereJsonContains('show_on', '1')->first();
|
||||||
if ($category && $product) {
|
if ($category && $product) {
|
||||||
|
|
@ -121,13 +122,12 @@ class SiteController extends Controller
|
||||||
return view('web.templates.produkte-show', $data);
|
return view('web.templates.produkte-show', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($site == 'produkte') {
|
||||||
if($site === 'produkte'){
|
if ($subsite || $subsite !== 'alle-produkte') {
|
||||||
if($subsite || $subsite !== 'alle-produkte') {
|
|
||||||
$category = Category::where('slug', $subsite)->where('active', true)->first();
|
$category = Category::where('slug', $subsite)->where('active', true)->first();
|
||||||
if ($category) {
|
if ($category) {
|
||||||
$headline_image = false;
|
$headline_image = false;
|
||||||
if($category->headline_image_id && $category->iq_image && $category->iq_image->active){
|
if ($category->headline_image_id && $category->iq_image && $category->iq_image->active) {
|
||||||
$headline_image = $category->iq_image;
|
$headline_image = $category->iq_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,9 +148,9 @@ class SiteController extends Controller
|
||||||
'yard_instance' => 'webshop',
|
'yard_instance' => 'webshop',
|
||||||
];
|
];
|
||||||
return view('web.templates.' . $site, $data);
|
return view('web.templates.' . $site, $data);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dd($subsite);
|
||||||
$data = [
|
$data = [
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
'mylangs' => Shop::getLangChange('webshop'),
|
'mylangs' => Shop::getLangChange('webshop'),
|
||||||
|
|
@ -163,22 +163,22 @@ class SiteController extends Controller
|
||||||
'headline_image' => false,
|
'headline_image' => false,
|
||||||
'yard_instance' => 'webshop',
|
'yard_instance' => 'webshop',
|
||||||
];
|
];
|
||||||
return view('web.templates.'.$site, $data);
|
return view('web.templates.' . $site, $data);
|
||||||
}
|
}
|
||||||
$data = [
|
$data = [
|
||||||
'user_shop' => Util::getUserShop(),
|
'user_shop' => Util::getUserShop(),
|
||||||
'mylangs' => Shop::getLangChange('webshop'),
|
'mylangs' => Shop::getLangChange('webshop'),
|
||||||
'yard_instance' => 'webshop',
|
'yard_instance' => 'webshop',
|
||||||
];
|
];
|
||||||
if($subsite){
|
if ($subsite) {
|
||||||
if(!view()->exists('web.templates.'.$subsite)){
|
if (!view()->exists('web.templates.' . $subsite)) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
return view('web.templates.'.$subsite, $data);
|
return view('web.templates.' . $subsite, $data);
|
||||||
}
|
}
|
||||||
if(!view()->exists('web.templates.'.$site)){
|
if (!view()->exists('web.templates.' . $site)) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
return view('web.templates.'.$site, $data);
|
return view('web.templates.' . $site, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
164
app/Http/Controllers/WizardController.php
Executable file → Normal file
164
app/Http/Controllers/WizardController.php
Executable file → Normal file
|
|
@ -38,17 +38,16 @@ class WizardController extends Controller
|
||||||
public function __construct(FileRepository $fileRepo)
|
public function __construct(FileRepository $fileRepo)
|
||||||
{
|
{
|
||||||
$this->fileRepo = $fileRepo;
|
$this->fileRepo = $fileRepo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::findOrFail(Auth::user()->id);
|
$user = User::findOrFail(Auth::user()->id);
|
||||||
if(!$user->account){
|
if (!$user->account) {
|
||||||
$account = UserAccount::create([]);
|
$account = UserAccount::create([]);
|
||||||
$user->account_id = $account->id;
|
$user->account_id = $account->id;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
@ -57,7 +56,7 @@ class WizardController extends Controller
|
||||||
|
|
||||||
$step = !$user->wizard ? 0 : $user->wizard;
|
$step = !$user->wizard ? 0 : $user->wizard;
|
||||||
|
|
||||||
if($step >= 20){
|
if ($step >= 20) {
|
||||||
return redirect('/home');
|
return redirect('/home');
|
||||||
}
|
}
|
||||||
$userHistoryWizardPayment = UserHistory::whereUserId($user->id)->whereAction('wizard_payment')->get()->last();
|
$userHistoryWizardPayment = UserHistory::whereUserId($user->id)->whereAction('wizard_payment')->get()->last();
|
||||||
|
|
@ -70,7 +69,7 @@ class WizardController extends Controller
|
||||||
'userHistoryWizardPayment' => $userHistoryWizardPayment,
|
'userHistoryWizardPayment' => $userHistoryWizardPayment,
|
||||||
];
|
];
|
||||||
|
|
||||||
if($step == 15){
|
if ($step == 15) {
|
||||||
return view('user.wizard.create_release', $data);
|
return view('user.wizard.create_release', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,11 +79,11 @@ class WizardController extends Controller
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
$user = User::findOrFail(Auth::user()->id);
|
$user = User::findOrFail(Auth::user()->id);
|
||||||
if(!$user->account){
|
if (!$user->account) {
|
||||||
$account = UserAccount::create([]);
|
$account = UserAccount::create([]);
|
||||||
$user->account_id = $account->id;
|
$user->account_id = $account->id;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
@ -93,7 +92,7 @@ class WizardController extends Controller
|
||||||
|
|
||||||
$step = !$user->wizard ? 0 : $user->wizard;
|
$step = !$user->wizard ? 0 : $user->wizard;
|
||||||
|
|
||||||
if($step >= 10){
|
if ($step >= 10) {
|
||||||
return redirect('/home');
|
return redirect('/home');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,8 +102,8 @@ class WizardController extends Controller
|
||||||
'products' => Product::where('active', true)->whereJsonContains('show_on', ['7', '8'])->orderBy('pos', 'ASC')->get(),
|
'products' => Product::where('active', true)->whereJsonContains('show_on', ['7', '8'])->orderBy('pos', 'ASC')->get(),
|
||||||
'products_on_board' => Product::where('active', true)->whereJsonContains('show_on', '9')->orderBy('pos', 'ASC')->get(),
|
'products_on_board' => Product::where('active', true)->whereJsonContains('show_on', '9')->orderBy('pos', 'ASC')->get(),
|
||||||
];
|
];
|
||||||
if($step == 5){
|
if ($step == 5) {
|
||||||
if($user->active){
|
if ($user->active) {
|
||||||
$user->active = false;
|
$user->active = false;
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
@ -116,12 +115,12 @@ class WizardController extends Controller
|
||||||
|
|
||||||
public function payment()
|
public function payment()
|
||||||
{
|
{
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::findOrFail(Auth::user()->id);
|
$user = User::findOrFail(Auth::user()->id);
|
||||||
if(!$user->account){
|
if (!$user->account) {
|
||||||
$account = UserAccount::create([]);
|
$account = UserAccount::create([]);
|
||||||
$user->account_id = $account->id;
|
$user->account_id = $account->id;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
@ -131,7 +130,7 @@ class WizardController extends Controller
|
||||||
$userHistoryWizardPayment = UserHistory::whereUserId($user->id)->whereAction('wizard_payment')->get()->last();
|
$userHistoryWizardPayment = UserHistory::whereUserId($user->id)->whereAction('wizard_payment')->get()->last();
|
||||||
|
|
||||||
$shipping_country_id = $this->checkShoppingCountry($user);
|
$shipping_country_id = $this->checkShoppingCountry($user);
|
||||||
if(!$shipping_country_id){
|
if (!$shipping_country_id) {
|
||||||
abort(403, __('validation.custom.shipping_not_found'));
|
abort(403, __('validation.custom.shipping_not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,23 +148,24 @@ class WizardController extends Controller
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
if($user->wizard == 20){
|
if ($user->wizard == 20) {
|
||||||
return view('user.wizard.register_payment', $data);
|
return view('user.wizard.register_payment', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect(route('/'));
|
return redirect(url('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkShoppingCountry($user ){
|
private function checkShoppingCountry($user)
|
||||||
|
{
|
||||||
|
|
||||||
$country_id = null;
|
$country_id = null;
|
||||||
if($user->account->same_as_billing){
|
if ($user->account->same_as_billing) {
|
||||||
$country_id = $user->account->country_id;
|
$country_id = $user->account->country_id;
|
||||||
}else{
|
} else {
|
||||||
$country_id = $user->account->shipping_country_id;
|
$country_id = $user->account->shipping_country_id;
|
||||||
}
|
}
|
||||||
if($country_id){
|
if ($country_id) {
|
||||||
if($shipping_country = ShippingCountry::whereCountryId($country_id)->first()){
|
if ($shipping_country = ShippingCountry::whereCountryId($country_id)->first()) {
|
||||||
return $shipping_country->id;
|
return $shipping_country->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +185,7 @@ class WizardController extends Controller
|
||||||
|
|
||||||
|
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if($step == 7 && Request::get('user_country_id')){
|
if ($step == 7 && Request::get('user_country_id')) {
|
||||||
$user->account->country_id = Request::get('user_country_id');
|
$user->account->country_id = Request::get('user_country_id');
|
||||||
$user->account->save();
|
$user->account->save();
|
||||||
return redirect(route('wizard_register', [1]));
|
return redirect(route('wizard_register', [1]));
|
||||||
|
|
@ -209,14 +209,14 @@ class WizardController extends Controller
|
||||||
return view('user.wizard.register', $data)->withErrors($validator);
|
return view('user.wizard.register', $data)->withErrors($validator);
|
||||||
}
|
}
|
||||||
$account = $user->account;
|
$account = $user->account;
|
||||||
if($account->accepted_contract === null){
|
if ($account->accepted_contract === null) {
|
||||||
$account->accepted_contract = now();
|
$account->accepted_contract = now();
|
||||||
}
|
}
|
||||||
if($account->data_protection === null){
|
if ($account->data_protection === null) {
|
||||||
$account->data_protection = now();
|
$account->data_protection = now();
|
||||||
}
|
}
|
||||||
$account->save();
|
$account->save();
|
||||||
if($user->agreement === null){
|
if ($user->agreement === null) {
|
||||||
$user->agreement = now();
|
$user->agreement = now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,14 +227,14 @@ class WizardController extends Controller
|
||||||
if ($step == 1) {
|
if ($step == 1) {
|
||||||
|
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate"){
|
if (isset($data['action']) && $data['action'] == "reverse_charge_validate") {
|
||||||
$user->wizard = 1;
|
$user->wizard = 1;
|
||||||
$user->save();
|
$user->save();
|
||||||
$userRepo = new UserRepository($user);
|
$userRepo = new UserRepository($user);
|
||||||
return $userRepo->reverse_charge_validate($data, $user, route('wizard_register', [0]));
|
return $userRepo->reverse_charge_validate($data, $user, route('wizard_register', [0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete"){
|
if (isset($data['action']) && $data['action'] == "reverse_charge_delete") {
|
||||||
$user->wizard = 1;
|
$user->wizard = 1;
|
||||||
$user->save();
|
$user->save();
|
||||||
$userRepo = new UserRepository($user);
|
$userRepo = new UserRepository($user);
|
||||||
|
|
@ -282,8 +282,8 @@ class WizardController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($step == 2) {
|
if ($step == 2) {
|
||||||
if(Request::get('submit') === 'do'){
|
if (Request::get('submit') === 'do') {
|
||||||
if(File::whereUserId($user->id)->whereIdentifier('id_card')->count() == 0){
|
if (File::whereUserId($user->id)->whereIdentifier('id_card')->count() == 0) {
|
||||||
$validator = Validator::make(Request::all(), []);
|
$validator = Validator::make(Request::all(), []);
|
||||||
$validator->errors()->add('field', __('msg.no_id_card_deposited_please_upload_first'));
|
$validator->errors()->add('field', __('msg.no_id_card_deposited_please_upload_first'));
|
||||||
$user->wizard = 2;
|
$user->wizard = 2;
|
||||||
|
|
@ -295,18 +295,18 @@ class WizardController extends Controller
|
||||||
return redirect(route('wizard_register'));
|
return redirect(route('wizard_register'));
|
||||||
}
|
}
|
||||||
$this->fileRepo->_set('disk', 'user');
|
$this->fileRepo->_set('disk', 'user');
|
||||||
$this->fileRepo->_set('dir', '/'.$user->id.'/verification/');
|
$this->fileRepo->_set('dir', '/' . $user->id . '/verification/');
|
||||||
$this->fileRepo->_set('user_id', $user->id);
|
$this->fileRepo->_set('user_id', $user->id);
|
||||||
$this->fileRepo->_set('identifier', 'id_card');
|
$this->fileRepo->_set('identifier', 'id_card');
|
||||||
return $this->fileRepo->uploadFile(Request::all());
|
return $this->fileRepo->uploadFile(Request::all());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($step == 3) {
|
if ($step == 3) {
|
||||||
if(Request::get('submit') === 'do'){
|
if (Request::get('submit') === 'do') {
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
|
|
||||||
if($data['business_license_choose'] === "now"){
|
if ($data['business_license_choose'] === "now") {
|
||||||
if(File::whereUserId($user->id)->whereIdentifier('business_license')->count() == 0){
|
if (File::whereUserId($user->id)->whereIdentifier('business_license')->count() == 0) {
|
||||||
$validator = Validator::make(Request::all(), []);
|
$validator = Validator::make(Request::all(), []);
|
||||||
$validator->errors()->add('field', __('msg.no_trade_licence_deposited_please_upload_first'));
|
$validator->errors()->add('field', __('msg.no_trade_licence_deposited_please_upload_first'));
|
||||||
$user->wizard = 3;
|
$user->wizard = 3;
|
||||||
|
|
@ -314,17 +314,16 @@ class WizardController extends Controller
|
||||||
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($data['business_license_choose'] === "later"){
|
if ($data['business_license_choose'] === "later") {
|
||||||
|
|
||||||
}
|
}
|
||||||
if($data['business_license_choose'] === "non"){
|
if ($data['business_license_choose'] === "non") {
|
||||||
if(!$data['non_business_license_reason'] || $data['non_business_license_reason'] == ""){
|
if (!$data['non_business_license_reason'] || $data['non_business_license_reason'] == "") {
|
||||||
$validator = Validator::make(Request::all(), []);
|
$validator = Validator::make(Request::all(), []);
|
||||||
$validator->errors()->add('field', __('msg.please_enter_reason_why_you_not_need_trade_licence'));
|
$validator->errors()->add('field', __('msg.please_enter_reason_why_you_not_need_trade_licence'));
|
||||||
$user->wizard = 3;
|
$user->wizard = 3;
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
||||||
}else{
|
} else {
|
||||||
$user->account->setNotice('business_license_reason', $data['non_business_license_reason']);
|
$user->account->setNotice('business_license_reason', $data['non_business_license_reason']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +335,7 @@ class WizardController extends Controller
|
||||||
return redirect(route('wizard_register'));
|
return redirect(route('wizard_register'));
|
||||||
}
|
}
|
||||||
$this->fileRepo->_set('disk', 'user');
|
$this->fileRepo->_set('disk', 'user');
|
||||||
$this->fileRepo->_set('dir', '/'.$user->id.'/verification/');
|
$this->fileRepo->_set('dir', '/' . $user->id . '/verification/');
|
||||||
$this->fileRepo->_set('user_id', $user->id);
|
$this->fileRepo->_set('user_id', $user->id);
|
||||||
$this->fileRepo->_set('identifier', 'business_license');
|
$this->fileRepo->_set('identifier', 'business_license');
|
||||||
return $this->fileRepo->uploadFile(Request::all());
|
return $this->fileRepo->uploadFile(Request::all());
|
||||||
|
|
@ -371,13 +370,13 @@ class WizardController extends Controller
|
||||||
$user->m_sponsor = $user->m_sponsor ? $user->m_sponsor : 1;
|
$user->m_sponsor = $user->m_sponsor ? $user->m_sponsor : 1;
|
||||||
$user->account->m_first_name = $user->account->m_first_name ? $user->account->m_first_name : $user->account->first_name;
|
$user->account->m_first_name = $user->account->m_first_name ? $user->account->m_first_name : $user->account->first_name;
|
||||||
$user->account->m_last_name = $user->account->m_last_name ? $user->account->m_last_name : $user->account->last_name;
|
$user->account->m_last_name = $user->account->m_last_name ? $user->account->m_last_name : $user->account->last_name;
|
||||||
$user->account->m_account = UserAccount::withTrashed()->max('m_account') +1;
|
$user->account->m_account = UserAccount::withTrashed()->max('m_account') + 1;
|
||||||
$user->account->save();
|
$user->account->save();
|
||||||
$user->save();
|
$user->save();
|
||||||
//create PDF
|
//create PDF
|
||||||
$pdf = new ContractPDFRepository($user);
|
$pdf = new ContractPDFRepository($user);
|
||||||
$pdf->_set('disk', 'user');
|
$pdf->_set('disk', 'user');
|
||||||
$pdf->_set('dir', '/'.$user->id.'/documents/');
|
$pdf->_set('dir', '/' . $user->id . '/documents/');
|
||||||
$pdf->_set('user_id', $user->id);
|
$pdf->_set('user_id', $user->id);
|
||||||
$pdf->_set('identifier', 'contract');
|
$pdf->_set('identifier', 'contract');
|
||||||
$pdf->createContractPDF();
|
$pdf->createContractPDF();
|
||||||
|
|
@ -393,15 +392,15 @@ class WizardController extends Controller
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
//mail with code to user?
|
//mail with code to user?
|
||||||
if($user->isTestMode()){
|
if ($user->isTestMode()) {
|
||||||
$mail = config('app.info_test_mail');
|
$mail = config('app.info_test_mail');
|
||||||
}else{
|
} else {
|
||||||
$mail = config('app.info_mail');
|
$mail = config('app.info_mail');
|
||||||
}
|
}
|
||||||
Mail::to($mail)->locale($user->getLocale())->send(new MailAutoReleaseAccount($user));
|
Mail::to($mail)->locale($user->getLocale())->send(new MailAutoReleaseAccount($user));
|
||||||
UserHistory::create(['user_id' => $user->id, 'action'=>'release_account', 'status'=>0]);
|
UserHistory::create(['user_id' => $user->id, 'action' => 'release_account', 'status' => 0]);
|
||||||
Mail::to($user->email)->locale($user->getLocale())->send(new MailAccountActive($user));
|
Mail::to($user->email)->locale($user->getLocale())->send(new MailAccountActive($user));
|
||||||
UserHistory::create(['user_id' => $user->id, 'action'=>'released_completed', 'status'=>0]);
|
UserHistory::create(['user_id' => $user->id, 'action' => 'released_completed', 'status' => 0]);
|
||||||
\Session()->flash('alert-success', __('msg.account_released'));
|
\Session()->flash('alert-success', __('msg.account_released'));
|
||||||
return redirect(route('wizard_payment'));
|
return redirect(route('wizard_payment'));
|
||||||
}
|
}
|
||||||
|
|
@ -409,16 +408,16 @@ class WizardController extends Controller
|
||||||
public function storeCreate($step = 0)
|
public function storeCreate($step = 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!Auth::check()){
|
if (!Auth::check()) {
|
||||||
return redirect('login');
|
return redirect('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::findOrFail(Auth::user()->id);
|
$user = User::findOrFail(Auth::user()->id);
|
||||||
if(!$user->account){
|
if (!$user->account) {
|
||||||
$user->account = new UserAccount();
|
$user->account = new UserAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($step == 10){
|
if ($step == 10) {
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'accepted_data_protection' => 'required',
|
'accepted_data_protection' => 'required',
|
||||||
'accepted_active' => 'required',
|
'accepted_active' => 'required',
|
||||||
|
|
@ -434,17 +433,16 @@ class WizardController extends Controller
|
||||||
$user->wizard = 10;
|
$user->wizard = 10;
|
||||||
$user->save();
|
$user->save();
|
||||||
return view('user.wizard.create', $data)->withErrors($validator);
|
return view('user.wizard.create', $data)->withErrors($validator);
|
||||||
|
|
||||||
}
|
}
|
||||||
$account = $user->account;
|
$account = $user->account;
|
||||||
if($account->accepted_contract === null){
|
if ($account->accepted_contract === null) {
|
||||||
$account->accepted_contract = now();
|
$account->accepted_contract = now();
|
||||||
}
|
}
|
||||||
if($account->data_protection === null){
|
if ($account->data_protection === null) {
|
||||||
$account->data_protection = now();
|
$account->data_protection = now();
|
||||||
}
|
}
|
||||||
$account->save();
|
$account->save();
|
||||||
if($user->agreement === null){
|
if ($user->agreement === null) {
|
||||||
$user->agreement = now();
|
$user->agreement = now();
|
||||||
}
|
}
|
||||||
$user->wizard = 11;
|
$user->wizard = 11;
|
||||||
|
|
@ -452,9 +450,9 @@ class WizardController extends Controller
|
||||||
|
|
||||||
return redirect(route('wizard_create', [11]));
|
return redirect(route('wizard_create', [11]));
|
||||||
}
|
}
|
||||||
if($step == 11){
|
if ($step == 11) {
|
||||||
|
|
||||||
if($user->isPasswort()){
|
if ($user->isPasswort()) {
|
||||||
$user->wizard = 12;
|
$user->wizard = 12;
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect(route('wizard_create', [12]));
|
return redirect(route('wizard_create', [12]));
|
||||||
|
|
@ -481,18 +479,18 @@ class WizardController extends Controller
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect(route('wizard_create', [12]));
|
return redirect(route('wizard_create', [12]));
|
||||||
}
|
}
|
||||||
if($step == 12){
|
if ($step == 12) {
|
||||||
|
|
||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
|
|
||||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate"){
|
if (isset($data['action']) && $data['action'] == "reverse_charge_validate") {
|
||||||
$user->wizard = 12;
|
$user->wizard = 12;
|
||||||
$user->save();
|
$user->save();
|
||||||
$userRepo = new UserRepository($user);
|
$userRepo = new UserRepository($user);
|
||||||
return $userRepo->reverse_charge_validate($data, $user, route('wizard_create', [12]));
|
return $userRepo->reverse_charge_validate($data, $user, route('wizard_create', [12]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete"){
|
if (isset($data['action']) && $data['action'] == "reverse_charge_delete") {
|
||||||
$user->wizard = 12;
|
$user->wizard = 12;
|
||||||
$user->save();
|
$user->save();
|
||||||
$userRepo = new UserRepository($user);
|
$userRepo = new UserRepository($user);
|
||||||
|
|
@ -513,12 +511,12 @@ class WizardController extends Controller
|
||||||
'birthday' => 'required',
|
'birthday' => 'required',
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!Request::get('same_as_billing')){
|
if (!Request::get('same_as_billing')) {
|
||||||
$rules = array_merge($rules, [
|
$rules = array_merge($rules, [
|
||||||
'shipping_firstname'=>'required',
|
'shipping_firstname' => 'required',
|
||||||
'shipping_lastname'=>'required',
|
'shipping_lastname' => 'required',
|
||||||
'shipping_address'=>'required',
|
'shipping_address' => 'required',
|
||||||
'shipping_zipcode'=>'required',
|
'shipping_zipcode' => 'required',
|
||||||
'shipping_city' => 'required',
|
'shipping_city' => 'required',
|
||||||
'shipping_salutation' => 'required'
|
'shipping_salutation' => 'required'
|
||||||
|
|
||||||
|
|
@ -541,26 +539,26 @@ class WizardController extends Controller
|
||||||
$user->confirmation_code_remider = 0;
|
$user->confirmation_code_remider = 0;
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect(route('wizard_create', [13]));
|
return redirect(route('wizard_create', [13]));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function storePayment($step = 0){
|
public function storePayment($step = 0)
|
||||||
|
{
|
||||||
|
|
||||||
if(Request::get('switchers-package-wizard')){
|
if (Request::get('switchers-package-wizard')) {
|
||||||
$user = User::find(Auth::user()->id);
|
$user = User::find(Auth::user()->id);
|
||||||
Yard::instance('shopping')->destroy();
|
Yard::instance('shopping')->destroy();
|
||||||
$product = Product::find(Request::get('switchers-package-wizard'));
|
$product = Product::find(Request::get('switchers-package-wizard'));
|
||||||
$showAboOptions = false;
|
$showAboOptions = false;
|
||||||
if(Request::get('abo_options')){
|
if (Request::get('abo_options')) {
|
||||||
$showAboOptions = false; //true Abo Option deaktivert
|
$showAboOptions = false; //true Abo Option deaktivert
|
||||||
$user->abo_options = false; //true Abo Option deaktivert
|
$user->abo_options = false; //true Abo Option deaktivert
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$shipping_country_id = $this->checkShoppingCountry($user);
|
$shipping_country_id = $this->checkShoppingCountry($user);
|
||||||
if(!$shipping_country_id){
|
if (!$shipping_country_id) {
|
||||||
abort(403, __('validation.custom.shipping_not_found'));
|
abort(403, __('validation.custom.shipping_not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -569,31 +567,31 @@ class WizardController extends Controller
|
||||||
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country_id);
|
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country_id);
|
||||||
|
|
||||||
|
|
||||||
if($product && $product->active){
|
if ($product && $product->active) {
|
||||||
//set membership product
|
//set membership product
|
||||||
$image = "";
|
$image = "";
|
||||||
if($product->images->count()){
|
if ($product->images->count()) {
|
||||||
$image = $product->images->first()->slug;
|
$image = $product->images->first()->slug;
|
||||||
}
|
}
|
||||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
||||||
if(\App\Services\UserService::getTaxFree()){
|
if (\App\Services\UserService::getTaxFree()) {
|
||||||
Yard::setTax($cartItem->rowId, 0);
|
Yard::setTax($cartItem->rowId, 0);
|
||||||
}else{
|
} else {
|
||||||
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
||||||
}
|
}
|
||||||
|
|
||||||
//set onboarding products
|
//set onboarding products
|
||||||
if(Request::get('products_on_board')){
|
if (Request::get('products_on_board')) {
|
||||||
foreach (Request::get('products_on_board') as $product_on_board_id){
|
foreach (Request::get('products_on_board') as $product_on_board_id) {
|
||||||
$product_on_board = Product::find($product_on_board_id);
|
$product_on_board = Product::find($product_on_board_id);
|
||||||
$image = "";
|
$image = "";
|
||||||
if($product_on_board->images->count()){
|
if ($product_on_board->images->count()) {
|
||||||
$image = $product_on_board->images->first()->slug;
|
$image = $product_on_board->images->first()->slug;
|
||||||
}
|
}
|
||||||
$cartItem = Yard::instance('shopping')->add($product_on_board->id, $product_on_board->getLang('name'), 1, $product_on_board->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product_on_board->slug, 'weight' => $product_on_board->weight, 'points' => $product_on_board->points, 'no_commission' => $product_on_board->no_commission, 'show_on' => $product_on_board->show_on]);
|
$cartItem = Yard::instance('shopping')->add($product_on_board->id, $product_on_board->getLang('name'), 1, $product_on_board->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product_on_board->slug, 'weight' => $product_on_board->weight, 'points' => $product_on_board->points, 'no_commission' => $product_on_board->no_commission, 'show_on' => $product_on_board->show_on]);
|
||||||
if(\App\Services\UserService::getTaxFree()){
|
if (\App\Services\UserService::getTaxFree()) {
|
||||||
Yard::setTax($cartItem->rowId, 0);
|
Yard::setTax($cartItem->rowId, 0);
|
||||||
}else{
|
} else {
|
||||||
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -601,7 +599,7 @@ class WizardController extends Controller
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$identifier = Util::getToken();
|
$identifier = Util::getToken();
|
||||||
} while( ShoppingInstance::where('identifier', $identifier)->count() );
|
} while (ShoppingInstance::where('identifier', $identifier)->count());
|
||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
$data['is_from'] = 'wizard';
|
$data['is_from'] = 'wizard';
|
||||||
|
|
@ -622,29 +620,27 @@ class WizardController extends Controller
|
||||||
]);
|
]);
|
||||||
Yard::instance('shopping')->store($identifier);
|
Yard::instance('shopping')->store($identifier);
|
||||||
//add to DB
|
//add to DB
|
||||||
$path = route('checkout.checkout_card', ['identifier'=>$identifier]);
|
$path = route('checkout.checkout_card', ['identifier' => $identifier]);
|
||||||
UserHistory::create(['user_id' => $user->id, 'action'=>'wizard_payment', 'status'=>1, 'product_id'=>$product->id, 'identifier'=>$identifier, 'abo_options'=>$showAboOptions]);
|
UserHistory::create(['user_id' => $user->id, 'action' => 'wizard_payment', 'status' => 1, 'product_id' => $product->id, 'identifier' => $identifier, 'abo_options' => $showAboOptions]);
|
||||||
//$path = str_replace('http', 'https', $path);
|
//$path = str_replace('http', 'https', $path);
|
||||||
return redirect()->secure($path);
|
return redirect()->secure($path);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\Session()->flash('alert-error', "Fehler beim Produkt");
|
\Session()->flash('alert-error', "Fehler beim Produkt");
|
||||||
return back();
|
return back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($id, $relation){
|
public function delete($id, $relation)
|
||||||
|
{
|
||||||
|
|
||||||
if($relation === 'upload'){
|
if ($relation === 'upload') {
|
||||||
$user = User::findOrFail(Auth::user()->id);
|
$user = User::findOrFail(Auth::user()->id);
|
||||||
$file = $user->files()->findOrFail($id);
|
$file = $user->files()->findOrFail($id);
|
||||||
//remove file
|
//remove file
|
||||||
\Storage::disk('user')->delete($file->dir.$file->filename);
|
\Storage::disk('user')->delete($file->dir . $file->filename);
|
||||||
$file->delete();
|
$file->delete();
|
||||||
\Session()->flash('alert-success', __('msg.file_deleted'));
|
\Session()->flash('alert-success', __('msg.file_deleted'));
|
||||||
}
|
}
|
||||||
return back();
|
return back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
2
app/Http/Kernel.php
Executable file → Normal file
2
app/Http/Kernel.php
Executable file → Normal file
|
|
@ -34,6 +34,8 @@ class Kernel extends HttpKernel
|
||||||
\Illuminate\Session\Middleware\StartSession::class,
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
\Illuminate\Session\Middleware\AuthenticateSession::class,
|
\Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
|
// WICHTIG: Nach StartSession, vor VerifyCsrfToken
|
||||||
|
\App\Http\Middleware\SubdomainResolver::class,
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
\App\Http\Middleware\Localization::class,
|
\App\Http\Middleware\Localization::class,
|
||||||
|
|
|
||||||
0
app/Http/Middleware/ActiveAccount.php
Executable file → Normal file
0
app/Http/Middleware/ActiveAccount.php
Executable file → Normal file
0
app/Http/Middleware/ActiveShop.php
Executable file → Normal file
0
app/Http/Middleware/ActiveShop.php
Executable file → Normal file
0
app/Http/Middleware/Admin.php
Executable file → Normal file
0
app/Http/Middleware/Admin.php
Executable file → Normal file
17
app/Http/Middleware/Checkout.php
Executable file → Normal file
17
app/Http/Middleware/Checkout.php
Executable file → Normal file
|
|
@ -27,33 +27,33 @@ class Checkout
|
||||||
'host' => $request->getHost()
|
'host' => $request->getHost()
|
||||||
]);
|
]);
|
||||||
$instance = 'checkout';
|
$instance = 'checkout';
|
||||||
if($shopping_instance = ShoppingInstance::where('identifier', $request->route('identifier'))->first()){
|
if ($shopping_instance = ShoppingInstance::where('identifier', $request->route('identifier'))->first()) {
|
||||||
//user shop
|
//user shop
|
||||||
//set Lang
|
//set Lang
|
||||||
\Session::put('locale', $shopping_instance->getLocale());
|
\Session::put('locale', $shopping_instance->getLocale());
|
||||||
\App::setLocale($shopping_instance->getLocale());
|
\App::setLocale($shopping_instance->getLocale());
|
||||||
$user_shop = $shopping_instance->user_shop;
|
$user_shop = $shopping_instance->user_shop;
|
||||||
|
|
||||||
if($user_shop && $user_shop->active == 1 && $user_shop->user->isActiveShop()){
|
if ($user_shop && $user_shop->active == 1 && $user_shop->user->isActiveShop()) {
|
||||||
Util::setPostRoute('user/');
|
Util::setPostRoute('user/');
|
||||||
\Session::put('user_shop', $user_shop);
|
\Session::put('user_shop', $user_shop);
|
||||||
\Session::put('user_shop_domain', $shopping_instance->subdomain);
|
\Session::put('user_shop_domain', $shopping_instance->subdomain);
|
||||||
\Session::put('user_shop_payment', $shopping_instance->payment);
|
\Session::put('user_shop_payment', $shopping_instance->payment);
|
||||||
\Session::put('user_shop_identifier', $shopping_instance->identifier);
|
\Session::put('user_shop_identifier', $shopping_instance->identifier);
|
||||||
|
|
||||||
if($shopping_instance->auth_user_id){
|
if ($shopping_instance->auth_user_id) {
|
||||||
\Session::put('auth_user', $shopping_instance->auth_user);
|
\Session::put('auth_user', $shopping_instance->auth_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($shopping_instance->back){
|
if ($shopping_instance->back) {
|
||||||
\Session::put('back_link', $shopping_instance->back);
|
\Session::put('back_link', $shopping_instance->back);
|
||||||
}
|
}
|
||||||
\Session::put('new_session', true);
|
\Session::put('new_session', true);
|
||||||
Yard::instance($instance)->destroy();
|
Yard::instance($instance)->destroy();
|
||||||
//restore yard
|
//restore yard
|
||||||
if($shopping_instance->payment !== 6){
|
if ($shopping_instance->payment !== 6) {
|
||||||
Yard::instance($instance)->restore($request->route('identifier'), [], true, $instance);
|
Yard::instance($instance)->restore($request->route('identifier'), [], true, $instance);
|
||||||
}else{
|
} else {
|
||||||
//dont delete shopping instance
|
//dont delete shopping instance
|
||||||
Yard::instance($instance)->restore($request->route('identifier'), [], false, $instance);
|
Yard::instance($instance)->restore($request->route('identifier'), [], false, $instance);
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ class Checkout
|
||||||
Yard::instance($instance)->setUserPriceInfos($shopping_instance->shopping_data['user_price_infos']);
|
Yard::instance($instance)->setUserPriceInfos($shopping_instance->shopping_data['user_price_infos']);
|
||||||
Yard::instance($instance)->setShippingCountryWithPrice($shopping_instance->country_id, $is_for);
|
Yard::instance($instance)->setShippingCountryWithPrice($shopping_instance->country_id, $is_for);
|
||||||
|
|
||||||
if($shopping_instance->payment !== 6){
|
if ($shopping_instance->payment !== 6) {
|
||||||
//delete shopping instance is not save for restore, payment link
|
//delete shopping instance is not save for restore, payment link
|
||||||
ShoppingInstance::where('identifier', $request->route('identifier'))->delete();
|
ShoppingInstance::where('identifier', $request->route('identifier'))->delete();
|
||||||
}
|
}
|
||||||
|
|
@ -76,10 +76,9 @@ class Checkout
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
// \Session::has('user_shop_identifier')
|
// \Session::has('user_shop_identifier')
|
||||||
if(\Session::has('user_shop') && Yard::instance($instance)->count() > 0){
|
if (\Session::has('user_shop') && Yard::instance($instance)->count() > 0) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
return redirect(Util::getUserCardBackUrl('/card/show', 'checkout'));
|
return redirect(Util::getUserCardBackUrl('/card/show', 'checkout'));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
app/Http/Middleware/EncryptCookies.php
Executable file → Normal file
0
app/Http/Middleware/EncryptCookies.php
Executable file → Normal file
0
app/Http/Middleware/Localization.php
Executable file → Normal file
0
app/Http/Middleware/Localization.php
Executable file → Normal file
0
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file → Normal file
0
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file → Normal file
0
app/Http/Middleware/RemoveExcessWhitespaceMiddleware.php
Executable file → Normal file
0
app/Http/Middleware/RemoveExcessWhitespaceMiddleware.php
Executable file → Normal file
255
app/Http/Middleware/SubdomainResolver.php
Normal file
255
app/Http/Middleware/SubdomainResolver.php
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Domain\EarlyDomainParser;
|
||||||
|
use App\Models\UserShop;
|
||||||
|
use App\Services\Util;
|
||||||
|
use Closure;
|
||||||
|
use Config;
|
||||||
|
use Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightweight subdomain resolution middleware
|
||||||
|
*
|
||||||
|
* Uses config/domains.php for domain configuration and provides
|
||||||
|
* simple, working subdomain handling without session timing issues.
|
||||||
|
*/
|
||||||
|
class SubdomainResolver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next)
|
||||||
|
{
|
||||||
|
// Skip for API and asset requests
|
||||||
|
if (!$this->shouldProcess($request)) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse domain information using config/domains.php
|
||||||
|
$host = $request->getHost();
|
||||||
|
$domainInfo = EarlyDomainParser::parseDomain($host);
|
||||||
|
Session::put('domainInfo', $domainInfo);
|
||||||
|
\Log::info('domainInfo', $domainInfo);
|
||||||
|
// Route to appropriate handler based on domain type
|
||||||
|
return match ($domainInfo['type']) {
|
||||||
|
'user-shop' => $this->handleUserShop($request, $next, $domainInfo),
|
||||||
|
'main-shop' => $this->handleMainShop($request, $next, $domainInfo),
|
||||||
|
'main' => $this->handleMainCare($request, $next, $domainInfo),
|
||||||
|
'crm' => $this->handleCrm($request, $next, $domainInfo),
|
||||||
|
'portal' => $this->handlePortal($request, $next, $domainInfo),
|
||||||
|
'checkout' => $this->handleCheckout($request, $next, $domainInfo),
|
||||||
|
default => $this->handleUnknownDomain($request, $domainInfo),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle user shop subdomain (e.g., user.mivita.care)
|
||||||
|
*/
|
||||||
|
private function handleUserShop($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
$subdomain = $domainInfo['subdomain'];
|
||||||
|
$userShop = UserShop::where('slug', $subdomain)->first();
|
||||||
|
|
||||||
|
// Remove subdomain parameter from route
|
||||||
|
if ($request->route('subdomain')) {
|
||||||
|
$request->route()->forgetParameter('subdomain');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$userShop) {
|
||||||
|
return $this->handleUnknownDomain($request, $domainInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate shop status
|
||||||
|
if (!$userShop->active || !$userShop->user || !$userShop->user->isActiveShop()) {
|
||||||
|
//hier ein routing zu shop???
|
||||||
|
abort(503, 'Shop temporarily unavailable');
|
||||||
|
}
|
||||||
|
$host = $this->getHost($domainInfo);
|
||||||
|
// Configure session domain based on domain config
|
||||||
|
$this->configureSessionDomain($host);
|
||||||
|
|
||||||
|
// Set up application context
|
||||||
|
$this->setupUserShopContext($userShop, $subdomain, $host);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle main shop domain (e.g., mivita.shop)
|
||||||
|
*/
|
||||||
|
private function handleMainShop($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Load default shop from domain config
|
||||||
|
$defaultShop = isset($domainInfo['default_user_shop']) ? $domainInfo['default_user_shop'] : 'aloevera';
|
||||||
|
$userShop = UserShop::where('slug', $defaultShop)->first();
|
||||||
|
|
||||||
|
// Configure session domain based on domain config, not getHost only for care domains
|
||||||
|
$host = isset($domainInfo['host']) ? $domainInfo['host'] : config('app.domain') . config('app.tld_shop');
|
||||||
|
Config::set('session.domain', '.' . $host);
|
||||||
|
|
||||||
|
if ($userShop) {
|
||||||
|
\Session::put('user_shop', $userShop);
|
||||||
|
\Session::put('user_shop_domain', config('app.protocol') . $host);
|
||||||
|
Util::setPostRoute('user/');
|
||||||
|
Config::set('app.url', $host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle main care domain (e.g., mivita.care)
|
||||||
|
*/
|
||||||
|
private function handleMainCare($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Configure session domain based on domain config
|
||||||
|
$host = $this->getHost($domainInfo);
|
||||||
|
$host = isset($domainInfo['host']) ? $domainInfo['host'] : config('app.domain') . config('app.tld_care');
|
||||||
|
$this->configureSessionDomain($host);
|
||||||
|
|
||||||
|
// Clear any existing shop session data, not needed for main care domain
|
||||||
|
Session::forget('user_shop');
|
||||||
|
Session::forget('user_shop_domain');
|
||||||
|
|
||||||
|
// Set app URL
|
||||||
|
Config::set('app.url', $host);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle CRM domain (e.g., my.mivita.care)
|
||||||
|
*/
|
||||||
|
private function handleCrm($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Configure session domain for CRM
|
||||||
|
$host = $this->getHost($domainInfo);
|
||||||
|
$this->configureSessionDomain($host);
|
||||||
|
|
||||||
|
// Clear shop data for CRM , not needed for crm domain
|
||||||
|
Session::forget('user_shop');
|
||||||
|
Session::forget('user_shop_domain');
|
||||||
|
|
||||||
|
// Set app URL
|
||||||
|
Config::set('app.url', $host);
|
||||||
|
\Log::info('Session all', Session::all());
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Portal domain (e.g., in.mivita.care)
|
||||||
|
*/
|
||||||
|
private function handlePortal($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Configure session domain for Portal
|
||||||
|
$host = $this->getHost($domainInfo);
|
||||||
|
$this->configureSessionDomain($host);
|
||||||
|
|
||||||
|
// Don't clear user_shop - checkout needs to know which shop
|
||||||
|
// Session::forget('user_shop');
|
||||||
|
// Session::forget('user_shop_domain');
|
||||||
|
|
||||||
|
// Set app URL
|
||||||
|
Config::set('app.url', $host);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Checkout domain (e.g., checkout.mivita.care)
|
||||||
|
*/
|
||||||
|
private function handleCheckout($request, Closure $next, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Configure session domain for Checkout
|
||||||
|
$host = $this->getHost($domainInfo);
|
||||||
|
$this->configureSessionDomain($host);
|
||||||
|
|
||||||
|
// Keep existing shop session data for checkout
|
||||||
|
// Don't clear user_shop - checkout needs to know which shop
|
||||||
|
|
||||||
|
// Set app URL
|
||||||
|
Config::set('app.url', $host);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle unknown domains
|
||||||
|
*/
|
||||||
|
private function handleUnknownDomain($request, array $domainInfo)
|
||||||
|
{
|
||||||
|
// Redirect to main domain
|
||||||
|
$mainDomain = config('domains.domains.main.host');
|
||||||
|
$mainUrl = config('domains.protocol') . $mainDomain;
|
||||||
|
|
||||||
|
return redirect()->away($mainUrl, 301);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up user shop context in session and config
|
||||||
|
*/
|
||||||
|
private function setupUserShopContext(UserShop $userShop, ?string $subdomain = null, string $host = '')
|
||||||
|
{
|
||||||
|
// Put shop data in session
|
||||||
|
Session::put('user_shop', $userShop);
|
||||||
|
|
||||||
|
// Build shop domain URL using protocol from config
|
||||||
|
$shopDomain = config('domains.protocol') . $host;
|
||||||
|
//$shopDomain = config('app.protocol').$user_shop->slug.".".config('app.domain').config('app.tld_care'));
|
||||||
|
Session::put('user_shop_domain', $shopDomain);
|
||||||
|
|
||||||
|
// Set app URL for URL generation
|
||||||
|
Config::set('app.url', rtrim($shopDomain, '/'));
|
||||||
|
|
||||||
|
// Set post route for compatibility
|
||||||
|
Util::setPostRoute('user/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure session domain based on host
|
||||||
|
*/
|
||||||
|
private function configureSessionDomain(string $host): void
|
||||||
|
{
|
||||||
|
Config::set('session.domain', '.' . config('app.domain') . config('app.tld_care'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host from domain info
|
||||||
|
*/
|
||||||
|
private function getHost(array $domainInfo): string
|
||||||
|
{
|
||||||
|
if (isset($domainInfo['host'])) {
|
||||||
|
return $domainInfo['host'];
|
||||||
|
}
|
||||||
|
abort(503, 'Host not found in domain info');
|
||||||
|
//throw new \Exception('Host not found in domain info');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Check if request should be processed by this middleware
|
||||||
|
*/
|
||||||
|
private function shouldProcess($request): bool
|
||||||
|
{
|
||||||
|
// Skip API requests
|
||||||
|
if ($request->is('api/*')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip asset requests
|
||||||
|
if ($request->isMethod('GET') && preg_match('/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/i', $request->path())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip Laravel internal requests
|
||||||
|
if ($request->is('_debugbar/*')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/Http/Middleware/SuperAdmin.php
Executable file → Normal file
0
app/Http/Middleware/SuperAdmin.php
Executable file → Normal file
0
app/Http/Middleware/SysAdmin.php
Executable file → Normal file
0
app/Http/Middleware/SysAdmin.php
Executable file → Normal file
0
app/Http/Middleware/TrimStrings.php
Executable file → Normal file
0
app/Http/Middleware/TrimStrings.php
Executable file → Normal file
0
app/Http/Middleware/TrustProxies.php
Executable file → Normal file
0
app/Http/Middleware/TrustProxies.php
Executable file → Normal file
0
app/Http/Middleware/VerifyCsrfToken.php
Executable file → Normal file
0
app/Http/Middleware/VerifyCsrfToken.php
Executable file → Normal file
|
|
@ -52,6 +52,7 @@ class Customer extends Authenticatable // Erbt von Authenticatable
|
||||||
'member_id',
|
'member_id',
|
||||||
'number',
|
'number',
|
||||||
'language',
|
'language',
|
||||||
|
'user_shop_domain',
|
||||||
'mode',
|
'mode',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,11 +101,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
* @property int|null $abo_interval
|
* @property int|null $abo_interval
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereAboInterval($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereAboInterval($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereIsAbo($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ShoppingOrder whereIsAbo($value)
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlOutboundShipments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlOutboundShipments
|
||||||
* @property-read int|null $dhl_outbound_shipments_count
|
* @property-read int|null $dhl_outbound_shipments_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlReturnShipments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlReturnShipments
|
||||||
* @property-read int|null $dhl_return_shipments_count
|
* @property-read int|null $dhl_return_shipments_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\DhlShipment> $dhlShipments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Acme\Dhl\Models\DhlShipment> $dhlShipments
|
||||||
* @property-read int|null $dhl_shipments_count
|
* @property-read int|null $dhl_shipments_count
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
|
|
@ -227,110 +227,120 @@ class ShoppingOrder extends Model
|
||||||
|
|
||||||
public function shopping_user()
|
public function shopping_user()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\ShoppingUser','shopping_user_id');
|
return $this->belongsTo('App\Models\ShoppingUser', 'shopping_user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function country()
|
public function country()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\ShippingCountry','country_id');
|
return $this->belongsTo('App\Models\ShippingCountry', 'country_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shipping_country()
|
public function shipping_country()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\ShippingCountry','country_id');
|
return $this->belongsTo('App\Models\ShippingCountry', 'country_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function homeparty()
|
public function homeparty()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\Homeparty','homeparty_id');
|
return $this->belongsTo('App\Models\Homeparty', 'homeparty_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_shop()
|
public function user_shop()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\UserShop','user_shop_id');
|
return $this->belongsTo('App\Models\UserShop', 'user_shop_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
//can null
|
//can null
|
||||||
public function member()
|
public function member()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\User','member_id');
|
return $this->belongsTo('App\User', 'member_id');
|
||||||
}
|
}
|
||||||
//can null
|
//can null
|
||||||
public function auth_user()
|
public function auth_user()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\User','auth_user_id');
|
return $this->belongsTo('App\User', 'auth_user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_history()
|
public function user_history()
|
||||||
{
|
{
|
||||||
return $this->hasOne('App\Models\UserHistory','shopping_order_id')->latest();
|
return $this->hasOne('App\Models\UserHistory', 'shopping_order_id')->latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_invoice(){
|
public function user_invoice()
|
||||||
|
{
|
||||||
return $this->hasOne('App\Models\UserInvoice', 'shopping_order_id', '');
|
return $this->hasOne('App\Models\UserInvoice', 'shopping_order_id', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shopping_collect_order(){
|
public function shopping_collect_order()
|
||||||
|
{
|
||||||
return $this->hasOne('App\Models\ShoppingCollectOrder', 'shopping_order_id', '');
|
return $this->hasOne('App\Models\ShoppingCollectOrder', 'shopping_order_id', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shopping_order_items(){
|
public function shopping_order_items()
|
||||||
|
{
|
||||||
return $this->hasMany('App\Models\ShoppingOrderItem', 'shopping_order_id');
|
return $this->hasMany('App\Models\ShoppingOrderItem', 'shopping_order_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shopping_payments(){
|
public function shopping_payments()
|
||||||
|
{
|
||||||
return $this->hasMany('App\Models\ShoppingPayment', 'shopping_order_id');
|
return $this->hasMany('App\Models\ShoppingPayment', 'shopping_order_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_sales_volume(){
|
public function user_sales_volume()
|
||||||
|
{
|
||||||
return $this->hasOne('App\Models\UserSalesVolume', 'shopping_order_id');
|
return $this->hasOne('App\Models\UserSalesVolume', 'shopping_order_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_sales_volume_no_userid(){
|
public function user_sales_volume_no_userid()
|
||||||
|
{
|
||||||
return $this->hasOne('App\Models\UserSalesVolume', 'shopping_order_id')->where('user_id', '=', NULL)->first();
|
return $this->hasOne('App\Models\UserSalesVolume', 'shopping_order_id')->where('user_id', '=', NULL)->first();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserAbo(){
|
public function getUserAbo()
|
||||||
|
{
|
||||||
$UserAboOrder = UserAboOrder::where('shopping_order_id', $this->id)->first();
|
$UserAboOrder = UserAboOrder::where('shopping_order_id', $this->id)->first();
|
||||||
if($UserAboOrder && $UserAboOrder->user_abo){
|
if ($UserAboOrder && $UserAboOrder->user_abo) {
|
||||||
return $UserAboOrder->user_abo;
|
return $UserAboOrder->user_abo;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLocale(){
|
public function getLocale()
|
||||||
|
{
|
||||||
return $this->language ? $this->language : \App::getLocale();
|
return $this->language ? $this->language : \App::getLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserHistoryValue($values = []){
|
public function setUserHistoryValue($values = [])
|
||||||
if($user_history = $this->user_history){
|
{
|
||||||
foreach ($values as $key=>$val){
|
if ($user_history = $this->user_history) {
|
||||||
|
foreach ($values as $key => $val) {
|
||||||
$user_history->{$key} = $val;
|
$user_history->{$key} = $val;
|
||||||
}
|
}
|
||||||
$user_history->save();
|
$user_history->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastShoppingPayment($key=false){
|
public function getLastShoppingPayment($key = false)
|
||||||
|
{
|
||||||
$shopping_payment = $this->shopping_payments->last();
|
$shopping_payment = $this->shopping_payments->last();
|
||||||
if($shopping_payment){
|
if ($shopping_payment) {
|
||||||
if($key === 'getPaymentType'){
|
if ($key === 'getPaymentType') {
|
||||||
return $shopping_payment->getPaymentType();
|
return $shopping_payment->getPaymentType();
|
||||||
}
|
}
|
||||||
if($key === 'reference'){
|
if ($key === 'reference') {
|
||||||
return $shopping_payment->reference;
|
return $shopping_payment->reference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastShoppingPaymentTransaction(){
|
public function getLastShoppingPaymentTransaction()
|
||||||
if($this->shopping_payments){
|
{
|
||||||
|
if ($this->shopping_payments) {
|
||||||
$shopping_payment = $this->shopping_payments->last();
|
$shopping_payment = $this->shopping_payments->last();
|
||||||
if($shopping_payment){
|
if ($shopping_payment) {
|
||||||
$payt = $shopping_payment->payment_transactions->last();
|
$payt = $shopping_payment->payment_transactions->last();
|
||||||
if($payt){
|
if ($payt) {
|
||||||
return $payt;
|
return $payt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -338,30 +348,36 @@ class ShoppingOrder extends Model
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShippedType(){
|
public function getShippedType()
|
||||||
return isset(self::$shippedTypes[$this->shipped]) ? __('payment.'.self::$shippedTypes[$this->shipped]) : "";
|
{
|
||||||
|
return isset(self::$shippedTypes[$this->shipped]) ? __('payment.' . self::$shippedTypes[$this->shipped]) : "";
|
||||||
}
|
}
|
||||||
public static function getTransShippedType(){
|
public static function getTransShippedType()
|
||||||
|
{
|
||||||
$ret = [];
|
$ret = [];
|
||||||
foreach(self::$shippedTypes as $key=>$val){
|
foreach (self::$shippedTypes as $key => $val) {
|
||||||
$ret[$key] = trans('payment.'.$val);
|
$ret[$key] = trans('payment.' . $val);
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAPIShippedType(){
|
public function getAPIShippedType()
|
||||||
|
{
|
||||||
return isset(self::$apiShippedTypes[$this->shipped]) ? self::$apiShippedTypes[$this->shipped] : "free";
|
return isset(self::$apiShippedTypes[$this->shipped]) ? self::$apiShippedTypes[$this->shipped] : "free";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShippedColor(){
|
public function getShippedColor()
|
||||||
|
{
|
||||||
return isset(self::$shippedColors[$this->shipped]) ? self::$shippedColors[$this->shipped] : "default";
|
return isset(self::$shippedColors[$this->shipped]) ? self::$shippedColors[$this->shipped] : "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAPIStatusType(){
|
public function getAPIStatusType()
|
||||||
return isset(self::$apiStatusTypes[$this->api_status]) ? __('payment.'.self::$apiStatusTypes[$this->api_status]) : "bestellt";
|
{
|
||||||
|
return isset(self::$apiStatusTypes[$this->api_status]) ? __('payment.' . self::$apiStatusTypes[$this->api_status]) : "bestellt";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAPIStatusColor(){
|
public function getAPIStatusColor()
|
||||||
|
{
|
||||||
return isset(self::$apiStatusColors[$this->api_status]) ? self::$apiStatusColors[$this->api_status] : "warning";
|
return isset(self::$apiStatusColors[$this->api_status]) ? self::$apiStatusColors[$this->api_status] : "warning";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,48 +423,53 @@ class ShoppingOrder extends Model
|
||||||
|
|
||||||
public function getPriceVkNetBy($product_id)
|
public function getPriceVkNetBy($product_id)
|
||||||
{
|
{
|
||||||
if($product = Product::find($product_id)){
|
if ($product = Product::find($product_id)) {
|
||||||
if($this->shipping_country && $this->shipping_country->country){
|
if ($this->shipping_country && $this->shipping_country->country) {
|
||||||
return $product->getPriceWith(true, false, $this->shipping_country->country);
|
return $product->getPriceWith(true, false, $this->shipping_country->country);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPaymentForType(){
|
public function getPaymentForType()
|
||||||
return isset(self::$paymentForTypes[$this->payment_for]) ? __('payment.'.self::$paymentForTypes[$this->payment_for]) : "";
|
{
|
||||||
|
return isset(self::$paymentForTypes[$this->payment_for]) ? __('payment.' . self::$paymentForTypes[$this->payment_for]) : "";
|
||||||
}
|
}
|
||||||
public function getPaymentForColor(){
|
public function getPaymentForColor()
|
||||||
|
{
|
||||||
return isset(self::$paymentForColors[$this->payment_for]) ? self::$paymentForColors[$this->payment_for] : "";
|
return isset(self::$paymentForColors[$this->payment_for]) ? self::$paymentForColors[$this->payment_for] : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserDiscount()
|
public function getUserDiscount()
|
||||||
{
|
{
|
||||||
if($this->auth_user && $this->auth_user->user_level){
|
if ($this->auth_user && $this->auth_user->user_level) {
|
||||||
return $this->auth_user->user_level->getFormattedMargin();
|
return $this->auth_user->user_level->getFormattedMargin();
|
||||||
}
|
}
|
||||||
if($this->member && $this->member->user_level){
|
if ($this->member && $this->member->user_level) {
|
||||||
return $this->member->user_level->getFormattedMargin();
|
return $this->member->user_level->getFormattedMargin();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItemsCount(){
|
public function getItemsCount()
|
||||||
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
if($this->shopping_order_items){
|
if ($this->shopping_order_items) {
|
||||||
foreach ($this->shopping_order_items as $shopping_order_item){
|
foreach ($this->shopping_order_items as $shopping_order_item) {
|
||||||
$count += $shopping_order_item->qty;
|
$count += $shopping_order_item->qty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
public function isInvoice(){
|
public function isInvoice()
|
||||||
|
{
|
||||||
return $this->user_invoice ? true : false;
|
return $this->user_invoice ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStatusByOrder(){
|
public function getStatusByOrder()
|
||||||
if($this->payment_for){
|
{
|
||||||
if($this->payment_for === 6){ //Kunde-Shop
|
if ($this->payment_for) {
|
||||||
|
if ($this->payment_for === 6) { //Kunde-Shop
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -461,21 +482,21 @@ class ShoppingOrder extends Model
|
||||||
$tax_split = [];
|
$tax_split = [];
|
||||||
$net_split = [];
|
$net_split = [];
|
||||||
|
|
||||||
if($this->homeparty){
|
if ($this->homeparty) {
|
||||||
foreach($this->homeparty->homeparty_order_items as $item){
|
foreach ($this->homeparty->homeparty_order_items as $item) {
|
||||||
$tax_rate = intval($item->tax_rate);
|
$tax_rate = intval($item->tax_rate);
|
||||||
if($tax_rate > 0){
|
if ($tax_rate > 0) {
|
||||||
$vk_tax = round((($item->price - $item->price_net) * $item->qty), 2);
|
$vk_tax = round((($item->price - $item->price_net) * $item->qty), 2);
|
||||||
$ek_tax = round((($item->ek_price - $item->ek_price_net) * $item->qty), 2);
|
$ek_tax = round((($item->ek_price - $item->ek_price_net) * $item->qty), 2);
|
||||||
$vk_net = round(($item->price_net * $item->qty), 2);
|
$vk_net = round(($item->price_net * $item->qty), 2);
|
||||||
$ek_net = round(($item->ek_price_net * $item->qty), 2);
|
$ek_net = round(($item->ek_price_net * $item->qty), 2);
|
||||||
if(isset($tax_split[$tax_rate])){
|
if (isset($tax_split[$tax_rate])) {
|
||||||
$tax_split[$tax_rate]['vk_tax'] = round($tax_split[$tax_rate]['vk_tax'] + $vk_tax, 2);
|
$tax_split[$tax_rate]['vk_tax'] = round($tax_split[$tax_rate]['vk_tax'] + $vk_tax, 2);
|
||||||
$tax_split[$tax_rate]['ek_tax'] = round($tax_split[$tax_rate]['ek_tax'] + $ek_tax, 2);
|
$tax_split[$tax_rate]['ek_tax'] = round($tax_split[$tax_rate]['ek_tax'] + $ek_tax, 2);
|
||||||
|
|
||||||
$net_split[$tax_rate]['vk_net'] = round($net_split[$tax_rate]['vk_net'] + $vk_net, 2);
|
$net_split[$tax_rate]['vk_net'] = round($net_split[$tax_rate]['vk_net'] + $vk_net, 2);
|
||||||
$net_split[$tax_rate]['ek_net'] = round($net_split[$tax_rate]['ek_net'] + $ek_net, 2);
|
$net_split[$tax_rate]['ek_net'] = round($net_split[$tax_rate]['ek_net'] + $ek_net, 2);
|
||||||
}else{
|
} else {
|
||||||
$tax_split[$tax_rate] = ['vk_tax' => $vk_tax, 'ek_tax' => $ek_tax];
|
$tax_split[$tax_rate] = ['vk_tax' => $vk_tax, 'ek_tax' => $ek_tax];
|
||||||
$net_split[$tax_rate] = ['vk_net' => $vk_net, 'ek_net' => $ek_net];
|
$net_split[$tax_rate] = ['vk_net' => $vk_net, 'ek_net' => $ek_net];
|
||||||
}
|
}
|
||||||
|
|
@ -487,8 +508,8 @@ class ShoppingOrder extends Model
|
||||||
$order_vk_net = 0;
|
$order_vk_net = 0;
|
||||||
$order_ek_net = 0;
|
$order_ek_net = 0;
|
||||||
|
|
||||||
if($this->homeparty->order){
|
if ($this->homeparty->order) {
|
||||||
if(isset($this->homeparty->order['ek_price_net'])){
|
if (isset($this->homeparty->order['ek_price_net'])) {
|
||||||
$order_vk_tax = round((($this->homeparty->order['price'] - $this->homeparty->order['price_net'])), 2);
|
$order_vk_tax = round((($this->homeparty->order['price'] - $this->homeparty->order['price_net'])), 2);
|
||||||
$order_ek_tax = round((($this->homeparty->order['ek_price'] - $this->homeparty->order['ek_price_net'])), 2);
|
$order_ek_tax = round((($this->homeparty->order['ek_price'] - $this->homeparty->order['ek_price_net'])), 2);
|
||||||
$order_vk_net = $this->homeparty->order['price_net'];
|
$order_vk_net = $this->homeparty->order['price_net'];
|
||||||
|
|
@ -496,17 +517,17 @@ class ShoppingOrder extends Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($tax_split[16])){
|
if (isset($tax_split[16])) {
|
||||||
$tax_split[16] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
$tax_split[16] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
||||||
$net_split[16] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
$net_split[16] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
||||||
}
|
}
|
||||||
if(isset($tax_split[19])){
|
if (isset($tax_split[19])) {
|
||||||
$tax_split[19] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
$tax_split[19] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
||||||
$net_split[19] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
$net_split[19] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($tax_split[5])){
|
if (isset($tax_split[5])) {
|
||||||
if(!isset($tax_split[16])){
|
if (!isset($tax_split[16])) {
|
||||||
$tax_split[16] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
$tax_split[16] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
||||||
$net_split[16] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
$net_split[16] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
||||||
}
|
}
|
||||||
|
|
@ -515,8 +536,8 @@ class ShoppingOrder extends Model
|
||||||
$net_split[16]['vk_net'] = round($net_split[16]['vk_net'] - $net_split[5]['vk_net'], 2);
|
$net_split[16]['vk_net'] = round($net_split[16]['vk_net'] - $net_split[5]['vk_net'], 2);
|
||||||
$net_split[16]['ek_net'] = round($net_split[16]['ek_net'] - $net_split[5]['ek_net'], 2);
|
$net_split[16]['ek_net'] = round($net_split[16]['ek_net'] - $net_split[5]['ek_net'], 2);
|
||||||
}
|
}
|
||||||
if(isset($tax_split[7])){
|
if (isset($tax_split[7])) {
|
||||||
if(!isset($tax_split[19])){
|
if (!isset($tax_split[19])) {
|
||||||
$tax_split[19] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
$tax_split[19] = ['vk_tax' => $order_vk_tax, 'ek_tax' => $order_ek_tax];
|
||||||
$net_split[19] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
$net_split[19] = ['vk_net' => $order_vk_net, 'ek_net' => $order_ek_net];
|
||||||
}
|
}
|
||||||
|
|
@ -527,20 +548,20 @@ class ShoppingOrder extends Model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach($tax_split as $key=>$value){
|
foreach ($tax_split as $key => $value) {
|
||||||
$tax_split[$key]['vk_tax'] = number_format($value['vk_tax'], 2);
|
$tax_split[$key]['vk_tax'] = number_format($value['vk_tax'], 2);
|
||||||
$tax_split[$key]['ek_tax'] = number_format($value['ek_tax'], 2);
|
$tax_split[$key]['ek_tax'] = number_format($value['ek_tax'], 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($net_split as $key=>$value){
|
foreach ($net_split as $key => $value) {
|
||||||
$net_split[$key]['vk_net'] = number_format($value['vk_net'], 2);
|
$net_split[$key]['vk_net'] = number_format($value['vk_net'], 2);
|
||||||
$net_split[$key]['ek_net'] = number_format($value['ek_net'], 2);
|
$net_split[$key]['ek_net'] = number_format($value['ek_net'], 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!isset($tax_split[16]) && !isset($tax_split[19])){
|
if (!isset($tax_split[16]) && !isset($tax_split[19])) {
|
||||||
$tax_split = NULL;
|
$tax_split = NULL;
|
||||||
}
|
}
|
||||||
if(!isset($net_split[16]) && !isset($net_split[19])){
|
if (!isset($net_split[16]) && !isset($net_split[19])) {
|
||||||
$net_split = NULL;
|
$net_split = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -555,13 +576,13 @@ class ShoppingOrder extends Model
|
||||||
$tax_split = NULL;
|
$tax_split = NULL;
|
||||||
$net_split = NULL;
|
$net_split = NULL;
|
||||||
|
|
||||||
if($this->tax > 0){
|
if ($this->tax > 0) {
|
||||||
$tax_split = [];
|
$tax_split = [];
|
||||||
$net_split = [];
|
$net_split = [];
|
||||||
|
|
||||||
foreach($this->shopping_order_items as $item){
|
foreach ($this->shopping_order_items as $item) {
|
||||||
$tax_rate = intval($item->tax_rate);
|
$tax_rate = intval($item->tax_rate);
|
||||||
if($tax_rate > 0){
|
if ($tax_rate > 0) {
|
||||||
$tax_split[$tax_rate] = isset($tax_split[$tax_rate]) ?
|
$tax_split[$tax_rate] = isset($tax_split[$tax_rate]) ?
|
||||||
round($tax_split[$tax_rate] + ($item->tax * $item->qty), 2) :
|
round($tax_split[$tax_rate] + ($item->tax * $item->qty), 2) :
|
||||||
round(($item->tax * $item->qty), 2);
|
round(($item->tax * $item->qty), 2);
|
||||||
|
|
@ -569,42 +590,38 @@ class ShoppingOrder extends Model
|
||||||
$net_split[$tax_rate] = isset($net_split[$tax_rate]) ?
|
$net_split[$tax_rate] = isset($net_split[$tax_rate]) ?
|
||||||
round($net_split[$tax_rate] + ($item->price_net * $item->qty), 2) :
|
round($net_split[$tax_rate] + ($item->price_net * $item->qty), 2) :
|
||||||
round(($item->price_net * $item->qty), 2);
|
round(($item->price_net * $item->qty), 2);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isset($tax_split[16])){
|
if (isset($tax_split[16])) {
|
||||||
$tax_split[16] = $this->tax;
|
$tax_split[16] = $this->tax;
|
||||||
$net_split[16] = $this->subtotal_ws;
|
$net_split[16] = $this->subtotal_ws;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(isset($tax_split[19])){
|
if (isset($tax_split[19])) {
|
||||||
$tax_split[19] = $this->tax;
|
$tax_split[19] = $this->tax;
|
||||||
$net_split[19] = $this->subtotal_ws;
|
$net_split[19] = $this->subtotal_ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($tax_split[5])){
|
if (isset($tax_split[5])) {
|
||||||
if(!isset($tax_split[16])){
|
if (!isset($tax_split[16])) {
|
||||||
$tax_split[16] = $this->tax;
|
$tax_split[16] = $this->tax;
|
||||||
$net_split[16] = $this->subtotal_ws;
|
$net_split[16] = $this->subtotal_ws;
|
||||||
|
|
||||||
}
|
}
|
||||||
$tax_split[16] = round($tax_split[16] - $tax_split[5], 2);
|
$tax_split[16] = round($tax_split[16] - $tax_split[5], 2);
|
||||||
$net_split[16] = round($net_split[16] - $net_split[5], 2);
|
$net_split[16] = round($net_split[16] - $net_split[5], 2);
|
||||||
}
|
}
|
||||||
if(isset($tax_split[7])){
|
if (isset($tax_split[7])) {
|
||||||
if(!isset($tax_split[19])){
|
if (!isset($tax_split[19])) {
|
||||||
$tax_split[19] = $this->tax;
|
$tax_split[19] = $this->tax;
|
||||||
$net_split[19] = $this->subtotal_ws;
|
$net_split[19] = $this->subtotal_ws;
|
||||||
|
|
||||||
}
|
}
|
||||||
$tax_split[19] = round($tax_split[19] - $tax_split[7], 2);
|
$tax_split[19] = round($tax_split[19] - $tax_split[7], 2);
|
||||||
$net_split[19] = round($net_split[19] - $net_split[7], 2);
|
$net_split[19] = round($net_split[19] - $net_split[7], 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($tax_split as $key=>$value){
|
foreach ($tax_split as $key => $value) {
|
||||||
$tax_split[$key] = number_format($value, 2);
|
$tax_split[$key] = number_format($value, 2);
|
||||||
}
|
}
|
||||||
foreach($net_split as $key=>$value){
|
foreach ($net_split as $key => $value) {
|
||||||
$net_split[$key] = number_format($value, 2);
|
$net_split[$key] = number_format($value, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -614,16 +631,17 @@ class ShoppingOrder extends Model
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShoppingUserFullName(){
|
public function getShoppingUserFullName()
|
||||||
|
{
|
||||||
|
|
||||||
if($this->shopping_user){
|
if ($this->shopping_user) {
|
||||||
$fullname = $this->shopping_user->getFullNameAsArray();
|
$fullname = $this->shopping_user->getFullNameAsArray();
|
||||||
$ret = "";
|
$ret = "";
|
||||||
$ret .= $fullname['company'] ? $fullname['company'].' | ' : '';
|
$ret .= $fullname['company'] ? $fullname['company'] . ' | ' : '';
|
||||||
$ret .= $fullname['salutation'] ? \App\Services\HTMLHelper::getSalutationLang($fullname['salutation']).' ' : '';
|
$ret .= $fullname['salutation'] ? \App\Services\HTMLHelper::getSalutationLang($fullname['salutation']) . ' ' : '';
|
||||||
$ret .= $fullname['firstname'] ? $fullname['firstname'].' ' : '';
|
$ret .= $fullname['firstname'] ? $fullname['firstname'] . ' ' : '';
|
||||||
$ret .= $fullname['lastname'] ? $fullname['lastname'] : '';
|
$ret .= $fullname['lastname'] ? $fullname['lastname'] : '';
|
||||||
$ret .= $fullname['email'] ? ' | '.$fullname['email'].'' : '';
|
$ret .= $fullname['email'] ? ' | ' . $fullname['email'] . '' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
@ -634,7 +652,7 @@ class ShoppingOrder extends Model
|
||||||
*/
|
*/
|
||||||
public function dhlShipments()
|
public function dhlShipments()
|
||||||
{
|
{
|
||||||
return $this->hasMany('App\Models\DhlShipment', 'shopping_order_id');
|
return $this->hasMany('Acme\Dhl\Models\DhlShipment', 'order_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -642,7 +660,7 @@ class ShoppingOrder extends Model
|
||||||
*/
|
*/
|
||||||
public function dhlOutboundShipments()
|
public function dhlOutboundShipments()
|
||||||
{
|
{
|
||||||
return $this->hasMany('App\Models\DhlShipment', 'shopping_order_id')->where('type', 'outbound');
|
return $this->hasMany('Acme\Dhl\Models\DhlShipment', 'order_id')->where('type', 'outbound');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -650,7 +668,7 @@ class ShoppingOrder extends Model
|
||||||
*/
|
*/
|
||||||
public function dhlReturnShipments()
|
public function dhlReturnShipments()
|
||||||
{
|
{
|
||||||
return $this->hasMany('App\Models\DhlShipment', 'shopping_order_id')->where('type', 'return');
|
return $this->hasMany('Acme\Dhl\Models\DhlShipment', 'order_id')->where('type', 'return');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -668,5 +686,4 @@ class ShoppingOrder extends Model
|
||||||
{
|
{
|
||||||
return $this->dhlShipments()->latest()->first();
|
return $this->dhlShipments()->latest()->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
app/Policies/ModelPolicy.php
Executable file → Normal file
0
app/Policies/ModelPolicy.php
Executable file → Normal file
|
|
@ -22,18 +22,20 @@ class AppServiceProvider extends ServiceProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domain-bewusster View Composer für user_shop
|
// Domain-bewusster View Composer für user_shop
|
||||||
|
// HOTFIX: DomainContext temporär deaktiviert
|
||||||
|
// TODO: Nach Claude v2 Implementation wieder aktivieren
|
||||||
\View::composer('*', function ($view) {
|
\View::composer('*', function ($view) {
|
||||||
try {
|
try {
|
||||||
$context = app(\App\Domain\DomainContext::class);
|
// $context = app(\App\Domain\DomainContext::class);
|
||||||
|
// if ($context->type === 'main') {
|
||||||
|
// $view->with('user_shop', null);
|
||||||
|
// } else {
|
||||||
|
// $userShop = $context->userShop ?? \App\Services\Util::getUserShop();
|
||||||
|
// $view->with('user_shop', $userShop);
|
||||||
|
// }
|
||||||
|
|
||||||
// Für die Main-Domain: user_shop immer auf null setzen
|
// Temporär: Verwende immer das normale Verhalten
|
||||||
if ($context->type === 'main') {
|
$view->with('user_shop', \App\Services\Util::getUserShop());
|
||||||
$view->with('user_shop', null);
|
|
||||||
} else {
|
|
||||||
// Für alle anderen Domains: normales Verhalten
|
|
||||||
$userShop = $context->userShop ?? \App\Services\Util::getUserShop();
|
|
||||||
$view->with('user_shop', $userShop);
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// Fallback bei Fehlern
|
// Fallback bei Fehlern
|
||||||
$view->with('user_shop', \App\Services\Util::getUserShop());
|
$view->with('user_shop', \App\Services\Util::getUserShop());
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Domain\DomainContext;
|
// use App\Domain\DomainContext; // HOTFIX: Temporär deaktiviert
|
||||||
|
use App\Domain\EarlyDomainParser;
|
||||||
use Illuminate\Cache\RateLimiting\Limit;
|
use Illuminate\Cache\RateLimiting\Limit;
|
||||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -32,7 +33,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
// $this->configureRateLimiting();
|
$this->configureRateLimiting();
|
||||||
|
|
||||||
$this->routes(function () {
|
$this->routes(function () {
|
||||||
// API-Routen werden global geladen
|
// API-Routen werden global geladen
|
||||||
|
|
@ -44,36 +45,45 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
// Web-Routen werden domain-bewusst geladen
|
// Web-Routen werden domain-bewusst geladen
|
||||||
Route::middleware('web')
|
Route::middleware('web')
|
||||||
->namespace($this->namespace)
|
->namespace($this->namespace)
|
||||||
->group(function() {
|
->group(function () {
|
||||||
$this->loadDomainAwareRoutes();
|
$this->loadDomainAwareRoutes();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lädt Routen basierend auf dem aktuellen Domain-Kontext.
|
* Lädt Routen basierend auf der domains.php Konfiguration.
|
||||||
|
* Vereinfachter Ansatz ohne DomainContext-Abhängigkeit
|
||||||
*/
|
*/
|
||||||
protected function loadDomainAwareRoutes(): void
|
protected function loadDomainAwareRoutes(): void
|
||||||
{
|
{
|
||||||
/** @var DomainContext $context */
|
$request = $this->app->make('request');
|
||||||
$context = app(DomainContext::class);
|
|
||||||
$this->loadSharedRoutes();
|
$this->loadSharedRoutes();
|
||||||
\Log::info('loadDomainAwareRoutes', ['context' => $context]);
|
// Lade alle Domain-spezifischen Routen
|
||||||
match ($context->type) {
|
// Die Domain-Logik wird von SubdomainResolver Middleware behandelt
|
||||||
'main' => $this->loadDomainRoutes('main', 'main.php'),
|
$domainType = EarlyDomainParser::getCurrentDomainType($request->getHost());
|
||||||
'main-shop' => [
|
|
||||||
$this->loadDomainRoutes('shop', 'shop.php'),
|
$routesToLoad = match ($domainType) {
|
||||||
$this->loadDomainRoutes('portal', 'portal.php'),
|
'main' => ['main'],
|
||||||
],
|
'main-shop' => ['shop', 'portal'],
|
||||||
'user-shop' => [
|
'user-shop' => ['user-shop', 'portal'],
|
||||||
$this->loadDomainRoutes('user-shop', 'user-shop.php'),
|
'crm' => ['crm'],
|
||||||
$this->loadDomainRoutes('portal', 'portal.php'),
|
'portal' => ['portal'],
|
||||||
],
|
'checkout' => ['checkout'],
|
||||||
'crm' => $this->loadDomainRoutes('crm', 'crm.php'),
|
'unknown' => ['main'], // Fallback für unbekannte Domains
|
||||||
'portal' => $this->loadDomainRoutes('portal', 'portal.php'),
|
default => ['main'],
|
||||||
'checkout' => $this->loadDomainRoutes('checkout', 'checkout.php'),
|
|
||||||
default => $this->loadAllDomainRoutesForCaching(),
|
|
||||||
};
|
};
|
||||||
|
foreach ($routesToLoad as $routeType) {
|
||||||
|
$this->loadDomainRoutes($routeType, $routeType . '.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config('app.debug')) {
|
||||||
|
\Log::channel('domain')->info('Domain-aware routes loaded', [
|
||||||
|
'domain_type' => $domainType,
|
||||||
|
'routes_loaded' => $routesToLoad,
|
||||||
|
'host' => EarlyDomainParser::parseDomain()['host'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -81,28 +91,18 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
protected function loadDomainRoutes(string $domainType, string $fileName): void
|
protected function loadDomainRoutes(string $domainType, string $fileName): void
|
||||||
{
|
{
|
||||||
$domain = config("domains.domains.{$domainType}.host");
|
$routePath = base_path('routes/domains/' . $fileName);
|
||||||
|
|
||||||
Route::domain($domain)
|
if (file_exists($routePath)) {
|
||||||
->group(base_path('routes/domains/' . $fileName));
|
Route::group([], $routePath);
|
||||||
|
} else {
|
||||||
|
if (config('app.debug')) {
|
||||||
|
\Log::channel('domain')->warning('Domain route file not found', [
|
||||||
|
'domain_type' => $domainType,
|
||||||
|
'file_path' => $routePath,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Lädt alle domainspezifischen Routen.
|
|
||||||
* Wird als Fallback für das Route-Caching benötigt.
|
|
||||||
*/
|
|
||||||
protected function loadAllDomainRoutesForCaching(): void
|
|
||||||
{
|
|
||||||
if (app()->routesAreCached()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loadDomainRoutes('main', 'main.php');
|
|
||||||
$this->loadDomainRoutes('shop', 'shop.php');
|
|
||||||
$this->loadDomainRoutes('crm', 'crm.php');
|
|
||||||
$this->loadDomainRoutes('portal', 'portal.php');
|
|
||||||
$this->loadDomainRoutes('checkout', 'checkout.php');
|
|
||||||
$this->loadDomainRoutes('user-shop', 'user-shop.php');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ use App\Models\PaymentMethod;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use App\Http\Controllers\Api\KasController;
|
use App\Http\Controllers\Api\KasController;
|
||||||
|
|
||||||
class UserRepository extends BaseRepository {
|
class UserRepository extends BaseRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
public function __construct(User $model)
|
public function __construct(User $model)
|
||||||
|
|
@ -23,28 +24,27 @@ class UserRepository extends BaseRepository {
|
||||||
public function update($data)
|
public function update($data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if($data['user_id'] === "new" || $data['user_id'] == 0){
|
if ($data['user_id'] === "new" || $data['user_id'] == 0) {
|
||||||
$this->model = User::create([
|
$this->model = User::create([
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'password' => env('APP_KEY'),
|
'password' => env('APP_KEY'),
|
||||||
]);
|
]);
|
||||||
$this->model->payment_methods = PaymentMethod::getDefaultAsArray();
|
$this->model->payment_methods = PaymentMethod::getDefaultAsArray();
|
||||||
$this->model->save();
|
$this->model->save();
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$this->model = $this->getById($data['user_id']);
|
$this->model = $this->getById($data['user_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->model->account_id){
|
if (!$this->model->account_id) {
|
||||||
$account = new UserAccount();
|
$account = new UserAccount();
|
||||||
}else{
|
} else {
|
||||||
$account = $this->model->account;
|
$account = $this->model->account;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['same_as_billing'] = !isset($data['same_as_billing']) ? 0 : 1;
|
$data['same_as_billing'] = !isset($data['same_as_billing']) ? 0 : 1;
|
||||||
$account->fill($data)->save();
|
$account->fill($data)->save();
|
||||||
|
|
||||||
if(!$this->model->account_id){
|
if (!$this->model->account_id) {
|
||||||
$this->model->account_id = $account->id;
|
$this->model->account_id = $account->id;
|
||||||
$this->model->save();
|
$this->model->save();
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +52,8 @@ class UserRepository extends BaseRepository {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create($data){
|
public function create($data)
|
||||||
|
{
|
||||||
|
|
||||||
$this->model = User::create([
|
$this->model = User::create([
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
|
|
@ -79,16 +80,17 @@ class UserRepository extends BaseRepository {
|
||||||
public function deleteUser(User $user, $complete = false)
|
public function deleteUser(User $user, $complete = false)
|
||||||
{
|
{
|
||||||
$active_sponsor = UserUtil::findNextActiveSponsor($user->id);
|
$active_sponsor = UserUtil::findNextActiveSponsor($user->id);
|
||||||
if($active_sponsor){
|
if ($active_sponsor) {
|
||||||
UserUtil::setNewSponsorToChilds($user->id, $active_sponsor->id);
|
UserUtil::setNewSponsorToChilds($user->id, $active_sponsor->id);
|
||||||
UserUtil::setShoppingUserToNewMember($user->id, $active_sponsor->id);
|
UserUtil::setShoppingUserToNewMember($user->id, $active_sponsor->id);
|
||||||
}
|
}
|
||||||
UserUtil::deleteUser($user, $complete);
|
UserUtil::deleteUser($user, $complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reverse_charge_validate($data, $user, $route){
|
public function reverse_charge_validate($data, $user, $route)
|
||||||
|
{
|
||||||
|
|
||||||
if(isset($data['action']) && $data['action'] == 'reverse_charge_validate'){
|
if (isset($data['action']) && $data['action'] == 'reverse_charge_validate') {
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'tax_identification_number' => 'required',
|
'tax_identification_number' => 'required',
|
||||||
);
|
);
|
||||||
|
|
@ -97,29 +99,30 @@ class UserRepository extends BaseRepository {
|
||||||
$data = [
|
$data = [
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
];
|
];
|
||||||
return redirect($route.'#user-vat-validation')->withErrors($validator)->withInput($data);
|
return redirect($route . '#user-vat-validation')->withErrors($validator)->withInput($data);
|
||||||
}
|
}
|
||||||
$ret = $this->reverse_charge_activate($data, $user);
|
$ret = $this->reverse_charge_activate($data, $user);
|
||||||
if($ret === 'error'){
|
if ($ret === 'error') {
|
||||||
$validator = Validator::make($data, []);
|
$validator = Validator::make($data, []);
|
||||||
$validator->errors()->add('tax_identification_number_validated', __('msg.VATID_could_not_be_validated'));
|
$validator->errors()->add('tax_identification_number_validated', __('msg.VATID_could_not_be_validated'));
|
||||||
$data['reverse_charge'] = 0;
|
$data['reverse_charge'] = 0;
|
||||||
$data = [
|
$data = [
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
];
|
];
|
||||||
return redirect($route.'#user-vat-validation')->withErrors($validator)->withInput($data);
|
return redirect($route . '#user-vat-validation')->withErrors($validator)->withInput($data);
|
||||||
}
|
}
|
||||||
if($ret === 'valid'){
|
if ($ret === 'valid') {
|
||||||
\Session()->flash('alert-success', __('msg.VATID_successfully_entered'));
|
\Session()->flash('alert-success', __('msg.VATID_successfully_entered'));
|
||||||
return redirect($route.'#user-vat-validation')->withInput($data);
|
return redirect($route . '#user-vat-validation')->withInput($data);
|
||||||
|
|
||||||
return redirect($route.'#user-vat-validation')->withInput($data);
|
return redirect($route . '#user-vat-validation')->withInput($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reverse_charge_delete($data, $user, $route){
|
public function reverse_charge_delete($data, $user, $route)
|
||||||
if(isset($data['action']) && $data['action'] == 'reverse_charge_delete'){
|
{
|
||||||
|
if (isset($data['action']) && $data['action'] == 'reverse_charge_delete') {
|
||||||
$user->account->tax_identification_number = '';
|
$user->account->tax_identification_number = '';
|
||||||
$user->account->reverse_charge = 0;
|
$user->account->reverse_charge = 0;
|
||||||
$user->account->reverse_charge_code = null;
|
$user->account->reverse_charge_code = null;
|
||||||
|
|
@ -127,11 +130,12 @@ class UserRepository extends BaseRepository {
|
||||||
$user->account->save();
|
$user->account->save();
|
||||||
$data['tax_identification_number'] = '';
|
$data['tax_identification_number'] = '';
|
||||||
\Session()->flash('alert-success', __('msg.reverse_charge_procedure_and_VATID_deleted'));
|
\Session()->flash('alert-success', __('msg.reverse_charge_procedure_and_VATID_deleted'));
|
||||||
return redirect($route.'#user-vat-validation')->withInput($data);
|
return redirect($route . '#user-vat-validation')->withInput($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reverse_charge_activate($data, $user){
|
public function reverse_charge_activate($data, $user)
|
||||||
|
{
|
||||||
|
|
||||||
/* 'AT' => 'AT-Oesterreich',
|
/* 'AT' => 'AT-Oesterreich',
|
||||||
'BE' => 'BE-Belgien',
|
'BE' => 'BE-Belgien',
|
||||||
|
|
@ -163,7 +167,7 @@ class UserRepository extends BaseRepository {
|
||||||
'XI' => 'XI-Nordirland', */
|
'XI' => 'XI-Nordirland', */
|
||||||
$countryCode = 'DE';
|
$countryCode = 'DE';
|
||||||
|
|
||||||
if($user->account->country_id){
|
if ($user->account->country_id) {
|
||||||
$countryCode = $user->account->country->code;
|
$countryCode = $user->account->country->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +192,7 @@ class UserRepository extends BaseRepository {
|
||||||
$client = new \SoapClient("https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl", $options);
|
$client = new \SoapClient("https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl", $options);
|
||||||
$result = $client->checkVat(['countryCode' => $countryCode, 'vatNumber' => $vatNo]);
|
$result = $client->checkVat(['countryCode' => $countryCode, 'vatNumber' => $vatNo]);
|
||||||
|
|
||||||
if($result->valid == true) {
|
if ($result->valid == true) {
|
||||||
$user->account->tax_identification_number = $data['tax_identification_number'];
|
$user->account->tax_identification_number = $data['tax_identification_number'];
|
||||||
$user->account->reverse_charge = 1;
|
$user->account->reverse_charge = 1;
|
||||||
$user->account->reverse_charge_code = $countryCode;
|
$user->account->reverse_charge_code = $countryCode;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ use stdClass;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use App\Models\UserLevel;
|
use App\Models\UserLevel;
|
||||||
use App\Models\UserBusiness;
|
use App\Models\UserBusiness;
|
||||||
|
use App\Models\UserAccount;
|
||||||
|
use App\Models\UserSalesVolume;
|
||||||
use App\Services\TranslationHelper;
|
use App\Services\TranslationHelper;
|
||||||
use App\Models\UserBusinessStructure;
|
use App\Models\UserBusinessStructure;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
@ -26,12 +28,14 @@ class BusinessUserItemOptimized
|
||||||
|
|
||||||
private $date;
|
private $date;
|
||||||
private $b_user;
|
private $b_user;
|
||||||
|
private ?TreeCalcBotOptimized $treeCalcBot = null;
|
||||||
private $user_level_active_pos;
|
private $user_level_active_pos;
|
||||||
private $needsQualificationRecalculation = false;
|
private $needsQualificationRecalculation = false;
|
||||||
|
|
||||||
public function __construct($date)
|
public function __construct($date, ?TreeCalcBotOptimized $treeCalcBot = null)
|
||||||
{
|
{
|
||||||
$this->date = $date;
|
$this->date = $date;
|
||||||
|
$this->treeCalcBot = $treeCalcBot;
|
||||||
$this->businessUserItems = []; // Initialize array
|
$this->businessUserItems = []; // Initialize array
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +92,6 @@ class BusinessUserItemOptimized
|
||||||
if ($forceLiveCalculation) {
|
if ($forceLiveCalculation) {
|
||||||
$this->calcQualPP();
|
$this->calcQualPP();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("BusinessUserItem: Error creating user {$user_id}: " . $e->getMessage());
|
\Log::error("BusinessUserItem: Error creating user {$user_id}: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|
@ -142,7 +145,6 @@ class BusinessUserItemOptimized
|
||||||
if ($forceLiveCalculation) {
|
if ($forceLiveCalculation) {
|
||||||
$this->calcQualPP();
|
$this->calcQualPP();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("BusinessUserItem: Error creating user from model {$user->id}: " . $e->getMessage());
|
\Log::error("BusinessUserItem: Error creating user from model {$user->id}: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|
@ -166,11 +168,8 @@ class BusinessUserItemOptimized
|
||||||
// Neues UserBusiness Objekt erstellen
|
// Neues UserBusiness Objekt erstellen
|
||||||
$this->b_user = new UserBusiness();
|
$this->b_user = new UserBusiness();
|
||||||
|
|
||||||
// Account-Daten (mit Error-Handling)
|
// Account-Daten (mit intelligentem Laden und Error-Handling)
|
||||||
$account = $user->relationLoaded('account') ? $user->account : null;
|
$account = $this->getAccountForUser($user);
|
||||||
if (!$account) {
|
|
||||||
\Log::warning("BusinessUserItem: No account found for user {$user->id}");
|
|
||||||
}
|
|
||||||
$fill = [
|
$fill = [
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'month' => $this->date->month,
|
'month' => $this->date->month,
|
||||||
|
|
@ -181,11 +180,11 @@ class BusinessUserItemOptimized
|
||||||
'payment_account_date' => $user->payment_account ? $user->getPaymentAccountDateFormat(false) : null,
|
'payment_account_date' => $user->payment_account ? $user->getPaymentAccountDateFormat(false) : null,
|
||||||
'active_date' => $user->active_date,
|
'active_date' => $user->active_date,
|
||||||
|
|
||||||
// Account-Daten mit Fallback
|
// Account-Daten mit korrekten Fallback-Werten
|
||||||
'm_account' => $account ? $account->m_account : '',
|
'm_account' => $account ? ($account->m_account ?? null) : null,
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'first_name' => $account ? $account->first_name : '',
|
'first_name' => $account ? ($account->first_name ?? '') : '',
|
||||||
'last_name' => $account ? $account->last_name : '',
|
'last_name' => $account ? ($account->last_name ?? '') : '',
|
||||||
'user_birthday' => $account ? $account->birthday : null,
|
'user_birthday' => $account ? $account->birthday : null,
|
||||||
'user_phone' => $account ? ($account->getPhoneNumber() ?? '') : '',
|
'user_phone' => $account ? ($account->getPhoneNumber() ?? '') : '',
|
||||||
|
|
||||||
|
|
@ -217,12 +216,13 @@ class BusinessUserItemOptimized
|
||||||
$this->b_user->business_lines = [];
|
$this->b_user->business_lines = [];
|
||||||
$this->b_user->user_items = [];
|
$this->b_user->user_items = [];
|
||||||
|
|
||||||
// Shop-Provision berechnen (mit Boundary-Check)
|
// Shop-Provision berechnen (mit verbessertem Logging)
|
||||||
$shopVolume = (float) $this->b_user->sales_volume_total_shop;
|
$shopVolume = (float) $this->b_user->sales_volume_total_shop;
|
||||||
$shopMargin = (float) $this->b_user->margin_shop;
|
$shopMargin = (float) $this->b_user->margin_shop;
|
||||||
$this->b_user->commission_shop_sales = round($shopVolume / 100 * $shopMargin, 2);
|
$calculatedCommission = round($shopVolume / 100 * $shopMargin, 2);
|
||||||
|
$this->b_user->commission_shop_sales = $calculatedCommission;
|
||||||
|
|
||||||
\Log::debug("BusinessUserItem: Created optimized user {$user->id} for {$this->date->month}/{$this->date->year}");
|
\Log::debug("BusinessUserItem: Created optimized user {$user->id} for {$this->date->month}/{$this->date->year} - Shop commission: {$calculatedCommission} (Volume: {$shopVolume}, Margin: {$shopMargin}%)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -232,16 +232,16 @@ class BusinessUserItemOptimized
|
||||||
private function enrichStoredDataWithUserModel(User $user): void
|
private function enrichStoredDataWithUserModel(User $user): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$account = $user->account;
|
$account = $this->getAccountForUser($user);
|
||||||
|
|
||||||
// Ergänze fehlende User-Grunddaten in gespeicherten UserBusiness-Daten
|
// Ergänze fehlende User-Grunddaten in gespeicherten UserBusiness-Daten
|
||||||
$this->b_user->user_id = $user->id;
|
$this->b_user->user_id = $user->id;
|
||||||
$this->b_user->email = $user->email;
|
$this->b_user->email = $user->email;
|
||||||
$this->b_user->first_name = $account ? $account->first_name : '';
|
$this->b_user->first_name = $account ? ($account->first_name ?? '') : '';
|
||||||
$this->b_user->last_name = $account ? $account->last_name : '';
|
$this->b_user->last_name = $account ? ($account->last_name ?? '') : '';
|
||||||
$this->b_user->user_birthday = $account ? $account->birthday : null;
|
$this->b_user->user_birthday = $account ? $account->birthday : null;
|
||||||
$this->b_user->user_phone = $account ? ($account->getPhoneNumber() ?? '') : '';
|
$this->b_user->user_phone = $account ? ($account->getPhoneNumber() ?? '') : '';
|
||||||
$this->b_user->m_account = $account ? $account->m_account : '';
|
$this->b_user->m_account = $account ? ($account->m_account ?? null) : null;
|
||||||
|
|
||||||
// Berechne aktiven Account-Status
|
// Berechne aktiven Account-Status
|
||||||
$this->b_user->active_account = $this->calculateActiveAccount($user);
|
$this->b_user->active_account = $this->calculateActiveAccount($user);
|
||||||
|
|
@ -257,13 +257,67 @@ class BusinessUserItemOptimized
|
||||||
// WICHTIG: Validiere Level-Qualifikationsdaten für Struktur-Ansicht
|
// WICHTIG: Validiere Level-Qualifikationsdaten für Struktur-Ansicht
|
||||||
$this->validateLevelQualificationData();
|
$this->validateLevelQualificationData();
|
||||||
|
|
||||||
\Log::debug("BusinessUserItem: Enriched stored data for user {$user->id} with current user model data");
|
// Prüfe ob Sales Volume Felder aktualisiert werden müssen
|
||||||
|
$this->updateSalesVolumeFields($user);
|
||||||
|
|
||||||
|
\Log::debug("BusinessUserItem: Enriched stored data for user {$user->id} with current user model data");
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("BusinessUserItem: Error enriching stored data for user {$user->id}: " . $e->getMessage());
|
\Log::error("BusinessUserItem: Error enriching stored data for user {$user->id}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert Sales Volume und Commission Felder bei gespeicherten Daten
|
||||||
|
*/
|
||||||
|
private function updateSalesVolumeFields(User $user): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Prüfe ob Sales Volume Felder leer sind
|
||||||
|
$fieldsToUpdate = [
|
||||||
|
'sales_volume_KP_points',
|
||||||
|
'sales_volume_TP_points',
|
||||||
|
'sales_volume_points_shop',
|
||||||
|
'sales_volume_points_KP_sum',
|
||||||
|
'sales_volume_points_TP_sum',
|
||||||
|
'sales_volume_total',
|
||||||
|
'sales_volume_total_shop',
|
||||||
|
'sales_volume_total_sum'
|
||||||
|
];
|
||||||
|
|
||||||
|
$needsUpdate = false;
|
||||||
|
foreach ($fieldsToUpdate as $field) {
|
||||||
|
if (!isset($this->b_user->{$field}) || $this->b_user->{$field} === null || $this->b_user->{$field} === 0) {
|
||||||
|
$newValue = $this->getUserSalesVolumeOptimized($user, $field);
|
||||||
|
$this->b_user->{$field} = $newValue;
|
||||||
|
|
||||||
|
if ($newValue > 0) {
|
||||||
|
$needsUpdate = true;
|
||||||
|
\Log::debug("BusinessUserItem: Updated {$field} for user {$user->id}: {$newValue}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aktualisiere Shop Commission falls nötig
|
||||||
|
if (!isset($this->b_user->commission_shop_sales) || $this->b_user->commission_shop_sales === 0) {
|
||||||
|
$shopVolume = (float) $this->b_user->sales_volume_total_shop;
|
||||||
|
$shopMargin = (float) $this->b_user->margin_shop;
|
||||||
|
|
||||||
|
if ($shopVolume > 0 && $shopMargin > 0) {
|
||||||
|
$calculatedCommission = round($shopVolume / 100 * $shopMargin, 2);
|
||||||
|
$this->b_user->commission_shop_sales = $calculatedCommission;
|
||||||
|
$needsUpdate = true;
|
||||||
|
\Log::debug("BusinessUserItem: Updated commission_shop_sales for user {$user->id}: {$calculatedCommission}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($needsUpdate) {
|
||||||
|
\Log::info("BusinessUserItem: Updated sales volume fields for user {$user->id}");
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("BusinessUserItem: Error updating sales volume fields for user {$user->id}: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validiert und aktualisiert Level-Qualifikationsdaten wenn nötig
|
* Validiert und aktualisiert Level-Qualifikationsdaten wenn nötig
|
||||||
* Stellt sicher, dass next_qual_user_level und next_can_user_level für Struktur-Ansicht verfügbar sind
|
* Stellt sicher, dass next_qual_user_level und next_can_user_level für Struktur-Ansicht verfügbar sind
|
||||||
|
|
@ -282,7 +336,6 @@ class BusinessUserItemOptimized
|
||||||
// Setze Flag für notwendige Neuberechnung
|
// Setze Flag für notwendige Neuberechnung
|
||||||
$this->needsQualificationRecalculation = true;
|
$this->needsQualificationRecalculation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::warning("BusinessUserItem: Error validating level qualification data for user {$this->b_user->user_id}: " . $e->getMessage());
|
\Log::warning("BusinessUserItem: Error validating level qualification data for user {$this->b_user->user_id}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -307,17 +360,41 @@ class BusinessUserItemOptimized
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimierte Sales Volume Abfrage (mit potenziellem Caching)
|
* Optimierte Sales Volume Abfrage mit detailliertem Logging
|
||||||
*/
|
*/
|
||||||
private function getUserSalesVolumeOptimized(User $user, string $field)
|
private function getUserSalesVolumeOptimized(User $user, string $field)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Hier könnte Caching implementiert werden
|
// Direkter Aufruf mit detailliertem Logging
|
||||||
$cacheKey = "sales_volume_{$user->id}_{$this->date->month}_{$this->date->year}_{$field}";
|
$value = $user->getUserSalesVolumeBy($this->date->month, $this->date->year, $field);
|
||||||
|
|
||||||
// Für jetzt: Direkter Aufruf (später durch Cache ersetzen)
|
// Log nur bei ersten Aufruf für diesen User (Performance)
|
||||||
return $user->getUserSalesVolumeBy($this->date->month, $this->date->year, $field);
|
static $loggedUsers = [];
|
||||||
|
if (!isset($loggedUsers[$user->id])) {
|
||||||
|
$loggedUsers[$user->id] = true;
|
||||||
|
|
||||||
|
// Prüfe ob UserSalesVolume Daten existieren
|
||||||
|
$userSalesVolume = $user->getUserSalesVolume($this->date->month, $this->date->year, 'first');
|
||||||
|
if (!$userSalesVolume) {
|
||||||
|
\Log::info("BusinessUserItem: No UserSalesVolume found for user {$user->id} in {$this->date->month}/{$this->date->year}");
|
||||||
|
|
||||||
|
// Prüfe neueste verfügbare Daten
|
||||||
|
$latestVolume = \App\Models\UserSalesVolume::where('user_id', $user->id)
|
||||||
|
->orderBy('year', 'desc')
|
||||||
|
->orderBy('month', 'desc')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($latestVolume) {
|
||||||
|
\Log::info("BusinessUserItem: Latest UserSalesVolume for user {$user->id}: {$latestVolume->month}/{$latestVolume->year}");
|
||||||
|
} else {
|
||||||
|
\Log::warning("BusinessUserItem: No UserSalesVolume records found for user {$user->id} at all");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
\Log::debug("BusinessUserItem: UserSalesVolume found for user {$user->id} in {$this->date->month}/{$this->date->year}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error("BusinessUserItem: Error getting sales volume {$field} for user {$user->id}: " . $e->getMessage());
|
\Log::error("BusinessUserItem: Error getting sales volume {$field} for user {$user->id}: " . $e->getMessage());
|
||||||
return 0; // Sicherer Fallback
|
return 0; // Sicherer Fallback
|
||||||
|
|
@ -333,7 +410,12 @@ class BusinessUserItemOptimized
|
||||||
|
|
||||||
public function addUserID()
|
public function addUserID()
|
||||||
{
|
{
|
||||||
TreeCalcBotOptimized::addUserID($this->b_user->user_id);
|
if ($this->treeCalcBot) {
|
||||||
|
$this->treeCalcBot->addProcessedUserId($this->b_user->user_id);
|
||||||
|
} else {
|
||||||
|
// Fallback für Rückwärtskompatibilität - sollte in Logs sichtbar sein
|
||||||
|
\Log::warning("BusinessUserItemOptimized: TreeCalcBotOptimized Referenz fehlt für User ID: " . $this->b_user->user_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBUser()
|
public function getBUser()
|
||||||
|
|
@ -452,7 +534,7 @@ class BusinessUserItemOptimized
|
||||||
for ($i = 1; $i <= $qualUserLevel->paylines; $i++) {
|
for ($i = 1; $i <= $qualUserLevel->paylines; $i++) {
|
||||||
if (isset($this->b_user->business_lines[$i])) {
|
if (isset($this->b_user->business_lines[$i])) {
|
||||||
$object = $this->b_user->business_lines[$i];
|
$object = $this->b_user->business_lines[$i];
|
||||||
$margin = (float) $this->b_user->qual_user_level['pr_line_'.$i];
|
$margin = (float) $this->b_user->qual_user_level['pr_line_' . $i];
|
||||||
|
|
||||||
// Handle both array and object types (JSON deserialization inconsistency)
|
// Handle both array and object types (JSON deserialization inconsistency)
|
||||||
if (is_array($object)) {
|
if (is_array($object)) {
|
||||||
|
|
@ -561,10 +643,10 @@ class BusinessUserItemOptimized
|
||||||
->first();
|
->first();
|
||||||
if ($qualUserLevelNext) {
|
if ($qualUserLevelNext) {
|
||||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||||
}else{
|
} else {
|
||||||
$this->b_user->qual_user_level_next = null;
|
$this->b_user->qual_user_level_next = null;
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
$this->b_user->qual_user_level_next = null;
|
$this->b_user->qual_user_level_next = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -654,7 +736,9 @@ class BusinessUserItemOptimized
|
||||||
'Sponsor: ' . $user->user_sponsor->account->first_name . ' ' .
|
'Sponsor: ' . $user->user_sponsor->account->first_name . ' ' .
|
||||||
$user->user_sponsor->account->last_name . ' | ' .
|
$user->user_sponsor->account->last_name . ' | ' .
|
||||||
$user->user_sponsor->email . ' | ' .
|
$user->user_sponsor->email . ' | ' .
|
||||||
$user->user_sponsor->account->m_account, 0, 250
|
$user->user_sponsor->account->m_account,
|
||||||
|
0,
|
||||||
|
250
|
||||||
);
|
);
|
||||||
$sponsor->first_name = $user->user_sponsor->account->first_name;
|
$sponsor->first_name = $user->user_sponsor->account->first_name;
|
||||||
$sponsor->last_name = $user->user_sponsor->account->last_name;
|
$sponsor->last_name = $user->user_sponsor->account->last_name;
|
||||||
|
|
@ -676,9 +760,17 @@ class BusinessUserItemOptimized
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lädt Parent Business Users rekursiv (Original-Implementation mit Optimierungen)
|
* Lädt Parent Business Users rekursiv (Original-Implementation mit Optimierungen)
|
||||||
|
* BUGFIX: Schutz vor unendlicher Rekursion durch zirkuläre Referenzen
|
||||||
*/
|
*/
|
||||||
public function readParentsBusinessUsers($forceLiveCalculation = false): void
|
public function readParentsBusinessUsers($forceLiveCalculation = false, $depth = 0): void
|
||||||
{
|
{
|
||||||
|
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 20 Levels)
|
||||||
|
$maxDepth = 20;
|
||||||
|
if ($depth > $maxDepth) {
|
||||||
|
Log::warning("BusinessUserItem: Maximale Rekursionstiefe ({$maxDepth}) erreicht für User {$this->b_user->user_id}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Optimiert: Lade mit Relations
|
// Optimiert: Lade mit Relations
|
||||||
$users = User::with(['account'])
|
$users = User::with(['account'])
|
||||||
|
|
@ -694,45 +786,64 @@ class BusinessUserItemOptimized
|
||||||
|
|
||||||
if ($users->isNotEmpty()) {
|
if ($users->isNotEmpty()) {
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
// KRITISCHER BUGFIX: Prüfe ob User bereits verarbeitet wurde
|
||||||
|
if ($this->treeCalcBot && $this->treeCalcBot->isUserProcessed($user->id)) {
|
||||||
|
Log::debug("BusinessUserItem: Überspringe bereits verarbeiteten User {$user->id} (zirkuläre Referenz verhindert)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this->treeCalcBot);
|
||||||
$businessUserItem->makeUserFromModel($user, $forceLiveCalculation);
|
$businessUserItem->makeUserFromModel($user, $forceLiveCalculation);
|
||||||
$businessUserItem->addUserID();
|
$businessUserItem->addUserID();
|
||||||
$this->businessUserItems[] = $businessUserItem;
|
$this->businessUserItems[] = $businessUserItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rekursiver Aufruf für alle Child-Items
|
// Rekursiver Aufruf für alle Child-Items mit Tiefenprüfung
|
||||||
foreach ($this->businessUserItems as $businessUserItem) {
|
foreach ($this->businessUserItems as $businessUserItem) {
|
||||||
$businessUserItem->readParentsBusinessUsers($forceLiveCalculation);
|
$businessUserItem->readParentsBusinessUsers($forceLiveCalculation, $depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("BusinessUserItem: Error reading parent users for {$this->b_user->user_id}: " . $e->getMessage());
|
Log::error("BusinessUserItem: Error reading parent users for {$this->b_user->user_id} at depth {$depth}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lädt Parent Business Users aus gespeicherter Struktur (Original-Implementation)
|
* Lädt Parent Business Users aus gespeicherter Struktur (Original-Implementation)
|
||||||
|
* BUGFIX: Schutz vor unendlicher Rekursion durch zirkuläre Referenzen
|
||||||
*/
|
*/
|
||||||
public function readStoredParentsBusinessUsers($structure): void
|
public function readStoredParentsBusinessUsers($structure, $depth = 0): void
|
||||||
{
|
{
|
||||||
|
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 50 Levels)
|
||||||
|
$maxDepth = 50;
|
||||||
|
if ($depth > $maxDepth) {
|
||||||
|
Log::warning("BusinessUserItem: Maximale Rekursionstiefe ({$maxDepth}) erreicht für gespeicherte User {$this->b_user->user_id}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$parents = $this->findParentsBusinessOnStored($this->b_user->user_id, $structure);
|
$parents = $this->findParentsBusinessOnStored($this->b_user->user_id, $structure);
|
||||||
|
|
||||||
if ($parents) {
|
if ($parents) {
|
||||||
foreach ($parents as $obj) {
|
foreach ($parents as $obj) {
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
// KRITISCHER BUGFIX: Prüfe ob User bereits verarbeitet wurde
|
||||||
|
if ($this->treeCalcBot && $this->treeCalcBot->isUserProcessed($obj->user_id)) {
|
||||||
|
Log::debug("BusinessUserItem: Überspringe bereits verarbeiteten gespeicherten User {$obj->user_id} (zirkuläre Referenz verhindert)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this->treeCalcBot);
|
||||||
$businessUserItem->makeUser($obj->user_id);
|
$businessUserItem->makeUser($obj->user_id);
|
||||||
$businessUserItem->addUserID();
|
$businessUserItem->addUserID();
|
||||||
$this->businessUserItems[] = $businessUserItem;
|
$this->businessUserItems[] = $businessUserItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->businessUserItems as $businessUserItem) {
|
foreach ($this->businessUserItems as $businessUserItem) {
|
||||||
$businessUserItem->readStoredParentsBusinessUsers($parents);
|
$businessUserItem->readStoredParentsBusinessUsers($parents, $depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("BusinessUserItem: Error reading stored parent users: " . $e->getMessage());
|
Log::error("BusinessUserItem: Error reading stored parent users at depth {$depth}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -794,4 +905,43 @@ class BusinessUserItemOptimized
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intelligentes Laden des UserAccount für einen User
|
||||||
|
* Prüft zuerst geladene Relations, lädt nach wenn nötig
|
||||||
|
*/
|
||||||
|
private function getAccountForUser(User $user): ?UserAccount
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Prüfe ob Account-Relation bereits geladen ist
|
||||||
|
if ($user->relationLoaded('account')) {
|
||||||
|
$account = $user->account;
|
||||||
|
if ($account instanceof UserAccount) {
|
||||||
|
\Log::debug("BusinessUserItem: Using pre-loaded account for user {$user->id}");
|
||||||
|
return $account;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn User keine account_id hat, gibt es definitiv kein Account
|
||||||
|
if (!$user->account_id) {
|
||||||
|
\Log::info("BusinessUserItem: User {$user->id} has no account_id - no account available");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account nachladen falls nötig
|
||||||
|
\Log::info("BusinessUserItem: Loading account for user {$user->id} (account_id: {$user->account_id})");
|
||||||
|
$account = UserAccount::find($user->account_id);
|
||||||
|
|
||||||
|
if (!$account) {
|
||||||
|
\Log::warning("BusinessUserItem: Account {$user->account_id} not found for user {$user->id}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
\Log::debug("BusinessUserItem: Successfully loaded account {$account->id} for user {$user->id}");
|
||||||
|
return $account;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("BusinessUserItem: Error loading account for user {$user->id}: " . $e->getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,9 +25,11 @@ class BusinessUserRepository
|
||||||
$this->month = $month;
|
$this->month = $month;
|
||||||
$this->year = $year;
|
$this->year = $year;
|
||||||
|
|
||||||
$date = Carbon::parse($year.'-'.$month.'-1');
|
$date = Carbon::parse($year . '-' . $month . '-1');
|
||||||
$this->startDate = $date->format('Y-m-d H:i:s');
|
$this->startDate = $date->format('Y-m-d H:i:s');
|
||||||
$this->endDate = $date->endOfMonth()->format('Y-m-d H:i:s');
|
$this->endDate = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||||
|
\Log::info("BusinessUserRepository: Start Date: " . $this->startDate);
|
||||||
|
\Log::info("BusinessUserRepository: End Date: " . $this->endDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,14 +38,12 @@ class BusinessUserRepository
|
||||||
public function getRootUsers(): Collection
|
public function getRootUsers(): Collection
|
||||||
{
|
{
|
||||||
$cacheKey = "root_users_{$this->month}_{$this->year}";
|
$cacheKey = "root_users_{$this->month}_{$this->year}";
|
||||||
|
//root hat keinen parent m_sponsor, hat
|
||||||
return cache()->remember($cacheKey, 3600, function() {
|
return cache()->remember($cacheKey, 3600, function () {
|
||||||
\Log::info("BusinessUserRepository: Loading root users from database (cache miss)");
|
|
||||||
|
|
||||||
return User::with([
|
return User::with([
|
||||||
'account',
|
'account',
|
||||||
'user_level',
|
'user_level',
|
||||||
'userBusiness' => function($query) {
|
'userBusiness' => function ($query) {
|
||||||
$query->where('month', $this->month)
|
$query->where('month', $this->month)
|
||||||
->where('year', $this->year);
|
->where('year', $this->year);
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +56,7 @@ class BusinessUserRepository
|
||||||
->where('users.m_sponsor', '=', null)
|
->where('users.m_sponsor', '=', null)
|
||||||
->where('users.payment_account', '!=', null)
|
->where('users.payment_account', '!=', null)
|
||||||
->where('users.active_date', '<=', $this->endDate)
|
->where('users.active_date', '<=', $this->endDate)
|
||||||
|
->where('users.payment_account', '>', $this->endDate)
|
||||||
->get();
|
->get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +69,7 @@ class BusinessUserRepository
|
||||||
$query = User::with([
|
$query = User::with([
|
||||||
'account',
|
'account',
|
||||||
'user_level',
|
'user_level',
|
||||||
'userBusiness' => function($query) {
|
'userBusiness' => function ($query) {
|
||||||
$query->where('month', $this->month)
|
$query->where('month', $this->month)
|
||||||
->where('year', $this->year);
|
->where('year', $this->year);
|
||||||
}
|
}
|
||||||
|
|
@ -94,13 +95,13 @@ class BusinessUserRepository
|
||||||
{
|
{
|
||||||
$cacheKey = "user_relations_{$userId}_{$this->month}_{$this->year}";
|
$cacheKey = "user_relations_{$userId}_{$this->month}_{$this->year}";
|
||||||
|
|
||||||
return cache()->remember($cacheKey, 1800, function() use ($userId) {
|
return cache()->remember($cacheKey, 1800, function () use ($userId) {
|
||||||
\Log::debug("BusinessUserRepository: Loading user {$userId} with relations (cache miss)");
|
\Log::debug("BusinessUserRepository: Loading user {$userId} with relations (cache miss)");
|
||||||
|
|
||||||
return User::with([
|
return User::with([
|
||||||
'account',
|
'account',
|
||||||
'user_level',
|
'user_level',
|
||||||
'userBusiness' => function($query) {
|
'userBusiness' => function ($query) {
|
||||||
$query->where('month', $this->month)
|
$query->where('month', $this->month)
|
||||||
->where('year', $this->year);
|
->where('year', $this->year);
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +130,7 @@ class BusinessUserRepository
|
||||||
{
|
{
|
||||||
$cacheKey = "stored_structure_{$this->month}_{$this->year}";
|
$cacheKey = "stored_structure_{$this->month}_{$this->year}";
|
||||||
|
|
||||||
return cache()->remember($cacheKey, 7200, function() {
|
return cache()->remember($cacheKey, 7200, function () {
|
||||||
\Log::debug("BusinessUserRepository: Loading stored structure (cache miss)");
|
\Log::debug("BusinessUserRepository: Loading stored structure (cache miss)");
|
||||||
|
|
||||||
$structure = UserBusinessStructure::where('year', $this->year)
|
$structure = UserBusinessStructure::where('year', $this->year)
|
||||||
|
|
@ -174,6 +175,22 @@ class BusinessUserRepository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht alle Cache-Einträge für den aktuellen Monat/Jahr
|
||||||
|
*/
|
||||||
|
public function clearCache(): void
|
||||||
|
{
|
||||||
|
$cacheKeys = [
|
||||||
|
"root_users_{$this->month}_{$this->year}",
|
||||||
|
"stored_structure_{$this->month}_{$this->year}"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($cacheKeys as $key) {
|
||||||
|
cache()->forget($key);
|
||||||
|
\Log::info("BusinessUserRepository: Cache cleared for key: {$key}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batch-Loading für User-Kollektionen
|
* Batch-Loading für User-Kollektionen
|
||||||
*/
|
*/
|
||||||
|
|
@ -185,7 +202,7 @@ class BusinessUserRepository
|
||||||
yield User::with([
|
yield User::with([
|
||||||
'account',
|
'account',
|
||||||
'user_level',
|
'user_level',
|
||||||
'userBusiness' => function($query) {
|
'userBusiness' => function ($query) {
|
||||||
$query->where('month', $this->month)
|
$query->where('month', $this->month)
|
||||||
->where('year', $this->year);
|
->where('year', $this->year);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ class TreeCalcBotOptimized
|
||||||
$this->logger->info("Building fresh business structure for {$this->date->month}/{$this->date->year}");
|
$this->logger->info("Building fresh business structure for {$this->date->month}/{$this->date->year}");
|
||||||
$this->buildFreshStructure();
|
$this->buildFreshStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error initializing admin structure: " . $e->getMessage());
|
$this->logger->error("Error initializing admin structure: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|
@ -114,7 +113,7 @@ class TreeCalcBotOptimized
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$businessUserItem->makeUserFromModel($user); // Erst User-Model laden, ohne forceLiveCalculation
|
$businessUserItem->makeUserFromModel($user); // Erst User-Model laden, ohne forceLiveCalculation
|
||||||
$this->addUserIdToProcessed($userId);
|
$this->addUserIdToProcessed($userId);
|
||||||
$this->businessUsers[] = $businessUserItem;
|
$this->businessUsers[] = $businessUserItem;
|
||||||
|
|
@ -156,7 +155,6 @@ class TreeCalcBotOptimized
|
||||||
//$this->calculateQualPPForAllUsers(); // Auch für alle Sub-User
|
//$this->calculateQualPPForAllUsers(); // Auch für alle Sub-User
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error initializing user structure for {$userId}: " . $e->getMessage());
|
$this->logger->error("Error initializing user structure for {$userId}: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|
@ -174,7 +172,7 @@ class TreeCalcBotOptimized
|
||||||
try {
|
try {
|
||||||
$this->logger->info("Initializing business user details for: {$user->id}");
|
$this->logger->info("Initializing business user details for: {$user->id}");
|
||||||
|
|
||||||
$this->businessUser = new BusinessUserItemOptimized($this->date);
|
$this->businessUser = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$this->businessUser->makeUserFromModel($user, $forceLiveCalculation); // ✅ Nutzt bereits User-Objekt
|
$this->businessUser->makeUserFromModel($user, $forceLiveCalculation); // ✅ Nutzt bereits User-Objekt
|
||||||
$this->businessUser->checkSponsor($user);
|
$this->businessUser->checkSponsor($user);
|
||||||
|
|
||||||
|
|
@ -195,9 +193,7 @@ class TreeCalcBotOptimized
|
||||||
}
|
}
|
||||||
// Qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
// Qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
||||||
$this->businessUser->calcQualPP();
|
$this->businessUser->calcQualPP();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error initializing business user details for {$user->id}: " . $e->getMessage());
|
$this->logger->error("Error initializing business user details for {$user->id}: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|
@ -337,10 +333,19 @@ class TreeCalcBotOptimized
|
||||||
return ($structure && $structure->completed) ? $structure : null;
|
return ($structure && $structure->completed) ? $structure : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Öffentliche Methode zum Hinzufügen einer User ID zu den verarbeiteten IDs
|
||||||
|
*/
|
||||||
|
public function addProcessedUserId(int $id): void
|
||||||
|
{
|
||||||
|
$this->addUserIdToProcessed($id);
|
||||||
|
}
|
||||||
|
|
||||||
public static function addUserID(int $id): void
|
public static function addUserID(int $id): void
|
||||||
{
|
{
|
||||||
// Deprecated: Wird durch Instanz-Methode ersetzt
|
// Deprecated: Statische Methode kann nicht auf Instanz-Variable zugreifen
|
||||||
// Bleibt für Rückwärtskompatibilität erhalten
|
// Verwende stattdessen die Instanz-Methode addProcessedUserId()
|
||||||
|
throw new \BadMethodCallException('addUserID ist deprecated. Verwende Instanz-Methode addProcessedUserId() stattdessen.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== Private Methoden =====
|
// ===== Private Methoden =====
|
||||||
|
|
@ -408,12 +413,11 @@ class TreeCalcBotOptimized
|
||||||
{
|
{
|
||||||
$startMemory = memory_get_usage();
|
$startMemory = memory_get_usage();
|
||||||
$users = $this->repository->getRootUsers();
|
$users = $this->repository->getRootUsers();
|
||||||
|
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
// Memory-Check vor jeder User-Verarbeitung
|
// Memory-Check vor jeder User-Verarbeitung
|
||||||
$this->checkMemoryUsage('loadRootUsers', $user->id);
|
$this->checkMemoryUsage('loadRootUsers', $user->id);
|
||||||
|
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
||||||
$this->addUserIdToProcessed($user->id);
|
$this->addUserIdToProcessed($user->id);
|
||||||
$this->businessUsers[] = $businessUserItem;
|
$this->businessUsers[] = $businessUserItem;
|
||||||
|
|
@ -448,7 +452,7 @@ class TreeCalcBotOptimized
|
||||||
$excludeIds = array_keys($this->processedUserIds);
|
$excludeIds = array_keys($this->processedUserIds);
|
||||||
|
|
||||||
foreach ($this->repository->getParentlessUsers($excludeIds) as $user) {
|
foreach ($this->repository->getParentlessUsers($excludeIds) as $user) {
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
||||||
$this->parentless[] = $businessUserItem;
|
$this->parentless[] = $businessUserItem;
|
||||||
$count++;
|
$count++;
|
||||||
|
|
@ -474,7 +478,6 @@ class TreeCalcBotOptimized
|
||||||
|
|
||||||
// Qualifikation nach qual_kp und qual_pp berechnen
|
// Qualifikation nach qual_kp und qual_pp berechnen
|
||||||
$businessUser->calcQualPP();
|
$businessUser->calcQualPP();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error calculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
$this->logger->error("Error calculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
||||||
// Weiter mit dem nächsten User, nicht abbrechen
|
// Weiter mit dem nächsten User, nicht abbrechen
|
||||||
|
|
@ -508,7 +511,6 @@ class TreeCalcBotOptimized
|
||||||
|
|
||||||
// Qualifikation berechnen
|
// Qualifikation berechnen
|
||||||
$parentlessUser->calcQualPP();
|
$parentlessUser->calcQualPP();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error calculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
$this->logger->error("Error calculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -538,7 +540,6 @@ class TreeCalcBotOptimized
|
||||||
$this->calculateUserPointsOptimized($businessUser->businessUserItems, 1, $businessUser);
|
$this->calculateUserPointsOptimized($businessUser->businessUserItems, 1, $businessUser);
|
||||||
}
|
}
|
||||||
$businessUser->calcQualPP();
|
$businessUser->calcQualPP();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error recalculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
$this->logger->error("Error recalculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -596,7 +597,6 @@ class TreeCalcBotOptimized
|
||||||
$this->calculateUserPointsOptimized($parentlessUser->businessUserItems, 1, $parentlessUser);
|
$this->calculateUserPointsOptimized($parentlessUser->businessUserItems, 1, $parentlessUser);
|
||||||
}
|
}
|
||||||
$parentlessUser->calcQualPP();
|
$parentlessUser->calcQualPP();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error recalculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
$this->logger->error("Error recalculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -617,7 +617,7 @@ class TreeCalcBotOptimized
|
||||||
$sponsorUser = $this->repository->getSponsorForUser($userId);
|
$sponsorUser = $this->repository->getSponsorForUser($userId);
|
||||||
|
|
||||||
if ($sponsorUser) {
|
if ($sponsorUser) {
|
||||||
$this->sponsor = new BusinessUserItemOptimized($this->date);
|
$this->sponsor = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$this->sponsor->makeUser($sponsorUser->id);
|
$this->sponsor->makeUser($sponsorUser->id);
|
||||||
$this->logger->info("Loaded sponsor {$sponsorUser->id} for user {$userId}");
|
$this->logger->info("Loaded sponsor {$sponsorUser->id} for user {$userId}");
|
||||||
}
|
}
|
||||||
|
|
@ -636,7 +636,7 @@ class TreeCalcBotOptimized
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($structure->structure as $obj) {
|
foreach ($structure->structure as $obj) {
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$businessUserItem->makeUser($obj->user_id);
|
$businessUserItem->makeUser($obj->user_id);
|
||||||
$this->addUserIdToProcessed($obj->user_id);
|
$this->addUserIdToProcessed($obj->user_id);
|
||||||
$this->businessUsers[] = $businessUserItem;
|
$this->businessUsers[] = $businessUserItem;
|
||||||
|
|
@ -664,7 +664,7 @@ class TreeCalcBotOptimized
|
||||||
|
|
||||||
foreach ($structure->parentless as $obj) {
|
foreach ($structure->parentless as $obj) {
|
||||||
if (!isset($this->processedUserIds[$obj->user_id])) {
|
if (!isset($this->processedUserIds[$obj->user_id])) {
|
||||||
$businessUserItem = new BusinessUserItemOptimized($this->date);
|
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$businessUserItem->makeUser($obj->user_id);
|
$businessUserItem->makeUser($obj->user_id);
|
||||||
$this->parentless[] = $businessUserItem;
|
$this->parentless[] = $businessUserItem;
|
||||||
}
|
}
|
||||||
|
|
@ -676,7 +676,7 @@ class TreeCalcBotOptimized
|
||||||
*/
|
*/
|
||||||
private function loadStoredSponsorUser(int $userId): void
|
private function loadStoredSponsorUser(int $userId): void
|
||||||
{
|
{
|
||||||
$this->sponsor = new BusinessUserItemOptimized($this->date);
|
$this->sponsor = new BusinessUserItemOptimized($this->date, $this);
|
||||||
$this->sponsor->makeUser($userId);
|
$this->sponsor->makeUser($userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -728,7 +728,7 @@ class TreeCalcBotOptimized
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 2: Sortiere nach Tiefe (tiefste zuerst, wie bei Rekursion)
|
// Phase 2: Sortiere nach Tiefe (tiefste zuerst, wie bei Rekursion)
|
||||||
usort($processingStack, function($a, $b) {
|
usort($processingStack, function ($a, $b) {
|
||||||
return $b['depth'] <=> $a['depth']; // Tiefste zuerst
|
return $b['depth'] <=> $a['depth']; // Tiefste zuerst
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -753,7 +753,6 @@ class TreeCalcBotOptimized
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug("Processed user {$current['id']} at line {$line} with {$points} points");
|
$this->logger->debug("Processed user {$current['id']} at line {$line} with {$points} points");
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error("Error processing user points for {$current['id']}: " . $e->getMessage());
|
$this->logger->error("Error processing user points for {$current['id']}: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -771,9 +770,9 @@ class TreeCalcBotOptimized
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob User bereits verarbeitet wurde
|
* Prüft ob User bereits verarbeitet wurde (Public für BusinessUserItemOptimized)
|
||||||
*/
|
*/
|
||||||
private function isUserProcessed(int $id): bool
|
public function isUserProcessed(int $id): bool
|
||||||
{
|
{
|
||||||
return isset($this->processedUserIds[$id]);
|
return isset($this->processedUserIds[$id]);
|
||||||
}
|
}
|
||||||
|
|
@ -809,13 +808,16 @@ class TreeCalcBotOptimized
|
||||||
private function parseMemoryLimit(string $limit): int
|
private function parseMemoryLimit(string $limit): int
|
||||||
{
|
{
|
||||||
$limit = trim($limit);
|
$limit = trim($limit);
|
||||||
$last = strtolower($limit[strlen($limit)-1]);
|
$last = strtolower($limit[strlen($limit) - 1]);
|
||||||
$number = (int) $limit;
|
$number = (int) $limit;
|
||||||
|
|
||||||
switch($last) {
|
switch ($last) {
|
||||||
case 'g': $number *= 1024;
|
case 'g':
|
||||||
case 'm': $number *= 1024;
|
$number *= 1024;
|
||||||
case 'k': $number *= 1024;
|
case 'm':
|
||||||
|
$number *= 1024;
|
||||||
|
case 'k':
|
||||||
|
$number *= 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $number;
|
return $number;
|
||||||
|
|
|
||||||
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