commit 08-2025
This commit is contained in:
parent
9ae662f63e
commit
480fdc65ed
404 changed files with 65310 additions and 2600431 deletions
241
dev/code/Services/BusinessPlan/TreeHtmlRenderer.php
Normal file
241
dev/code/Services/BusinessPlan/TreeHtmlRenderer.php
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\Services\TranslationHelper;
|
||||
|
||||
/**
|
||||
* Klasse für die HTML-Darstellung von Business-Trees
|
||||
* Trennt Präsentationslogik von Geschäftslogik
|
||||
*/
|
||||
class TreeHtmlRenderer
|
||||
{
|
||||
private string $initFrom;
|
||||
|
||||
public function __construct(string $initFrom = 'member')
|
||||
{
|
||||
$this->initFrom = $initFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert den kompletten Business-Tree als HTML
|
||||
*/
|
||||
public function renderTree(array $businessUsers): string
|
||||
{
|
||||
if (empty($businessUsers)) {
|
||||
return '<div class="alert alert-info">Keine Business-User gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '<ol class="dd-list">';
|
||||
foreach ($businessUsers as $businessUser) {
|
||||
$html .= $this->renderUserItem($businessUser, 0);
|
||||
}
|
||||
$html .= '</ol>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert parentlose User als HTML
|
||||
*/
|
||||
public function renderParentless(array $parentless): string
|
||||
{
|
||||
if (empty($parentless)) {
|
||||
return '<div class="alert alert-info">Keine parentlosen User gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '';
|
||||
foreach ($parentless as $item) {
|
||||
$html .= $this->renderParentlessItem($item);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Sponsor-Information als HTML
|
||||
*/
|
||||
public function renderSponsor($sponsor): string
|
||||
{
|
||||
if (!$sponsor) {
|
||||
return '<div class="alert alert-warning">' . __('team.no_sponsor_assigned') . '</div>';
|
||||
}
|
||||
|
||||
return '<li class="dd-item dd-nodrag" data-id="">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserInfo($sponsor, false, true) .
|
||||
'</div>' .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert einen einzelnen User-Item mit Hierarchie
|
||||
*/
|
||||
private function renderUserItem($item, int $deep): string
|
||||
{
|
||||
$childrenHtml = '';
|
||||
if (isset($item->businessUserItems) && $item->businessUserItems) {
|
||||
$childrenHtml = '<ol class="dd-list dd-nodrag">';
|
||||
foreach ($item->businessUserItems as $child) {
|
||||
$childrenHtml .= $this->renderUserItem($child, $deep + 1);
|
||||
}
|
||||
$childrenHtml .= '</ol>';
|
||||
}
|
||||
|
||||
return '<li class="dd-item dd-nodrag" data-id="' . $item->user_id . '">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserCardWithDepth($item, $deep) .
|
||||
'</div>' .
|
||||
$childrenHtml .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert parentlosen User-Item
|
||||
*/
|
||||
private function renderParentlessItem($item): string
|
||||
{
|
||||
return '<li class="dd-item dd-nodrag" data-id="' . $item->user_id . '">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserInfo($item, true, false) .
|
||||
'</div>' .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert User-Card mit Tiefe-Anzeige
|
||||
*/
|
||||
private function renderUserCardWithDepth($item, int $deep): string
|
||||
{
|
||||
$depthBadge = '';
|
||||
if ($deep > 0) {
|
||||
$depthBadge = '<div class="d-flex flex-column justify-content-center align-items-center">' .
|
||||
'<div class="text-large font-weight-bolder line-height-1 my-2 text-secondary badge badge-outline-secondary">' . $deep . '</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
return '<div class="media align-items-center">' .
|
||||
$depthBadge .
|
||||
'<div class="media-body ml-2">' .
|
||||
$this->renderUserInfo($item, false, false) .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert die Basis-User-Informationen
|
||||
*/
|
||||
private function renderUserInfo($item, bool $showSponsor = false, bool $isSponsor = false): string
|
||||
{
|
||||
$statusClass = $item->active_account ? '' : 'text-muted';
|
||||
$iconClass = $item->active_account ? 'text-primary' : 'text-danger';
|
||||
|
||||
$html = '<span class="' . $statusClass . '">';
|
||||
|
||||
// User Link
|
||||
$html .= '<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" ' .
|
||||
'data-id="' . $item->user_id . '" data-action="business-user-show" data-back="" ' .
|
||||
'data-modal="modal-md" data-init_from="' . $this->initFrom . '" data-route="' . route('modal_load') . '">' .
|
||||
'<span class="mr-1 ion ion-ios-contact ' . $iconClass . '"></span> ' .
|
||||
'<strong>' . e($item->first_name . ' ' . $item->last_name) . '</strong>' .
|
||||
'</a>';
|
||||
|
||||
// Email
|
||||
$html .= ' <a href="mailto:' . e($item->email) . '">' . e($item->email) . '</a>';
|
||||
|
||||
// Optional: Geburtstag
|
||||
if (isset($item->user_birthday) && $item->user_birthday) {
|
||||
$html .= ' | <i class="ion ion-ios-gift text-primary"></i> ' . e($item->user_birthday);
|
||||
}
|
||||
|
||||
// Optional: Telefon
|
||||
if (isset($item->user_phone) && $item->user_phone) {
|
||||
$html .= ' | <i class="ion ion-ios-call text-primary"></i> ' . e($item->user_phone);
|
||||
}
|
||||
|
||||
// Level Badge
|
||||
$levelName = isset($item->user_level_name) ? TranslationHelper::transUserLevelName($item->user_level_name) : '';
|
||||
$account = isset($item->m_account) ? $item->m_account : '';
|
||||
$html .= ' <span class="badge badge-outline-default ' . $statusClass . '">' . e($levelName . ' | ' . $account) . '</span>';
|
||||
|
||||
// Details für aktive Accounts
|
||||
if ($item->active_account) {
|
||||
$html .= '<br><span class="small">';
|
||||
$html .= $this->renderAccountDetails($item);
|
||||
|
||||
// Action Button (außer für Sponsor-Ansicht)
|
||||
if (!$isSponsor && $this->shouldShowActionButton()) {
|
||||
$html .= $this->renderActionButton($item->user_id);
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
} else {
|
||||
// Inaktive Accounts
|
||||
$paymentDate = isset($item->payment_account_date) ? $item->payment_account_date : '';
|
||||
$html .= '<br><span class="small">' . __('team.account_to') . ': ' . e($paymentDate) . '</span>';
|
||||
}
|
||||
|
||||
// Sponsor für parentlose User
|
||||
if ($showSponsor && isset($item->m_sponsor_name)) {
|
||||
$html .= '<br>' . e($item->m_sponsor_name);
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Account-Details (Punkte, Umsatz)
|
||||
*/
|
||||
private function renderAccountDetails($item): string
|
||||
{
|
||||
$totalPoints = isset($item->sales_volume_points_KP_sum) ? $item->sales_volume_points_KP_sum : 0;
|
||||
$ePoints = isset($item->sales_volume_KP_points) ? $item->sales_volume_KP_points : 0;
|
||||
$sPoints = isset($item->sales_volume_points_shop) ? $item->sales_volume_points_shop : 0;
|
||||
|
||||
$totalSum = isset($item->sales_volume_total_sum) ? $item->sales_volume_total_sum : 0;
|
||||
$eSum = isset($item->sales_volume_total) ? $item->sales_volume_total : 0;
|
||||
$sSum = isset($item->sales_volume_total_shop) ? $item->sales_volume_total_shop : 0;
|
||||
|
||||
return '<strong>' . __('team.total_points') . ': ' . $totalPoints . '</strong> | ' .
|
||||
__('team.e') . ': ' . $ePoints . ' | ' .
|
||||
__('team.s') . ': ' . $sPoints . ' <strong> | ' .
|
||||
__('team.net_turnover') . ': ' . formatNumber($totalSum) . ' €</strong> | ' .
|
||||
__('team.e') . ': ' . formatNumber($eSum) . ' € | ' .
|
||||
__('team.s') . ': ' . formatNumber($sSum) . ' €';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Action-Button für User-Details
|
||||
*/
|
||||
private function renderActionButton(int $userId): string
|
||||
{
|
||||
return ' | <button type="button" class="btn icon-btn btn-xs btn-secondary" ' .
|
||||
'data-toggle="modal" data-target="#modals-load-content" ' .
|
||||
'data-id="' . $userId . '" data-action="business-user-detail" ' .
|
||||
'data-back="" data-modal="modal-xl" ' .
|
||||
'data-init_from="' . $this->initFrom . '" ' .
|
||||
'data-route="' . route('modal_load') . '">' .
|
||||
'<span class="fa fa-calculator"></span>' .
|
||||
'</button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob Action-Button angezeigt werden soll
|
||||
*/
|
||||
private function shouldShowActionButton(): bool
|
||||
{
|
||||
return ($this->initFrom === 'admin' && \Auth::user()->isAdmin()) ||
|
||||
($this->initFrom === 'member');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Kontext für die Darstellung
|
||||
*/
|
||||
public function setInitFrom(string $initFrom): self
|
||||
{
|
||||
$this->initFrom = $initFrom;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue