mivita/app/Services/ShoppingUserService.php
2025-04-01 10:36:47 +02:00

198 lines
No EOL
7.5 KiB
PHP

<?php
namespace App\Services;
use App\Models\ShoppingOrder;
use App\Models\ShoppingUser;
use App\User;
use Yard;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\QueryException;
class ShoppingUserService
{
/**
* Gibt alle Bestellungen eines Mitglieds zurück
*
* @param ShoppingUser $shopping_user Das Mitglied, dessen Bestellungen zurückgegeben werden sollen
* @return Collection Die Bestellungen des Mitglieds
*/
public static function getAllOrdersByMember($shopping_user){
$users = ShoppingUser::where('billing_email', '=', $shopping_user->billing_email)->where('member_id', '=', $shopping_user->member_id)->get();
return $users->flatMap(function($user) {
return $user->shopping_orders;
})->sortByDesc('created_at');
}
public static function syncOrdersByEmail($user)
{
$maxAttempts = 3;
$attempt = 1;
while ($attempt <= $maxAttempts) {
try {
DB::beginTransaction();
$shopping_user = ShoppingUser::where('member_id', $user->id)
->first();
if (!$shopping_user) {
DB::commit();
return;
}
$shopping_users = ShoppingUser::where('billing_email', '=', $shopping_user->billing_email)
->whereHas('shopping_order', function($q) {
$q->where('txaction', 'paid')
->orWhere('txaction', 'appointed')
->orWhere('txaction', 'extern')
->orWhere('txaction', 'invoice_open')
->orWhere('txaction', 'invoice_paid');
})
->lockForUpdate()
->get();
$order_count = $shopping_users->count();
foreach($shopping_users as $user) {
$user->orders = $order_count;
$user->save();
}
DB::commit();
return; // Erfolgreicher Fall
} catch (QueryException $e) {
DB::rollBack();
// Wenn es ein Deadlock ist, versuchen wir es erneut
if ($e->getCode() == 40001 && $attempt < $maxAttempts) {
$sleepTime = pow(2, $attempt) * 100000; // Exponentielles Backoff in Mikrosekunden
usleep($sleepTime);
$attempt++;
continue;
}
throw $e; // Andere Fehler oder zu viele Versuche
}
}
}
/*public static function syncOrdersByEmail($user){
ShoppingUser::where('member_id', $user->id)
->whereNotNull('billing_email')
->where('billing_email', '!=', '')
->select('billing_email')
->groupBy('billing_email')
->get()
->each(function($shopping_user) {
self::snycOrdersByShoppingUser($shopping_user);
});
}*/
/**
* Synchronisiert die Bestellungen eines ShoppingOrders mit den Bestellungen des zugehörigen ShoppingUsers
*
* @param ShoppingOrder $shopping_order Der zu synchronisierende ShoppingOrder
*/
public static function snycOrdersByShoppingOrder(ShoppingOrder $shopping_order) {
$shopping_user = $shopping_order->shopping_user ? $shopping_order->shopping_user : null;
if($shopping_user){
self::snycOrdersByShoppingUser($shopping_user);
}
}
/**
* Synchronisiert die Bestellungen eines ShoppingUsers mit den Bestellungen des zugehörigen Benutzers
*
* @param ShoppingUser $shopping_user Der zu synchronisierende ShoppingUser
*/
public static function snycOrdersByShoppingUser(ShoppingUser $shopping_user) {
// Aktualisiere alle Benutzer mit einer einzigen Datenbankabfrage
ShoppingUser::where('billing_email', $shopping_user->billing_email)
->update([
'orders' => ShoppingUser::where('billing_email', $shopping_user->billing_email)
->whereHas('shopping_order', function($q) {
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'invoice_open', 'invoice_paid']);
})
->count()
]);
}
public static function snycOrdersByNumber($number){
if($number <= 0) {
return;
}
// Aktualisiere alle Benutzer mit einer einzigen Datenbankabfrage
ShoppingUser::where('number', '=', $number)
->update([
'orders' => ShoppingUser::where('number', '=', $number)
->whereHas('shopping_order', function($q) {
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'invoice_open', 'invoice_paid']);
})
->count()
]);
// Setze orders auf NULL für alle anderen
ShoppingUser::where('number', '=', $number)
->whereDoesntHave('shopping_order', function($q) {
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'extern_paid']);
})
->update(['orders' => null]);
}
/**
* Synchronisiert die Nummern aller ShoppingUser eines Benutzers anhand der E-Mails
*
* @param User $user Der Benutzer, dessen ShoppingUser synchronisiert werden sollen
*/
public static function syncNumbersByEmail($user) {
// Hole alle ShoppingUser mit E-Mail gruppiert
$emailGroups = ShoppingUser::where('member_id', $user->id)
->whereNotNull('billing_email')
->where('billing_email', '!=', '')
->get()
->groupBy('billing_email');
foreach($emailGroups as $email => $users) {
// Suche ob es bereits eine Nummer für diese E-Mail gibt
$existingNumber = ($users->whereNotNull('number')->first()) ? $users->whereNotNull('number')->first()->number : null;
if($existingNumber) {
// Wenn eine Nummer existiert, nutze diese für alle User mit der E-Mail
ShoppingUser::where('member_id', $user->id)
->where('billing_email', $email)
->whereNull('number')
->update(['number' => $existingNumber]);
} else {
// Wenn keine Nummer existiert, generiere eine neue
$maxNumber = ShoppingUser::max('number') ?: 1000;
$newNumber = $maxNumber + 1;
ShoppingUser::where('member_id', $user->id)
->where('billing_email', $email)
->update(['number' => $newNumber]);
}
}
}
/**
* Setzt alle Faker-E-Mails für einen Benutzer auf 1
*
* @param User $user Der Benutzer, dessen Faker-E-Mails gesetzt werden sollen
*/
public static function setFakerMail($user){
// Aktualisiere alle Faker-E-Mails für den Benutzer in einem einzigen Update
// Schneller da nur ein einzelner SQL Query ausgeführt wird
ShoppingUser::where('member_id', $user->id)
->where('faker_mail', '!=', 1)
->where('billing_email', 'LIKE', '%faker@mivita.care')
->update(['faker_mail' => 1]);
// Setze alle anderen auf NULL zurück
ShoppingUser::where('member_id', $user->id)
->where('billing_email', 'NOT LIKE', '%faker@mivita.care')
->update(['faker_mail' => null]);
}
}