Updates to 03-2025

This commit is contained in:
Kevin Adametz 2025-04-01 10:39:21 +02:00
parent 6167273a48
commit 9b54eb0512
348 changed files with 34535 additions and 5774 deletions

View file

@ -0,0 +1,269 @@
<?php
namespace App\Services\Stats;
use Carbon\Carbon;
use App\Services\Util;
use App\Models\ShoppingOrder;
class Sales
{
private $month;
private $year;
private $products;
private $objects;
public function __construct()
{
$this->month = 0;
$this->year = 0;
$this->products = [];
$this->objects = [];
}
public function setFilterVars($month = null, $year = null, $products = null){
$this->month = $month ? $month : intval(date('m'));
$this->year = $year ? $year : intval(date('Y'));
$this->products = $products;
}
public function setFilterProducts(){
$ShoppingOrders = $this->getShoppingOrdersBy($this->month, $this->year);
$products = [];
foreach($ShoppingOrders as $ShoppingOrder){
foreach($ShoppingOrder->shopping_order_items as $shopping_order_item){
if($shopping_order_item->product && !$shopping_order_item->product->exclude_stats_sales && !isset($products[$shopping_order_item->product->id])){
$products[$shopping_order_item->product->id] = $shopping_order_item->product->name.' # '.
($shopping_order_item->product->single_commission ? $shopping_order_item->product->value_commission.' / '.$shopping_order_item->product->partner_commission : 'Staffelrabatt');
}
}
}
return $products;
}
private function getShoppingOrdersBy($month, $year){
if($month == '13'){ //all the year
$date_start = Carbon::parse('01.01.'.$year)->format('Y-m-d H:i:s');
$date_end = Carbon::parse('31.12.'.$year)->endOfMonth()->format('Y-m-d H:i:s');
}else{
$date_start = Carbon::parse('01.'.$month.'.'.$year)->format('Y-m-d H:i:s');
$date_end = Carbon::parse('01.'.$month.'.'.$year)->endOfMonth()->format('Y-m-d H:i:s');
}
return ShoppingOrder::where('paid', 1)->where('mode', 'live')->whereBetween('created_at', [$date_start, $date_end])->get();
}
public function getCollection(){
$this->getObjects();
$collection = collect();
foreach($this->objects as $key => $obj){
$collection->push([
'id' => $key,
'name' => $obj['name'],
'number' => $obj['number'],
'qty' => $obj['qty'],
'total' => $obj['total'],
'pre_qty' => $obj['pre_qty'],
'pre_total' => $obj['pre_total'],
'single_commission' => $obj['single_commission'],
'value_commission' => $obj['value_commission'],
'partner_commission' => $obj['partner_commission'],
]);
}
return $collection;
}
public function getObjects(){
$this->readObjects();
$this->readObjectsPreview();
return $this->objects;
}
private function readObjects()
{
$shoppingOrders = $this->getShoppingOrdersBy($this->month, $this->year);
$this->objects = [];
$subtotal_full = 0; // gesamtumsatz
$subtotal = 0; // gesamtumsatz ohne rabatte
$discount = 0; // gesamtrabatte
$subtotal_hide = 0; // ausgeschlossene Produkte
foreach($shoppingOrders as $ShoppingOrder){
$subtotal_full += $ShoppingOrder->subtotal_full;
$subtotal += $ShoppingOrder->subtotal;
$discount += $ShoppingOrder->discount;
foreach($ShoppingOrder->shopping_order_items as $shopping_order_item){
if($shopping_order_item->product){
if(!in_array($shopping_order_item->product->id, $this->products) && !$shopping_order_item->product->exclude_stats_sales){ //ausschließen der Produkte über filter und exclude_stats_sales
if(isset($this->objects[$shopping_order_item->product->id])){
$qty = intval($this->objects[$shopping_order_item->product->id]['qty'] + $shopping_order_item->qty);
$total = round($this->objects[$shopping_order_item->product->id]['total'] + ($shopping_order_item->price_net * $shopping_order_item->qty), 3);
$this->objects[$shopping_order_item->product->id]['qty'] = $qty;
$this->objects[$shopping_order_item->product->id]['total'] = $total;
}else{
$this->objects[$shopping_order_item->product->id] = [
'name' => $shopping_order_item->product->name,
'number' => $shopping_order_item->product->number,
'qty' => $shopping_order_item->qty,
'total' => round($shopping_order_item->price_net * $shopping_order_item->qty, 3),
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => $shopping_order_item->product->single_commission ? 'Ja' : 'Nein',
'value_commission' => $shopping_order_item->product->single_commission ? $shopping_order_item->product->value_commission : '',
'partner_commission' => $shopping_order_item->product->single_commission ? $shopping_order_item->product->partner_commission : '',
];
}
}else{
$subtotal_hide += $shopping_order_item->price_net * $shopping_order_item->qty;
}
}
}
}
$this->objects[9990] = [
'name' => 'Angezeigter Umsatz netto €',
'number' => '',
'qty' => '',
'total' => round($subtotal_full - $subtotal_hide, 2),
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => '',
'value_commission' => '',
'partner_commission' => '',
];
$this->objects[9991] = [
'name' => 'Ausgeblendeter Umsatz netto €',
'number' => '',
'qty' => '',
'total' => $subtotal_hide,
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => '',
'value_commission' => '',
'partner_commission' => '',
];
$this->objects[9992] = [
'name' => 'Gesamter Umsatz netto € (alle Verkäufe)',
'number' => '',
'qty' => '',
'total' => $subtotal_full,
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => '',
'value_commission' => '',
'partner_commission' => '',
];
$this->objects[9998] = [
'name' => 'Gesamte Rabatte netto € (alle Verkäufe)',
'number' => '',
'qty' => '',
'total' => ($discount),
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => '',
'value_commission' => '',
'partner_commission' => '',
];
$this->objects[9999] = [
'name' => 'Gesamt netto € (alle Verkäufe)',
'number' => '',
'qty' => '',
'total' => ($subtotal),
'pre_qty' => 0,
'pre_total' => 0,
'single_commission' => '',
'value_commission' => '',
'partner_commission' => '',
];
//format total
foreach($this->objects as $key => $obj){
$this->objects[$key]['total'] = formatNumber($obj['total']);
}
}
private function readObjectsPreview(){
$shoppingOrders = $this->getShoppingOrdersBy($this->month, $this->year-1);
$subtotal_full = 0; // gesamtumsatz
$subtotal = 0; // gesamtumsatz ohne rabatte
$discount = 0; // gesamtrabatte
$subtotal_hide = 0; // ausgeschlossene Produkte
foreach($shoppingOrders as $ShoppingOrder){
$subtotal_full += $ShoppingOrder->subtotal_full;
$subtotal += $ShoppingOrder->subtotal;
$discount += $ShoppingOrder->discount;
foreach($ShoppingOrder->shopping_order_items as $shopping_order_item){
if($shopping_order_item->product){
if(!in_array($shopping_order_item->product->id, $this->products) && !$shopping_order_item->product->exclude_stats_sales){ //ausschließen der Produkte über filter und exclude_stats_sales
if(isset($this->objects[$shopping_order_item->product->id])){ //einsetzen der Zahlen, wenn vorhanden
$qty = intval($this->objects[$shopping_order_item->product->id]['pre_qty'] + $shopping_order_item->qty);
$total = round($this->objects[$shopping_order_item->product->id]['pre_total'] + ($shopping_order_item->price_net * $shopping_order_item->qty), 3);
$this->objects[$shopping_order_item->product->id]['pre_qty'] = $qty;
$this->objects[$shopping_order_item->product->id]['pre_total'] = $total;
}else{ // nicht vorhanden, anlegen
$this->objects[$shopping_order_item->product->id] = [
'name' => $shopping_order_item->product->name,
'number' => $shopping_order_item->product->number,
'qty' => 0,
'total' => 0,
'pre_qty' => $shopping_order_item->qty,
'pre_total' => round($shopping_order_item->price_net * $shopping_order_item->qty, 3),
'single_commission' => $shopping_order_item->product->single_commission ? 'Ja' : 'Nein',
'value_commission' => $shopping_order_item->product->single_commission ? $shopping_order_item->product->value_commission : '',
'partner_commission' => $shopping_order_item->product->single_commission ? $shopping_order_item->product->partner_commission : '',
];
}
}else{
//ausgeschlossene Produkte
$subtotal_hide += $shopping_order_item->price_net * $shopping_order_item->qty;
}
}
}
}
$this->objects[9990]['pre_total'] = round($subtotal_full - $subtotal_hide, 2);
$this->objects[9991]['pre_total'] = $subtotal_hide;
$this->objects[9992]['pre_total'] = $subtotal_full;
$this->objects[9998]['pre_total'] = ($discount);
$this->objects[9999]['pre_total'] = ($subtotal);
//format total
foreach($this->objects as $key => $obj){
$this->objects[$key]['pre_total'] = formatNumber($obj['pre_total']);
}
}
}

View file

@ -0,0 +1,303 @@
<?php
namespace App\Services\Payment;
use App\Models\ShoppingOrderMargin;
use App\Models\UserCreditMargin;
use App\Services\Payment\UserCredits;
use App\Services\UserHelper;
use App\Services\UserMarign;
use Carbon\Carbon;
class UserBot
{
public $users;
public $users_pending;
public function __construct()
{
$this->users = [];
$this->users_pending = [];
}
public function readUserHasCredits(){
//user by m_sponsor_id die Partner Provisionen haben
$usersWithPartnerCommission = $this->getUsersWithPartnerCommission(false);
//user die manuelle Gutschriften haben
$usersWithCreditMargin = $this->getUsersWithCreditMargin();
//user die Shop Provisionen haben
$usersWithShopCommission = $this->getUsersWithShopCommission(false);
// Alle Benutzer zum Array hinzufügen
$allUsers = $usersWithPartnerCommission->concat($usersWithCreditMargin)->concat($usersWithShopCommission);
foreach ($allUsers as $user) {
//prüfe ob der User Account noch aktiv ist
if(UserHelper::isActiveAccountByID($user->user_id)){
$this->addUser($user);
}
}
}
public function readUserHasPendingCredit(){
//sponsor Users von Provisionen die bezahlt wurden die noch im pending sind
$usersWithPartnerCommissionPending = $this->getUsersWithPartnerCommission(true);
$usersWithShopCommissionPending = $this->getUsersWithShopCommission(true);
// Alle Benutzer zum Array hinzufügen
$allUsers = $usersWithPartnerCommissionPending->concat($usersWithShopCommissionPending);
foreach ($allUsers as $user) {
//prüfe ob der User Account noch aktiv ist
if(UserHelper::isActiveAccountByID($user->user_id)){
$this->addUserPending($user);
}
}
}
public function getUsers(){
return $this->users;
}
public function getUsersPending(){
return $this->users_pending;
}
private function addUser($user){
// Prüfen, ob Benutzer bereits existiert
if (!isset($this->users[$user->user_id])) {
$this->users[$user->user_id] = $this->createUserCredit($user);
$this->addCreditItems($user->user_id, false);
}
}
private function addUserPending($user){
// Prüfen, ob Benutzer bereits existiert
if (!isset($this->users_pending[$user->user_id])) {
$this->users_pending[$user->user_id] = $this->createUserCredit($user);
$this->addCreditItems($user->user_id, true);
}
}
private function addCreditItems($user_id, $isPending){
// Partner Provisionen hinzufügen
$this->addPartnerCommissionItems($user_id, $isPending);
// Shop Provisionen hinzufügen
$this->addShopCommissionItems($user_id, $isPending);
// Wenn es nicht ausstehende Credits sind, füge manuelle Gutschriften hinzu
if (!$isPending) {
$this->addCreditMarginItems($user_id);
}
}
private function addPartnerCommissionItems($user_id, $isPending){
$shoppingOrderMargins = UserMarign::getPartnerCommissionItems($user_id, $isPending);
if ($isPending) {
$targetArray = 'users_pending';
} else {
$targetArray = 'users';
}
foreach ($shoppingOrderMargins as $shoppingOrderMargin) {
$entry = $this->createCreditEntry($shoppingOrderMargin);
if ($shoppingOrderMargin->net_partner_commission) {
$entry->price_formatted = $shoppingOrderMargin->getFormattedNetPartnerCommission();
$entry->price = $shoppingOrderMargin->net_partner_commission;
}
$this->{$targetArray}[$user_id]->addItem($entry);
if (!empty($entry->price)) {
$this->{$targetArray}[$user_id]->total += $entry->price;
}
}
}
private function addShopCommissionItems($user_id, $isPending){
$shoppingOrderMargins = UserMarign::getShopCommissionItems($user_id, $isPending);
if ($isPending) {
$targetArray = 'users_pending';
} else {
$targetArray = 'users';
}
foreach ($shoppingOrderMargins as $shoppingOrderMargin) {
$entry = $this->createCreditEntry($shoppingOrderMargin);
$entry->delete = $this->addDeleteButton($shoppingOrderMargin->id, 'shopping_order_margin');
if ($shoppingOrderMargin->net_discount) {
$entry->price_formatted = $shoppingOrderMargin->getFormattedNetDiscount();
$entry->price = $shoppingOrderMargin->net_discount;
}
$this->{$targetArray}[$user_id]->addItem($entry);
if (!empty($entry->price)) {
$this->{$targetArray}[$user_id]->total += $entry->price;
}
}
}
private function addCreditMarginItems($user_id){
$creditMargins = UserMarign::getUserCreditMarginByUserID($user_id);
foreach ($creditMargins as $creditMargin) {
$entry = new \stdClass();
$entry->badge = '<i class="fa fa-plus-circle text-secondary"></i> ';
$entry->link = '';//route('admin_credits_detail', [$creditMargin->id]);
$entry->name = nl2br($creditMargin->message);
$entry->reference = '';
$entry->total = '';
$entry->date = $creditMargin->created_at->format("d.m.Y");
$entry->price_formatted = formatNumber($creditMargin->credit);
$entry->price = $creditMargin->credit;
$entry->delete = $this->addDeleteButton($creditMargin->id, 'user_credit_margin', $creditMargin->deleteTime());
$this->users[$user_id]->addItem($entry);
if (!empty($entry->price)) {
$this->users[$user_id]->total += $entry->price;
}
}
}
private function createCreditEntry($shoppingOrderMargin){
$entry = new \stdClass();
$entry->badge = \App\Services\Payment::getPaymentForTypeBadge($shoppingOrderMargin->shopping_order);
if ($shoppingOrderMargin->shopping_order->payment_for === 7 || $shoppingOrderMargin->shopping_order->payment_for === 8) {
$entry->link = route('admin_sales_customers_detail', [$shoppingOrderMargin->shopping_order->id]);
} else {
$entry->link = route('admin_sales_users_detail', [$shoppingOrderMargin->shopping_order->id]);
}
$entry->name = $shoppingOrderMargin->shopping_order->shopping_user->billing_firstname . " " .
$shoppingOrderMargin->shopping_order->shopping_user->billing_lastname;
$entry->reference = $shoppingOrderMargin->shopping_order->getLastShoppingPayment('reference');
$entry->total = $shoppingOrderMargin->shopping_order->getFormattedTotalWithoutCredit() . "";
$entry->date = $shoppingOrderMargin->shopping_order->created_at->format("d.m.Y");
return $entry;
}
private function addDeleteButton($id, $type, $deleteTime = false){
if($type === 'shopping_order_margin'){
return '<span class="no-line-break">
<a class="btn btn-danger btn-xs" href="'.route('admin_payments_credit_delete', [$id, $type]).'" onclick="return confirm(\'Wirklich löschen?\');">
<i class="ion ion-ios-trash"></i>
</a>
</span>';
}
if($type === 'user_credit_margin'){
if($deleteTime){
return '<span class="no-line-break">
<a class="btn btn-danger btn-xs" href="'.route('admin_payments_credit_delete', [$id, $type]).'" onclick="return confirm(\'Wirklich löschen?\');">
<i class="ion ion-ios-trash"></i>
</a> noch '. $deleteTime .' min.
</span>';
}
}
return '';
}
/**
* Gibt User mit Partner Provisionen zurück
*
* @param bool $isPending True für künftige Provisionen, False für fällige Provisionen
* @return \Illuminate\Database\Eloquent\Collection
*/
private function getUsersWithPartnerCommission(bool $isPending)
{
$query = ShoppingOrderMargin::join('users', 'm_sponsor_id', '=', 'users.id')
->groupBy('m_sponsor_id')
->join('user_accounts', 'account_id', '=', 'user_accounts.id')
->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
->whereOrderPaid(true)
->whereOutPaid(false)
->whereCancellation(false)
->wherePartnerCommissionPaid(false)
->whereNotNull('partner_commission_pending_to');
if ($isPending) {
$query->where('partner_commission_pending_to', '>=', Carbon::now());
} else {
$query->where('partner_commission_pending_to', '<', Carbon::now());
}
return $query->get();
}
/**
* Gibt User mit Shop Provisionen zurück
*
* @param bool $isPending True für künftige Provisionen, False für fällige Provisionen
* @return \Illuminate\Database\Eloquent\Collection
*/
private function getUsersWithShopCommission(bool $isPending)
{
$query = ShoppingOrderMargin::join('users', 'user_id', '=', 'users.id')
->groupBy('user_id')
->join('user_accounts', 'account_id', '=', 'user_accounts.id')
->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
->whereOrderPaid(true)
->whereOutPaid(false)
->whereCancellation(false)
->whereMarginPaid(false)
->whereNotNull('margin_pending_to');
if ($isPending) {
$query->where('margin_pending_to', '>=', Carbon::now());
} else {
$query->where('margin_pending_to', '<', Carbon::now());
}
return $query->get();
}
/**
* Gibt User mit manuellen Gutschriften zurück
*
* @return \Illuminate\Database\Eloquent\Collection
*/
private function getUsersWithCreditMargin()
{
return UserCreditMargin::join('users', 'user_id', '=', 'users.id')
->join('user_accounts', 'account_id', '=', 'user_accounts.id')
->select('user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
->wherePaid(false)
->get();
}
/**
* Erstellt ein neues UserCredits-Objekt
*
* @param object $user Benutzerdaten
* @return UserCredits
*/
private function createUserCredit($user)
{
$userCredit = new UserCredits();
$userCredit->email = $user->email;
$userCredit->first_name = $user->first_name;
$userCredit->last_name = $user->last_name;
$userCredit->user_id = $user->user_id;
$userCredit->total = 0;
return $userCredit;
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace App\Services\Payment;
use App\Models\ShoppingOrder;
use App\Models\ShoppingOrderMargin;
use App\Models\UserCreditMargin;
use App\Services\Util;
use Carbon\Carbon;
class UserCredits
{
public $email;
public $first_name;
public $last_name;
public $user_id;
public $items;
public $total;
public function __construct()
{
$this->items = [];
}
public function addItem($entry){
$this->items[] = $entry;
}
}