Cocker Setup

This commit is contained in:
Kevin Adametz 2025-08-29 14:48:03 +02:00
parent fdb4aa7358
commit 8ccd81b770
184 changed files with 2115 additions and 13038 deletions

74
.env.dhl.example Normal file
View file

@ -0,0 +1,74 @@
# =============================================================================
# DHL VERSANDMODUL KONFIGURATION - BEISPIEL
# =============================================================================
# Diese Datei enthält alle DHL-spezifischen Environment-Variablen
# Kopieren Sie die benötigten Variablen in Ihre .env Datei
# DHL API Zugangsdaten
# Option 1: DHL Developer API (developer.dhl.com) - Empfohlen
DHL_API_KEY=your_api_key_from_developer_dhl_com
DHL_API_SECRET=your_api_secret_from_developer_dhl_com
# Option 2: DHL Business Customer API (Klassisch)
DHL_API_USERNAME=your_dhl_username
DHL_API_PASSWORD=your_dhl_password
DHL_ACCOUNT_NUMBER=your_14_digit_account_number
# API-Konfiguration
DHL_SANDBOX=true # false für Produktion
DHL_TEST_MODE=true # false für Produktion
DHL_API_TYPE=developer # 'developer' oder 'business_customer'
# Absenderadresse (Ihre Firmenadresse)
DHL_SENDER_COMPANY="Ihr Firmenname"
DHL_SENDER_NAME="Versandabteilung"
DHL_SENDER_STREET="Ihre Straße"
DHL_SENDER_STREET_NUMBER=123
DHL_SENDER_POSTAL_CODE=12345
DHL_SENDER_CITY="Ihre Stadt"
DHL_SENDER_STATE=
DHL_SENDER_COUNTRY=DE
DHL_SENDER_EMAIL=versand@ihrefirma.de
DHL_SENDER_PHONE="+49 123 456789"
# Standard-Einstellungen
DHL_DEFAULT_PRODUCT=V01PAK # V01PAK = DHL Paket
DHL_LABEL_FORMAT=PDF # PDF oder ZPL
DHL_LABEL_SIZE=A4 # A4 oder 10x15cm
DHL_LABEL_STORAGE_PATH=storage/app/dhl/labels
DHL_LABEL_PUBLIC_PATH=dhl/labels
# Retouren
DHL_RETURNS_ENABLED=true
DHL_RETURN_PRODUCT=V07PAK # V07PAK = DHL Paket Return
DHL_RETURN_RECEIVER_ID=your_return_receiver_id
# Tracking
DHL_TRACKING_ENABLED=true
DHL_TRACKING_AUTO_UPDATE=true
DHL_TRACKING_UPDATE_INTERVAL=60 # Minuten
# Logging
DHL_LOGGING_ENABLED=true
DHL_LOGGING_LEVEL=info # debug, info, warning, error
DHL_LOG_REQUESTS=true
DHL_LOG_RESPONSES=true
# Queue (verwende bestehende Queue-Konfiguration)
DHL_QUEUE_CONNECTION=database
DHL_QUEUE_NAME=dhl
DHL_QUEUE_TIMEOUT=60
DHL_QUEUE_MAX_TRIES=3
# Fehlerbehandlung
DHL_THROW_EXCEPTIONS=true
DHL_ERROR_NOTIFICATION_EMAIL=admin@ihrefirma.de
# Cache
DHL_CACHE_ENABLED=true
DHL_CACHE_TTL=3600 # Sekunden
# Entwicklung/Testing
DHL_FAKE_API_CALLS=false # true um API-Calls zu simulieren
DHL_MOCK_RESPONSES=false # true um Mock-Responses zu verwenden
DHL_DEBUG_MODE=false # true für detaillierte Debug-Informationen

74
.env.example Normal file
View file

@ -0,0 +1,74 @@
# =============================================================================
# DHL VERSANDMODUL KONFIGURATION - BEISPIEL
# =============================================================================
# Diese Datei enthält alle DHL-spezifischen Environment-Variablen
# Kopieren Sie die benötigten Variablen in Ihre .env Datei
# DHL API Zugangsdaten
# Option 1: DHL Developer API (developer.dhl.com) - Empfohlen
DHL_API_KEY=your_api_key_from_developer_dhl_com
DHL_API_SECRET=your_api_secret_from_developer_dhl_com
# Option 2: DHL Business Customer API (Klassisch)
DHL_API_USERNAME=your_dhl_username
DHL_API_PASSWORD=your_dhl_password
DHL_ACCOUNT_NUMBER=your_14_digit_account_number
# API-Konfiguration
DHL_SANDBOX=true # false für Produktion
DHL_TEST_MODE=true # false für Produktion
DHL_API_TYPE=developer # 'developer' oder 'business_customer'
# Absenderadresse (Ihre Firmenadresse)
DHL_SENDER_COMPANY="Ihr Firmenname"
DHL_SENDER_NAME="Versandabteilung"
DHL_SENDER_STREET="Ihre Straße"
DHL_SENDER_STREET_NUMBER=123
DHL_SENDER_POSTAL_CODE=12345
DHL_SENDER_CITY="Ihre Stadt"
DHL_SENDER_STATE=
DHL_SENDER_COUNTRY=DE
DHL_SENDER_EMAIL=versand@ihrefirma.de
DHL_SENDER_PHONE="+49 123 456789"
# Standard-Einstellungen
DHL_DEFAULT_PRODUCT=V01PAK # V01PAK = DHL Paket
DHL_LABEL_FORMAT=PDF # PDF oder ZPL
DHL_LABEL_SIZE=A4 # A4 oder 10x15cm
DHL_LABEL_STORAGE_PATH=storage/app/dhl/labels
DHL_LABEL_PUBLIC_PATH=dhl/labels
# Retouren
DHL_RETURNS_ENABLED=true
DHL_RETURN_PRODUCT=V07PAK # V07PAK = DHL Paket Return
DHL_RETURN_RECEIVER_ID=your_return_receiver_id
# Tracking
DHL_TRACKING_ENABLED=true
DHL_TRACKING_AUTO_UPDATE=true
DHL_TRACKING_UPDATE_INTERVAL=60 # Minuten
# Logging
DHL_LOGGING_ENABLED=true
DHL_LOGGING_LEVEL=info # debug, info, warning, error
DHL_LOG_REQUESTS=true
DHL_LOG_RESPONSES=true
# Queue (verwende bestehende Queue-Konfiguration)
DHL_QUEUE_CONNECTION=database
DHL_QUEUE_NAME=dhl
DHL_QUEUE_TIMEOUT=60
DHL_QUEUE_MAX_TRIES=3
# Fehlerbehandlung
DHL_THROW_EXCEPTIONS=true
DHL_ERROR_NOTIFICATION_EMAIL=admin@ihrefirma.de
# Cache
DHL_CACHE_ENABLED=true
DHL_CACHE_TTL=3600 # Sekunden
# Entwicklung/Testing
DHL_FAKE_API_CALLS=false # true um API-Calls zu simulieren
DHL_MOCK_RESPONSES=false # true um Mock-Responses zu verwenden
DHL_DEBUG_MODE=false # true für detaillierte Debug-Informationen

View file

@ -38,23 +38,23 @@ class CheckPaymentsAccount extends Command
$this->info('COMMAND [payments:check-accounts] started.');
// Die Logik wurde 1:1 aus der checkPaymentsAccounts-Methode übernommen
$renewalDate = Carbon::now()->modify('+'.(config('mivita.remind_first_days')+1).' days');
$renewalDate = Carbon::now()->modify('+' . (config('mivita.remind_first_days') + 1) . ' days');
Log::channel('cron')->info('Erneuerungsdatum für Zahlungen: ' . $renewalDate->format('Y-m-d H:i:s'));
$users = User::where('payment_account', '!=', NULL)
->where('active', '=', 1)
->where('blocked', '!=', 1)
->where('payment_account', '<', $renewalDate)
->get();
->where('active', '=', 1)
->where('blocked', '!=', 1)
->where('payment_account', '<', $renewalDate)
->get();
Log::channel('cron')->info('Found ' . $users->count() . ' users for payment reminders.');
$this->info('Found ' . $users->count() . ' users for payment reminders.');
foreach ($users as $user){
Log::channel('cron')->info('Prüfe Zahlungserinnerungen für Benutzer: ' . $user->email);
$this->checkReminderPayments($user);
foreach ($users as $user) {
Log::channel('cron')->info('Prüfe Zahlungserinnerungen für Benutzer: ' . $user->email);
$this->checkReminderPayments($user);
}
Log::channel('cron')->info('COMMAND [payments:check-accounts] finished.');
$this->info('COMMAND [payments:check-accounts] finished.');
return 0; // Success
@ -79,28 +79,28 @@ class CheckPaymentsAccount extends Command
private function checkReminderPayments(User $user)
{
//35 reminder_deaktiv, 36 reminder_deaktiv_sepa
if(!$user->isActiveAccount()){
if (!$user->isActiveAccount()) {
Log::channel('cron')->info('Inaktives Konto für Benutzer: ' . $user->email);
$this->checkIsReminderSend($user, 35);
return;
}
//34 reminder_last
if($user->daysActiveAccount() <= config('mivita.remind_last_days')){
if ($user->daysActiveAccount() <= config('mivita.remind_last_days')) {
Log::channel('cron')->info('Letzte Erinnerung für Benutzer: ' . $user->email . ' (Tage aktiv: ' . $user->daysActiveAccount() . ')');
$this->checkIsReminderSend($user, 34);
return;
}
//33 reminder_sec
if($user->daysActiveAccount() <= config('mivita.remind_sec_days')){
if ($user->daysActiveAccount() <= config('mivita.remind_sec_days')) {
Log::channel('cron')->info('Zweite Erinnerung für Benutzer: ' . $user->email . ' (Tage aktiv: ' . $user->daysActiveAccount() . ')');
$this->checkIsReminderSend($user, 33);
return;
}
//31 reminder_first
if($user->daysActiveAccount() > config('mivita.remind_sec_days')){
if ($user->daysActiveAccount() > config('mivita.remind_sec_days')) {
Log::channel('cron')->info('Erste Erinnerung für Benutzer: ' . $user->email . ' (Tage aktiv: ' . $user->daysActiveAccount() . ')');
$this->checkIsReminderSend($user, 31);
return;
@ -117,28 +117,28 @@ class CheckPaymentsAccount extends Command
private function checkIsReminderSend(User $user, $status)
{
$isSend = UserHistory::whereUserId($user->id)
->whereAction('reminder_payments')
->whereIdentifier($user->payment_account)
->whereStatus($status)
->latest()
->first();
->whereAction('reminder_payments')
->whereIdentifier($user->payment_account)
->whereStatus($status)
->latest()
->first();
if($isSend){
if ($isSend) {
Log::channel('cron')->info('Erinnerung bereits gesendet für Benutzer: ' . $user->email . ' (Status: ' . $status . ')');
return true;
}
Log::channel('cron')->info('Sende neue Erinnerung für Benutzer: ' . $user->email . ' (Status: ' . $status . ')');
$referenz = $this->sendReminderMail($user, $status);
UserHistory::create([
'user_id' => $user->id,
'action' => 'reminder_payments',
'referenz' => $referenz,
'identifier' => $user->payment_account,
'user_id' => $user->id,
'action' => 'reminder_payments',
'referenz' => $referenz,
'identifier' => $user->payment_account,
'status' => $status
]);
return false;
}
@ -155,8 +155,8 @@ class CheckPaymentsAccount extends Command
$pay_date = Carbon::parse($user->payment_account)->modify('- ' . config('mivita.abo_booking_days') . ' days')->format('d.m.Y');
$datetime = $user->getPaymentAccountDateFormat();
$price = "";
if($user->payment_order_id && isset($user->payment_order_product->price)){
if ($user->payment_order_id && isset($user->payment_order_product->price)) {
$price = 'von ' . $user->payment_order_product->getFormattedPrice() . ' EUR';
}
@ -171,16 +171,16 @@ class CheckPaymentsAccount extends Command
'subject' => __('reminder.subject') . " | ID: " . $status,
'message' => $message,
'message_last' => $message_last,
'url' => route('user_membership'),
'url' => config('app.url') . '/user/membership',
'button' => $button,
];
$sender = User::find(1);
$customer_mail = UserMessage::create(['user_id' => $user->id, 'send_user_id' => $sender->id, 'email' => $user->email, 'subject' => $data['subject'], 'message' => $data['message'] . " " . $data['message_last']]);
try {
if(!Util::isTestSystem()){
if($status >= 34){
if (!Util::isTestSystem()) {
if ($status >= 34) {
Log::channel('cron')->info('Sende kritische Erinnerung mit BCC an: ' . $user->email);
Mail::to($user->email)
->locale($user->getLocale())
@ -195,19 +195,19 @@ class CheckPaymentsAccount extends Command
} else {
Log::channel('cron')->info('Testsystem: E-Mail-Versand simuliert für: ' . $user->email);
}
} catch(\Exception $e) {
} catch (\Exception $e) {
Log::channel('cron')->error('Mail-Fehler für Benutzer ' . $user->email . ': ' . $e->getMessage());
$customer_mail->fail = true;
$customer_mail->error = $e->getMessage();
$customer_mail->save();
return 0;
}
$customer_mail->send = true;
$customer_mail->sent_at = now();
$customer_mail->save();
Log::channel('cron')->info('Erinnerungsmail erfolgreich gesendet an: ' . $user->email);
return 1;
}
}
}

View file

@ -25,7 +25,7 @@ class CheckoutController extends Controller
{
private $checkoutRepo;
private $instance = 'checkout';
/**
* Create a new controller instance.
*
@ -50,7 +50,7 @@ class CheckoutController extends Controller
<a href="{{ Util::getMyMivitaPortalUrl() }}" class="btn btn-primary btn-block mt-3 faa-parent animated-hover"><i class="fa fa-sign-in"></i> {{ __('website.to_customer_portal') }} </a>
@endif
@if(Auth::guard('user')->check())
*/
*/
$shopping_data = Yard::instance($this->instance)->getYardExtra('shopping_data');
$is_from = $shopping_data['is_from'] ?? 'shopping';
$is_for = $shopping_data['is_for'] ?? false;
@ -70,14 +70,17 @@ class CheckoutController extends Controller
}
}
if (Session::has('new_session')) {
$this->checkoutRepo->sessionDestroy();
$this->checkoutRepo->sessionDestroy();
Session::forget('new_session');
}
}
$shopping_user = $this->initializeShoppingUserSession($is_from, $is_for, $shopping_data, $homeparty_id);
$this->prepareShoppingUserData($shopping_user);
$payment_methods = $this->checkoutRepo->getPaymentsMethods($is_from, $is_abo);
if ($shopping_user === null) {
abort(403, 'ShoppingUser not found');
}
$data = [
'is_from' => $is_from,
'is_for' => $is_for,
@ -97,8 +100,8 @@ class CheckoutController extends Controller
return view('web.templates.checkout', $data);
}
/**
* Bereitet die ShoppingUser-Daten vor
*
@ -142,7 +145,7 @@ class CheckoutController extends Controller
if (isset($data['payment_method'])) {
$this->checkoutRepo->isPaymentsMethodsActive($data['payment_method'], $data['is_from'], $data['is_abo']);
}
Util::setInstanceStatus(2, true); // link_check
// Länderwechsel verarbeiten
@ -155,16 +158,16 @@ class CheckoutController extends Controller
if ($validator->fails()) {
return back()->withErrors($validator)->withInput(Request::all());
}
// Benutzer und Bestellung erstellen
$shopping_user = $this->checkoutRepo->makeShoppingUser($data);
$shopping_order = $this->checkoutRepo->makeShoppingOrder($shopping_user, $data);
// CustomerPriority prüfen
if ($shopping_user->is_from === 'shopping') {
CustomerPriority::checkOne(ShoppingUser::find($shopping_user->id), true);
}
Util::setUserHistoryValue(['status' => 2, 'shopping_order_id' => $shopping_order->id]);
// Zahlungsmethode verarbeiten
@ -188,7 +191,7 @@ class CheckoutController extends Controller
} else {
Yard::instance($this->instance)->setShippingCountryWithPrice($data['shipping_state'], $data['is_for']);
}
return back()->withInput(Request::all());
}
@ -220,7 +223,7 @@ class CheckoutController extends Controller
'shipping_salutation' => 'required'
]);
}
return Validator::make(Request::all(), $rules);
}
@ -236,7 +239,7 @@ class CheckoutController extends Controller
{
$result = [];
$payment_method = Request::get('payment_method');
// Kreditkarte prüfen
if ($payment_method === 'cc') {
$result = $this->checkCreditCard($data, $shopping_user, $shopping_order);
@ -260,7 +263,7 @@ class CheckoutController extends Controller
$reference = $pay->setPrePayment($payment_method, $amount, 'EUR', $result);
$this->checkoutRepo->putSessionPayments('payment_reference', $reference);
$pay->setPersonalData();
return $pay->ResponseData();
}
@ -277,7 +280,7 @@ class CheckoutController extends Controller
$pay = new PayoneController();
$pay->init($shopping_user, $shopping_order);
$ret['cc'] = $pay->checkCreditCard($data);
if ($ret['cc']['status'] === 'ERROR' || $ret['cc']['status'] === 'INVALID') {
Session::flash('cc-error', 1);
Session::flash('errormessage', $ret['cc']['errormessage']);
@ -303,14 +306,14 @@ class CheckoutController extends Controller
$pay->init($shopping_user, $shopping_order);
$amount = Yard::instance($this->instance)->totalWithShipping(2, '.', '') * 100;
$ret['elv'] = $pay->checkBankAccount($data, $amount, 'EUR', $shopping_user);
if ($ret['elv']['status'] === 'ERROR' || $ret['elv']['status'] === 'INVALID') {
Session::flash('elv-error', 1);
Session::flash('errormessage', $ret['elv']['errormessage']);
Session::flash('customermessage', $ret['elv']['customermessage']);
return redirect(route('checkout.checkout_card'))->withInput(Request::all());
}
if ($ret['elv']['status'] === 'APPROVED' && $ret['elv']['mandate_status'] !== "active") {
Session::flash('elv-managemandate', 1);
Session::flash('elv-mandate_identification', $ret['elv']['mandate_identification']);
@ -318,7 +321,7 @@ class CheckoutController extends Controller
Session::flash('elv-creditor_identifier', $ret['elv']['creditor_identifier']);
return redirect(route('checkout.checkout_card'))->withInput(Request::all());
}
$ret['elv']['bankaccountholder'] = $data['elv_bankaccountholder'];
} else {
$ret['elv'] = [
@ -328,7 +331,7 @@ class CheckoutController extends Controller
'bic' => $data['elv_bic'],
'bankaccountholder' => $data['elv_bankaccountholder']
];
$this->storeUserPaymentsData($shopping_user, $ret);
}
$ret['returnstatus'] = 'VALID';
@ -347,7 +350,7 @@ class CheckoutController extends Controller
'is_checkout' => true,
'yard_instance' => $this->instance,
];
return view('web.templates.checkout-is-final', $data);
}
@ -364,13 +367,13 @@ class CheckoutController extends Controller
$ShoppingPayment = ShoppingPayment::where('shopping_order_id', $shopping_order_id)
->where('reference', $reference)
->first();
if (!$ShoppingPayment) {
Util::setUserHistoryValue(['status' => 21]);
Session::flash('checkout-error', 'Der Zahlungsvorgang konnte nicht abgeschlossen werden, die Zahlung wurde nicht gefunden: ' . $reference);
return redirect(route('checkout.checkout_card'));
}
$ShoppingPayment->status = $status;
$ShoppingPayment->save();
@ -384,7 +387,7 @@ class CheckoutController extends Controller
Session::flash('checkout-error', 'Der Zahlungsvorgang wurde abgebrochen, die Bestellung konnte nicht ausgeführt werden.');
return redirect(route('checkout.checkout_card'));
}
if ($status === "error") {
Util::setUserHistoryValue(['status' => 23]);
Util::setInstanceStatus(6); // link_failed
@ -419,7 +422,7 @@ class CheckoutController extends Controller
'is_checkout' => true,
'yard_instance' => $this->instance,
];
return view('web.templates.checkout-final', $data);
}
@ -457,7 +460,7 @@ class CheckoutController extends Controller
'is_checkout' => true,
'yard_instance' => $this->instance,
];
return view('web.templates.checkout-final', $data);
}
@ -493,20 +496,20 @@ class CheckoutController extends Controller
$shopping_order = ShoppingOrder::find($payt->transmitted_data['param']);
$shopping_order->txaction = 'invoice_open';
$shopping_order->save();
$shopping_payment = ShoppingPayment::where('reference', $payt->transmitted_data['reference'])->first();
if ($shopping_payment) {
$shopping_payment->txaction = 'invoice_open';
$shopping_payment->save();
}
$send_link = Payment::paymentStatusPaidAction($shopping_order, false, $shopping_payment);
$data = [
'mode' => $payt->transmitted_data['mode'],
'txaction' => $payt->txaction,
'send_link' => $send_link,
];
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
}
}
@ -539,7 +542,7 @@ class CheckoutController extends Controller
//Bestelllink
if ($is_for === 'ot-customer' || $is_for === 'abo-ot-customer') {
//customer shop mit den Daten aus dem Salescenter shopping_data
return $this->checkoutRepo->makeCustomerShoppingUser($shopping_data, $is_for, $is_from);
return $this->checkoutRepo->makeCustomerShoppingUser($shopping_data, $is_for, $is_from);
}
//Webshop
return $this->checkoutRepo->initShoppingUser($is_for, $is_from, $homeparty_id);
@ -548,7 +551,7 @@ class CheckoutController extends Controller
return $this->getExistingShoppingUser();
}
/**
/**
* Holt den existierenden ShoppingUser und bereitet ihn vor
*
* @return ShoppingUser
@ -559,8 +562,7 @@ class CheckoutController extends Controller
$shopping_user->billing_state = Shop::getCountryShippingCountryId($shopping_user->billing_country_id);
$shopping_user->shipping_state = Shop::getCountryShippingCountryId($shopping_user->shipping_country_id);
$shopping_user->same_as_billing = $shopping_user->same_as_billing ? false : true; // reinvert
return $shopping_user;
}
}
}

View file

@ -1,4 +1,5 @@
<?php
namespace App\Mail;
use App\User;
@ -24,34 +25,34 @@ class MailAutoReleaseAccount extends Mailable
public function build()
{
$content = __(strtoupper($this->user->account->salutation))." ";
$content .= $this->user->account->first_name." ".$this->user->account->last_name."\n";
$content .= $this->user->account->address."\n";
$content .= $this->user->account->zipcode." ".$this->user->account->city."\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de."\n\n" : "\n\n";
if($this->user->account->phone){
$content = __(strtoupper($this->user->account->salutation)) . " ";
$content .= $this->user->account->first_name . " " . $this->user->account->last_name . "\n";
$content .= $this->user->account->address . "\n";
$content .= $this->user->account->zipcode . " " . $this->user->account->city . "\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de . "\n\n" : "\n\n";
if ($this->user->account->phone) {
$content .= "Telefon: ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone." " : " ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone . " " : " ";
$content .= $this->user->account->phone;
}
if($this->user->account->mobil){
if ($this->user->account->mobil) {
$content .= "Mobil: ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone." " : " ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone . " " : " ";
$content .= $this->user->account->mobil;
}
$content .= "E-Mail: ".$this->user->email;
$content .= "E-Mail: " . $this->user->email;
$copy1line = "Ein neuer Berater hat sich registriert und wurde automatisch freigeschaltet. Seine Daten müssen nachträglich Überprüfung werden:"."\n";
$copy1line .= "+ Überprüfung der Ausweisdaten"."\n";
$copy1line .= "+ Überprüfung des Gewerbenachweises"."\n";
$copy1line .= "+ Eintrag Account ID"."\n";
$copy1line .= "+ Überprüfung / Kenntnisnahme Sponsor"."\n";
$copy1line .= "+ Überprüfung der Rechnungsdaten"."\n";
$copy1line .= 'Sollte Daten nicht vollständig sein, bitte Kontakt zum Berater aufnehmen.'."\n";
$copy1line = "Ein neuer Berater hat sich registriert und wurde automatisch freigeschaltet. Seine Daten müssen nachträglich Überprüfung werden:" . "\n";
$copy1line .= "+ Überprüfung der Ausweisdaten" . "\n";
$copy1line .= "+ Überprüfung des Gewerbenachweises" . "\n";
$copy1line .= "+ Eintrag Account ID" . "\n";
$copy1line .= "+ Überprüfung / Kenntnisnahme Sponsor" . "\n";
$copy1line .= "+ Überprüfung der Rechnungsdaten" . "\n";
$copy1line .= 'Sollte Daten nicht vollständig sein, bitte Kontakt zum Berater aufnehmen.' . "\n";
return $this->view('emails.info')->with([
'url' => config('app.url_crm') . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'url' => \App\Services\Util::getMyMivitaUrl() . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'title' => 'Berater Registrierung prüfen',
'button' => 'zur Berater Prüfung',
'copy1line' => $copy1line,
@ -59,4 +60,4 @@ class MailAutoReleaseAccount extends Mailable
'content' => $content,
]);
}
}
}

View file

@ -1,4 +1,5 @@
<?php
namespace App\Mail;
use App\User;
@ -24,13 +25,13 @@ class MailInfo extends Mailable
$this->action = $action;
$this->data = $data;
if($this->action === "delete_membership"){
if ($this->action === "delete_membership") {
$this->subject = 'Mitgliedschaft beenden - beantragt';
}
if($this->action === "check_is_like_customer"){
if ($this->action === "check_is_like_customer") {
$this->subject = 'Kunden überprüfen - Kundenhoheit';
}
if($this->action === "change_is_like_customer"){
if ($this->action === "change_is_like_customer") {
$this->subject = 'Kunden erneut überprüfen - Kundenhoheit';
}
}
@ -40,68 +41,68 @@ class MailInfo extends Mailable
{
$content = "";
if($this->action === "delete_membership"){
$content .= __(strtoupper($this->user->account->salutation))." ";
$content .= $this->user->account->first_name." ".$this->user->account->last_name."\n";
$content .= $this->user->account->address."\n";
$content .= $this->user->account->zipcode." ".$this->user->account->city."\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de."\n\n" : "\n\n";
if($this->user->account->phone){
if ($this->action === "delete_membership") {
$content .= __(strtoupper($this->user->account->salutation)) . " ";
$content .= $this->user->account->first_name . " " . $this->user->account->last_name . "\n";
$content .= $this->user->account->address . "\n";
$content .= $this->user->account->zipcode . " " . $this->user->account->city . "\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de . "\n\n" : "\n\n";
if ($this->user->account->phone) {
$content .= "Telefon: ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone." " : " ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone . " " : " ";
$content .= $this->user->account->phone;
}
if($this->user->account->mobil){
if ($this->user->account->mobil) {
$content .= "Mobil: ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone." " : " ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone . " " : " ";
$content .= $this->user->account->mobil;
}
$content .= "E-Mail: ".$this->user->email;
$content .= "E-Mail: " . $this->user->email;
$copy1line = "Infos zum Berater:"."\n";
$copy1line = "Infos zum Berater:" . "\n";
$button = "zum Berater";
$title = "Ein Berater möchte seine Mitgliedschaft beenden.";
$url = config('app.url_crm') . '/admin/lead/edit/' . $this->user->id . '?show=check_lead';
$url = \App\Services\Util::getMyMivitaUrl() . '/admin/lead/edit/' . $this->user->id . '?show=check_lead';
}
if($this->action === "check_is_like_customer") {
$copy1line = "Hier geht es zum Kunden:"."\n";
if ($this->action === "check_is_like_customer") {
$copy1line = "Hier geht es zum Kunden:" . "\n";
$button = "zum Kunden";
$title = "Ein Kunden muss überprüft werden und einem Berater zugeordnet werden, da die Adresse nicht eindeutig ist.";
$url = config('app.url_crm') . '/admin/customer/detail/' . $this->user->id;
$content .= $this->user ? 'Firma: '.$this->user->billing_company."\n" : '';
$content .= \App\Services\HTMLHelper::getSalutationLang($this->user->billing_salutation)." ";
$content .= $this->user->billing_firstname." ";
$content .= $this->user->billing_lastname."\n";
$url = \App\Services\Util::getMyMivitaUrl() . '/admin/customer/detail/' . $this->user->id;
$content .= $this->user ? 'Firma: ' . $this->user->billing_company . "\n" : '';
$content .= \App\Services\HTMLHelper::getSalutationLang($this->user->billing_salutation) . " ";
$content .= $this->user->billing_firstname . " ";
$content .= $this->user->billing_lastname . "\n";
$content .= $this->user->billing_address;
$content .= $this->user->billing_address_2 ? '/ '.$this->user->billing_address_2."\n" : "\n";
$content .= $this->user->billing_zipcode." ";
$content .= $this->user->billing_city."\n";
$content .= $this->user->billing_email."\n";
$content .= $this->user->billing_phone."\n";
$content .= $this->user->billing_address_2 ? '/ ' . $this->user->billing_address_2 . "\n" : "\n";
$content .= $this->user->billing_zipcode . " ";
$content .= $this->user->billing_city . "\n";
$content .= $this->user->billing_email . "\n";
$content .= $this->user->billing_phone . "\n";
$content .= $this->user->billing_country->getLocated();
}
if($this->action === "change_is_like_customer"){
$copy1line = "Hier geht es zum Kunden:"."\n";
if ($this->action === "change_is_like_customer") {
$copy1line = "Hier geht es zum Kunden:" . "\n";
$button = "zum Kunden";
$title = "Ein Kunden muss erneut überprüft werden, da bei einer Änderung eine bestehende Kundenhoheit gefunden wurde.";
$url = config('app.url_crm') . '/admin/customer/detail/' . $this->user->id;
$content .= "Folgende Daten für die Kundenhoheit wurden geändert:"."\n";
foreach ($this->data as $key=>$value){
$content .= $this->user->{$key}." => ".$value."\n";
$url = \App\Services\Util::getMyMivitaUrl() . '/admin/customer/detail/' . $this->user->id;
$content .= "Folgende Daten für die Kundenhoheit wurden geändert:" . "\n";
foreach ($this->data as $key => $value) {
$content .= $this->user->{$key} . " => " . $value . "\n";
}
$content .= "\n"."\n"."Rechnungsadresse des Kunden vor der Änderung:"."\n";
$content .= $this->user ? 'Firma: '.$this->user->billing_company."\n" : '';
$content .= \App\Services\HTMLHelper::getSalutationLang($this->user->billing_salutation)." ";
$content .= $this->user->billing_firstname." ";
$content .= $this->user->billing_lastname."\n";
$content .= "\n" . "\n" . "Rechnungsadresse des Kunden vor der Änderung:" . "\n";
$content .= $this->user ? 'Firma: ' . $this->user->billing_company . "\n" : '';
$content .= \App\Services\HTMLHelper::getSalutationLang($this->user->billing_salutation) . " ";
$content .= $this->user->billing_firstname . " ";
$content .= $this->user->billing_lastname . "\n";
$content .= $this->user->billing_address;
$content .= $this->user->billing_address_2 ? '/ '.$this->user->billing_address_2."\n" : "\n";
$content .= $this->user->billing_zipcode." ";
$content .= $this->user->billing_city."\n";
$content .= $this->user->billing_email."\n";
$content .= $this->user->billing_phone."\n";
$content .= $this->user->billing_address_2 ? '/ ' . $this->user->billing_address_2 . "\n" : "\n";
$content .= $this->user->billing_zipcode . " ";
$content .= $this->user->billing_city . "\n";
$content .= $this->user->billing_email . "\n";
$content .= $this->user->billing_phone . "\n";
$content .= $this->user->billing_country->getLocated();
}
return $this->view('emails.info')->with([
@ -113,4 +114,4 @@ class MailInfo extends Mailable
'content' => $content,
]);
}
}
}

View file

@ -1,4 +1,5 @@
<?php
namespace App\Mail;
use App\User;
@ -24,35 +25,35 @@ class MailReleaseAccount extends Mailable
public function build()
{
$content = __(strtoupper($this->user->account->salutation))." ";
$content .= $this->user->account->first_name." ".$this->user->account->last_name."\n";
$content .= $this->user->account->address."\n";
$content .= $this->user->account->zipcode." ".$this->user->account->city."\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de."\n\n" : "\n\n";
if($this->user->account->phone){
$content = __(strtoupper($this->user->account->salutation)) . " ";
$content .= $this->user->account->first_name . " " . $this->user->account->last_name . "\n";
$content .= $this->user->account->address . "\n";
$content .= $this->user->account->zipcode . " " . $this->user->account->city . "\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de . "\n\n" : "\n\n";
if ($this->user->account->phone) {
$content .= "Telefon: ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone." " : " ";
$content .= $this->user->account->pre_phone_id ? $this->user->account->pre_phone->phone . " " : " ";
$content .= $this->user->account->phone;
}
if($this->user->account->mobil){
if ($this->user->account->mobil) {
$content .= "Mobil: ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone." " : " ";
$content .= $this->user->account->pre_mobil_id ? $this->user->account->pre_mobil->phone . " " : " ";
$content .= $this->user->account->mobil;
}
$content .= "E-Mail: ".$this->user->email;
$content .= "E-Mail: " . $this->user->email;
$copy1line = "Ein neuer Berater hat sich registriert und wartet auf die Überprüfung und Freigabe seiner Daten:"."\n";
$copy1line .= "+ Überprüfung der Ausweisdaten"."\n";
$copy1line .= "+ Überprüfung des Gewerbenachweises"."\n";
$copy1line .= "+ Eintrag Account ID"."\n";
$copy1line .= "+ Überprüfung / Kenntnisnahme Sponsor"."\n";
$copy1line .= "+ Überprüfung der Rechnungsdaten"."\n";
$copy1line .= 'Nach erfolgreicher Überprüfung mit dem Button „Daten vollständig => Berater freischalten“ den Berater freischalten.'."\n";
$copy1line .= 'Der Berater erhält eine Mail, dass sein Account freigeschaltet wurde. Der Vertrag wird automatisch mit den Daten des Vertriebspartners erstellt.'."\n";
$copy1line = "Ein neuer Berater hat sich registriert und wartet auf die Überprüfung und Freigabe seiner Daten:" . "\n";
$copy1line .= "+ Überprüfung der Ausweisdaten" . "\n";
$copy1line .= "+ Überprüfung des Gewerbenachweises" . "\n";
$copy1line .= "+ Eintrag Account ID" . "\n";
$copy1line .= "+ Überprüfung / Kenntnisnahme Sponsor" . "\n";
$copy1line .= "+ Überprüfung der Rechnungsdaten" . "\n";
$copy1line .= 'Nach erfolgreicher Überprüfung mit dem Button „Daten vollständig => Berater freischalten“ den Berater freischalten.' . "\n";
$copy1line .= 'Der Berater erhält eine Mail, dass sein Account freigeschaltet wurde. Der Vertrag wird automatisch mit den Daten des Vertriebspartners erstellt.' . "\n";
return $this->view('emails.info')->with([
'url' => config('app.url_crm') . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'url' => \App\Services\Util::getMyMivitaUrl() . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'title' => 'Berater Registrierung prüfen',
'button' => 'zur Berater Prüfung',
'copy1line' => $copy1line,
@ -60,4 +61,4 @@ class MailReleaseAccount extends Mailable
'content' => $content,
]);
}
}
}

View file

@ -1,4 +1,5 @@
<?php
namespace App\Mail;
use App\User;
@ -23,32 +24,32 @@ class MailReleaseDocument extends Mailable
public function build()
{
$content = __(strtoupper($this->user->account->salutation))." ";
$content .= $this->user->account->first_name." ".$this->user->account->last_name."\n";
$content .= $this->user->account->address."\n";
$content .= $this->user->account->zipcode." ".$this->user->account->city."\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de."\n\n" : "\n\n";
$content .= "E-Mail: ".$this->user->email;
$content = __(strtoupper($this->user->account->salutation)) . " ";
$content .= $this->user->account->first_name . " " . $this->user->account->last_name . "\n";
$content .= $this->user->account->address . "\n";
$content .= $this->user->account->zipcode . " " . $this->user->account->city . "\n";
$content .= $this->user->account->country_id ? $this->user->account->country->de . "\n\n" : "\n\n";
$content .= "E-Mail: " . $this->user->email;
$copy1line = "Ein Berater hat Daten zum Gewerbenachweis geändert, bitte um Prüfung:"."\n\n";
$copy1line = "Ein Berater hat Daten zum Gewerbenachweis geändert, bitte um Prüfung:" . "\n\n";
$business_license_choose = $this->user->account->getNotice('business_license');
if($business_license_choose === 'now'){
$copy1line .= "+ Gewerbeschein jetzt zur Freigabe"."\n\n";
if ($business_license_choose === 'now') {
$copy1line .= "+ Gewerbeschein jetzt zur Freigabe" . "\n\n";
}
if($business_license_choose === 'later'){
$copy1line .= "+ Ich reiche meinen Gewerbeschein innerhalb der nächsten 4 Wochen nach"."\n\n";
if ($business_license_choose === 'later') {
$copy1line .= "+ Ich reiche meinen Gewerbeschein innerhalb der nächsten 4 Wochen nach" . "\n\n";
}
if($business_license_choose === 'non'){
$copy1line .= "+ Ich benötige keinen Gewerbeschein"."\n";
$copy1line .= "+ Begründung: ".$this->user->account->getNotice('business_license_reason')."\n\n";
if ($business_license_choose === 'non') {
$copy1line .= "+ Ich benötige keinen Gewerbeschein" . "\n";
$copy1line .= "+ Begründung: " . $this->user->account->getNotice('business_license_reason') . "\n\n";
}
$copy1line .= 'Bei fehlerhafter Angabe nimm bitte kontakt mit dem Berater auf.'."\n";
$copy1line .= 'Bei fehlerhafter Angabe nimm bitte kontakt mit dem Berater auf.' . "\n";
return $this->view('emails.info')->with([
'url' => config('app.url_crm') . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'url' => \App\Services\Util::getMyMivitaUrl() . '/admin/lead/edit/' . $this->user->id . '?show=check_lead',
'title' => 'Berater Unterlagen prüfen',
'button' => 'zur Berater Prüfung',
'copy1line' => $copy1line,
@ -56,4 +57,4 @@ class MailReleaseDocument extends Mailable
'content' => $content,
]);
}
}
}

View file

@ -8,8 +8,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; // Wichtig!
/**
*
*
* @property int $id
* @property string|null $name
* @property string $email

View file

@ -0,0 +1,36 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\HorizonApplicationServiceProvider;
class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
parent::boot();
// Horizon::routeSmsNotificationsTo('15556667777');
// Horizon::routeMailNotificationsTo('example@example.com');
// Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}
/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*/
protected function gate(): void
{
Gate::define('viewHorizon', function ($user = null) {
return in_array(optional($user)->email, [
//
]);
});
}
}

View file

@ -58,7 +58,7 @@ class RouteServiceProvider extends ServiceProvider
/** @var DomainContext $context */
$context = app(DomainContext::class);
$this->loadSharedRoutes();
\Log::info('loadDomainAwareRoutes', ['context' => $context]);
match ($context->type) {
'main' => $this->loadDomainRoutes('main', 'main.php'),
'main-shop' => [

9
bootstrap/cache/events.php vendored Normal file
View file

@ -0,0 +1,9 @@
<?php return array (
'App\\Providers\\EventServiceProvider' =>
array (
'App\\Events\\Event' =>
array (
0 => 'App\\Listeners\\EventListener',
),
),
);

View file

@ -66,6 +66,17 @@
0 => 'Laracasts\\Flash\\FlashServiceProvider',
),
),
'laravel/horizon' =>
array (
'aliases' =>
array (
'Horizon' => 'Laravel\\Horizon\\Horizon',
),
'providers' =>
array (
0 => 'Laravel\\Horizon\\HorizonServiceProvider',
),
),
'laravel/legacy-factories' =>
array (
'providers' =>

View file

@ -31,31 +31,33 @@
27 => 'JoeDixon\\Translation\\TranslationServiceProvider',
28 => 'JoeDixon\\Translation\\TranslationBindingsServiceProvider',
29 => 'Laracasts\\Flash\\FlashServiceProvider',
30 => 'Illuminate\\Database\\Eloquent\\LegacyFactoryServiceProvider',
31 => 'Laravel\\Passport\\PassportServiceProvider',
32 => 'Laravel\\Sail\\SailServiceProvider',
33 => 'Laravel\\Tinker\\TinkerServiceProvider',
34 => 'Laravel\\Ui\\UiServiceProvider',
35 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
36 => 'Carbon\\Laravel\\ServiceProvider',
37 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
38 => 'Termwind\\Laravel\\TermwindServiceProvider',
39 => 'Pest\\Laravel\\PestServiceProvider',
40 => 'Spatie\\Html\\HtmlServiceProvider',
41 => 'Spatie\\LaravelIgnition\\IgnitionServiceProvider',
42 => 'Yajra\\DataTables\\DataTablesServiceProvider',
43 => 'Laravel\\Tinker\\TinkerServiceProvider',
44 => 'Acme\\Dhl\\DhlServiceProvider',
45 => 'App\\Providers\\AppServiceProvider',
46 => 'App\\Providers\\AuthServiceProvider',
47 => 'App\\Providers\\EventServiceProvider',
48 => 'App\\Providers\\DomainServiceProvider',
49 => 'App\\Providers\\RouteServiceProvider',
50 => 'Jenssegers\\Date\\DateServiceProvider',
51 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
52 => 'Yajra\\DataTables\\DataTablesServiceProvider',
53 => 'App\\Providers\\YardServiceProvider',
54 => 'Alban\\LaravelCollectiveSpatieHtmlParser\\ServiceProvider',
30 => 'Laravel\\Horizon\\HorizonServiceProvider',
31 => 'Illuminate\\Database\\Eloquent\\LegacyFactoryServiceProvider',
32 => 'Laravel\\Passport\\PassportServiceProvider',
33 => 'Laravel\\Sail\\SailServiceProvider',
34 => 'Laravel\\Tinker\\TinkerServiceProvider',
35 => 'Laravel\\Ui\\UiServiceProvider',
36 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
37 => 'Carbon\\Laravel\\ServiceProvider',
38 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
39 => 'Termwind\\Laravel\\TermwindServiceProvider',
40 => 'Pest\\Laravel\\PestServiceProvider',
41 => 'Spatie\\Html\\HtmlServiceProvider',
42 => 'Spatie\\LaravelIgnition\\IgnitionServiceProvider',
43 => 'Yajra\\DataTables\\DataTablesServiceProvider',
44 => 'Laravel\\Tinker\\TinkerServiceProvider',
45 => 'Acme\\Dhl\\DhlServiceProvider',
46 => 'App\\Providers\\AppServiceProvider',
47 => 'App\\Providers\\AuthServiceProvider',
48 => 'App\\Providers\\EventServiceProvider',
49 => 'App\\Providers\\HorizonServiceProvider',
50 => 'App\\Providers\\DomainServiceProvider',
51 => 'App\\Providers\\RouteServiceProvider',
52 => 'Jenssegers\\Date\\DateServiceProvider',
53 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
54 => 'Yajra\\DataTables\\DataTablesServiceProvider',
55 => 'App\\Providers\\YardServiceProvider',
56 => 'Alban\\LaravelCollectiveSpatieHtmlParser\\ServiceProvider',
),
'eager' =>
array (
@ -75,28 +77,30 @@
13 => 'Jenssegers\\Date\\DateServiceProvider',
14 => 'JoeDixon\\Translation\\TranslationServiceProvider',
15 => 'Laracasts\\Flash\\FlashServiceProvider',
16 => 'Illuminate\\Database\\Eloquent\\LegacyFactoryServiceProvider',
17 => 'Laravel\\Passport\\PassportServiceProvider',
18 => 'Laravel\\Ui\\UiServiceProvider',
19 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
20 => 'Carbon\\Laravel\\ServiceProvider',
21 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
22 => 'Termwind\\Laravel\\TermwindServiceProvider',
23 => 'Pest\\Laravel\\PestServiceProvider',
24 => 'Spatie\\Html\\HtmlServiceProvider',
25 => 'Spatie\\LaravelIgnition\\IgnitionServiceProvider',
26 => 'Yajra\\DataTables\\DataTablesServiceProvider',
27 => 'Acme\\Dhl\\DhlServiceProvider',
28 => 'App\\Providers\\AppServiceProvider',
29 => 'App\\Providers\\AuthServiceProvider',
30 => 'App\\Providers\\EventServiceProvider',
31 => 'App\\Providers\\DomainServiceProvider',
32 => 'App\\Providers\\RouteServiceProvider',
33 => 'Jenssegers\\Date\\DateServiceProvider',
34 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
35 => 'Yajra\\DataTables\\DataTablesServiceProvider',
36 => 'App\\Providers\\YardServiceProvider',
37 => 'Alban\\LaravelCollectiveSpatieHtmlParser\\ServiceProvider',
16 => 'Laravel\\Horizon\\HorizonServiceProvider',
17 => 'Illuminate\\Database\\Eloquent\\LegacyFactoryServiceProvider',
18 => 'Laravel\\Passport\\PassportServiceProvider',
19 => 'Laravel\\Ui\\UiServiceProvider',
20 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
21 => 'Carbon\\Laravel\\ServiceProvider',
22 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
23 => 'Termwind\\Laravel\\TermwindServiceProvider',
24 => 'Pest\\Laravel\\PestServiceProvider',
25 => 'Spatie\\Html\\HtmlServiceProvider',
26 => 'Spatie\\LaravelIgnition\\IgnitionServiceProvider',
27 => 'Yajra\\DataTables\\DataTablesServiceProvider',
28 => 'Acme\\Dhl\\DhlServiceProvider',
29 => 'App\\Providers\\AppServiceProvider',
30 => 'App\\Providers\\AuthServiceProvider',
31 => 'App\\Providers\\EventServiceProvider',
32 => 'App\\Providers\\HorizonServiceProvider',
33 => 'App\\Providers\\DomainServiceProvider',
34 => 'App\\Providers\\RouteServiceProvider',
35 => 'Jenssegers\\Date\\DateServiceProvider',
36 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
37 => 'Yajra\\DataTables\\DataTablesServiceProvider',
38 => 'App\\Providers\\YardServiceProvider',
39 => 'Alban\\LaravelCollectiveSpatieHtmlParser\\ServiceProvider',
),
'deferred' =>
array (

View file

@ -17,6 +17,7 @@
"joedixon/laravel-translation": "2.x-dev",
"laracasts/flash": "^3.2",
"laravel/framework": "^11.0",
"laravel/horizon": "^5.33",
"laravel/passport": "^12.0",
"laravel/prompts": "^0.1.14",
"laravel/tinker": "^2.9",
@ -29,16 +30,16 @@
"yajra/laravel-datatables-oracle": "^11.0"
},
"require-dev": {
"spatie/laravel-ignition": "^2.0",
"nunomaduro/collision": "^8.1",
"fakerphp/faker": "^1.23",
"laravel/pint": "^1.0",
"laravel/sail": "^1.26",
"barryvdh/laravel-debugbar": "^3.13",
"barryvdh/laravel-ide-helper": "^3.6",
"fakerphp/faker": "^1.23",
"laravel/pint": "^1.0",
"laravel/sail": "^1.44",
"mockery/mockery": "^1.6.2",
"pestphp/pest": "^2.0",
"pestphp/pest-plugin-laravel": "^2.0",
"barryvdh/laravel-debugbar": "^3.13",
"barryvdh/laravel-ide-helper": "^3.0"
"nunomaduro/collision": "^8.1",
"pestphp/pest": "^2.0",
"pestphp/pest-plugin-laravel": "^2.0",
"spatie/laravel-ignition": "^2.0"
},
"config": {
"optimize-autoloader": true,

291
composer.lock generated Normal file → Executable file
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7fc21677cad34a62767eaccbc243e7d6",
"content-hash": "925483d8104ae55ae4bf5fd0ada18726",
"packages": [
{
"name": "barryvdh/laravel-dompdf",
@ -1432,22 +1432,22 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.9.3",
"version": "7.10.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
"reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
"reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"guzzlehttp/promises": "^2.3",
"guzzlehttp/psr7": "^2.8",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
@ -1538,7 +1538,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
"source": "https://github.com/guzzle/guzzle/tree/7.10.0"
},
"funding": [
{
@ -1554,20 +1554,20 @@
"type": "tidelift"
}
],
"time": "2025-03-27T13:37:11+00:00"
"time": "2025-08-23T22:36:01+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.2.0",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
"reference": "481557b130ef3790cf82b713667b43030dc9c957"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
"url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957",
"reference": "481557b130ef3790cf82b713667b43030dc9c957",
"shasum": ""
},
"require": {
@ -1575,7 +1575,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
},
"type": "library",
"extra": {
@ -1621,7 +1621,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.2.0"
"source": "https://github.com/guzzle/promises/tree/2.3.0"
},
"funding": [
{
@ -1637,20 +1637,20 @@
"type": "tidelift"
}
],
"time": "2025-03-27T13:27:01+00:00"
"time": "2025-08-22T14:34:08+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.7.1",
"version": "2.8.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
"reference": "21dc724a0583619cd1652f673303492272778051"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
"reference": "21dc724a0583619cd1652f673303492272778051",
"shasum": ""
},
"require": {
@ -1666,7 +1666,7 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@ -1737,7 +1737,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
"source": "https://github.com/guzzle/psr7/tree/2.8.0"
},
"funding": [
{
@ -1753,20 +1753,20 @@
"type": "tidelift"
}
],
"time": "2025-03-27T12:30:47+00:00"
"time": "2025-08-23T21:21:41+00:00"
},
{
"name": "guzzlehttp/uri-template",
"version": "v1.0.4",
"version": "v1.0.5",
"source": {
"type": "git",
"url": "https://github.com/guzzle/uri-template.git",
"reference": "30e286560c137526eccd4ce21b2de477ab0676d2"
"reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/30e286560c137526eccd4ce21b2de477ab0676d2",
"reference": "30e286560c137526eccd4ce21b2de477ab0676d2",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1",
"reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1",
"shasum": ""
},
"require": {
@ -1775,7 +1775,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
"phpunit/phpunit": "^8.5.44 || ^9.6.25",
"uri-template/tests": "1.0.0"
},
"type": "library",
@ -1823,7 +1823,7 @@
],
"support": {
"issues": "https://github.com/guzzle/uri-template/issues",
"source": "https://github.com/guzzle/uri-template/tree/v1.0.4"
"source": "https://github.com/guzzle/uri-template/tree/v1.0.5"
},
"funding": [
{
@ -1839,7 +1839,7 @@
"type": "tidelift"
}
],
"time": "2025-02-03T10:55:03+00:00"
"time": "2025-08-22T14:27:06+00:00"
},
{
"name": "intervention/gif",
@ -2401,6 +2401,86 @@
},
"time": "2025-08-13T20:28:00+00:00"
},
{
"name": "laravel/horizon",
"version": "v5.33.4",
"source": {
"type": "git",
"url": "https://github.com/laravel/horizon.git",
"reference": "678362049ce5b9ce96673ac0282bbfda3279eca9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/horizon/zipball/678362049ce5b9ce96673ac0282bbfda3279eca9",
"reference": "678362049ce5b9ce96673ac0282bbfda3279eca9",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-pcntl": "*",
"ext-posix": "*",
"illuminate/contracts": "^9.21|^10.0|^11.0|^12.0",
"illuminate/queue": "^9.21|^10.0|^11.0|^12.0",
"illuminate/support": "^9.21|^10.0|^11.0|^12.0",
"nesbot/carbon": "^2.17|^3.0",
"php": "^8.0",
"ramsey/uuid": "^4.0",
"symfony/console": "^6.0|^7.0",
"symfony/error-handler": "^6.0|^7.0",
"symfony/polyfill-php83": "^1.28",
"symfony/process": "^6.0|^7.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^7.0|^8.0|^9.0|^10.0",
"phpstan/phpstan": "^1.10|^2.0",
"phpunit/phpunit": "^9.0|^10.4|^11.5|^12.0",
"predis/predis": "^1.1|^2.0|^3.0"
},
"suggest": {
"ext-redis": "Required to use the Redis PHP driver.",
"predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0|^3.0)."
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"Horizon": "Laravel\\Horizon\\Horizon"
},
"providers": [
"Laravel\\Horizon\\HorizonServiceProvider"
]
},
"branch-alias": {
"dev-master": "6.x-dev"
}
},
"autoload": {
"psr-4": {
"Laravel\\Horizon\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Dashboard and code-driven configuration for Laravel queues.",
"keywords": [
"laravel",
"queue"
],
"support": {
"issues": "https://github.com/laravel/horizon/issues",
"source": "https://github.com/laravel/horizon/tree/v5.33.4"
},
"time": "2025-08-25T13:31:24+00:00"
},
{
"name": "laravel/legacy-factories",
"version": "v1.4.1",
@ -3613,16 +3693,16 @@
},
{
"name": "maatwebsite/excel",
"version": "3.1.66",
"version": "3.1.67",
"source": {
"type": "git",
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
"reference": "3b29c2426a46674f444890c45f742452a396aae8"
"reference": "e508e34a502a3acc3329b464dad257378a7edb4d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/3b29c2426a46674f444890c45f742452a396aae8",
"reference": "3b29c2426a46674f444890c45f742452a396aae8",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/e508e34a502a3acc3329b464dad257378a7edb4d",
"reference": "e508e34a502a3acc3329b464dad257378a7edb4d",
"shasum": ""
},
"require": {
@ -3630,7 +3710,7 @@
"ext-json": "*",
"illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0||^12.0",
"php": "^7.0||^8.0",
"phpoffice/phpspreadsheet": "^1.29.12",
"phpoffice/phpspreadsheet": "^1.30.0",
"psr/simple-cache": "^1.0||^2.0||^3.0"
},
"require-dev": {
@ -3678,7 +3758,7 @@
],
"support": {
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.66"
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.67"
},
"funding": [
{
@ -3690,26 +3770,26 @@
"type": "github"
}
],
"time": "2025-08-07T08:31:22+00:00"
"time": "2025-08-26T09:13:16+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "3.1.2",
"version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f"
"reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f",
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/9712d8fa4cdf9240380b01eb4be55ad8dcf71416",
"reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-zlib": "*",
"php-64bit": "^8.2"
"php-64bit": "^8.3"
},
"require-dev": {
"brianium/paratest": "^7.7",
@ -3718,7 +3798,7 @@
"guzzlehttp/guzzle": "^7.5",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.5",
"phpunit/phpunit": "^11.0",
"phpunit/phpunit": "^12.0",
"vimeo/psalm": "^6.0"
},
"suggest": {
@ -3760,7 +3840,7 @@
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2"
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.0"
},
"funding": [
{
@ -3768,7 +3848,7 @@
"type": "github"
}
],
"time": "2025-01-27T12:07:53+00:00"
"time": "2025-07-17T11:15:13+00:00"
},
{
"name": "markbaker/complex",
@ -6406,16 +6486,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v7.3.0",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d"
"reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d",
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191",
"reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191",
"shasum": ""
},
"require": {
@ -6466,7 +6546,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0"
"source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3"
},
"funding": [
{
@ -6477,12 +6557,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2025-04-22T09:11:45+00:00"
"time": "2025-08-13T11:49:31+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@ -6630,16 +6714,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6"
"reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/6877c122b3a6cc3695849622720054f6e6fa5fa6",
"reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/7475561ec27020196c49bb7c4f178d33d7d3dc00",
"reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00",
"shasum": ""
},
"require": {
@ -6689,7 +6773,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.3.2"
"source": "https://github.com/symfony/http-foundation/tree/v7.3.3"
},
"funding": [
{
@ -6709,20 +6793,20 @@
"type": "tidelift"
}
],
"time": "2025-07-10T08:47:49+00:00"
"time": "2025-08-20T08:04:18+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c"
"reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/6ecc895559ec0097e221ed2fd5eb44d5fede083c",
"reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/72c304de37e1a1cec6d5d12b81187ebd4850a17b",
"reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b",
"shasum": ""
},
"require": {
@ -6807,7 +6891,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-kernel/tree/v7.3.2"
"source": "https://github.com/symfony/http-kernel/tree/v7.3.3"
},
"funding": [
{
@ -6827,20 +6911,20 @@
"type": "tidelift"
}
],
"time": "2025-07-31T10:45:04+00:00"
"time": "2025-08-29T08:23:45+00:00"
},
{
"name": "symfony/mailer",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b"
"reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/d43e84d9522345f96ad6283d5dfccc8c1cfc299b",
"reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b",
"url": "https://api.github.com/repos/symfony/mailer/zipball/a32f3f45f1990db8c4341d5122a7d3a381c7e575",
"reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575",
"shasum": ""
},
"require": {
@ -6891,7 +6975,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v7.3.2"
"source": "https://github.com/symfony/mailer/tree/v7.3.3"
},
"funding": [
{
@ -6911,7 +6995,7 @@
"type": "tidelift"
}
],
"time": "2025-07-15T11:36:08+00:00"
"time": "2025-08-13T11:49:31+00:00"
},
{
"name": "symfony/mime",
@ -7672,16 +7756,16 @@
},
{
"name": "symfony/process",
"version": "v7.3.0",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1",
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1",
"shasum": ""
},
"require": {
@ -7713,7 +7797,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.3.0"
"source": "https://github.com/symfony/process/tree/v7.3.3"
},
"funding": [
{
@ -7724,12 +7808,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2025-04-17T09:11:12+00:00"
"time": "2025-08-18T09:42:54+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@ -7984,16 +8072,16 @@
},
{
"name": "symfony/string",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
"url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
"shasum": ""
},
"require": {
@ -8051,7 +8139,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v7.3.2"
"source": "https://github.com/symfony/string/tree/v7.3.3"
},
"funding": [
{
@ -8071,7 +8159,7 @@
"type": "tidelift"
}
],
"time": "2025-07-10T08:47:49+00:00"
"time": "2025-08-25T06:35:40+00:00"
},
{
"name": "symfony/translation",
@ -8326,16 +8414,16 @@
},
{
"name": "symfony/var-dumper",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "53205bea27450dc5c65377518b3275e126d45e75"
"reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/53205bea27450dc5c65377518b3275e126d45e75",
"reference": "53205bea27450dc5c65377518b3275e126d45e75",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/34d8d4c4b9597347306d1ec8eb4e1319b1e6986f",
"reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f",
"shasum": ""
},
"require": {
@ -8389,7 +8477,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v7.3.2"
"source": "https://github.com/symfony/var-dumper/tree/v7.3.3"
},
"funding": [
{
@ -8409,7 +8497,7 @@
"type": "tidelift"
}
],
"time": "2025-07-29T20:02:46+00:00"
"time": "2025-08-13T11:49:31+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@ -11980,16 +12068,16 @@
},
{
"name": "spatie/backtrace",
"version": "1.7.4",
"version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/backtrace.git",
"reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe"
"reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe",
"reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe",
"url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110",
"reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110",
"shasum": ""
},
"require": {
@ -12027,7 +12115,8 @@
"spatie"
],
"support": {
"source": "https://github.com/spatie/backtrace/tree/1.7.4"
"issues": "https://github.com/spatie/backtrace/issues",
"source": "https://github.com/spatie/backtrace/tree/1.8.1"
},
"funding": [
{
@ -12039,7 +12128,7 @@
"type": "other"
}
],
"time": "2025-05-08T15:41:09+00:00"
"time": "2025-08-26T08:22:30+00:00"
},
{
"name": "spatie/error-solutions",
@ -12360,16 +12449,16 @@
},
{
"name": "symfony/yaml",
"version": "v7.3.2",
"version": "v7.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30"
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30",
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d",
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d",
"shasum": ""
},
"require": {
@ -12412,7 +12501,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v7.3.2"
"source": "https://github.com/symfony/yaml/tree/v7.3.3"
},
"funding": [
{
@ -12432,7 +12521,7 @@
"type": "tidelift"
}
],
"time": "2025-07-10T08:47:49+00:00"
"time": "2025-08-27T11:34:33+00:00"
},
{
"name": "ta-tikoma/phpunit-architecture-test",
@ -12554,6 +12643,6 @@
"platform": {
"php": "^8.2"
},
"platform-dev": [],
"plugin-api-version": "2.2.0"
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

View file

@ -59,7 +59,7 @@ return [
'tld_shop' => env('APP_TLD_SHOP', '.lshop'),
'protocol' => env('APP_PROTOCOL', 'https://'),
'pre_url_main' => env('APP_URL_MAIN', ''),
'pre_url_crm' => env('APP_URL_CRM', 'my.'),
'pre_url_crm' => env('APP_PRE_URL_CRM', 'my.'),
'pre_url_portal' => env('APP_URL_PORTAL', 'in.'),
'checkout_url' => env('APP_URL_CHECKOUT', 'checkout.'),
@ -198,6 +198,7 @@ return [
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\HorizonServiceProvider::class,
App\Providers\DomainServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Jenssegers\Date\DateServiceProvider::class,

View file

@ -30,13 +30,13 @@ return [
// Das CRM (z.B. my.mivita.care)
'crm' => [
'host' => env('APP_URL_CRM', 'my.') . env('APP_DOMAIN', 'mivita') . env('APP_TLD_CARE', '.care'),
'host' => env('APP_PRE_URL_CRM', 'my.') . env('APP_DOMAIN', 'mivita') . env('APP_TLD_CARE', '.care'),
'type' => 'crm',
],
// Das Partner-Portal (z.B. in.mivita.care)
'portal' => [
'host' => env('APP_URL_PORTAL', 'in.') . env('APP_DOMAIN', 'mivita') . env('APP_TLD_CARE', '.care'),
'host' => env('APP_PRE_URL_PORTAL', 'in.') . env('APP_DOMAIN', 'mivita') . env('APP_TLD_CARE', '.care'),
'type' => 'portal',
],

213
config/horizon.php Normal file
View file

@ -0,0 +1,213 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Horizon Domain
|--------------------------------------------------------------------------
|
| This is the subdomain where Horizon will be accessible from. If this
| setting is null, Horizon will reside under the same domain as the
| application. Otherwise, this value will serve as the subdomain.
|
*/
'domain' => env('HORIZON_DOMAIN'),
/*
|--------------------------------------------------------------------------
| Horizon Path
|--------------------------------------------------------------------------
|
| This is the URI path where Horizon will be accessible from. Feel free
| to change this path to anything you like. Note that the URI will not
| affect the paths of its internal API that aren't exposed to users.
|
*/
'path' => env('HORIZON_PATH', 'horizon'),
/*
|--------------------------------------------------------------------------
| Horizon Redis Connection
|--------------------------------------------------------------------------
|
| This is the name of the Redis connection where Horizon will store the
| meta information required for it to function. It includes the list
| of supervisors, failed jobs, job metrics, and other information.
|
*/
'use' => 'default',
/*
|--------------------------------------------------------------------------
| Horizon Redis Prefix
|--------------------------------------------------------------------------
|
| This prefix will be used when storing all Horizon data in Redis. You
| may modify the prefix when you are running multiple installations
| of Horizon on the same server so that they don't have problems.
|
*/
'prefix' => env(
'HORIZON_PREFIX',
Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:'
),
/*
|--------------------------------------------------------------------------
| Horizon Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will get attached onto each Horizon route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/
'middleware' => ['web'],
/*
|--------------------------------------------------------------------------
| Queue Wait Time Thresholds
|--------------------------------------------------------------------------
|
| This option allows you to configure when the LongWaitDetected event
| will be fired. Every connection / queue combination may have its
| own, unique threshold (in seconds) before this event is fired.
|
*/
'waits' => [
'redis:default' => 60,
],
/*
|--------------------------------------------------------------------------
| Job Trimming Times
|--------------------------------------------------------------------------
|
| Here you can configure for how long (in minutes) you desire Horizon to
| persist the recent and failed jobs. Typically, recent jobs are kept
| for one hour while all failed jobs are stored for an entire week.
|
*/
'trim' => [
'recent' => 60,
'pending' => 60,
'completed' => 60,
'recent_failed' => 10080,
'failed' => 10080,
'monitored' => 10080,
],
/*
|--------------------------------------------------------------------------
| Silenced Jobs
|--------------------------------------------------------------------------
|
| Silencing a job will instruct Horizon to not place the job in the list
| of completed jobs within the Horizon dashboard. This setting may be
| used to fully remove any noisy jobs from the completed jobs list.
|
*/
'silenced' => [
// App\Jobs\ExampleJob::class,
],
/*
|--------------------------------------------------------------------------
| Metrics
|--------------------------------------------------------------------------
|
| Here you can configure how many snapshots should be kept to display in
| the metrics graph. This will get used in combination with Horizon's
| `horizon:snapshot` schedule to define how long to retain metrics.
|
*/
'metrics' => [
'trim_snapshots' => [
'job' => 24,
'queue' => 24,
],
],
/*
|--------------------------------------------------------------------------
| Fast Termination
|--------------------------------------------------------------------------
|
| When this option is enabled, Horizon's "terminate" command will not
| wait on all of the workers to terminate unless the --wait option
| is provided. Fast termination can shorten deployment delay by
| allowing a new instance of Horizon to start while the last
| instance will continue to terminate each of its workers.
|
*/
'fast_termination' => false,
/*
|--------------------------------------------------------------------------
| Memory Limit (MB)
|--------------------------------------------------------------------------
|
| This value describes the maximum amount of memory the Horizon master
| supervisor may consume before it is terminated and restarted. For
| configuring these limits on your workers, see the next section.
|
*/
'memory_limit' => 64,
/*
|--------------------------------------------------------------------------
| Queue Worker Configuration
|--------------------------------------------------------------------------
|
| Here you may define the queue worker settings used by your application
| in all environments. These supervisors and settings handle all your
| queued jobs and will be provisioned by Horizon during deployment.
|
*/
'defaults' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'maxProcesses' => 1,
'maxTime' => 0,
'maxJobs' => 0,
'memory' => 128,
'tries' => 1,
'timeout' => 60,
'nice' => 0,
],
],
'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
];

View file

@ -1,8 +0,0 @@
#!/bin/bash
echo $(date) # Will print the output of date command
/Applications/MAMP/bin/php/php7.3.33/bin/php -v
/Applications/MAMP/bin/php/php7.3.33/bin/php ../artisan business:store 0 0 2>&1
#/usr/bin/php74 -v
#/usr/bin/php74 ../artisan business:store 0 0 2>&1
# php /path/to/artisan schedule:run 1>> /dev/null 2>&1
# cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

View file

@ -1,79 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserInvoiceCreditsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_invoice_credits', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('auth_user_id')->nullable();
$table->unsignedInteger('shopping_order_id')->nullable();
$table->unsignedInteger('shopping_user_id')->nullable();
//invoice //credit
$table->string('type', 7)->index();
$table->string('str_number', 255)->nullable();
$table->unsignedInteger('number', 255)->nullable();
$table->decimal('net', 13, 2)->nullable();
$table->decimal('tax_rate', 8, 2)->nullable();
$table->decimal('tax', 8, 2)->nullable();
$table->decimal('total', 13, 2)->nullable();
$table->text('file')->nullable();
$table->text('contents')->nullable();
$table->text('infos')->nullable();
$table->string('subject')->nullable();
$table->text('address')->nullable();
$table->boolean('paid')->default(false);
$table->date('paid_date')->nullable();
$table->unsignedInteger('cancellation_id')->nullable();
$table->date('cancellation_date')->nullable();
$table->unsignedTinyInteger('status')->index()->default(0);
$table->timestamps();
$table->softDeletes();
$table->foreign('auth_user_id')
->references('id')
->on('users');
$table->foreign('shopping_order_id')
->references('id')
->on('shopping_orders');
$table->foreign('shopping_user_id')
->references('id')
->on('shopping_users');
$table->foreign('cancellation_id')
->references('id')
->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_credits');
}
}

View file

@ -1,81 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserInvoiceCreditsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_invoice_credits', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('auth_user_id')->index()->nullable();
$table->unsignedInteger('shopping_order_id')->index()->nullable();
$table->unsignedInteger('shopping_user_id')->index()->nullable();
//invoice //credit
$table->string('type', 7)->index();
$table->unsignedTinyInteger('month')->nullable();
$table->unsignedSmallInteger('year')->nullable();
$table->string('full_number', 255)->nullable();
$table->unsignedInteger('number')->nullable();
$table->decimal('net', 13, 2)->nullable();
$table->decimal('tax_rate', 8, 2)->nullable();
$table->decimal('tax', 8, 2)->nullable();
$table->decimal('total', 13, 2)->nullable();
$table->text('file')->nullable();
$table->text('contents')->nullable();
$table->text('infos')->nullable();
$table->string('subject')->nullable();
$table->text('address')->nullable();
$table->boolean('paid')->default(false);
$table->date('paid_date')->nullable();
$table->unsignedInteger('cancellation_id')->nullable();
$table->date('cancellation_date')->nullable();
$table->unsignedTinyInteger('status')->index()->default(0);
$table->timestamps();
$table->softDeletes();
$table->foreign('auth_user_id')
->references('id')
->on('users');
$table->foreign('shopping_order_id')
->references('id')
->on('shopping_orders');
$table->foreign('shopping_user_id')
->references('id')
->on('shopping_users');
$table->foreign('cancellation_id')
->references('id')
->on('user_invoice_credits');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_invoice_credits');
}
}

View file

@ -1,56 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersSalesVolumesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users_sales_volumes', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('shopping_order_id')->index()->nullable();
$table->unsignedTinyInteger('month')->nullable();
$table->unsignedSmallInteger('year')->nullable();
$table->date('date')->nullable();
$table->unsignedInteger('points')->nullable();
$table->unsignedInteger('month_points')->nullable();
$table->decimal('total_net', 13, 2)->nullable();
$table->decimal('month_total_net', 13, 2)->nullable();
$table->string('message', 255)->nullable();
$table->unsignedTinyInteger('status')->index()->default(0);
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users');
$table->foreign('shopping_order_id')
->references('id')
->on('shopping_orders');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users_sales_volumes');
}
}

View file

@ -1,95 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserBusinessesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_businesses', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedTinyInteger('month')->nullable();
$table->unsignedSmallInteger('year')->nullable();
$table->unsignedInteger('m_level_id')->nullable();
$table->unsignedInteger('m_sponsor_id')->nullable();
$table->text('sponsor')->nullable();
$table->string('m_sponsor_name')->nullable();
$table->string('user_level_name')->nullable();
$table->boolean('active_account')->default(false);
$table->date('payment_account_date')->nullable();
$table->date('active_date')->nullable();
$table->unsignedInteger('m_account')->nullable();
$table->string('email')->nullable();
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->integer('sales_volume_points')->nullable();
$table->integer('sales_volume_points_shop')->nullable();
$table->integer('sales_volume_points_sum')->nullable();
$table->decimal('sales_volume_total', 13, 2)->nullable();
$table->decimal('sales_volume_total_shop', 13, 2)->nullable();
$table->decimal('sales_volume_total_sum', 13, 2)->nullable();
$table->unsignedTinyInteger('margin')->nullable();
$table->unsignedTinyInteger('margin_shop')->nullable();
$table->decimal('commission_shop_sales', 13, 2)->nullable();
$table->unsignedSmallInteger('qual_kp')->nullable();
$table->unsignedInteger('qual_tp')->nullable();
$table->integer('total_tp')->nullable();
$table->integer('total_qual_tp')->nullable();
$table->decimal('commission_lines_total', 13, 2)->nullable();
$table->decimal('commission_shop_sales', 13, 2)->nullable();
$table->text('businessLines')->nullable();
$table->text('userItems')->nullable();
$table->text('qual_user_level')->nullable();
$table->timestamps();
/*$table->foreign('user_id')
->references('id')
->on('users');
$table->foreign('m_level')
->references('id')
->on('user_levels');
$table->foreign('m_sponsor')
->references('id')
->on('users');*/
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_businesses');
}
}

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('jobs');
}
};

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('failed_jobs');
}
};

View file

@ -1,599 +0,0 @@
<?php
namespace App\Services\BusinessPlan;
use App\User;
use stdClass;
use Carbon\Carbon;
use App\Models\UserBusinessStructure;
use Illuminate\Support\Facades\Log;
use Illuminate\Contracts\Logging\Log as LogContract;
/**
* Optimierte Version der TreeCalcBot Klasse
*
* Verbesserungen:
* - Trennung von Datenzugriff (Repository Pattern)
* - Trennung von HTML-Rendering (Renderer Pattern)
* - Optimierte Datenbankabfragen (N+1 Problem gelöst)
* - Memory-effiziente Verarbeitung großer Datenmengen
* - Robuste Fehlerbehandlung mit Logging
* - Dependency Injection für bessere Testbarkeit
*/
class TreeCalcBotOptimized
{
private stdClass $date;
private string $initFrom;
private array $businessUsers = [];
private array $parentless = [];
private ?BusinessUserItem $businessUser = null;
private ?BusinessUserItem $sponsor = null;
private array $processedUserIds = [];
private BusinessUserRepository $repository;
private TreeHtmlRenderer $renderer;
private LogContract $logger;
public function __construct(
int $month,
int $year,
string $initFrom = 'member',
?BusinessUserRepository $repository = null,
?TreeHtmlRenderer $renderer = null,
?LogContract $logger = null
) {
$this->validateInput($month, $year);
$this->initializeDate($month, $year);
$this->initFrom = $initFrom;
// Dependency Injection mit Fallback
$this->repository = $repository ?? new BusinessUserRepository($month, $year);
$this->renderer = $renderer ?? new TreeHtmlRenderer($initFrom);
$this->logger = $logger ?? app(LogContract::class);
}
/**
* Initialisiert die Business-Struktur für Admin-Ansicht
*/
public function initStructureAdmin(bool $check = true): void
{
try {
$storedStructure = null;
if ($check) {
$storedStructure = $this->repository->getStoredStructure();
}
if ($storedStructure) {
$this->logger->info("Loading stored business structure for {$this->date->month}/{$this->date->year}");
$this->loadStoredStructure($storedStructure);
} else {
$this->logger->info("Building fresh business structure for {$this->date->month}/{$this->date->year}");
$this->buildFreshStructure();
}
} catch (\Exception $e) {
$this->logger->error("Error initializing admin structure: " . $e->getMessage());
throw $e;
}
}
/**
* Initialisiert die Struktur für einen spezifischen User
*/
public function initStructureUser(int $userId): void
{
try {
$this->logger->info("Initializing structure for user: {$userId}");
$user = $this->repository->getUserWithRelations($userId);
if (!$user) {
$this->logger->warning("User not found: {$userId}");
return;
}
$businessUserItem = new BusinessUserItemOptimized($this->date);
$businessUserItem->makeUserFromModel($user); // ✅ Nutzt bereits geladene Relations
$this->addUserIdToProcessed($userId);
$this->businessUsers[] = $businessUserItem;
$storedStructure = $this->repository->getStoredStructure();
if ($storedStructure) {
$this->loadStoredParentsUsers($storedStructure);
if (isset($this->businessUsers[0]) && $this->businessUsers[0]->sponsor) {
$this->loadStoredSponsorUser($this->businessUsers[0]->sponsor->user_id);
}
} else {
$this->loadParentsUsers();
$this->loadSponsorUser($userId);
}
} catch (\Exception $e) {
$this->logger->error("Error initializing user structure for {$userId}: " . $e->getMessage());
throw $e;
}
}
/**
* Initialisiert detaillierte Business-User-Informationen
*/
public function initBusinesslUserDetail(User $user): void
{
try {
$this->logger->info("Initializing business user details for: {$user->id}");
$this->businessUser = new BusinessUserItemOptimized($this->date);
$this->businessUser->makeUserFromModel($user); // ✅ Nutzt bereits User-Objekt
$this->businessUser->checkSponsor($user);
if (!$this->businessUser->isSave()) {
// Aufbau der Struktur für den User in die unendliche Tiefe
$this->businessUser->readParentsBusinessUsers();
// Calculate Points in Lines (optimiert für Memory-Effizienz)
if (count($this->businessUser->businessUserItems) > 0) {
$this->calculateUserPointsOptimized($this->businessUser->businessUserItems, 1);
}
// Qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
$this->businessUser->calcQualPP();
}
} catch (\Exception $e) {
$this->logger->error("Error initializing business user details for {$user->id}: " . $e->getMessage());
throw $e;
}
}
/**
* Gibt Growth Bonus zurück (ab Linie 6)
*/
public function getGrowthBonus(): array
{
if (!$this->businessUser || !$this->businessUser->business_lines) {
return [];
}
if (count($this->businessUser->business_lines) > 6) {
$bLines = $this->businessUser->business_lines->toArray();
return array_slice($bLines, 6);
}
return [];
}
/**
* Gibt Wert für spezifische Linie zurück
*/
public function getKeybyLine(int $line, string $key)
{
if (!$this->businessUser || !$this->businessUser->business_lines) {
return 0;
}
$bLines = $this->businessUser->business_lines;
if (!isset($bLines[$line])) {
return 0;
}
$lineData = $bLines[$line];
if ($lineData instanceof stdClass) {
return $lineData->{$key} ?? 0;
}
if (is_array($lineData)) {
return $lineData[$key] ?? 0;
}
return 0;
}
/**
* HTML-Rendering Methoden (Delegation an Renderer)
*/
public function makeHtmlTree(): string
{
return $this->renderer->renderTree($this->businessUsers);
}
public function makeParentlessHtml(): string
{
return $this->renderer->renderParentless($this->parentless);
}
public function makeSponsorHtml(): string
{
return $this->renderer->renderSponsor($this->sponsor);
}
/**
* Getter-Methoden (Rückwärtskompatibilität)
*/
public function getItems(): array
{
return $this->businessUsers;
}
public function isParentless(): bool
{
return !empty($this->parentless);
}
/**
* Static Methoden (Rückwärtskompatibilität)
*/
public static function isFromStored(int $month, int $year): ?UserBusinessStructure
{
$structure = UserBusinessStructure::where('year', $year)
->where('month', $month)
->first();
return ($structure && $structure->completed) ? $structure : null;
}
public static function addUserID(int $id): void
{
// Deprecated: Wird durch Instanz-Methode ersetzt
// Bleibt für Rückwärtskompatibilität erhalten
}
// ===== Private Methoden =====
/**
* Validiert Eingabeparameter
*/
private function validateInput(int $month, int $year): void
{
if ($month < 1 || $month > 12) {
throw new \InvalidArgumentException("Invalid month: {$month}");
}
$currentYear = (int) date('Y');
if ($year < 2020 || $year > $currentYear + 1) {
throw new \InvalidArgumentException("Invalid year: {$year}");
}
}
/**
* Initialisiert Datums-Objekt
*/
private function initializeDate(int $month, int $year): void
{
$this->date = new stdClass();
$date = Carbon::parse($year . '-' . $month . '-1');
$this->date->month = $month;
$this->date->year = $year;
$this->date->start_date = $date->format('Y-m-d H:i:s');
$this->date->end_date = $date->endOfMonth()->format('Y-m-d H:i:s');
}
/**
* Lädt gespeicherte Struktur
*/
private function loadStoredStructure(UserBusinessStructure $structure): void
{
$this->loadStoredRootUsers($structure);
$this->loadStoredParentsUsers($structure);
$this->loadStoredParentlessUsers($structure);
}
/**
* Baut frische Struktur auf
*/
private function buildFreshStructure(): void
{
$this->loadRootUsers();
$this->loadParentsUsers();
$this->loadParentlessUsers();
}
/**
* Lädt Root-Users (optimiert mit Memory-Monitoring)
*/
private function loadRootUsers(): void
{
$startMemory = memory_get_usage();
$users = $this->repository->getRootUsers();
foreach ($users as $user) {
// Memory-Check vor jeder User-Verarbeitung
$this->checkMemoryUsage('loadRootUsers', $user->id);
$businessUserItem = new BusinessUserItemOptimized($this->date);
$businessUserItem->makeUserFromModel($user); // ✅ Nutzt bereits geladene Relations
$this->addUserIdToProcessed($user->id);
$this->businessUsers[] = $businessUserItem;
}
$endMemory = memory_get_usage();
$memoryUsed = $this->formatBytes($endMemory - $startMemory);
$this->logger->info("Loaded " . count($users) . " root users with optimized relations. Memory used: {$memoryUsed}");
}
/**
* Lädt Parent-Users für alle Business-Users
*/
private function loadParentsUsers(): void
{
foreach ($this->businessUsers as $businessUser) {
$businessUser->readParentsBusinessUsers();
}
}
/**
* Lädt parentlose Users (Memory-optimiert)
*/
private function loadParentlessUsers(): void
{
$count = 0;
$excludeIds = array_keys($this->processedUserIds);
foreach ($this->repository->getParentlessUsers($excludeIds) as $user) {
$businessUserItem = new BusinessUserItemOptimized($this->date);
$businessUserItem->makeUserFromModel($user); // ✅ Nutzt bereits geladene Relations
$this->parentless[] = $businessUserItem;
$count++;
}
$this->logger->info("Loaded {$count} parentless users with optimized relations");
}
/**
* Lädt Sponsor für User
*/
private function loadSponsorUser(int $userId): void
{
try {
$sponsorUser = $this->repository->getSponsorForUser($userId);
if ($sponsorUser) {
$this->sponsor = new BusinessUserItem($this->date);
$this->sponsor->makeUser($sponsorUser->id);
$this->logger->info("Loaded sponsor {$sponsorUser->id} for user {$userId}");
}
} catch (\Exception $e) {
$this->logger->warning("Could not load sponsor for user {$userId}: " . $e->getMessage());
}
}
/**
* Gespeicherte Root-Users laden
*/
private function loadStoredRootUsers(UserBusinessStructure $structure): void
{
if (!$structure->structure) {
return;
}
foreach ($structure->structure as $obj) {
$businessUserItem = new BusinessUserItem($this->date);
$businessUserItem->makeUser($obj->user_id);
$this->addUserIdToProcessed($obj->user_id);
$this->businessUsers[] = $businessUserItem;
}
}
/**
* Gespeicherte Parent-Users laden
*/
private function loadStoredParentsUsers(UserBusinessStructure $structure): void
{
foreach ($this->businessUsers as $businessUser) {
$businessUser->readStoredParentsBusinessUsers($structure->structure);
}
}
/**
* Gespeicherte parentlose Users laden
*/
private function loadStoredParentlessUsers(UserBusinessStructure $structure): void
{
if (!$structure->parentless) {
return;
}
foreach ($structure->parentless as $obj) {
if (!isset($this->processedUserIds[$obj->user_id])) {
$businessUserItem = new BusinessUserItem($this->date);
$businessUserItem->makeUser($obj->user_id);
$this->parentless[] = $businessUserItem;
}
}
}
/**
* Gespeicherten Sponsor laden
*/
private function loadStoredSponsorUser(int $userId): void
{
$this->sponsor = new BusinessUserItem($this->date);
$this->sponsor->makeUser($userId);
}
/**
* Optimierte Punkte-Berechnung (Stack-basiert mit korrekter Depth-First Reihenfolge)
*
* KRITISCH: Stack muss gleiche Reihenfolge wie Original-Rekursion produzieren
* Original: Depth-First Traversierung (erst tief, dann Punkte addieren)
* Stack: Muss umgekehrt arbeiten - erst alle Kinder sammeln, dann von tief zu flach verarbeiten
*/
private function calculateUserPointsOptimized(array $businessUserItems, int $startLine): void
{
$processingStack = [];
$collectionStack = []; // Sammelt Items in korrekter Reihenfolge
// Phase 1: Sammle alle Items in Depth-First Reihenfolge
foreach ($businessUserItems as $item) {
$collectionStack[] = ['item' => $item, 'line' => $startLine, 'depth' => 0];
}
// Expandiere alle Kinder (Depth-First)
$processedItems = [];
while (!empty($collectionStack)) {
$current = array_shift($collectionStack); // FIFO für Breadth-First Sammlung
$item = $current['item'];
$line = $current['line'];
$depth = $current['depth'];
// Markiere für Verarbeitung (mit Tiefe für spätere Sortierung)
$processingStack[] = [
'item' => $item,
'line' => $line,
'depth' => $depth,
'id' => $item->user_id ?? uniqid()
];
// Füge Kinder hinzu (werden später verarbeitet = Depth-First)
if (isset($item->businessUserItems) && count($item->businessUserItems) > 0) {
// Kinder in umgekehrter Reihenfolge hinzufügen für korrekte Stack-Verarbeitung
$children = array_reverse($item->businessUserItems);
foreach ($children as $childItem) {
array_unshift($collectionStack, [
'item' => $childItem,
'line' => $line + 1,
'depth' => $depth + 1
]);
}
}
}
// Phase 2: Sortiere nach Tiefe (tiefste zuerst, wie bei Rekursion)
usort($processingStack, function($a, $b) {
return $b['depth'] <=> $a['depth']; // Tiefste zuerst
});
// Phase 3: Verarbeite in korrekter Reihenfolge (von tief zu flach)
foreach ($processingStack as $current) {
$item = $current['item'];
$line = $current['line'];
try {
// Business Line initialisieren falls nötig
if (!isset($this->businessUser->business_lines[$line])) {
$obj = new stdClass();
$obj->points = 0;
$this->businessUser->addBusinessLineToUser($line, $obj);
}
// Punkte hinzufügen (mit Validierung)
$points = (float) ($item->sales_volume_points_TP_sum ?? 0);
if ($points > 0) {
$this->businessUser->addBusinessLinePoints($line, $points);
$this->businessUser->addTotalTP($points);
}
$this->logger->debug("Processed user {$current['id']} at line {$line} with {$points} points");
} catch (\Exception $e) {
$this->logger->error("Error processing user points for {$current['id']}: " . $e->getMessage());
}
}
$this->logger->info("Processed " . count($processingStack) . " business user items in depth-first order");
}
/**
* User-ID zu verarbeiteten IDs hinzufügen
*/
private function addUserIdToProcessed(int $id): void
{
$this->processedUserIds[$id] = true;
}
/**
* Prüft ob User bereits verarbeitet wurde
*/
private function isUserProcessed(int $id): bool
{
return isset($this->processedUserIds[$id]);
}
/**
* Memory-Monitoring Methoden
*/
private function checkMemoryUsage(string $operation, $identifier = null): void
{
$currentMemory = memory_get_usage();
$memoryLimit = $this->parseMemoryLimit(ini_get('memory_limit'));
$memoryPercent = ($currentMemory / $memoryLimit) * 100;
if ($memoryPercent > 80) {
$currentFormatted = $this->formatBytes($currentMemory);
$limitFormatted = $this->formatBytes($memoryLimit);
$this->logger->warning("High memory usage detected in {$operation}", [
'identifier' => $identifier,
'current_memory' => $currentFormatted,
'memory_limit' => $limitFormatted,
'usage_percent' => round($memoryPercent, 2)
]);
// Garbage Collection bei hohem Memory-Verbrauch
if ($memoryPercent > 90) {
$this->logger->warning("Critical memory usage - forcing garbage collection");
gc_collect_cycles();
}
}
}
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;
}
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];
}
/**
* Public Properties für Rückwärtskompatibilität
*/
public function __get(string $name)
{
switch ($name) {
case 'date':
return $this->date;
case 'business_user':
return $this->businessUser;
case 'business_users':
return $this->businessUsers;
case 'parentless':
return $this->parentless;
default:
throw new \InvalidArgumentException("Property {$name} does not exist");
}
}
public function __set(string $name, $value)
{
switch ($name) {
case 'business_users':
$this->businessUsers = $value;
break;
case 'parentless':
$this->parentless = $value;
break;
default:
throw new \InvalidArgumentException("Property {$name} cannot be set");
}
}
}

View file

@ -1,272 +0,0 @@
<?php
namespace App\Services;
use App\Models\UserShop;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
/**
* Domain Service - Centralized domain and subdomain management
*
* This service provides a centralized way to handle domain resolution,
* subdomain validation, and domain-specific configuration management.
*/
class DomainService
{
private const CACHE_TTL = 3600; // 1 hour
private const FIXED_SUBDOMAINS = ['my', 'in', 'checkout'];
private array $domainConfig;
public function __construct()
{
$this->domainConfig = $this->loadDomainConfiguration();
}
/**
* Load domain configuration from config files
*/
private function loadDomainConfiguration(): array
{
return [
'main_domain' => config('app.domain'),
'main_tld' => config('app.tld_care'),
'shop_tld' => config('app.tld_shop'),
'protocol' => config('app.protocol'),
'subdomains' => [
'crm' => config('app.pre_url_crm', 'my.'),
'portal' => config('app.pre_url_portal', 'in.'),
'checkout' => config('app.pre_url_checkout', 'checkout.'),
]
];
}
/**
* Determine the type of subdomain
*/
public function getSubdomainType(string $subdomain): string
{
// Check if it's a fixed subdomain
if (in_array($subdomain, self::FIXED_SUBDOMAINS)) {
return match($subdomain) {
'my' => 'crm',
'in' => 'portal',
'checkout' => 'checkout',
default => 'unknown'
};
}
// Check if it's a valid user shop
if ($this->isValidUserShop($subdomain)) {
return 'user-shop';
}
return 'unknown';
}
/**
* Check if a subdomain represents a valid user shop
*/
public function isValidUserShop(string $slug): bool
{
$cacheKey = "user_shop_valid_{$slug}";
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($slug) {
$userShop = UserShop::where('slug', $slug)->first();
if (!$userShop) {
return false;
}
if (!$userShop->active) {
return false;
}
if (!$userShop->user) {
return false;
}
if (!$userShop->user->isActiveShop()) {
return false;
}
return true;
});
}
/**
* Get user shop by slug with caching
*/
public function getUserShop(string $slug): ?UserShop
{
if (!$this->isValidUserShop($slug)) {
return null;
}
$cacheKey = "user_shop_{$slug}";
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($slug) {
return UserShop::where('slug', $slug)
->with('user')
->first();
});
}
/**
* Parse domain from request and determine context
*/
public function parseDomain(string $host): array
{
$parts = explode('.', $host);
// Handle different TLD scenarios
if (count($parts) < 2) {
return [
'type' => 'invalid',
'domain' => $host,
'subdomain' => null,
'tld' => null
];
}
// Extract TLD and domain
$tld = '.' . end($parts);
$domain = $parts[count($parts) - 2];
// Check for subdomain
$subdomain = null;
if (count($parts) > 2) {
$subdomain = $parts[0];
}
// Determine domain type
$type = $this->determineDomainType($domain, $subdomain, $tld);
return [
'type' => $type,
'domain' => $domain,
'subdomain' => $subdomain,
'tld' => $tld,
'full_domain' => $host
];
}
/**
* Determine domain type based on domain, subdomain, and TLD
*/
private function determineDomainType(string $domain, ?string $subdomain, string $tld): string
{
// Check if it's the main domain
if ($domain === $this->domainConfig['main_domain']) {
if ($subdomain === null) {
// Main domain without subdomain
if ($tld === $this->domainConfig['shop_tld']) {
return 'main-shop'; // mivita.shop
}
return 'main'; // mivita.care
}
// Main domain with subdomain
return $this->getSubdomainType($subdomain);
}
return 'unknown';
}
/**
* Build URL for specific domain type
*/
public function buildUrl(string $type, ?string $path = null, ?string $slug = null): string
{
$base = $this->domainConfig['protocol'];
switch ($type) {
case 'main':
$base .= $this->domainConfig['main_domain'] . $this->domainConfig['main_tld'];
break;
case 'main-shop':
$base .= $this->domainConfig['main_domain'] . $this->domainConfig['shop_tld'];
break;
case 'crm':
$base .= rtrim($this->domainConfig['subdomains']['crm'], '.') .
$this->domainConfig['main_domain'] . $this->domainConfig['main_tld'];
break;
case 'portal':
$base .= rtrim($this->domainConfig['subdomains']['portal'], '.') .
$this->domainConfig['main_domain'] . $this->domainConfig['main_tld'];
break;
case 'checkout':
$base .= rtrim($this->domainConfig['subdomains']['checkout'], '.') .
$this->domainConfig['main_domain'] . $this->domainConfig['main_tld'];
break;
case 'user-shop':
if (!$slug) {
throw new \InvalidArgumentException('Slug required for user-shop URLs');
}
$base .= $slug . '.' . $this->domainConfig['main_domain'] . $this->domainConfig['main_tld'];
break;
default:
throw new \InvalidArgumentException("Unknown domain type: {$type}");
}
if ($path) {
$base .= '/' . ltrim($path, '/');
}
return $base;
}
/**
* Get domain configuration
*/
public function getDomainConfiguration(): array
{
return $this->domainConfig;
}
/**
* Clear user shop cache
*/
public function clearUserShopCache(string $slug): void
{
Cache::forget("user_shop_valid_{$slug}");
Cache::forget("user_shop_{$slug}");
}
/**
* Get default user shop for main domain (fallback)
*/
public function getDefaultUserShop(): ?UserShop
{
return $this->getUserShop('aloevera'); // Current hardcoded fallback
}
/**
* Validate domain configuration
*/
public function validateConfiguration(): array
{
$errors = [];
if (empty($this->domainConfig['main_domain'])) {
$errors[] = 'Main domain not configured';
}
if (empty($this->domainConfig['main_tld'])) {
$errors[] = 'Main TLD not configured';
}
if (empty($this->domainConfig['protocol'])) {
$errors[] = 'Protocol not configured';
}
return $errors;
}
}

121
docker-compose.yml Normal file
View file

@ -0,0 +1,121 @@
services:
laravel.test:
build:
context: './docker/8.4'
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.4/app'
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
# - '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
IGNITION_LOCAL_SITES_PATH: '${PWD}'
volumes:
- '.:/var/www/html'
networks:
- sail
- proxy
depends_on:
- mysql
- redis
- mailpit
labels:
- "traefik.enable=true"
# Hauptdomain
- "traefik.http.routers.mivita.rule=Host(`mivita.test`)"
- "traefik.http.routers.mivita.entrypoints=websecure"
- "traefik.http.routers.mivita.tls=true"
- "traefik.http.routers.mivita.service=mivita-service"
# Wildcard für alle Subdomains - WICHTIG: Gleicher Service!
- "traefik.http.routers.mivita-sub.rule=HostRegexp(`^.+\\.mivita\\.test$`)"
- "traefik.http.routers.mivita-sub.entrypoints=websecure"
- "traefik.http.routers.mivita-sub.tls=true"
- "traefik.http.routers.mivita-sub.service=mivita-service"
- "traefik.http.routers.mivita-sub.priority=10"
# Service Definition - NUR EINMAL!
- "traefik.http.services.mivita-service.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
horizon:
image: sail-8.4/app
container_name: mivita-horizon-1
restart: unless-stopped
command: php /var/www/html/artisan horizon
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- redis
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-33061}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_EXTRA_OPTIONS: '${MYSQL_EXTRA_OPTIONS}'
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
- '-p${DB_PASSWORD}'
retries: 3
timeout: 5s
redis:
image: 'redis:alpine'
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sail-redis:/data'
networks:
- sail
healthcheck:
test:
- CMD
- redis-cli
- ping
retries: 3
timeout: 5s
mailpit:
image: 'axllent/mailpit:latest'
ports:
- '${FORWARD_MAILPIT_PORT:-1025}:1025'
- '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.mivita-mail.rule=Host(`mivita-mail.test`)"
- "traefik.http.routers.mivita-mail.entrypoints=websecure"
- "traefik.http.routers.mivita-mail.tls=true"
- "traefik.http.services.mivita-mail.loadbalancer.server.port=8025"
- "traefik.docker.network=proxy"
networks:
sail:
driver: bridge
proxy:
external: true
volumes:
sail-mysql:
driver: local
sail-redis:
driver: local

70
docker/8.0/Dockerfile Normal file
View file

@ -0,0 +1,70 @@
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=22
ARG POSTGRES_VERSION=17
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.0-cli php8.0-dev \
php8.0-pgsql php8.0-sqlite3 php8.0-gd php8.0-imagick \
php8.0-curl php8.0-memcached php8.0-mongodb \
php8.0-imap php8.0-mysql php8.0-mbstring \
php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \
php8.0-intl php8.0-readline php8.0-pcov \
php8.0-msgpack php8.0-igbinary php8.0-ldap \
php8.0-redis php8.0-swoole php8.0-xdebug \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g bun \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN update-alternatives --set php /usr/bin/php8.0
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]

5
docker/8.0/php.ini Normal file
View file

@ -0,0 +1,5 @@
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
exit 1
fi
if [ ! -z "$WWWUSER" ]; then
usermod -u $WWWUSER sail
fi
if [ ! -d /.composer ]; then
mkdir /.composer
fi
chmod -R ugo+rw /.composer
if [ $# -gt 0 ]; then
if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
exec "$@"
else
exec gosu $WWWUSER "$@"
fi
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi

View file

@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:php]
command=%(ENV_SUPERVISOR_PHP_COMMAND)s
user=%(ENV_SUPERVISOR_PHP_USER)s
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

69
docker/8.1/Dockerfile Normal file
View file

@ -0,0 +1,69 @@
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=22
ARG POSTGRES_VERSION=17
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.1-cli php8.1-dev \
php8.1-pgsql php8.1-sqlite3 php8.1-gd php8.1-imagick \
php8.1-curl php8.1-mongodb \
php8.1-imap php8.1-mysql php8.1-mbstring \
php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \
php8.1-intl php8.1-readline \
php8.1-ldap \
php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \
php8.1-memcached php8.1-pcov php8.1-xdebug \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g bun \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]

5
docker/8.1/php.ini Normal file
View file

@ -0,0 +1,5 @@
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
exit 1
fi
if [ ! -z "$WWWUSER" ]; then
usermod -u $WWWUSER sail
fi
if [ ! -d /.composer ]; then
mkdir /.composer
fi
chmod -R ugo+rw /.composer
if [ $# -gt 0 ]; then
if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
exec "$@"
else
exec gosu $WWWUSER "$@"
fi
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi

View file

@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:php]
command=%(ENV_SUPERVISOR_PHP_COMMAND)s
user=%(ENV_SUPERVISOR_PHP_USER)s
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

70
docker/8.2/Dockerfile Normal file
View file

@ -0,0 +1,70 @@
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=22
ARG POSTGRES_VERSION=17
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.2-cli php8.2-dev \
php8.2-pgsql php8.2-sqlite3 php8.2-gd php8.2-imagick \
php8.2-curl php8.2-mongodb \
php8.2-imap php8.2-mysql php8.2-mbstring \
php8.2-xml php8.2-zip php8.2-bcmath php8.2-soap \
php8.2-intl php8.2-readline \
php8.2-ldap \
php8.2-msgpack php8.2-igbinary php8.2-redis php8.2-swoole \
php8.2-memcached php8.2-pcov php8.2-xdebug \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g pnpm \
&& npm install -g bun \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.2/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]

5
docker/8.2/php.ini Normal file
View file

@ -0,0 +1,5 @@
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
exit 1
fi
if [ ! -z "$WWWUSER" ]; then
usermod -u $WWWUSER sail
fi
if [ ! -d /.composer ]; then
mkdir /.composer
fi
chmod -R ugo+rw /.composer
if [ $# -gt 0 ]; then
if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
exec "$@"
else
exec gosu $WWWUSER "$@"
fi
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi

View file

@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:php]
command=%(ENV_SUPERVISOR_PHP_COMMAND)s
user=%(ENV_SUPERVISOR_PHP_USER)s
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

71
docker/8.3/Dockerfile Normal file
View file

@ -0,0 +1,71 @@
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=22
ARG MYSQL_CLIENT="mysql-client"
ARG POSTGRES_VERSION=17
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.3-cli php8.3-dev \
php8.3-pgsql php8.3-sqlite3 php8.3-gd \
php8.3-curl php8.3-mongodb \
php8.3-imap php8.3-mysql php8.3-mbstring \
php8.3-xml php8.3-zip php8.3-bcmath php8.3-soap \
php8.3-intl php8.3-readline \
php8.3-ldap \
php8.3-msgpack php8.3-igbinary php8.3-redis \
php8.3-memcached php8.3-pcov php8.3-imagick php8.3-xdebug php8.3-swoole \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g pnpm \
&& npm install -g bun \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y $MYSQL_CLIENT \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.3/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]

5
docker/8.3/php.ini Normal file
View file

@ -0,0 +1,5 @@
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
exit 1
fi
if [ ! -z "$WWWUSER" ]; then
usermod -u $WWWUSER sail
fi
if [ ! -d /.composer ]; then
mkdir /.composer
fi
chmod -R ugo+rw /.composer
if [ $# -gt 0 ]; then
if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
exec "$@"
else
exec gosu $WWWUSER "$@"
fi
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi

View file

@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:php]
command=%(ENV_SUPERVISOR_PHP_COMMAND)s
user=%(ENV_SUPERVISOR_PHP_USER)s
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

71
docker/8.4/Dockerfile Normal file
View file

@ -0,0 +1,71 @@
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=22
ARG MYSQL_CLIENT="mysql-client"
ARG POSTGRES_VERSION=17
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.4-cli php8.4-dev \
php8.4-pgsql php8.4-sqlite3 php8.4-gd \
php8.4-curl php8.4-mongodb \
php8.4-imap php8.4-mysql php8.4-mbstring \
php8.4-xml php8.4-zip php8.4-bcmath php8.4-soap \
php8.4-intl php8.4-readline \
php8.4-ldap \
php8.4-msgpack php8.4-igbinary php8.4-redis php8.4-swoole \
php8.4-memcached php8.4-pcov php8.4-imagick php8.4-xdebug \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g pnpm \
&& npm install -g bun \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y $MYSQL_CLIENT \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.4
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.4/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]

5
docker/8.4/php.ini Normal file
View file

@ -0,0 +1,5 @@
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
exit 1
fi
if [ ! -z "$WWWUSER" ]; then
usermod -u $WWWUSER sail
fi
if [ ! -d /.composer ]; then
mkdir /.composer
fi
chmod -R ugo+rw /.composer
if [ $# -gt 0 ]; then
if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
exec "$@"
else
exec gosu $WWWUSER "$@"
fi
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi

View file

@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:php]
command=%(ENV_SUPERVISOR_PHP_COMMAND)s
user=%(ENV_SUPERVISOR_PHP_USER)s
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
/usr/bin/mariadb --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL
CREATE DATABASE IF NOT EXISTS testing;
GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%';
EOSQL

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
mysql --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL
CREATE DATABASE IF NOT EXISTS testing;
GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%';
EOSQL

View file

@ -0,0 +1,2 @@
SELECT 'CREATE DATABASE testing'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'testing')\gexec

View file

@ -3,8 +3,5 @@
{
"path": "."
}
],
"settings": {
"CodeGPT.apiKey": "CodeGPT Plus Beta"
}
]
}

View file

@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('shipments', function (Blueprint $t) {
$t->id();
$t->unsignedBigInteger('order_id')->nullable();
$t->string('carrier')->default('dhl');
$t->string('dhl_shipment_no')->nullable()->index();
$t->string('product_code')->nullable();
$t->string('billing_number')->nullable();
$t->decimal('weight_kg', 8, 3)->nullable();
$t->string('status')->default('created');
$t->string('label_format')->nullable();
$t->string('label_path')->nullable();
$t->json('meta')->nullable();
$t->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('shipments');
}
};

View file

@ -1,22 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('shipment_labels', function (Blueprint $t) {
$t->id();
$t->foreignId('shipment_id')->constrained('shipments')->cascadeOnDelete();
$t->string('format')->default('PDF');
$t->string('path');
$t->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('shipment_labels');
}
};

View file

@ -1,24 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('tracking_events', function (Blueprint $t) {
$t->id();
$t->foreignId('shipment_id')->constrained('shipments')->cascadeOnDelete();
$t->string('status_code')->nullable();
$t->string('status_text')->nullable();
$t->string('location')->nullable();
$t->timestamp('event_time')->nullable();
$t->json('raw')->nullable();
});
}
public function down(): void
{
Schema::dropIfExists('tracking_events');
}
};

View file

@ -1,22 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('return_labels', function (Blueprint $t) {
$t->id();
$t->unsignedBigInteger('order_id')->nullable()->index();
$t->string('dhl_return_no')->nullable()->index();
$t->string('label_path')->nullable();
$t->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('return_labels');
}
};

View file

@ -1,10 +0,0 @@
<?php
namespace Acme\Dhl\Models;
use Illuminate\Database\Eloquent\Model;
class ReturnLabel extends Model
{
protected $fillable = ['order_id', 'dhl_return_no', 'label_path'];
}

View file

@ -1,14 +0,0 @@
<?php
namespace Acme\Dhl\Models;
use Illuminate\Database\Eloquent\Model;
class ShipmentLabel extends Model
{
protected $fillable = ['shipment_id', 'format', 'path'];
public function shipment()
{
return $this->belongsTo(Shipment::class);
}
}

View file

@ -1,16 +0,0 @@
<?php
namespace Acme\Dhl\Models;
use Illuminate\Database\Eloquent\Model;
class TrackingEvent extends Model
{
public $timestamps = false;
protected $fillable = ['shipment_id', 'status_code', 'status_text', 'location', 'event_time', 'raw'];
protected $casts = ['raw' => 'array', 'event_time' => 'datetime',];
public function shipment()
{
return $this->belongsTo(Shipment::class);
}
}

View file

@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"master"
]
}

4
public/phpinfo.php Normal file
View file

@ -0,0 +1,4 @@
<?php
phpinfo();
?>

View file

@ -1,6 +1,7 @@
{
"MR": "Mr",
"MS": "Ms",
"DIV": "Various",
"please select": "please choose",
"please specify": "Please specify.",
"further countries": "more countrys",

View file

@ -1,6 +1,7 @@
{
"MR": "Sr.",
"MS": "Sra.",
"DIV": "Varios",
"please select": "seleccione",
"please specify": "Especifíquelo.",
"further countries": "otros paises",

View file

@ -1,109 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<div class="card">
<h6 class="card-header">
{{__('Business')}}
</h6>
<div class="card-body p-0">
{!! Form::open(['url' => route('admin_payments_invoice'), 'class' => 'form-horizontal', 'id'=>'form_filter_payment_invoices']) !!}
<div class="form-row align-items-center px-4 pb-2 pt-3">
{{-- <div class="col-12 col-sm-4 col-md-4 col-lg-4 mb-1">
<input class="form-control on_keyup_invoice" name="business_user_filter_name" type="text" value="{{session('business_user_filter_name')}}" placeholder="Name">
</div>
--}}
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
<select class="custom-select on_change_invoice" name="business_user_filter_month">
@foreach($filter_months as $key=>$value)
<option value="{{$key}}" @if(session('business_user_filter_month') == $key) selected @endif>{{$value}}</option>
@endforeach
</select>
</div>
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
<select class="custom-select on_change_invoice" name="business_user_filter_year">
@foreach($filter_years as $key=>$value)
<option value="{{$value}}" @if(session('business_user_filter_year') == $value) selected @endif>{{$value}}</option>
@endforeach
</select>
</div>
</div>
{!! Form::close() !!}
<div class="card-datatable table-responsive pt-0">
<table class="datatables-style table table-striped table-bordered" id="datatable-users">
<thead>
<tr>
<th>{{__('ID') }}</th>
<th>{{__('Berater-ID') }}</th>
<th>{{__('Points')}}</th>
<th>{{__('Points Shop')}}</th>
<th>{{__('Gesamt')}}</th>
<th>{{__('Umsatz')}}</th>
<th>{{__('Umsatz Shop')}}</th>
<th>{{__('Gesamt Shop')}}</th>
<th>{{__('E-Mail')}}</th>
<th>{{__('Vorname')}}</th>
<th>{{__('Nachname')}}</th>
<th>{{__('Level')}}</th>
<th>{{__('Mitglied')}}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<script>
$( document ).ready(function() {
var oTable = $('#datatable-users').DataTable({
"processing": true,
"serverSide": true,
"stateSave": true,
"searching": true,
ajax: {
url: '{!! route('admin_business_user_datatable') !!}',
data: function(d) {
d.business_user_filter_name = $('input[name=business_user_filter_name]').val();
d.business_user_filter_month = $('select[name=business_user_filter_month]').val();
d.business_user_filter_year = $('select[name=business_user_filter_year]').val();
}
},
"order": [[0, "asc" ]],
"columns": [
{ data: 'id', name: 'users.id', searchable: false },
{ data: 'account.m_account', name: 'account.m_account' },
{ data: 'sales_volume_points', name: 'sales_volume_points', orderable: false, searchable: false },
{ data: 'sales_volume_points_shop', name: 'sales_volume_points_shop', orderable: false, searchable: false },
{ data: 'sales_volume_points_sum', name: 'sales_volume_points_sum', orderable: false, searchable: false },
{ data: 'sales_volume_total', name: 'sales_volume_total', orderable: false, searchable: false },
{ data: 'sales_volume_total_shop', name: 'sales_volume_total_shop', orderable: false, searchable: false },
{ data: 'sales_volume_total_sum', name: 'sales_volume_total_sum', orderable: false, searchable: false },
{ data: 'email', name: 'users.email' },
{ data: 'account.first_name', name: 'account.first_name' },
{ data: 'account.last_name', name: 'account.last_name' },
{ data: 'user_level', name: 'user_level', orderable: false, searchable: false },
{ data: 'active_account', name: 'active_account' },
],
"bLengthChange": false,
"iDisplayLength": 100,
"language": {
"url": "/js/German.json"
}
});
$('select.on_change_invoice').on('change', function(){
oTable.draw();
});
$('input.on_keyup_invoice').on('keyup', function(){
oTable.draw();
});
});
/*$('#filter_sales_year').on('change', function(){
$('#form_filter_payment_invoices').submit();
});*/
</script>
@endsection

View file

@ -31,9 +31,9 @@
<tr>
<td class="font-weight-semibold">Kunde:</td>
<td>
{{ $order->user->first_name ?? '' }} {{ $order->user->last_name ?? '' }}
{{ $order->shopping_user->billing_firstname ?? '' }} {{ $order->shopping_user->billing_lastname ?? '' }}
<br>
<small class="text-muted">{{ $order->user->email ?? '' }}</small>
<small class="text-muted">{{ $order->shopping_user->billing_email ?? '' }}</small>
</td>
</tr>
<tr>
@ -42,7 +42,7 @@
</tr>
<tr>
<td class="font-weight-semibold">Bestellwert:</td>
<td><strong>{{ number_format($order->order_total, 2) }} €</strong></td>
<td><strong>{{ number_format($order->total, 2) }} €</strong></td>
</tr>
</table>
</div>
@ -51,9 +51,9 @@
<tr>
<td class="font-weight-semibold">Lieferadresse:</td>
<td>
{{ $order->shipping_first_name ?? $order->user->first_name }} {{ $order->shipping_last_name ?? $order->user->last_name }}<br>
{{ $order->shipping_street ?? $order->user->street }} {{ $order->shipping_house_number ?? $order->user->house_number }}<br>
{{ $order->shipping_postcode ?? $order->user->postcode }} {{ $order->shipping_city ?? $order->user->city }}<br>
{{ $order->shopping_user->shipping_firstname ?? $order->shopping_user->billing_firstname }} {{ $order->shopping_user->shipping_lastname ?? $order->shopping_user->billing_lastname }}<br>
{{ $order->shopping_user->shipping_address ?? $order->shopping_user->billing_address }} {{ $order->shopping_user->shipping_address_2 ?? $order->shopping_user->billing_address_2 }}<br>
{{ $order->shopping_user->shipping_zipcode ?? $order->shopping_user->billing_zipcode }} {{ $order->shopping_user->shipping_city ?? $order->shopping_user->billing_city }}<br>
{{ $order->shippingCountry->name ?? 'Deutschland' }}
</td>
</tr>
@ -67,7 +67,7 @@
</tr>
<tr>
<td class="font-weight-semibold">Artikel:</td>
<td>{{ $order->items->count() }} Artikel</td>
<td>{{ $order->shopping_order_items->count() }} Artikel</td>
</tr>
</table>
</div>
@ -97,7 +97,7 @@
</thead>
<tbody>
@php $totalWeight = 0; @endphp
@foreach($order->items as $item)
@foreach($order->shopping_order_items as $item)
@php
$itemWeight = ($item->product->weight ?? 0) * $item->qty;
$totalWeight += $itemWeight;

View file

@ -1,353 +0,0 @@
<div class="card mb-2">
<h5 class="card-header">
{{ __('Produkt') }}
</h5>
<div class="card-body">
<div class="form-group">
<label class="custom-control custom-checkbox float-right">
{!! Form::checkbox('active', 1, $product->active, ['class'=>'custom-control-input']) !!}
<span class="custom-control-label">{{__('aktiv')}}</span>
</label>
<label class="form-label" for="name">{{ __('Produktname / Titel') }}*</label>
{{ Form::text('name', $product->name, array('placeholder'=>__('Name'), 'class'=>'form-control', 'id'=>'name', 'required')) }}
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<label class="form-label" for="number">{{ __('Artikelnummer') }}</label>
{{ Form::text('number', $product->number, array('placeholder'=>__('number'), 'class'=>'form-control', 'id'=>'number')) }}
</div>
<div class="form-group col-sm-6">
<label class="form-label" for="ean">{{ __('EAN') }}</label>
{{ Form::text('ean', $product->ean, array('placeholder'=>__('EAN'), 'class'=>'form-control', 'id'=>'ean')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-10">
<label class="form-label" for="title">{{ __('Kategorie (Mehrfachauswahl)') }}*</label>
<select class="selectpicker" name="categories[]" id="categories" data-style="btn-light" data-live-search="false" multiple required>
{!! HTMLHelper::getCategoriesOptions($product->categories()->pluck('category_id')->toArray(), false) !!}
</select>
</div>
{{--
<div class="form-group col-sm-5">
<label class="form-label" for="show_at">{{ __('Produkt anzeigen') }} alt</label>
{{ Form::select('show_at', $product->showATs, $product->show_at, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'show_at') ) }}
</div>
--}}
<div class="form-group col-sm-2">
<label class="form-label" for="pos">{{ __('Listenposition') }}</label>
{{ Form::text('pos', $product->pos, array('placeholder'=>__('1, 2, 3, etc'), 'class'=>'form-control', 'id'=>'pos')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-10">
<label class="form-label" for="show_on">{{ __('Produkt anzeigen (Mehrfachauswahl)') }}</label>
{{ Form::select('show_on[]', $product->showONs, $product->show_on, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'show_on', 'multiple') ) }}
</div>
</div>
<div class="form-group">
<label class="form-label" for="copy">{{ __('Produktbeschreibung') }}</label>
{{ Form::textarea('copy', $product->copy , array('placeholder'=>__('Produktbeschreibung'), 'class'=>'form-control summernote', 'id'=>'copy')) }}
</div>
<label class="custom-control custom-checkbox float-right">
{!! Form::checkbox('shipping_addon', 1, $product->shipping_addon, ['class'=>'custom-control-input']) !!}
<span class="custom-control-label">Kompensationprodukt beim Versand für Berater</span>
</label>
</div>
</div>
<div class="card mb-2">
<h5 class="card-header">
{{ __('Preise in EUR') }}
</h5>
<div class="card-body">
<div class="form-row">
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="price">{{ __('Preis VK in EUR (Brutto)') }}</label>
{{ Form::text('price', $product->getFormattedPrice(), array('placeholder'=>__('Preis VK in EUR (Brutto)'), 'class'=>'form-control', 'id'=>'price')) }}
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="price_ek">{{ __('Preis EK in EUR') }}</label>
{{ Form::text('price_ek', $product->getFormattedPriceEk(), array('placeholder'=>__('Preis EK in EUR'), 'class'=>'form-control', 'id'=>'price_ek')) }}
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="tax">{{ __('MwSt in %') }}</label>
{{ Form::text('tax', $product->getFormattedTax(), array('placeholder'=>__('MwSt in %'), 'class'=>'form-control', 'id'=>'tax')) }}
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="price_old">{{ __('Streichpreis in EUR (wenn > 0)') }}</label>
{{ Form::text('price_old', $product->getFormattedPriceOld(), array('placeholder'=>__('Streichpreis'), 'class'=>'form-control', 'id'=>'price_old')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-4">
<label class="form-label" for="weight">{{ __('Gewicht in g') }}</label>
{{ Form::text('weight', $product->weight, array('placeholder'=>__('Gewicht in g'), 'class'=>'form-control', 'id'=>'weight')) }}
</div>
<div class="form-group col-sm-4">
<label class="form-label" for="points">{{ __('Points pro Produkt') }}</label>
{{ Form::text('points', $product->points, array('placeholder'=>__('Points pro Produkt'), 'class'=>'form-control', 'id'=>'points')) }}
</div>
<div class="form-group col-sm-4">
<label class="form-label" for="amount">{{ __('Anzahl/Verfügbarkeit') }}</label>
{{ Form::text('amount', $product->amount, array('placeholder'=>__('Anzahl/Verfügbarkeit'), 'class'=>'form-control', 'id'=>'amount')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-12">
<label class="form-label">Keine Provision</label>
<label class="custom-control custom-checkbox">
{!! Form::checkbox('no_commission', 1, $product->no_commission, ['class'=>'custom-control-input', 'id'=>'no_commission']) !!}
<span class="custom-control-label">Dieses Produkt ist nicht provisionsfähig.</span>
</label>
</div>
</div>
</div>
</div>
<div class="card mb-2">
<h5 class="card-header">
Landesspezifische Preise
</h5>
<div class="card-body pt-0">
@foreach($country_for_prices as $country)
{{ Form::hidden('country_prices[]', $country->id) }}
<div class="card-header bg-light pb-0 mt-3">
<h6>{{$country->de}}</h6>
</div>
<div class="bg-lighter p-2">
@if($country->own_eur)
<div class="form-row">
<div class="form-group col-sm-4 col-md-3">
<label class="form-label">Land hat eigenen EURO Preis</label>
<p></p>
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="price">{{ __('Preis VK in EUR Brutto') }}</label>
{{ Form::text('c_price['.$country->id.']', formatNumber($product->getCPrice($country)), array('placeholder'=>__('Preis VK in EUR Brutto'), 'class'=>'form-control', 'id'=>'c_price_'.$country->id)) }}
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="tax">{{ __('MwSt in %') }}</label>
{{ Form::text('c_tax['.$country->id.']', formatNumber($product->getCTax($country)), array('placeholder'=>__('MwSt in %'), 'class'=>'form-control', 'id'=>'c_tax'.$country->id)) }}
</div>
<div class="form-group col-sm-4 col-md-3">
<label class="form-label" for="price_old">{{ __('Streichpreis (wenn > 0)') }}</label>
{{ Form::text('c_price_old['.$country->id.']', formatNumber($product->getCPriceOld($country)), array('placeholder'=>__('Streichpreis'), 'class'=>'form-control', 'id'=>'c_price_old'.$country->id)) }}
</div>
</div>
@endif
@if($country->currency)
<div class="form-row">
<div class="form-group col-sm-4 col-md-3">
<label class="form-label">Land hat eigene Währung</label>
<p>@if($country->currency_calc) Preis Berechnung automatisch @else Preis manuell
angegeben @endif</p>
</div>
{{-- NUR Anzeige vom automatisch berechneten Preis currency_faktor
Auf Basis vom price
Wenn own_eur auf basis vom own_eur price
--}}
<div class="form-group col-sm-4 col-md-3">
<label class="form-label">Preis VK in {{ $country->currency_unit }}</label>
{{ Form::text('c_currency['.$country->id.']', formatNumber($product->getRealPrice($country) * $country->currency_faktor), array('class'=>'form-control', 'readonly')) }}
</div>
{{--@if($country->currency_calc)
@else
Eingabe
Währungs Namen aus currency_name
currency_faktor als Hinweis ausgeben
Auf Basis vom price
Wenn own_eur auf basis vom own_eur price
<div class="form-group col-sm-4 col-md-3">
<label class="form-label">{{__('Preis VK in ')}} {{ $country->currency_unit }} ({{formatNumber($product->getRealPrice($country) * $country->currency_faktor)}})</label>
{{ Form::text('c_currency['.$country->id.']', formatNumber($product->getCCurrency($country->id)), array('placeholder'=>__('Preis VK in ').$country->currency_unit, 'class'=>'form-control')) }}
</div>
@endif --}}
<div class="form-group col-sm-4 col-md-2">
<label class="form-label">{{ __('Währungs Faktor' ) }}</label>
{{ Form::text('currency_faktor['.$country->id.']', formatNumber($country->currency_faktor, 4), array('class'=>'form-control', 'readonly')) }}
</div>
<div class="form-group col-sm-4 col-md-2">
<label class="form-label">{{ __('Preis VK in EUR ') }}</label>
{{ Form::text('preis_eur['.$country->id.']', formatNumber($product->getRealPrice($country)), array('class'=>'form-control', 'readonly')) }}
</div>
<div class="form-group col-sm-4 col-md-2">
<label class="form-label">{{ __('Währung') }}</label>
{{ Form::text('currency_unit['.$country->id.']', $country->currency_unit, array('class'=>'form-control', 'readonly')) }}
</div>
</div>
@endif
</div>
@endforeach
<em class="float-right text-muted small">für die Einstellung von landesspezifischen Preisen müssen diese unter
<a href="{{route('admin_countries')}}">Länder</a> -> Land aktiviert werden.</em>
</div>
</div>
<div class="card mb-2">
<h5 class="card-header">
{{ __('Details') }}
</h5>
<div class="card-body">
<div class="form-row">
<div class="form-group col-sm-5">
<label class="form-label" for="contents">{{ __('Menge Inhalt (ml / g) als Text') }}</label>
{{ Form::text('contents', $product->contents, array('placeholder'=>__('Bsp: 150 ml'), 'class'=>'form-control', 'id'=>'contents')) }}
</div>
<div class="form-group col-sm-3">
<label class="form-label" for="contents_total">{{ __('Gesamter Inhalt (ml / g) als Zahl') }}</label>
{{ Form::text('contents_total', $product->contents_total, array('placeholder'=>__('Bsp: 150'), 'class'=>'form-control', 'id'=>'contents_total')) }}
</div>
<div class="form-group col-sm-2">
<label class="form-label" for="contents">{{ __('Grundpreis Einheit') }}</label>
{{ Form::select('unit', $product->unitTypes, $product->unit, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'unit') ) }}
</div>
<div class="form-group col-sm-2">
<label class="form-label" for="base_price">{{ __('Grundpreis') }}</label>
{{ Form::text('base_price', $product->getBasePriceFormattedFull(), array('placeholder'=>__(''), 'class'=>'form-control', 'id'=>'base_price', 'readonly')) }}
</div>
{{-- <div class="form-group col-sm-4">
<label class="form-label" for="title">{{ __('Attribute') }}</label>
<select class="selectpicker" name="attributes[]" id="attributes" data-style="btn-light"
data-live-search="false" multiple>
{!! HTMLHelper::getAttributesOptions($product->attributes()->pluck('attribute_id')->toArray()) !!}
</select>
</div>
--}}
</div>
<div class="form-group">
<label class="form-label" for="description">{{ __('Beschreibung') }}</label>
{{ Form::textarea('description', $product->description , array('placeholder'=>__('description'), 'class'=>'form-control summernote', 'id'=>'description')) }}
</div>
<div class="form-group">
<label class="form-label" for="usage">{{ __('Anwendung') }}</label>
{{ Form::textarea('usage', $product->usage , array('placeholder'=>__('usage'), 'class'=>'form-control summernote', 'id'=>'usage')) }}
</div>
<div class="form-group">
<label class="form-label" for="ingredients">{{ __('Hinweise') }}</label>
{{ Form::textarea('ingredients', $product->ingredients , array('placeholder'=>__('ingredients'), 'class'=>'form-control summernote', 'id'=>'ingredients')) }}
</div>
<div class="form-group col-sm-6">
<label class="form-label" for="icons">{{ __('Icons') }}</label>
{{ Form::text('icons', $product->icons, array('placeholder'=>__('icons'), 'class'=>'form-control', 'id'=>'icons')) }}
"product_icons_1.png"
</div>
</div>
</div>
<div class="card mb-2">
<h5 class="card-header">
{{ __('Inhalte') }}
</h5>
<div class="card-body">
<div class="card-datatable table-responsive pt-0">
<table class="datatables-style table table-striped table-bordered">
<thead>
<tr>
<th>{{__('Name')}}</th>
<th>{{__('INCI')}}</th>
<th>{{__('Wirkung') }}</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach($product->p_ingredients as $ingredient)
<tr>
<td>{{ $ingredient->name }}</td>
<td>{{ $ingredient->inci }}</td>
<td>{{ $ingredient->effect }}</td>
<td><a class="text-danger" href="{{ route('admin_product_delete', [$product->id, 'ingredient', $ingredient->id]) }}" onclick="return confirm('{{__('Eintrag entfernen?')}}');"><i class="far fa-trash-alt"></i></a></td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="form-row">
<div class="form-group col-sm-10">
<label class="form-label" for="title">{{ __('Inhaltsstoffe hinzufügen (Mehrfachauswahl)') }}</label>
<select class="selectpicker" name="product_ingredients[]" id="product_ingredients" data-style="btn-light" data-live-search="false" multiple>
{!! HTMLHelper::getProductIngredientsOptions($product->p_ingredients()->pluck('ingredient_id')->toArray()) !!}
</select>
<a class="btn btn-default btn-xs mt-2" href="{{route('admin_product_ingredients')}}">Inhaltsstoffe anlegen</a>
</div>
<div class="form-group col-sm-2">
<button type="submit" class="btn btn-submit mt-0 mt-sm-4">{{ __('save') }}</button>&nbsp;
</div>
</div>
</div>
</div>
@if(Auth::user()->isSuperAdmin())
<div class="card mb-2">
<h5 class="card-header">
{{ __('SuperAdmin Einstellungen') }}
</h5>
<div class="card-body">
<div class="form-row">
<div class="form-group col-sm-6">
<label class="form-label" for="action">{{ __('Aktion beim Zahlungsprozess') }}</label>
{{ Form::select('action[]', $product->actionNames, $product->action, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'action', 'multiple') ) }}
</div>
<div class="form-group col-sm-6">
<label class="form-label" for="identifier">{{ __('Anzeigeoptionen Zahlung Mitglieder-Accounts') }}</label>
{{ Form::select('identifier', $product->identifiers_types, $product->identifier, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'identifier') ) }}
</div>
<div class="form-group col-sm-2">
<label class="form-label" for="upgrade_to_id">{{ __('Bei Upgrade auf ID') }}</label>
{{ Form::text('upgrade_to_id', $product->upgrade_to_id, array('placeholder'=>__('Upgrade-ID'), 'class'=>'form-control', 'id'=>'upgrade_to_id')) }}
</div>
<div class="form-group col-sm-6">
@if($product->action && is_array($product->action))
@foreach ($product->action as $do )
@if($product->getActionName($do) === 'payment_for_shop_upgrade')
<label class="form-label" for="">{{ __('Upgrade auf das Produkt') }} <span class="small">(Wird nach dem Speichern aktualisiert)</span></label>
<div class="mt-2"><strong>{{ $product->getUpgradeToIdName('payment_for_shop_upgrade') }}</strong>
</div>
@endif
@if($product->getActionName($do) === 'payment_for_lead_upgrade')
<label class="form-label" for="">{{ __('Upgrade auf Karriere Level') }} <span class="small">(Wird nach dem Speichern aktualisiert)</span></label>
<div class="mt-2"><strong>{{ $product->getUpgradeToIdName('payment_for_lead_upgrade') }}</strong>
@endif
@endforeach
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-5">
<label class="form-label" for="wp_number">WP Artikel Number (als Zahl ohne Leerzeichen für die WP-API)</label>
{{ Form::text('wp_number', $product->wp_number, array('placeholder'=>__('WP Number'), 'class'=>'form-control', 'id'=>'wp_number')) }}
</div>
</div>
</div>
</div>
@endif

View file

@ -1,124 +0,0 @@
<style>
/* Basis-Styles */
.btn-md-extra {
padding: 0.3rem 0.6rem;
font-size: 0.8rem;
line-height: 1.5;
border-radius: 0.25rem;
}
.md-btn-extra {
width: calc(1.7rem + 2px) !important;
line-height: 1.5rem;
}
.form-control.input-extra {
padding: 0.28rem 0.6rem;
font-size: 0.8rem;
font-weight: 600;
min-height: calc(1.8rem + 2px);
height: calc(1.8rem + 2px);
width: 44px;
}
.form-control.input-extra.active {
background-color: #f0f0f0;
}
.input-group-min-w {
min-width: 102px;
}
.img-extra {
min-width: 55px;
max-height: 160px;
}
.product-active {
opacity: 1;
}
.product-inactive {
opacity: 0.6;
}
/* Mobile Optimierungen */
@media (max-width: 767px) {
.table thead {
display: none;
}
.table, .table tbody, .table tr, .table td {
display: block;
width: 100%;
}
.table tr {
margin-bottom: 1.5rem;
border: 1px solid #dee2e6;
border-radius: 0.25rem;
padding: 1rem;
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.table td {
border: none;
padding: 0.75rem 0;
position: relative;
padding-left: 50%;
}
.table td:before {
content: attr(data-label);
position: absolute;
left: 0;
width: 45%;
padding-right: 1rem;
font-weight: 600;
color: #666;
}
.table td:first-child {
padding-top: 1rem;
}
.table td:last-child {
padding-bottom: 1rem;
}
.media {
flex-direction: column;
align-items: flex-start !important;
}
.media img {
margin-bottom: 1rem;
margin-right: 0 !important;
max-width: 100%;
height: auto;
}
.media-body {
width: 100%;
}
.input-group-min-w {
min-width: auto;
width: 100%;
}
.input-group {
width: 100% !important;
justify-content: center;
}
.form-control.input-extra {
width: 60px;
}
.no-line-break {
white-space: normal;
}
}
</style>

View file

@ -1,117 +0,0 @@
@props([
'products' => [],
'productType' => 'base', // 'base' oder 'upgrade'
'formRoute' => '',
'formStep' => 3
])
{!! Form::open(['action' => route($formRoute, $formStep), 'method' => 'POST', 'class' => '']) !!}
@include('components.abo.product-table-styles')
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('payment.ordering_country') }}</div>
{{ App\Services\UserService::getOrderInfo('billing_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('payment.country_of_delivery') }}</div>
{{ App\Services\UserService::getOrderInfo('shipping_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('payment.VAT') }}</div>
{{ App\Services\UserService::getOrderInfo('tax_free') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('payment.reverse_charge_procedure') }}</div>
{{ App\Services\UserService::getOrderInfo('user_reverse_charge') }}
</div>
</div>
@if($productType === 'base')
<div class="alert alert-warning">
<strong>{!! __('abo.abo_type_info', ['base'=>get_abo_type_badge('base'), 'upgrade'=>get_abo_type_badge('upgrade')]) !!}</strong>
</div>
@if(isset($error))
<div class="alert alert-danger">
<strong>{{ $error }}</strong>
</div>
@endif
@endif
@if(count($products) > 0)
<div class="table-responsive">
<table class="table table- m-0">
<thead>
<tr>
<th>{{ __('abo.' . $productType . '_product') }}</th>
<th>&nbsp;</th>
<th class="text-right">{{ __('order.unit_price') }}</th>
</tr>
</thead>
<tbody>
@foreach($products as $product)
<tr>
<td class="text-center align-middle px-0" data-label="{{ __('abo.' . $productType . '_product') }}">
<div class="no-line-break input-group-min-w">
<div class="input-group d-inline-flex w-auto">
<span class="input-group-prepend">
<button type="button" class="btn btn-secondary icon-btn md-btn-extra remove-product-qty"
data-row-id="{{ $product->id }}"
data-product-id="{{ $product->id }}">-</button>
</span>
<input type="text"
class="form-control text-center input-extra table-input-event-onchange"
name="{{ $productType }}_product_qty[{{ $product->id }}]"
data-row-id="{{ $product->id }}"
data-product-id="{{ $product->id }}"
value="0">
<span class="input-group-append">
<button type="button" class="btn btn-secondary icon-btn md-btn-extra add-product-qty"
data-row-id="{{ $product->id }}"
data-product-id="{{ $product->id }}">+</button>
</span>
</div>
</div>
</td>
<td class="p-4" data-label="">
<div class="media align-items-center product-inactive" id="product-{{ $product->id }}">
@if(count($product->images))
<img src="{{ route('product_image', [$product->images->first()->slug]) }}"
class="d-block ui-w-100 ui-bordered mr-4"
alt="{{ $product->getLang('name') }}">
@endif
<div class="media-body">
<h5 class="d-block text-dark">
{{$product->getLang('name')}}
<br>{!! get_abo_type_badge($productType) !!}
</h5>
{!! $product->getLang('copy') !!}
</div>
</div>
</td>
<td class="text-right font-weight-semibold align-middle p-4" data-label="{{ __('order.unit_price') }}">
<span class="no-line-break">
{{ $product->getFormattedPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country) }} €
</span>
@if(\App\Services\UserService::$user_country && \App\Services\UserService::$user_country->currency)
<span class="no-line-break">
{!! $product->getFormattedPriceCurrencyWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country) !!}
</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
<div class="card-footer">
<button type="submit" class="btn btn-secondary" name="action" value="next">{{ __('abo.confirm_and_next') }}</button>
</div>
{!! Form::close() !!}

View file

@ -1,62 +0,0 @@
@if($user->active == 1)
@if($user->payment_account && $user->daysActiveAccount() <= config('mivita.remind_first_days'))
<div class="d-flex col-xl-12 align-items-stretch">
<!-- SHOP -->
<div class="card w-100 mb-4">
<h5 class="card-header">
{{__('membership.home_hl') }}
</h5>
<div class="card-body">
@if($user->daysActiveAccount() <= 0)
@if($user->isActiveAccount())
<h5 class="alert badge-danger">{{__('membership.home_copy_alert_35')}}</h5>
<p>{{__('membership.home_copy_last_35', ['days'=>$user->daysActiveAccount(), 'datetime'=>$user->getPaymentAccountDateFormat()])}}</p>
@else
{{-- 35, 36 --}}
@if($user->daysActiveAccount() == 0)
<h5 class="alert badge-danger">{{__('membership.home_copy_alert_36_today', ['datetime'=>$user->getPaymentAccountDateFormat()])}}</h5>
@else
<h5 class="alert badge-danger">{{__('membership.home_copy_alert_36', ['days'=>$user->daysActiveAccount()*-1, 'datetime'=>$user->getPaymentAccountDateFormat()])}}</h5>
@endif
@if($user->payment_account && $user->isAboOption())
{{ __('membership.home_copy_SEPA_36', ['price'=> 'von '.$user->payment_order_product->getFormattedPrice().' EUR', 'pay_date'=>Carbon::parse($user->payment_account)->modify('- '.config('mivita.abo_booking_days').' days')->format('d.m.Y')]) }}
<hr>
@endif
<p>{{__('membership.home_copy_last_36', ['days'=>$user->daysActiveAccount(), 'datetime'=>$user->getPaymentAccountDateFormat()])}}</p>
@endif
@elseif($user->daysActiveAccount() < config('mivita.remind_last_days') )
{{-- 33 --}}
<h5 class="alert badge-warning">{{ __('membership.home_copy_alert_31', ['datetime'=>$user->getPaymentAccountDateFormat()]) }}</h5>
<p>{{__('membership.home_copy_last_34', ['days'=>$user->daysActiveAccount(), 'datetime'=>$user->getPaymentAccountDateFormat()])}}</p>
@elseif($user->daysActiveAccount() < config('mivita.remind_sec_days'))
{{-- 33 --}}
<h5 class="alert badge-warning">{{ __('membership.home_copy_alert_31', ['datetime'=>$user->getPaymentAccountDateFormat()]) }}</h5>
@if($user->payment_account && $user->isAboOption())
@if($user->daysActiveAccount() < config('mivita.abo_booking_days') )
<p>{{ __('membership.home_copy_SEPA_33', ['price'=> 'von '.$user->payment_order_product->getFormattedPrice().' EUR', 'pay_date'=>Carbon::parse($user->payment_account)->modify('- '.config('mivita.abo_booking_days').' days')->format('d.m.Y')]) }}</p>
@else
<p>{{ __('membership.home_copy_SEPA_32', ['price'=> 'von '.$user->payment_order_product->getFormattedPrice().' EUR', 'pay_date'=>Carbon::parse($user->payment_account)->modify('- '.config('mivita.abo_booking_days').' days')->format('d.m.Y')]) }}</p>
@endif
<hr>
@endif
<p>{{__('membership.home_copy_last_33', ['days'=>$user->daysActiveAccount()])}}</p>
@else
{{-- 32 / 31 --}}
<h5 class="alert badge-default">{{ __('membership.home_copy_alert_31', ['datetime'=>$user->getPaymentAccountDateFormat()]) }}</h5>
@if($user->payment_account && $user->isAboOption())
{{ __('membership.home_copy_SEPA_32', ['price'=> 'von '.$user->payment_order_product->getFormattedPrice().' EUR', 'pay_date'=>Carbon::parse($user->payment_account)->modify('- '.config('mivita.abo_booking_days').' days')->format('d.m.Y')]) }}
<hr>
@endif
<p>{{__('membership.home_copy_last_31', ['days'=>$user->daysActiveAccount()])}}</p>
@endif
</div>
<div class="card-footer py-3">
<a href="{{route('user_membership')}}" class="btn btn-info mb-3"><i class="ion ion-ios-refresh text-default mr-1"></i> Mitgliedschaft jetzt hier verwalten</a>
</div>
</div>
<!-- / SHOP -->
</div>
@endif
@endif

View file

@ -1,227 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>mivita.care</title>
<style type="text/css">
img {
max-width: 600px;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
a {
text-decoration: none;
border: 0;
outline: none;
color: #919f7a;
}
a:hover {
color: #b6b600;
}
a img {
border: none;
}
td, h1, h2, h3 {
font-family: Helvetica, Verdana, Arial, sans-serif;
font-weight: 400;
}
td {
text-align: center;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
width: 100%;
height: 100%;
color: #37302d;
background: #ffffff;
font-size: 15px;
line-height: 26px
}
table {
border-collapse: collapse !important;
}
.headline {
color: #37302d;
font-size: 16px;
}
.force-full-width {
width: 100% !important;
}
</style>
</head>
<body class="body" style="padding:0; margin:0; display:block; background:#f8f8f8; -webkit-text-size-adjust:none" bgcolor="#f8f8f8">
<div style="display: none; mso-hide: all; width: 0px; height: 0px; max-width: 0px; max-height: 0px; font-size: 0px; line-height: 0px;">
@if(isset($copy1line))
{{ strip_tags($copy1line) }}
@endif
@if(isset($content))
{{ strip_tags($content) }}
@endif
</div>
<table align="center" cellpadding="0" cellspacing="0" width="100%" height="100%">
<tr>
<td align="center" valign="top" bgcolor="#f8f8f8" width="100%">
<center>
<br>
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="700" class="w320">
<tr>
<td align="center" valign="top">
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td style=" text-align:center;">
<center>
<table width="100%" cellpadding="0" cellspacing="0" border="0" class="">
<tbody class="">
<tr class="">
<td align="center" valign="top" style="font-size: 0px;" class="">
<picture class="">
<img src="https://my.mivita.care/images/logo_mivita.png" alt="mivita.care" style="border:none" width="230">
</picture>
</td>
</tr>
<tr>
<td><br></td>
</tr>
</tbody>
</table>
</center>
</td>
</tr>
</table>
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="100%"
bgcolor="#ffffff">
<tr>
<td class="headline" align="center">
<br><br>
<b>{{ $salutation }} </b>
</td>
</tr>
@if(isset($copy1line))
<tr>
<td>
<center>
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="90%">
<tr>
<td style="color:#37302d;line-height:1.6em;" align="center">
<br>
{!! nl2br($copy1line) !!}
<br>
<br>
</td>
</tr>
</table>
</center>
</td>
</tr>
@endif
@if(isset($content))
<tr>
<td>
<table style="padding: 20px;line-height:1.6em; border:1px solid #eee; background-color: #f6fdf5" cellpadding="2" cellspacing="0" align="center" width="100%">
<tr>
<td>
{!! nl2br($content) !!}
</td>
</tr>
</table>
</td>
</tr>
@endif
<tr>
<td>
<center>
<table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="word-wrap:break-word;background:transparent;font-size:0px;padding:10px 25px;padding-top:15px;padding-bottom:15px;padding-right:40px;padding-left:40px;" align="center" valign="top" background="data:image/gif;base64,">
<table role="presentation" cellpadding="0" cellspacing="0" align="center" border="0">
<tbody>
<tr>
<td style="border:none;border-radius:20px;color:#ffffff;cursor:auto;padding:15px 25px;" align="center" valign="middle" bgcolor="#b5c49b">
<p style="text-decoration:none;background:#b5c49b;color:#ffffff;font-family:Arial, sans-serif;font-size:13px;font-weight:normal;line-height:120%;text-transform:none;margin:0px;">
<a href="{{ $url }}" style="color:#ffffff;font-size:14px;font-weight:bold;text-align:center;text-decoration:none;-webkit-text-size-adjust:none;">{{ $button }}</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</center>
</td>
<tr>
<tr>
<td style="color:#37302d;font-size: 14px;">
<center>
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="90%">
<tr>
<td style="color:#37302d;padding:20px;line-height:1.6em" align="center">
<br>
{{ $copy2line }}<br>
<span style="color: #cabda9; font-weight: normal; font-size: 13px; text-decoration: underline; word-wrap: break-word;white-space: pre-line;">{{ $url }}</span>
<br><br>
{{ $copy3line }}
<br><br>
{{ $greetings }} <br><b>{{ $sender }}</b>
<br>
</td>
</tr>
<tr>
<td><br></td>
</tr>
</table>
</center>
</td>
</tr>
</table>
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" class="force-full-width"
bgcolor="#f8f8f8">
<tr>
<td style="color:#7B7B7E; font-size:14px;padding:20px;line-height:1.6em" align="center">
<p>
{{__('email.footer_copy1')}}
</p>
<br>
<a href="https://www.mivita.care" style="color: #7B7B7E; text-decoration: underline;">www.mivita.care</a>
<br>
</td>
</tr>
<tr>
<td style="color:#bbbbbb; font-size:12px;padding:20px;line-height:1.6em" align="center">
<p>{{__('email.footer_copy2')}}</p>
<a href="https://www.mivita.care/datenschutz">{{ __('dataprotect.data_protect') }}</a> <br>
<p>{{__('email.footer_copy3')}}</p>
<br>
<br>
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,71 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="light-style">
<head>
<title>404 Not Found - Appwork</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="{{ asset('/fonts/roboto-pacifico.css?v=1') }}">
<!-- Icons. Uncomment required icon fonts -->
<link rel="stylesheet" href="{{ mix('/vendor/fonts/fontawesome.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/ionicons.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/linearicons.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/open-iconic.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/pe-icon-7-stroke.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/bootstrap.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/appwork.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/theme-corporate.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/colors.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/uikit.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/css/mycolors.css') }}">
<script src="assets/vendor/js/material-ripple.js"></script>
<script src="{{ mix('/vendor/js/layout-helpers.js') }}"></script>
<!-- Core scripts -->
<script src="{{ asset('/js/jquery.min.js') }}"></script>
<!-- Page -->
<link rel="stylesheet" href="{{ asset('/vendor/css/error.css') }}">
</head>
<body class="bg-primary">
<div class="overflow-hidden">
<div class="container d-flex align-items-stretch ui-mh-100vh p-0">
<div class="row w-100">
<div class="d-flex col-md justify-content-center align-items-center order-2 order-md-1 position-relative p-5">
<div class="error-bg-skew theme-bg-white"></div>
<div class="text-md-left text-center">
<h1 class="display-2 font-weight-bolder mb-4">Whoops...</h1>
<div class="text-xlarge font-weight-light mb-5">We couldn't find the page<br> you are looking for :(</div>
<button type="button" class="btn btn-primary">←&nbsp; Go Back</button>
</div>
</div>
<div class="d-flex col-md-5 justify-content-center align-items-center order-1 order-md-2 text-center text-white p-5">
<div>
<div class="error-code font-weight-bolder mb-2">404</div>
<div class="error-description font-weight-light">Not Found</div>
</div>
</div>
</div>
</div>
</div>
<!-- Core scripts -->
<script src="assets/vendor/libs/popper/popper.js"></script>
<script src="assets/vendor/js/bootstrap.js"></script>
</body>
</html>

View file

@ -1,114 +0,0 @@
@extends('portal.layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold py-2 mb-2">
{{__('abo.create_abo')}}
</h4>
<div id="smartwizard" class="smartwizard-abo">
<ul class="card px-4 pt-3 mb-3">
<li>
<a href="#smartwizard-step-0" class="mb-3">
<span class="sw-done-icon ion ion-md-checkmark"></span>
<span class="sw-number">1</span>
{{__('abo.abo')}}
<div class="text-muted small">{{__('abo.info')}}</div>
</a>
</li>
<li>
<a href="#smartwizard-step-1" class="mb-3">
<span class="sw-done-icon ion ion-md-checkmark"></span>
<span class="sw-number">1</span>
{{__('abo.data')}}
<div class="text-muted small">{{__('abo.check')}}</div>
</a>
</li>
<li>
<a href="#smartwizard-step-2" class="mb-3">
<span class="sw-done-icon ion ion-md-checkmark"></span>
<span class="sw-number">2</span>
{{__('abo.basis_product')}}
<div class="text-muted small">{{__('abo.choose')}}</div>
</a>
</li>
<li>
<a href="#smartwizard-step-3" class="mb-3">
<span class="sw-done-icon ion ion-md-checkmark"></span>
<span class="sw-number">3</span>
{{__('abo.upgrade_products')}}
<div class="text-muted small">{{__('abo.choose')}}</div>
</a>
</li>
<li>
<a href="#smartwizard-step-4" class="mb-3">
<span class="sw-done-icon ion ion-md-checkmark"></span>
<span class="sw-number">4</span>
{{__('abo.check')}}
<div class="text-muted small">{{__('abo.order')}}</div>
</a>
</li>
</ul>
<div class="mb-3">
<div id="smartwizard-step-0" class="card animated fadeIn">
@include('portal.abo._create_info')
</div>
<div id="smartwizard-step-1" class="card animated fadeIn">
</div>
<div id="smartwizard-step-2" class="card animated fadeIn">
</div>
<div id="smartwizard-step-3" class="card animated fadeIn">
</div>
<div id="smartwizard-step-4" class="card animated fadeIn">
</div>
</div>
</div>
@endsection
@section('scripts')
<link rel="stylesheet" href="{{ mix('/vendor/libs/smartwizard/smartwizard.css') }}">
<script src="{{ mix('/vendor/libs/smartwizard/smartwizard.js') }}"></script>
<script>
$( document ).ready(function() {
$('.smartwizard-abo').smartWizard({
autoAdjustHeight: true,
backButtonSupport: true,
useURLhash: false,
showStepURLhash: false,
selected: '{{$step}}',
toolbarSettings: {
showNextButton: false,
showPreviousButton: false,
}
});
});
</script>
@endsection

View file

@ -1,437 +0,0 @@
<div class="card mb-4">
<h5 class="card-header">
<div class="row">
<div class="col-xs-12 col-sm-6">
{{ __('customer.customer_billing_address') }}
</div>
<div class="col-xs-12 col-sm-6">
<span class="text-tiny float-right">* {{trans('register.required_fields')}}</span>
<span class="d-none d-lg-inline">{{ __('Delivery address') }}</span>
</div>
</div>
</h5>
<div class="card-body">
<div class="row">
<div class="col-12 col-lg-6">
<div class="form-row">
<div class="form-group col-md-12">
<label for="billing_company" class="form-label">{{ __('Company name') }} ({{__('optional')}})</label>
{{ Form::text('billing_company', $shopping_user->billing_company, array('placeholder'=>__('Company name'), 'class'=>'form-control', 'id'=>'billing_company', 'tabindex' => 1)) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('billing_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="billing_salutation" id="billing_salutation" required tabindex="2">
{!! HTMLHelper::getSalutation($shopping_user->billing_salutation) !!}
</select>
@if ($errors->has('billing_salutation'))
<span class="help-block">
<strong>{{ $errors->first('billing_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('billing_firstname') ? 'has-error' : '' }}">
<label class="form-label" for="billing_firstname">{{ __('First name') }}*</label>
{{ Form::text('billing_firstname', $shopping_user->billing_firstname, array('placeholder'=>__('First name'), 'class'=>'form-control', 'id'=>'billing_firstname', 'required'=>true, 'tabindex' => 4)) }}
@if ($errors->has('billing_firstname'))
<span class="help-block">
<strong>{{ $errors->first('billing_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('billing_lastname') ? 'has-error' : '' }}">
<label class="form-label" for="billing_lastname">{{ __('Last name') }}*</label>
{{ Form::text('billing_lastname', $shopping_user->billing_lastname, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'id'=>'billing_lastname', 'required'=>true, 'tabindex' => 5)) }}
@if ($errors->has('billing_lastname'))
<span class="help-block">
<strong>{{ $errors->first('billing_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('billing_address') ? 'has-error' : '' }}">
<label class="form-label" for="billing_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('billing_address', $shopping_user->billing_address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true, 'id'=>'billing_address', 'tabindex' => 6)) }}
@if ($errors->has('billing_address'))
<span class="help-block">
<strong>{{ $errors->first('billing_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('billing_address_2') ? 'has-error' : '' }}">
<label class="form-label" for="billing_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('billing_address_2', $shopping_user->billing_address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control', 'id'=>'billing_address_2', 'tabindex' => 6)) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('billing_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for="billing_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('billing_zipcode', $shopping_user->billing_zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true, 'id'=>'billing_zipcode', 'tabindex' => 7)) }}
@if ($errors->has('billing_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('billing_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('billing_city') ? 'has-error' : '' }}">
<label class="form-label" for="billing_city">{{ __('City') }}*</label>
{{ Form::text('billing_city', $shopping_user->billing_city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true, 'id'=>'billing_city', 'tabindex' => 8)) }}
@if ($errors->has('billing_city'))
<span class="help-block">
<strong>{{ $errors->first('billing_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('billing_country_id') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Country') }}*</label>
<select class="selectpicker" name="billing_country_id" id="billing_country_id" data-style="btn-light" data-live-search="true" required tabindex="9">
{!! HTMLHelper::getContriesWithMore($shopping_user->billing_country_id) !!}
</select>
@if ($errors->has('billing_country_id'))
<span class="help-block">
<strong>{{ $errors->first('billing_country_id') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('billing_phone') ? 'has-error' : '' }}">
<label class="form-label" for="billing_phone">{{ __('Phone') }}</label>
{{ Form::text('billing_phone', $shopping_user->billing_phone, array('placeholder'=>__('Phone'), 'class'=>'form-control', 'id'=>'billing_phone', 'tabindex' => 11)) }}
</div>
</div>
</div>
<div class="col-12 col-lg-6">
<div class="d-md-block d-lg-none">
<hr>
<h5 class="mt-4">{{ __('Delivery address') }}</h5>
</div>
<div id="show_shipping_address" style="@if($shopping_user->same_as_billing) display:none @endif">
<div class="form-row">
<div class="form-group col-md-12">
<label for="shipping_company" class="form-label">{{ __('Company name') }} ({{__('optional')}})</label>
{{ Form::text('shipping_company', $shopping_user->shipping_company, array('placeholder'=>__('Company name'), 'class'=>'form-control', 'id'=>'shipping_company', 'tabindex' => 16)) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="shipping_salutation" id="shipping_salutation" required tabindex="17">
{!! HTMLHelper::getSalutation($shopping_user->shipping_salutation) !!}
</select>
@if ($errors->has('shipping_salutation'))
<span class="help-block">
<strong>{{ $errors->first('shipping_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_firstname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_firstname">{{ __('First name') }}*</label>
{{ Form::text('shipping_firstname', $shopping_user->shipping_firstname, array('placeholder'=>__('First name'), 'class'=>'form-control', 'required'=>true, 'id'=>'shipping_firstname', 'tabindex' => 18)) }}
@if ($errors->has('shipping_firstname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_lastname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_lastname">{{ __('Last name') }}*</label>
{{ Form::text('shipping_lastname', $shopping_user->shipping_lastname, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'required'=>true, 'id'=>'shipping_lastname', 'tabindex' => 19)) }}
@if ($errors->has('shipping_lastname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('shipping_address', $shopping_user->shipping_address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true, 'id'=>'shipping_address', 'tabindex' => 20)) }}
@if ($errors->has('shipping_address'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address_2') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('shipping_address_2', $shopping_user->shipping_address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control', 'id'=>'shipping_address_2', 'tabindex' => 21)) }}
@if ($errors->has('shipping_address_2'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address_2') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('shipping_zipcode', $shopping_user->shipping_zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true, 'id'=>'shipping_zipcode', 'tabindex' => 22)) }}
@if ($errors->has('shipping_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('shipping_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_city') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_city">{{ __('City') }}*</label>
{{ Form::text('shipping_city', $shopping_user->shipping_city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true, 'id'=>'shipping_city', 'tabindex' => 23)) }}
@if ($errors->has('shipping_city'))
<span class="help-block">
<strong>{{ $errors->first('shipping_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_country_id') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Country') }}*</label>
<select class="selectpicker" name="shipping_country_id" id="shipping_country_id" data-style="btn-light" data-live-search="true" required tabindex="24">
{!! HTMLHelper::getContriesWithMore($shopping_user->shipping_country_id) !!}
</select>
@if ($errors->has('shipping_country_id'))
<span class="help-block">
<strong>{{ $errors->first('shipping_country_id') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="shipping_phone">{{ __('Phone') }}</label>
{{ Form::text('shipping_phone', $shopping_user->shipping_phone, array('placeholder'=>__('Phone'), 'class'=>'form-control', 'id'=>'shipping_phone', 'tabindex' => 26)) }}
</div>
</div>
</div>
<div class="form-group">
<label class="custom-control custom-checkbox m-0">
<input type="checkbox" class="custom-control-input" name="same_as_billing" id="same_as_billing" @if($shopping_user->same_as_billing) checked="checked" @endif>
<span class="custom-control-label">{{__('Shipping to the same address')}}</span>
</label>
</div>
<hr>
</div>
</div>
@if($isView === 'customer')
@endif
<div class="card mb-4">
<div class="card-body">
<div class="form-group">
<label class="custom-control custom-checkbox m-0">
<input type="checkbox" class="custom-control-input" name="has_buyed" id="has_buyed" @if($shopping_user->has_buyed) checked="checked" @endif>
<span class="custom-control-label">{{ __('customer.customer_has_already_buy') }}</span>
</label>
</div>
<div class="alert alert-warning mt-3" id="show_has_buyed" style="display: @if($shopping_user->has_buyed) block @else none @endif;">
<label class="custom-control custom-checkbox m-0">
<input type="checkbox" class="custom-control-input" name="subscribed" id="subscribed" @if($shopping_user->subscribed) checked="checked" @endif >
<span class="custom-control-label">{{ __('customer.newsletter_subscribed_copy1') }}</span>
</label>
</div>
</div>
</div>
<hr>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="remarks">{{ __('Comments') }}</label>
{{ Form::textarea('remarks', $shopping_user->remarks, array('placeholder'=>__('Comments'), 'class'=>'form-control', 'rows'=>4, 'id'=>'remarks')) }}
</div>
</div>
<hr>
{{ Form::hidden('faker_mail', $shopping_user->faker_mail) }}
{{ Form::hidden('language', $shopping_user->language) }}
@if($isView === 'customer-add')
{{ Form::hidden('billing_email_1', $billing_email) }}
{{ Form::hidden('billing_email-confirm_1', $billing_email) }}
@if($shopping_user->faker_mail)
{{ Form::hidden('billing_email', $billing_email) }}
{{ Form::hidden('billing_email-confirm', $billing_email) }}
@else
<div class="form-row">
<div class="form-group col-md-6">
<label class="form-label" for="billing_email">{{ __('E-Mail Address') }}*</label>
{{ Form::text('billing_email', $billing_email, array('placeholder'=>'E-Mail', 'class'=>'form-control', 'id'=>'billing_email', 'readonly')) }}
</div>
<div class="form-group col-md-6">
<label class="form-label" for="billing_email-confirm">{{ __('Confirm E-Mail') }}*</label>
{{ Form::text('billing_email-confirm', $billing_email, array('placeholder'=>__('Confirm E-Mail'), 'class'=>'form-control', 'id'=>'billing_email-confirm', 'readonly')) }}
</div>
</div>
@endif
@else
@if($shopping_user->faker_mail)
{{ Form::hidden('billing_email', $shopping_user->billing_email) }}
{{ Form::hidden('billing_email-confirm', $shopping_user->billing_email) }}
@if($isAdmin != 1)
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
<h6 class="card-header bg-light">
<a href="#" class="" data-toggle="collapse" data-target="#collapseNewMailAddress" aria-expanded="@if($errors->has('new_email_address')) true @else false @endif" aria-controls="collapseNewMailAddress">
<i class="fa fa-caret-expand"></i> {{ __('E-Mail Address') }} {{ __('add') }}
</a>
</h6>
<div class="collapse @if($errors->has('new_email_address')) show @endif" id="collapseNewMailAddress">
<div class="form-row mt-2 mb-0">
<div class="form-group col-md-12 {{ $errors->has('new_email_address') ? 'has-error' : '' }}">
<label class="form-label" for="new_email_address">{{ __('E-Mail Address') }}*</label>
{{ Form::text('new_email_address', '', array('placeholder'=>__('E-Mail Address'), 'class'=>'form-control', 'id'=>'new_email_address', 'required'=>true ,'tabindex' => 1)) }}
@if ($errors->has('new_email_address'))
<span class="help-block">
<strong>{{ $errors->first('new_email_address') }}</strong>
</span>
@endif
<p class="mt-2">{{ __('customer.customer_sovereignty_info1') }}</p>
<button type="submit" class="btn btn-secondary btn-sm" name="action" value="add-mail-shopping-user-store">{{ __('E-Mail Address') }} {{ __('customer.check_and_save') }}</button>
</div>
</div>
</div>
@endif
@else
<div class="form-row">
<div class="form-group col-md-6">
<label class="form-label" for="billing_email">{{ __('E-Mail Address') }}*</label>
{{ Form::text('billing_email', $shopping_user->billing_email, array('placeholder'=>'E-Mail', 'class'=>'form-control', 'id'=>'billing_email')) }}
</div>
<div class="form-group col-md-6">
<label class="form-label" for="billing_email-confirm">{{ __('Confirm E-Mail') }}</label>
{{ Form::text('billing_email-confirm', $shopping_user->billing_email, array('placeholder'=>__('Confirm E-Mail'), 'class'=>'form-control', 'id'=>'billing_email-confirm')) }}
</div>
</div>
@endif
@endif
</div>
</div>
<script type="application/javascript">
$( document ).ready(function() {
$('input#has_buyed').on('change', function () {
if($(this).prop('checked')){
$('input#subscribed').prop('checked', true);
$('#show_has_buyed').show('slow');
}else{
$('input#subscribed').prop('checked', false);
$('#show_has_buyed').hide('slow');
}
});
// Shipping Address show|hide
$("#same_as_billing").on("change", function () {
$('#show_shipping_address').slideToggle(200, function () {
// scroll down to shipping area.
if ($('#show_shipping_address').is(":visible")) {
_scrollTo('#show_shipping_address', 20);
}
});
});
$.extend( $.validator.messages, {
required: "{{__('account.validator_required')}}",
maxlength: $.validator.format( "{{__('account.validator_maxlength')}}" ),
minlength: $.validator.format( "{{__('account.validator_minlength')}}" ),
rangelength: $.validator.format( "{{__('account.validator_rangelength')}}" ),
email: "{{__('account.validator_email')}}",
url: "{{__('account.validator_url')}}",
date: "{{__('account.validator_date')}}",
number: "{{__('account.validator_number')}}",
digits: "{{__('account.validator_digits')}}",
equalTo: "{{__('account.validator_equalTo')}}",
range: $.validator.format( "{{__('account.validator_range')}}" ),
max: $.validator.format( "{{__('account.validator_max')}}" ),
min: $.validator.format( "{{__('account.validator_min')}}" ),
creditcard: "{{__('account.validator_creditcard')}}"
});
// Set up validator
$('#lead-form-validation').validate({
rules: {
'billing_email-confirm': {
required: true,
equalTo: "#billing_email"
},
},
errorPlacement: function errorPlacement(error, element) {
$(element).parents('.form-group').append(
error.addClass('invalid-feedback small d-block')
)
},
highlight: function (element) {
if ($(element).hasClass('selectpicker')) {
$(element).parent().addClass('is-invalid');
}
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
$(element).parents('.form-group').find('.is-invalid').removeClass('is-invalid');
},
messages : {
required: "{{__('This field is required.')}}",
country_id : {
required: "{{__('This field is required.')}}",
},
salutation : {
required: "{{__('please specify')}}",
},
first_name : {
required: "{{__('This field is required.')}}",
},
last_name : {
required: "{{__('This field is required.')}}",
},
zipcode : {
required: "{{__('This field is required.')}}",
},
address : {
required: "{{__('This field is required.')}}",
},
city : {
required: "{{__('This field is required.')}}",
},
equalTo : "{{__('Please enter the same value again.')}}",
'billing_email-confirm' : {
equalTo : "{{__('Please enter the same value again.')}}",
required: "{{__('This field is required.')}}",
},
billing_email: {
required : "{{__('This field is required.')}}",
email: "{{ __('Please enter a valid email address.') }}",
remote : "{{ __('This E-mail is already in use.') }}"
},
},
onkeyup: false
});
});
</script>

View file

@ -1,192 +0,0 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}" class="default-style layout-collapsed">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name') }}</title>
<!-- Main font -->
<link rel="stylesheet" href="{{ asset('/fonts/roboto-pacifico.css?v=1') }}">
<!-- Icons. Uncomment required icon fonts -->
<link rel="stylesheet" href="{{ mix('/vendor/fonts/fontawesome.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/ionicons.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/linearicons.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/open-iconic.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/fonts/pe-icon-7-stroke.css') }}">
<!-- Core stylesheets -->
<link rel="stylesheet" href="{{ mix('/vendor/css/bootstrap.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/appwork.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/theme-corporate.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/colors.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/css/uikit.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/css/mycolors.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/libs/growl/growl.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/libs/bootstrap-select/bootstrap-select.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/libs/select2/select2.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/libs/datatables/datatables.css') }}">
<link rel="stylesheet" href="{{ mix('/vendor/libs/bootstrap-datepicker/bootstrap-datepicker.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/libs/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/libs/summernote/dist/summernote-bs4.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/libs/slim-image-cropper/slim/slim.css') }}">
<link rel="stylesheet" href="{{ asset('/vendor/libs/dropzone/dropzone.css?v=1') }}">
<!-- Layout helpers -->
<script src="{{ mix('/vendor/js/layout-helpers.js') }}"></script>
<!-- Libs -->
<!-- `perfect-scrollbar` library required by SideNav plugin -->
<link rel="stylesheet" href="{{ mix('/vendor/libs/perfect-scrollbar/perfect-scrollbar.css') }}">
@yield('styles')
<!-- Application stylesheets -->
<link rel="stylesheet" href="{{ mix('/css/application.css') }}?v=1{{ get_file_last_time('css/application.css') }}">
<script src="{{ asset('/js/jquery.min.js') }}"></script>
<link rel="stylesheet" type="text/css" href="{{ asset('/css/cookieconsent.min.css') }}" />
<script src="{{ asset('/js/cookieconsent.min.js') }}"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": {
"popup": {
"background": "#b5c49b",
"text": "#ffffff"
},
"button": {
"background": "#d7d700",
"text": "#ffffff"
}
},
"content": {
"message": "{{__('This website uses cookies') }}",
"dismiss": "{{__('OK')}}",
"link": "{{__('register.data_protection')}}",
"href": "{{ url('datenschutz') }}",
"target": "_blank",
}
})});
</script>
<style>
</style>
</head>
<body>
@yield('layout-content')
<div class="modal fade" id="modals-load-content">
<div class="modal-dialog modal-lg">
</div>
</div>
<!-- Core scripts -->
<script src="{{ mix('/vendor/libs/popper/popper.js') }}"></script>
<script src="{{ mix('/vendor/js/bootstrap.js') }}"></script>
<script src="{{ mix('/vendor/js/sidenav.js') }}"></script>
<script src="{{ mix('/vendor/libs/growl/growl.js') }}"></script>
<script src="{{ asset('/vendor/libs/moment-develop/min/moment.min.js') }}"></script>
<script src="{{ asset('/vendor/libs/moment-develop/locale/de.js') }}"></script>
<script src="{{ mix('/vendor/libs/validate/validate.js') }}"></script>
<script src="{{ mix('/vendor/libs/bootstrap-select/bootstrap-select.js') }}"></script>
<script src="{{ mix('/vendor/libs/select2/select2.js') }}"></script>
<script src="{{ mix('/vendor/libs/datatables/datatables.js') }}"></script>
<script src="{{ mix('/vendor/libs/bootstrap-datepicker/bootstrap-datepicker.js') }}"></script>
<script src="{{asset('/js/bootstrap-datepicker.de.min.js')}}"></script>
<script src="{{ asset('/vendor/libs/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.js') }}"></script>
<script src="{{ asset('/vendor/libs/summernote/dist/summernote-bs4.min.js') }}"></script>
<script src="{{ asset('/vendor/libs/summernote/lang/summernote-de-DE.js') }}"></script>
<script src="{{ asset('/vendor/libs/summernote-cleaner/summernote-cleaner.js') }}"></script>
<script src="{{ asset('/vendor/libs/slim-image-cropper/slim/slim.kickstart.min.js') }}"></script>
<script src="{{ asset('/vendor/libs/dropzone/dropzone.js?v=1')}}"></script>
<script src="{{ asset('/js/forms_file-upload.js?v=1') }}"></script>
<script src="{{ asset('/vendor/libs/clipboard/clipboard.min.js')}}"></script>
<!-- `perfect-scrollbar` library required by SideNav plugin -->
<script src="{{ mix('/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') }}"></script>
<script src="{{ asset('/js/shopping_card.js') }}?v=1{{ get_file_last_time('/js/shopping_card.js') }}"></script>
<!-- Application javascripts -->
<script src="{{ mix('/js/application.js') }}"></script>
<script src="{{ asset('/js/custom.js') }}?v=1{{ get_file_last_time('/js/custom.js') }}"></script>
@yield('scripts')
<script type="text/javascript">
$(document).ready(function() {
$('.summernote').summernote({
height: 140,
lang: 'de-DE',
cleaner:{
action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
newline: '<br>', // Summernote's default is to use '<p><br></p>'
notStyle: 'position:absolute;top:0;left:0;right:0', // Position of Notification
icon: '<i class="note-icon">[Your Button]</i>',
keepHtml: false, // Remove all Html formats
keepOnlyTags: ['<p>', '<br>', '<ul>', '<li>', '<b>', '<strong>','<i>', '<a>'], // If keepHtml is true, remove all tags except these
keepClasses: false, // Remove Classes
badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'noscript', 'html'], // Remove full tags with contents
badAttributes: ['style', 'start'], // Remove attributes from remaining tags
limitChars: false, // 0/false|# 0/false disables option
limitDisplay: 'both', // text|html|both
limitStop: false // true/false
}
});
$('.summernote-small').summernote({
height: 140,
lang: 'de-DE',
toolbar: [
// [groupName, [list of button]]
['style', ['style']],
['style', ['bold', 'italic', 'underline', 'clear']],
['fontsize', ['fontsize']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['height', ['height']],
['view',['fullscreen','codeview']],
],
cleaner:{
action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
newline: '<br>', // Summernote's default is to use '<p><br></p>'
notStyle: 'position:absolute;top:0;left:0;right:0', // Position of Notification
icon: '<i class="note-icon">[Your Button]</i>',
keepHtml: false, // Remove all Html formats
keepOnlyTags: ['<p>', '<br>', '<ul>', '<li>', '<b>', '<strong>','<i>', '<a>'], // If keepHtml is true, remove all tags except these
keepClasses: false, // Remove Classes
badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'noscript', 'html'], // Remove full tags with contents
badAttributes: ['style', 'start'], // Remove attributes from remaining tags
limitChars: false, // 0/false|# 0/false disables option
limitDisplay: 'both', // text|html|both
limitStop: false // true/false
}
});
$('.note-status-output').hide();
});
</script>
</body>
</html>

View file

@ -1,97 +0,0 @@
@extends('portal.layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold py-2 mb-2">
{{ __('navigation.my_orders') }}
</h4>
<div class="card">
<div class="card-datatable table-responsive">
<table class="table table-striped table-bordered" style="min-width:550px;" id="datatables-orders">
<thead>
<tr>
<th>#</th>
<th>{{__('tables.date')}}</th>
<th>{{__('tables.amount')}}</th>
<th>{{__('tables.status')}}</th>
<th>{{__('tables.shipping')}}</th>
<th>{{__('tables.firstname')}}</th>
<th>{{__('tables.lastname')}}</th>
<th>{{__('tables.email')}}</th>
<th>{{__('tables.invoice')}}</th>
<th>{{__('tables.art')}}</th>
</tr>
</thead>
<tbody>
@if($shopping_user->shopping_order)
@forelse($shopping_user->getAllOrdersByMember() as $shopping_order)
<tr>
<td>
<a href="{{ route('portal.my_orders.show', $shopping_order->id) }}"
class="btn icon-btn btn-sm btn-primary">
<span class="fa fa-eye"></span>
</a>
</td>
<td>{{ $shopping_order->created_at->format('d.m.Y') }}</td>
<td>
<span class="no-line-break">
{{ $shopping_order->getFormattedTotalShipping() }} €
</span>
</td>
<td>{!! \App\Services\Payment::getShoppingOrderBadge($shopping_order) !!}</td>
<td>
<span class="badge badge-pill badge-{{ $shopping_order->getShippedColor() }}">
{{ $shopping_order->getShippedType() }}
</span>
</td>
<td>{{ $shopping_order->shopping_user->billing_firstname }}</td>
<td>{{ $shopping_order->shopping_user->billing_lastname }}</td>
<td>{{ $shopping_order->shopping_user->billing_email }}</td>
<td>{{ $shopping_order->isInvoice() ? '<span class="no-line-break"><a href="'.route('storage_file', [$shopping_order->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>' : '-';
}}</td>
<td>{!! \App\Services\Payment::getPaymentForBadge($shopping_order) !!}</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center">{{ __('order.no_orders_found') }}</td>
</tr>
@endforelse
@endif
</tbody>
</table>
</div>
</div>
@endsection
@section('scripts')
<script>
$( document ).ready(function() {
$('#datatables-orders').DataTable({
"bLengthChange": false,
"iDisplayLength": 50,
"order": [[ 1, "desc" ]],
"language": {
"url": "/js/datatables-{{ \App::getLocale() }}.json"
}
});
});
</script>
@endsection

View file

@ -26,12 +26,11 @@
@endif
<div class="media-body">
<a href="{{route('admin_product_edit', [$shopping_order_item->product->id])}}" class="d-block"><strong>{{ $shopping_order_item->product->getLang('name') }} </strong>
<div class="d-block"><strong>{{ $shopping_order_item->product->getLang('name') }} </strong>
@if($shopping_order->is_abo)
&nbsp; {!! get_abo_type_badge_by_product($shopping_order_item->product) !!}
@endif
</a>
</div>
<small>
<span class="text-muted">{{ __('order.content') }}: </span> {{ $shopping_order_item->product->contents }}<br>
<span class="text-muted">{{ __('order.weight') }}: </span> {{ $shopping_order_item->product->weight }} g<br>

View file

@ -0,0 +1,454 @@
@extends('web.layouts.layout')
@section('content')
<div class="container">
<!-- Hero Section -->
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="text-center mb-5">
<h1 class="display-4 font-weight-bold text-primary mb-3">
<i class="fas fa-search"></i>
Sendungsverfolgung
</h1>
<p class="lead text-muted">
Verfolgen Sie den Status Ihrer DHL-Sendung in Echtzeit
</p>
</div>
</div>
</div>
<!-- Tracking Form -->
<div class="row justify-content-center mb-5">
<div class="col-lg-6">
<div class="card shadow-lg border-0">
<div class="card-body p-5">
<form id="tracking-form">
<div class="form-group">
<label for="tracking_number" class="font-weight-semibold text-primary">
<i class="fas fa-hashtag"></i>
Tracking-Nummer
</label>
<input type="text"
class="form-control form-control-lg"
id="tracking_number"
name="tracking_number"
placeholder="z.B. 1234567890"
value="{{ request('tracking_number') }}"
required>
<small class="form-text text-muted">
Geben Sie Ihre DHL Tracking-Nummer ein (10-20 Zeichen)
</small>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block" id="track-btn">
<i class="fas fa-search"></i>
Sendung verfolgen
</button>
</form>
</div>
</div>
</div>
</div>
<!-- Tracking Results -->
<div id="tracking-results" style="display: none;">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow border-0">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">
<i class="fas fa-info-circle"></i>
Sendungsinformationen
</h4>
</div>
<div class="card-body">
<div id="tracking-content">
<!-- Dynamic content will be loaded here -->
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Error Message -->
<div id="error-message" class="row justify-content-center" style="display: none;">
<div class="col-lg-6">
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">
<i class="fas fa-exclamation-triangle"></i>
Sendung nicht gefunden
</h4>
<p class="mb-0">
Die eingegebene Tracking-Nummer konnte nicht gefunden werden.
Bitte überprüfen Sie die Nummer und versuchen Sie es erneut.
</p>
</div>
</div>
</div>
<!-- Loading Spinner -->
<div id="loading-spinner" class="row justify-content-center" style="display: none;">
<div class="col-lg-6">
<div class="card border-0">
<div class="card-body text-center py-5">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<p class="mt-3 text-muted">
Tracking-Informationen werden abgerufen...
</p>
</div>
</div>
</div>
</div>
<!-- How to find Tracking Number -->
<div class="row justify-content-center mt-5">
<div class="col-lg-10">
<div class="card bg-light border-0">
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-8">
<h5 class="font-weight-bold text-primary mb-3">
<i class="fas fa-question-circle"></i>
Wo finde ich meine Tracking-Nummer?
</h5>
<ul class="mb-0">
<li>In der Versandbestätigungs-E-Mail</li>
<li>Auf dem Versandlabel oder Paketschein</li>
<li>In Ihrem Kundenkonto unter "Bestellungen"</li>
<li>Als SMS-Benachrichtigung (falls aktiviert)</li>
</ul>
</div>
<div class="col-md-4 text-center">
<i class="fas fa-box fa-4x text-muted"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Support Information -->
<div class="row justify-content-center mt-4 mb-5">
<div class="col-lg-10">
<div class="text-center">
<p class="text-muted">
<strong>Probleme bei der Sendungsverfolgung?</strong><br>
Kontaktieren Sie uns unter
<a href="mailto:support@mivita.care" class="text-primary">support@mivita.care</a>
oder besuchen Sie unsere
<a href="{{ route('contact_create') }}" class="text-primary">Kontaktseite</a>.
</p>
</div>
</div>
</div>
</div>
<!-- Back to Top Button -->
<button type="button" class="btn btn-primary btn-sm" id="back-to-top" style="position: fixed; bottom: 20px; right: 20px; display: none; z-index: 99;">
<i class="fas fa-arrow-up"></i>
</button>
@endsection
@section('scripts')
<script>
$(document).ready(function() {
// Auto-track if tracking number is provided in URL
if ($('#tracking_number').val()) {
$('#tracking-form').submit();
}
// Form submission
$('#tracking-form').on('submit', function(e) {
e.preventDefault();
var trackingNumber = $('#tracking_number').val().trim();
if (!trackingNumber || trackingNumber.length < 10) {
showError('Bitte geben Sie eine gültige Tracking-Nummer ein (mindestens 10 Zeichen).');
return;
}
// Hide previous results and errors
hideAllResults();
// Show loading spinner
$('#loading-spinner').show();
// Disable form
$('#track-btn').prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird verfolgt...');
// Perform AJAX request
$.ajax({
url: '{{ route("public.tracking.check") }}',
method: 'POST',
data: {
tracking_number: trackingNumber,
_token: '{{ csrf_token() }}'
},
success: function(response) {
$('#loading-spinner').hide();
resetForm();
if (response.success && response.data) {
showTrackingResult(response.data);
} else {
showError(response.message || 'Sendung nicht gefunden.');
}
},
error: function(xhr) {
$('#loading-spinner').hide();
resetForm();
var errorMessage = 'Fehler beim Abrufen der Tracking-Informationen.';
if (xhr.responseJSON && xhr.responseJSON.message) {
errorMessage = xhr.responseJSON.message;
}
showError(errorMessage);
}
});
});
// Show tracking results
function showTrackingResult(data) {
var statusBadge = getStatusBadge(data.status);
var trackingStatusInfo = data.tracking_status ?
`<p class="mb-2"><strong>DHL Status:</strong> <em>${data.tracking_status}</em></p>` : '';
var lastTrackedInfo = data.last_tracked_at ?
`<p class="mb-2"><strong>Zuletzt aktualisiert:</strong> ${data.last_tracked_at}</p>` : '';
var html = `
<div class="row">
<div class="col-md-6">
<h5 class="text-primary mb-3">
<i class="fas fa-hashtag"></i>
${data.tracking_number}
</h5>
<p class="mb-2"><strong>Status:</strong> ${statusBadge}</p>
${trackingStatusInfo}
${lastTrackedInfo}
</div>
<div class="col-md-6">
<div class="text-center">
<div class="mb-3">
${getStatusIcon(data.status)}
</div>
<p class="text-muted small">
Die Informationen werden regelmäßig aktualisiert.
Für detaillierte Tracking-Informationen besuchen Sie die
<a href="https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc=${data.tracking_number}"
target="_blank" class="text-primary">
DHL Website <i class="fas fa-external-link-alt"></i>
</a>
</p>
</div>
</div>
</div>
`;
$('#tracking-content').html(html);
$('#tracking-results').show();
// Smooth scroll to results
$('html, body').animate({
scrollTop: $('#tracking-results').offset().top - 20
}, 500);
// Update URL without page refresh
if (history.pushState) {
var newUrl = window.location.protocol + "//" + window.location.host +
window.location.pathname + '?tracking_number=' + encodeURIComponent(data.tracking_number);
window.history.pushState({path: newUrl}, '', newUrl);
}
}
// Show error message
function showError(message) {
$('#error-message .alert p').html(message);
$('#error-message').show();
// Smooth scroll to error
$('html, body').animate({
scrollTop: $('#error-message').offset().top - 20
}, 500);
}
// Hide all result sections
function hideAllResults() {
$('#tracking-results, #error-message, #loading-spinner').hide();
}
// Reset form
function resetForm() {
$('#track-btn').prop('disabled', false).html('<i class="fas fa-search"></i> Sendung verfolgen');
}
// Get status badge HTML
function getStatusBadge(status) {
var badgeClass = '';
var text = status;
switch(status) {
case 'pending':
badgeClass = 'badge-warning';
text = 'Wartend';
break;
case 'created':
badgeClass = 'badge-success';
text = 'Erstellt';
break;
case 'shipped':
badgeClass = 'badge-primary';
text = 'Unterwegs';
break;
case 'delivered':
badgeClass = 'badge-info';
text = 'Zugestellt';
break;
case 'cancelled':
badgeClass = 'badge-secondary';
text = 'Storniert';
break;
case 'failed':
badgeClass = 'badge-danger';
text = 'Fehler';
break;
default:
badgeClass = 'badge-light';
}
return `<span class="badge ${badgeClass}">${text}</span>`;
}
// Get status icon
function getStatusIcon(status) {
var iconClass = '';
var color = 'text-muted';
switch(status) {
case 'pending':
iconClass = 'fas fa-clock';
color = 'text-warning';
break;
case 'created':
iconClass = 'fas fa-check-circle';
color = 'text-success';
break;
case 'shipped':
iconClass = 'fas fa-truck';
color = 'text-primary';
break;
case 'delivered':
iconClass = 'fas fa-home';
color = 'text-info';
break;
case 'cancelled':
iconClass = 'fas fa-ban';
color = 'text-secondary';
break;
case 'failed':
iconClass = 'fas fa-exclamation-triangle';
color = 'text-danger';
break;
default:
iconClass = 'fas fa-question-circle';
}
return `<i class="${iconClass} fa-4x ${color}"></i>`;
}
// Input validation
$('#tracking_number').on('input', function() {
var value = $(this).val().trim();
var isValid = value.length >= 10;
if (!isValid && value.length > 0) {
$(this).addClass('is-invalid');
} else {
$(this).removeClass('is-invalid');
}
});
// Back to top button
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
$('#back-to-top').fadeIn();
} else {
$('#back-to-top').fadeOut();
}
});
$('#back-to-top').click(function() {
$('html, body').animate({scrollTop: 0}, 600);
return false;
});
// Clear form when clicking on input
$('#tracking_number').focus(function() {
hideAllResults();
});
});
</script>
<style>
/* Custom styles for tracking page */
.border-left-primary {
border-left: 0.25rem solid #007bff !important;
}
.card {
transition: all 0.3s ease-in-out;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.1) !important;
}
.form-control-lg {
padding: 1rem;
font-size: 1.1rem;
}
.btn-lg {
padding: 0.8rem 2rem;
font-size: 1.1rem;
}
.spinner-border {
animation: spinner-border 1s linear infinite;
}
#back-to-top {
border-radius: 50%;
width: 50px;
height: 50px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transition: all 0.3s ease;
}
#back-to-top:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(0,0,0,0.25);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.display-4 {
font-size: 2.5rem;
}
.card-body.p-5 {
padding: 2rem !important;
}
.btn-lg {
padding: 0.75rem 1.5rem;
font-size: 1rem;
}
}
</style>
@endsection

View file

@ -1,50 +0,0 @@
@extends('layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold mb-4">
Cron Jobs
</h4>
<div class="card mb-4">
{{-- <div class="card-body">
<!-- Controls -->
{!! Form::open(['url' => url()->current(), 'class' => '']) !!}
<div class="form-group mb-1">
<label class="form-label" for="description">Description</label>
{{ Form::textarea('text', $text, array('class'=>'form-control', 'rows'=>20)) }}
</div>
<button type="submit" class="btn btn-primary"><i class="ion"></i> action</button>
{!! Form::close() !!}
</div>--}}
@if(count($values)>0)
<div class="card-body">
<!-- Controls -->
@foreach($values as $name=>$link)
<a href="{{$link}}" target="_blank">{{$name}} | {{$link}}</a><br><br>
@endforeach
</div>
@endif
</div>
@endsection

View file

@ -1,80 +0,0 @@
@extends('layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold mb-4">
Kunden
</h4>
{!! Form::open(['url' => url()->current(), 'class' => '']) !!}
<div class="card mb-4">
<div class="card-body">
<!-- Controls -->
<div class="form-group mb-1">
<label class="form-label" for="description">Description</label>
{{ Form::textarea('text', $text, array('class'=>'form-control', 'rows'=>1)) }}
</div>
<button type="submit" name="action" value="checkForAll" class="btn btn-primary"><i class="ion"></i> checkForAll</button>
<button type="submit" name="action" value="makePaymentMethodsDefault" class="btn btn-primary"><i class="ion"></i> make PaymentMethods Default</button>
<button type="submit" name="action" value="checkContractPDF" class="btn btn-primary"><i class="ion"></i> check Contract PDF</button>
</div>
@if(count($values)>0)
<div class="card-body">
<div class="card-datatable table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th style="max-width: 60px;">ID</th>
<th>{{__('Mail')}}</th>
<th>{{__('is like')}}</th>
<th>{{__('OrderID')}}</th>
<th>{{__('txaction')}}</th>
<th>{{__('Action')}}</th>
</tr>
</thead>
<tbody>
@foreach($values as $shopping_user)
<tr>
<td>{{$shopping_user->id}}</td>
<td>{{$shopping_user->billing_email}}</td>
<td>{{$shopping_user->is_like}}</td>
<td>@if($shopping_user->shopping_order){{$shopping_user->shopping_order->id}}@endif</td>
<td>@if($shopping_user->shopping_order){{$shopping_user->shopping_order->txaction}}@endif</td>
<td><button type="submit" name="action" value="checkOne_{{$shopping_user->id}}" class="btn btn-xs btn-primary"><i class="ion"></i> checkOne</button></td>
</tr>
@endforeach
</tbody>
</table>
<!-- Controls -->
</div>
</div>
@endif
</div>
{!! Form::close() !!}
@endsection

View file

@ -1,97 +0,0 @@
@extends('layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold mb-4">
Content Tools: Links
</h4>
<div class="card mb-4">
<div class="card-body">
<!-- Controls -->
{!! Form::open(['url' => url()->current(), 'class' => '']) !!}
<div class="form-group mb-1">
<label class="form-label" for="description">Description</label>
{{ Form::textarea('text', $text, array('class'=>'form-control', 'rows'=>20)) }}
</div>
<button type="submit" class="btn btn-primary"><i class="ion"></i> action</button>
{!! Form::close() !!}
</div>
@if(count($values)>0)
<div class="card-body">
<div class="card-datatable table-responsive">
<table class="datatables-style table table-striped table-bordered">
<thead>
<tr>
<th style="max-width: 60px;">ID</th>
<th style="max-width: 60px;">User-ID</th>
<th>{{__('Name')}}</th>
<th>{{__('seit')}}</th>
<th>Datum</th>
<th>Erreichbar</th>
<th>{{__('Status')}}</th>
</tr>
</thead>
<tbody>
@foreach($values as $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->user_id }}</td>
<td>{{ $value->name }}.mivita.care</td>
<td>{{ $value->getActiveDateFormatSmall() }}</td>
<td>
@if($value->user && $value->user->payment_shop)
@if($value->user->isActiveShop())
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> {{ $value->user->getPaymentShopDateFormat() }}</span>
@else
<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i>{{ $value->user->getPaymentShopDateFormat() }}</span></a>
@endif
@else
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
@endif
</td>
<td>
@if($value->getSubdomainAvailable())
<span class="badge badge-pill badge-success"><i class="fa fa-check"> {{ __('available') }} </i>
@if($value->getSubdomainSslSin()) HTTPS @else HTTP @endif
</span>
@else
<span class="badge badge-pill badge-danger"><i class="fa fa-times"> {{ __('not available') }} </i> HTTP </span>
@endif
</td>
<td>{!! get_active_badge($value->active) !!}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
</div>
@endsection

View file

@ -1,104 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-3 mb-4">
Kontakte Import Status
</h4>
<div class="row">
<div class="col-sm-6 col-xl-3">
<div class="card mb-4">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="lnr lnr-users display-4 text-primary"></div>
<div class="ml-3">
<div class="text-muted small">{{ __('eingelesene Datensätze') }}</div>
<div class="text-large">{{ $import['count'] }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card mb-4">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="lnr lnr-users display-4 text-success"></div>
<div class="ml-3">
<div class="text-muted small">{{ __('Kontakte importiert') }}</div>
<div class="text-large">{{ count($import['imported']) }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card mb-4">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="lnr lnr-users display-4 text-danger"></div>
<div class="ml-3">
<div class="text-muted small">{{ __('ohne E-Mai Adresse') }}</div>
<div class="text-large">{{ $import['not'] }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card mb-4">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="lnr lnr-users display-4 text-danger"></div>
<div class="ml-3">
<div class="text-muted small">{{__('Mail schon vorhanden')}}</div>
<div class="text-large">{{ count($import['has_imported']) }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card mb-4">
<div class="card-body">
<table class="table user-view-table m-0">
<tbody>
<tr>
<td style="border-top: none">{{__('Datei')}}:</td>
<td style="border-top: none">{{ $file }} </td>
</tr>
<tr>
<td>{{__('Import Position start')}}:</td>
<td>{{$skip}}</td>
</tr>
<tr>
<td>{{__('Import limit')}}:</td>
<td>{{ $limit }}</td>
</tr>
</tbody>
</table>
<hr>
<h5>Vorhandene Mails</h5>
@foreach($import['has_imported'] as $row)
{{$row}} <br>
@endforeach
</div>
</div>
@endsection

View file

@ -1,109 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<style>
/* Dropzone */
.dropzone {
min-height: 230px;
border: 2px dashed rgba(0, 0, 0, 0.3);
background: white;
border-radius: 6px;
}
.dropzone .dz-message {
font-size: 28px;
}
</style>
<h4 class="font-weight-bold py-3 mb-4">
Kontakte importieren
</h4>
<div class="card mb-4">
<h6 class="card-header">
Excel-Datei hochladen
</h6>
<div class="card-body">
{!! Form::open([ 'url' => route('sysadmin_import_store'), 'method' => 'post', 'files' => true, 'enctype' => 'multipart/form-data', 'class' => 'dropzone', 'id' => 'realDropzone' ]) !!}
<div class="fallback">
<input name="file" type="file" multiple>
</div>
{!! Form::close() !!}
<br>
<div class="alert alert-danger alert-dismissable" style="display:none;"></div>
</div>
</div>
@endsection
@section('scripts')
<script type="text/javascript">
var real_dropzone = {
uploadMultiple: false,
parallelUploads: 1,
maxFilesize: 32,
addRemoveLinks: true,
dictDefaultMessage: 'Hier klicken, oder Datei hier reinziehen (Drag&Drop)',
dictFallbackMessage: 'Dein Browser unterstützt Drag&Drop Dateiuploads nicht',
dictFallbackText: 'Benutze das Formular um Deine Dateien hochzuladen',
dictFileTooBig: "Die Datei ist zu groß. Die maximale Dateigröße beträgt 32 MB",
dictInvalidFileType: 'Eine Datei dieses Typs kann nicht hochgeladen werden',
dictResponseError: "Der Server hat ihre Anfrage mit Status error abgelehnt",
dictCancelUpload: 'Hochladen abbrechen',
dictCancelUploadConfirmation: null,
dictRemoveFile: 'Datei entfernen',
dictMaxFilesExceeded: 'Du kannst keine weiteren Dateien mehr hochladen',
// The setting up of the dropzone
init:function() {
console.log("init");
this.on("removedfile", function(file) {
var _ele = $('.alert-danger');
_ele.fadeOut();
} );
this.on("addedfile", function (file) {
var _ele = $('.alert-danger');
_ele.fadeOut();
});
},
error: function(file, response) {
console.log(file);
console.log(response);
var message
if($.type(response) === "string")
message = response; //dropzone sends it's own error messages in string
else
message = response.message;
var _ele = $('.alert-danger');
_ele.fadeIn();
_ele.text(message);
},
success: function(file,response) {
console.log(file);
console.log(response.filename);
console.log(response.filedata);
console.log(response);
if(response.redirect){
window.location.href = response.redirect;
}else{
if(response.error === false){
//true
window.location.href = window.location.href;
}
}
}
};
Dropzone.options.realDropzone = real_dropzone;
</script>
@endsection

View file

@ -1,51 +0,0 @@
@extends('layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold mb-4">
Content Tools: Links
</h4>
<div class="card mb-4">
<div class="card-body">
<!-- Controls -->
{!! Form::open(['url' => url()->current(), 'class' => '']) !!}
<div class="form-group mb-1">
<label class="form-label" for="description">Description</label>
{{ Form::textarea('text', $text, array('class'=>'form-control', 'rows'=>1)) }}
</div>
<button type="submit" name="action" value="first_run" class="btn btn-primary"><i class="ion"></i> first run</button>
<button type="submit" name="action" value="next_run" class="btn btn-primary"><i class="ion"></i> next run</button>
{!! Form::close() !!}
</div>
@if(count($values)>0)
<div class="card-body">
<!-- Controls -->
@foreach($values as $value)
<pre>{{$value->billing_email}} | {{$value->orders}}</pre>
@endforeach
</div>
@endif
</div>
@endsection

View file

@ -1,65 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<div class="card">
<h6 class="card-header">
Berater Bestellungen
</h6>
<div class="col-sm-6 mb-2">
{!! Form::open(['url' => route('sysadmin_tool_store', ['sales_members']), 'class' => 'form-horizontal', 'id'=>'filter_sales_member']) !!}
<label class="form-label" for="filter_user_shop_id">Filter Jahr</label>
<select class="custom-select" name="filter_sales_year" id="filter_sales_year">
@foreach($years as $year)
<option value="{{$year}}" @if($active_year == $year) selected @endif>{{$year}}</option>
@endforeach
</select>
{!! Form::close() !!}
</div>
<div class="card-datatable table-responsive">
<table class="datatables-style table table-striped table-bordered">
<thead>
<tr>
<th>{{__('Vorname')}}</th>
<th>{{__('Nachname') }}</th>
<th>{{__('E-Mail') }}</th>
<th>{{__('Betrag') }}</th>
<th>{{__('Datum') }}</th>
<th>{{__('Order')}}</th>
<th>{{__('Status')}}</th>
</tr>
</thead>
<tbody>
@foreach($values as $value)
<tr>
<td>{{ $value->shopping_user->billing_firstname }}</td>
<td>{{ $value->shopping_user->billing_lastname }}</td>
<td>{{ $value->shopping_user->billing_email }}</td>
<td>{{ $value->getFormattedTotalShipping()." €" }}</td>
<td>{{ $value->created_at->format("d.m.Y") }}</td>
<td>@foreach($value->shopping_order_items as $shopping_order_item)
{{ $shopping_order_item->product->name }}<br>
@endforeach
</td>
<td>{!! App\Services\Payment::getShoppingOrderBadge($value) !!}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
<script>
$('#filter_sales_year').on('change', function(){
$('#filter_sales_member').submit();
});
</script>
@endsection

View file

@ -1,283 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<style>
.table-small {
font-size: 0.9em;
width: auto;
}
.table-small td {
padding: 0.225rem 1rem 0.225rem 0;
}
.btn-md-extra {
padding: 0.3rem 0.6rem;
font-size: 0.8rem;
line-height: 1.5;
border-radius: 0.25rem;
}
.md-btn-extra {
width: calc(1.7rem + 2px) !important;
line-height: 1.5rem;
}
.form-control.input-extra {
padding: 0.28rem 0.6rem;
font-size: 0.8rem;
font-weight: 500;
min-height: calc(1.8rem + 2px);
height: calc(1.8rem + 2px);
width: 44px;
}
.input-group-min-w {
min-width: 102px;
}
.img-extra {
min-width:55px;
max-height: 120px;
}
.table td.border-top {
border: none;
border-top: 1px solid #ccccdb;
}
.table td {
border: none;
}
.table th {
border: none;
border-bottom: 1px solid #c3c3d2;
}
@media (max-width: 767px) {
.default-style:not([dir=rtl]) div.card-datatable table.dataTable thead th:first-child,
.default-style:not([dir=rtl]) div.card-datatable table.dataTable tbody td:first-child,
.default-style:not([dir=rtl]) div.card-datatable table.dataTable tfoot th:first-child {
padding-left: 0.6rem !important;
}
.img-extra {
min-width:35px;
max-height: 160px;
}
}
.table .foot-small td {
padding: 0.225rem 0.625rem;
}
.table .text-body {
font-size: 0.9em;
}
.table .options a.auto-delete-product {
font-size: 0.7em;
font-weight: bold;
text-transform: uppercase;
}
.table .min-width-80 {
min-width: 160px;
}
.bg-warning-light {
background-color: rgba(255, 217, 80, 0.6) !important;
}
</style>
<h4 class="font-weight-bold py-2 mb-2 d-flex justify-content-between align-items-center w-100 ">
<div>{{ __('navigation.my_homeparty') }} / {{ $homeparty->name }} - {{ $homeparty->date }}</div>
<a href="{{route('user_homepartys')}}" class="btn btn-sm btn-default float-right">zurück</a>
</h4>
@if(Session::has('custom-error'))
<div class="alert alert-dark-warning alert-dismissible fade show">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ Session::get('custom-error') }}</strong>
</div>
@endif
@if($userHistoryPaymentOrder && $userHistoryPaymentOrder->status > 2)
<h6 class="alert badge-{{$userHistoryPaymentOrder->getStatusColor()}}">Eine Zahlung wurde ausgeführt. Status: {{ trans('payment.status.'.$userHistoryPaymentOrder->getStatusType())}}</h6>
@endif
<div class="card mb-4">
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">Bestellland</div>
{{ App\Services\UserService::getOrderInfo('billing_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">Lieferland</div>
{{ App\Services\UserService::getOrderInfo('shipping_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">MwSt</div>
{{ App\Services\UserService::getOrderInfo('tax_free') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">Reverse Charge Verfahren</div>
{{ App\Services\UserService::getOrderInfo('user_reverse_charge') }}
</div>
</div>
<i>Das Lieferland kann nicht mehr geändert werden.</i>
</div>
</div>
{!! Form::open(['url' => route('user_homeparty_order', [$homeparty->id]), 'class' => 'form-horizontal', 'id'=>'homeparty-order-form']) !!}
<div class="card mb-4">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung anlegen</div>
@if(!$homeparty->completed)
<div class="float-right">
<a href="{{route('user_homeparty_detail', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-1"><i class="ion ion-ios-cog"></i> Verwalten</a>
<a href="{{route('user_homeparty_guests', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-1"><i class="ion ion-md-person-add"></i> Gäste anlegen</a>
</div>
@endif
</div>
</div>
</div>
</h5>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6>Lieferadresse
@if(!$homeparty->completed)
<a href="{{route('user_homeparty_detail', [$homeparty->id, 13])}}"><i class="fa fa-edit"></i> </a>
@endif
</h6>
@include('user.homeparty._address', ['homeparty_user' => $homeparty->homeparty_host])
</div>
{{-- TODO Berechnung Bonus --}}
<div class="col-md-6">
<h6>Aktuelle Bonusansicht</h6>
<div id="insert_show_bonus">
@include('user.homeparty.show_bonus', ['homeparty' => $homeparty])
</div>
</div>
</div>
</div>
</div>
@if($homeparty->homeparty_host)
<div class="card mb-3">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung Gastgeber:in {{$homeparty->homeparty_host->billing_firstname}} {{$homeparty->homeparty_host->billing_lastname}}</div>
</div>
</div>
@if(!$homeparty->completed)
<div class="col-12">
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal" data-target="#modals-load-content"
data-id="{{ $homeparty->id }}"
data-action="homeparty-add-product"
data-user_id="{{$homeparty->homeparty_host->id}}"
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> Produkt hinzufügen</button>
</div>
@endif
</div>
</h5>
<div class="card-body">
<div class="insert_show_products_order" id="insert_show_products_order_{{$homeparty->homeparty_host->id}}" data-homeparty-id="{{ $homeparty->id }}" data-homeparty-user-id="{{$homeparty->homeparty_host->id}}">
@include('user.homeparty.show_products_order', ['homeparty_guest' => $homeparty->homeparty_host])
</div>
</div>
</div>
@endif
@if($homeparty->homeparty_guests)
@php($g_count = 1)
@foreach($homeparty->homeparty_guests as $homeparty_guest)
<div class="card mb-3">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung {!! $g_count++ !!}. Gast {{$homeparty_guest->billing_firstname}} {{$homeparty_guest->billing_lastname}}</div>
</div>
</div>
@if(!$homeparty->completed)
<div class="col-12">
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal" data-target="#modals-load-content"
data-id="{{ $homeparty->id }}"
data-action="homeparty-add-product"
data-user_id="{{$homeparty_guest->id}}"
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> Produkt hinzufügen</button>
</div>
@endif
</div>
</h5>
<div class="card-body">
<div class="insert_show_products_order" id="insert_show_products_order_{{$homeparty_guest->id}}" data-homeparty-id="{{ $homeparty->id }}" data-homeparty-user-id="{{$homeparty_guest->id}}">
@include('user.homeparty.show_products_order', ['homeparty_guest' => $homeparty_guest])
</div>
</div>
</div>
@endforeach
@endif
<hr>
<div class="card mb-4">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Gesamtübersicht</div>
</div>
</div>
</div>
</h5>
<div class="card-body">
<div id="insert_show_total_order">
@include('user.homeparty.show_total_order', ['homeparty' => $homeparty])
</div>
@if(!$homeparty->completed)
<hr>
@if($homeparty->homeparty_host && $homeparty->homeparty_host->isAddress())
<div class="float-right">
<button type="submit" class="btn btn-secondary"><i class="ion ion-ios-redo"></i> bestätigen und weiter zur Kasse</button>
</div>
<br><br>
<em class="small text-center"> <i class="fa fa-lock"></i> Du wirst auf unseren checkout Server weitergeletet, die Verbindung ist SSL verschlüsselt.</em>
@else
<div class="alert alert-warning">
Die Bestellung kann erst abgesendet werden, wenn die Lieferadresse Gastgeber/in angelegt ist. <a href="{{route('user_homeparty_guest_detail', [$homeparty->id, $homeparty->homeparty_host->id])}}"><i class="fa fa-edit"></i> </a></h6>
</div>
@endif
@endif
</div>
</div>
<div class="text-left mt-3">
@if(!$homeparty->completed)
<a href="{{route('user_homeparty_detail', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-2"><i class="ion ion-ios-cog"></i> Homparty verwalten</a>
@endif
<a href="{{route('user_homepartys')}}" class="btn btn-sm btn-default mb-2">zurück zur Übersicht</a>
</div>
{!! Form::close() !!}
@endsection
@section('scripts')
<script src="{{ asset('/js/iq-homeparty-cart.js') }}?v=1{{ get_file_last_time('/js/iq-homeparty-cart.js') }}"></script>
<script type="application/javascript">
var iqHomepartyCart = IqHomepartyCart.init();
$( document ).ready(function() {
});
</script>
@endsection

View file

@ -1,71 +0,0 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
{{ __('homeparty.add_product') }} /
@if($homeparty_user->is_host)
{{ __('homeparty.host') }}
@else
{{ __('homeparty.guest') }}
@endif
{{ $homeparty_user->billing_firstname }} {{ $homeparty_user->billing_lastname }}
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body px-0">
<div class="card-datatable pt-0 table-responsive">
<table id="datatable-homeparty" class="table table-striped table-bordered" data-homeparty-id="{{$homeparty->id}}" data-homeparty-user-id="{{$homeparty_user->id}}">
<thead>
<tr>
<th></th>
<th>{{__('tables.image')}}</th>
<th>{{__('tables.products')}}</th>
<th>{{__('tables.article_no')}}</th>
@if($homeparty->getCardInfo('user_tax_free'))
<th><span class="no-line-break">{{ __('tables.ek_price') }}</span> {{__('tables.net')}}</th>
<th><span class="no-line-break">{{__('tables.vk_price')}}</span> {{__('tables.net')}}</th>
@else
<th><span class="no-line-break">{{ __('tables.ek_price') }}</span> {{__('tables.gross')}}</th>
<th><span class="no-line-break">{{__('tables.vk_price')}}</span> {{__('tables.gross')}}</th>
@endif
<th>{{__('tables.points')}}</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
</div>
</div>
<script>
$( document ).ready(function() {
var oTable = $('#datatable-homeparty').DataTable({
"processing": true,
"serverSide": true,
"ajax": '{!! route('user_homeparty_datatable', [$homeparty->id]) !!}',
"order": [[3, "asc" ]],
"columns": [
{ data: 'add_card', name: 'add_card', searchable: false, orderable: false },
{ data: 'picture', name: 'picture', searchable: false, width: 35 },
{ data: 'name', name: 'name' },
{ data: 'number', name: 'number' },
{ data: 'price_gross', name: 'price_gross', searchable: false, orderable: false },
{ data: 'price_vk_gross', name: 'price_vk_gross', searchable: false },
{ data: 'points', name: 'points', searchable: false },
],
"bLengthChange": false,
"iDisplayLength": 1000,
"paging": false,
"language": {
"url": "/js/datatables-{{ \App::getLocale() }}.json"
},
drawCallback: function (settings) {
iqHomepartyCart.reInitModal();
}
});
iqHomepartyCart.setDatabase('#datatable-homeparty');
});
</script>

View file

@ -1,215 +0,0 @@
@if($user->account)
@if($user->account->same_as_billing)
<!-- Billing -->
<div class="">
<div class="form-row">
<div class="form-group col-md-12">
<label for="shipping_company" class="form-label">{{ __('Company name') }} (optional)</label>
{{ Form::text('shipping_company', $user->account->company, array('placeholder'=>__('Company name'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="shipping_salutation" id="shipping_salutation" required>
{!! HTMLHelper::getSalutation($user->account->salutation) !!}
</select>
@if ($errors->has('shipping_salutation'))
<span class="help-block">
<strong>{{ $errors->first('shipping_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_firstname') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_firstname">{{ __('First name') }}*</label>
{{ Form::text('shipping_firstname', $user->account->first_name, array('placeholder'=>__('First name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_firstname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_lastname') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_lastname">{{ __('Last name') }}*</label>
{{ Form::text('shipping_lastname', $user->account->last_name, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_lastname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('shipping_address', $user->account->address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_address'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address_2') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('shipping_address_2', $user->account->address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('shipping_zipcode', $user->account->zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('shipping_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_city') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_city">{{ __('City') }}*</label>
{{ Form::text('shipping_city', $user->account->city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_city'))
<span class="help-block">
<strong>{{ $errors->first('shipping_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_state') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Delivery country') }}*</label>
<select name="shipping_state" class="selectpicker" id="change_shipping_state" data-is-for="me">
{!! HTMLHelper::getCountriesForShipping(Yard::instance('shopping')->getShippingCountryId()) !!}
</select>
@if ($errors->has('shipping_state'))
<span class="help-block">
<strong>{{ $errors->first('shipping_state') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="shipping_phone">{{ __('Phone') }}</label>
{{ Form::text('shipping_phone', $user->account->phone, array('placeholder'=>__('Phone'), 'class'=>'form-control')) }}
</div>
</div>
</div>
<!-- / Billing -->
@else
<div class="">
<div class="form-row">
<div class="form-group col-md-12">
<label for="shipping_company" class="form-label">{{ __('Company name') }} (optional)</label>
{{ Form::text('shipping_company', $user->account->shipping_company, array('placeholder'=>__('Company name'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="shipping_salutation" id="shipping_salutation" required>
{!! HTMLHelper::getSalutation($user->account->shipping_salutation) !!}
</select>
@if ($errors->has('shipping_salutation'))
<span class="help-block">
<strong>{{ $errors->first('shipping_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_firstname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_firstname">{{ __('First name') }}*</label>
{{ Form::text('shipping_firstname', $user->account->shipping_firstname, array('placeholder'=>__('First name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_firstname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_lastname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_lastname">{{ __('Last name') }}*</label>
{{ Form::text('shipping_lastname', $user->account->shipping_lastname, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_lastname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('shipping_address', $user->account->shipping_address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_address'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address_2') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('shipping_address_2', $user->account->shipping_address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control')) }}
@if ($errors->has('shipping_address_2'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address_2') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('shipping_zipcode', $user->account->shipping_zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('shipping_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_city') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_city">{{ __('City') }}*</label>
{{ Form::text('shipping_city', $user->account->shipping_city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_city'))
<span class="help-block">
<strong>{{ $errors->first('shipping_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_state') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Delivery country') }}*</label>
<select name="shipping_state" class="selectpicker" id="change_shipping_state" data-is-for="me">
{!! HTMLHelper::getCountriesForShipping(Yard::instance('shopping')->getShippingCountryId()) !!}
</select>
@if ($errors->has('shipping_state'))
<span class="help-block">
<strong>{{ $errors->first('shipping_state') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="shipping_phone">{{ __('Phone') }}</label>
{{ Form::text('shipping_phone', $user->account->shipping_phone, array('placeholder'=>__('Phone'), 'class'=>'form-control')) }}
</div>
</div>
</div>
@endif
@else
<h4>Fehler: Keine Adressdaten gefunden!</h4>
@endif

View file

@ -1,210 +0,0 @@
@if($shopping_user->same_as_billing)
<!-- Billing -->
<div class="">
<div class="form-row">
<div class="form-group col-md-12">
<label for="shipping_company" class="form-label">{{ __('Company name') }} (optional)</label>
{{ Form::text('shipping_company', $shopping_user->billing_company, array('placeholder'=>__('Company name'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="shipping_salutation" id="shipping_salutation" required>
{!! HTMLHelper::getSalutation($shopping_user->billing_salutation) !!}
</select>
@if ($errors->has('shipping_salutation'))
<span class="help-block">
<strong>{{ $errors->first('shipping_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_firstname') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_firstname">{{ __('First name') }}*</label>
{{ Form::text('shipping_firstname', $shopping_user->billing_firstname, array('placeholder'=>__('First name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_firstname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_lastname') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_lastname">{{ __('Last name') }}*</label>
{{ Form::text('shipping_lastname', $shopping_user->billing_lastname, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_lastname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('shipping_address', $shopping_user->billing_address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_address'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address_2') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('shipping_address_2', $shopping_user->billing_address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('shipping_zipcode', $shopping_user->billing_zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('shipping_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_city') ? 'has-error' : '' }}">
<label class="form-label" for=shipping_city">{{ __('City') }}*</label>
{{ Form::text('shipping_city', $shopping_user->billing_city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_city'))
<span class="help-block">
<strong>{{ $errors->first('shipping_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_state') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Delivery country') }}*</label>
<select name="shipping_state" class="selectpicker" id="change_shipping_state" data-is-for="ot">
{!! HTMLHelper::getCountriesForShipping(Yard::instance('shopping')->getShippingCountryId()) !!}
</select>
@if ($errors->has('shipping_state'))
<span class="help-block">
<strong>{{ $errors->first('shipping_state') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="shipping_phone">{{ __('Phone') }}</label>
{{ Form::text('shipping_phone', $shopping_user->billing_phone, array('placeholder'=>__('Phone'), 'class'=>'form-control')) }}
</div>
</div>
</div>
<!-- / Billing -->
@else
<div class="">
<div class="form-row">
<div class="form-group col-md-12">
<label for="shipping_company" class="form-label">{{ __('Company name') }} (optional)</label>
{{ Form::text('shipping_company', $shopping_user->shipping_company, array('placeholder'=>__('Company name'), 'class'=>'form-control')) }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_salutation') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Salutation') }}*</label>
<select class="selectpicker" data-style="btn-light" name="shipping_salutation" id="shipping_salutation" required>
{!! HTMLHelper::getSalutation($shopping_user->shipping_salutation) !!}
</select>
@if ($errors->has('shipping_salutation'))
<span class="help-block">
<strong>{{ $errors->first('shipping_salutation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_firstname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_firstname">{{ __('First name') }}*</label>
{{ Form::text('shipping_firstname', $shopping_user->shipping_firstname, array('placeholder'=>__('First name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_firstname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_firstname') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_lastname') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_lastname">{{ __('Last name') }}*</label>
{{ Form::text('shipping_lastname', $shopping_user->shipping_lastname, array('placeholder'=>__('Last name'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_lastname'))
<span class="help-block">
<strong>{{ $errors->first('shipping_lastname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address">{{ __('Street') }} / {{ __('House number') }}*</label>
{{ Form::text('shipping_address', $shopping_user->shipping_address, array('placeholder'=>__('Street'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_address'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_address_2') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_address_2">{{ __('Flat Building optional') }}</label>
{{ Form::text('shipping_address_2', $shopping_user->shipping_address_2, array('placeholder'=>__('Flat Building optional'), 'class'=>'form-control')) }}
@if ($errors->has('shipping_address_2'))
<span class="help-block">
<strong>{{ $errors->first('shipping_address_2') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 {{ $errors->has('shipping_zipcode') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_zipcode">{{ __('Postcode') }}*</label>
{{ Form::text('shipping_zipcode', $shopping_user->shipping_zipcode, array('placeholder'=>__('Postcode'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_zipcode'))
<span class="help-block">
<strong>{{ $errors->first('shipping_zipcode') }}</strong>
</span>
@endif
</div>
<div class="form-group col-md-6 {{ $errors->has('shipping_city') ? 'has-error' : '' }}">
<label class="form-label" for="shipping_city">{{ __('City') }}*</label>
{{ Form::text('shipping_city', $shopping_user->shipping_city, array('placeholder'=>__('City'), 'class'=>'form-control', 'required'=>true)) }}
@if ($errors->has('shipping_city'))
<span class="help-block">
<strong>{{ $errors->first('shipping_city') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12 {{ $errors->has('shipping_state') ? 'has-error' : '' }}">
<label class="form-label">{{ __('Delivery country') }}}*</label>
<select name="shipping_state" class="selectpicker" id="change_shipping_state" data-is-for="ot">
{!! HTMLHelper::getCountriesForShipping(Yard::instance('shopping')->getShippingCountryId()) !!}
</select>
@if ($errors->has('shipping_state'))
<span class="help-block">
<strong>{{ $errors->first('shipping_state') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label class="form-label" for="shipping_phone">{{ __('Phone') }}</label>
{{ Form::text('shipping_phone', $shopping_user->shipping_phone, array('placeholder'=>__('Phone'), 'class'=>'form-control')) }}
</div>
</div>
</div>
@endif

View file

@ -1,283 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<style>
.table-small {
font-size: 0.9em;
width: auto;
}
.table-small td {
padding: 0.225rem 1rem 0.225rem 0;
}
.btn-md-extra {
padding: 0.3rem 0.6rem;
font-size: 0.8rem;
line-height: 1.5;
border-radius: 0.25rem;
}
.md-btn-extra {
width: calc(1.7rem + 2px) !important;
line-height: 1.5rem;
}
.form-control.input-extra {
padding: 0.28rem 0.6rem;
font-size: 0.8rem;
font-weight: 500;
min-height: calc(1.8rem + 2px);
height: calc(1.8rem + 2px);
width: 44px;
}
.input-group-min-w {
min-width: 102px;
}
.img-extra {
min-width:55px;
max-height: 120px;
}
.table td.border-top {
border: none;
border-top: 1px solid #ccccdb;
}
.table td {
border: none;
}
.table th {
border: none;
border-bottom: 1px solid #c3c3d2;
}
@media (max-width: 767px) {
.default-style:not([dir=rtl]) div.card-datatable table.dataTable thead th:first-child,
.default-style:not([dir=rtl]) div.card-datatable table.dataTable tbody td:first-child,
.default-style:not([dir=rtl]) div.card-datatable table.dataTable tfoot th:first-child {
padding-left: 0.6rem !important;
}
.img-extra {
min-width:35px;
max-height: 160px;
}
}
.table .foot-small td {
padding: 0.225rem 0.625rem;
}
.table .text-body {
font-size: 0.9em;
}
.table .options a.auto-delete-product {
font-size: 0.7em;
font-weight: bold;
text-transform: uppercase;
}
.table .min-width-80 {
min-width: 160px;
}
.bg-warning-light {
background-color: rgba(255, 217, 80, 0.6) !important;
}
</style>
<h4 class="font-weight-bold py-2 mb-2 d-flex justify-content-between align-items-center w-100 ">
<div>{{ __('navigation.my_homeparty') }} / {{ $homeparty->name }} - {{ $homeparty->date }}</div>
<a href="{{route('user_homepartys')}}" class="btn btn-sm btn-default float-right">zurück</a>
</h4>
@if(Session::has('custom-error'))
<div class="alert alert-dark-warning alert-dismissible fade show">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ Session::get('custom-error') }}</strong>
</div>
@endif
@if($userHistoryPaymentOrder && $userHistoryPaymentOrder->status > 2)
<h6 class="alert badge-{{$userHistoryPaymentOrder->getStatusColor()}}">Eine Zahlung wurde ausgeführt. Status: {{ trans('payment.status.'.$userHistoryPaymentOrder->getStatusType())}}</h6>
@endif
<div class="card mb-4">
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">Bestellland</div>
{{ App\Services\UserService::getOrderInfo('billing_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">Lieferland</div>
{{ App\Services\UserService::getOrderInfo('shipping_state') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">MwSt</div>
{{ App\Services\UserService::getOrderInfo('tax_free') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">Reverse Charge Verfahren</div>
{{ App\Services\UserService::getOrderInfo('user_reverse_charge') }}
</div>
</div>
<i>Das Lieferland kann nicht mehr geändert werden.</i>
</div>
</div>
{!! Form::open(['url' => route('user_homeparty_order', [$homeparty->id]), 'class' => 'form-horizontal', 'id'=>'homeparty-order-form']) !!}
<div class="card mb-4">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung anlegen</div>
@if(!$homeparty->completed)
<div class="float-right">
<a href="{{route('user_homeparty_detail', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-1"><i class="ion ion-ios-cog"></i> Verwalten</a>
<a href="{{route('user_homeparty_guests', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-1"><i class="ion ion-md-person-add"></i> Gäste anlegen</a>
</div>
@endif
</div>
</div>
</div>
</h5>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6>Lieferadresse
@if(!$homeparty->completed)
<a href="{{route('user_homeparty_detail', [$homeparty->id, 13])}}"><i class="fa fa-edit"></i> </a>
@endif
</h6>
@include('user.homeparty._address', ['homeparty_user' => $homeparty->homeparty_host])
</div>
{{-- TODO Berechnung Bonus --}}
<div class="col-md-6">
<h6>Aktuelle Bonusansicht</h6>
<div id="insert_show_bonus">
@include('user.homeparty.show_bonus', ['homeparty' => $homeparty])
</div>
</div>
</div>
</div>
</div>
@if($homeparty->homeparty_host)
<div class="card mb-3">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung Gastgeber:in {{$homeparty->homeparty_host->billing_firstname}} {{$homeparty->homeparty_host->billing_lastname}}</div>
</div>
</div>
@if(!$homeparty->completed)
<div class="col-12">
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal" data-target="#modals-load-content"
data-id="{{ $homeparty->id }}"
data-action="homeparty-add-product"
data-user_id="{{$homeparty->homeparty_host->id}}"
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> Produkt hinzufügen</button>
</div>
@endif
</div>
</h5>
<div class="card-body">
<div class="insert_show_products_order" id="insert_show_products_order_{{$homeparty->homeparty_host->id}}" data-homeparty-id="{{ $homeparty->id }}" data-homeparty-user-id="{{$homeparty->homeparty_host->id}}">
@include('user.homeparty.show_products_order', ['homeparty_guest' => $homeparty->homeparty_host])
</div>
</div>
</div>
@endif
@if($homeparty->homeparty_guests)
@php($g_count = 1)
@foreach($homeparty->homeparty_guests as $homeparty_guest)
<div class="card mb-3">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Bestellung {!! $g_count++ !!}. Gast {{$homeparty_guest->billing_firstname}} {{$homeparty_guest->billing_lastname}}</div>
</div>
</div>
@if(!$homeparty->completed)
<div class="col-12">
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal" data-target="#modals-load-content"
data-id="{{ $homeparty->id }}"
data-action="homeparty-add-product"
data-user_id="{{$homeparty_guest->id}}"
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> Produkt hinzufügen</button>
</div>
@endif
</div>
</h5>
<div class="card-body">
<div class="insert_show_products_order" id="insert_show_products_order_{{$homeparty_guest->id}}" data-homeparty-id="{{ $homeparty->id }}" data-homeparty-user-id="{{$homeparty_guest->id}}">
@include('user.homeparty.show_products_order', ['homeparty_guest' => $homeparty_guest])
</div>
</div>
</div>
@endforeach
@endif
<hr>
<div class="card mb-4">
<h5 class="card-header">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center w-100">
<div>Gesamtübersicht</div>
</div>
</div>
</div>
</h5>
<div class="card-body">
<div id="insert_show_total_order">
@include('user.homeparty.show_total_order', ['homeparty' => $homeparty])
</div>
@if(!$homeparty->completed)
<hr>
@if($homeparty->homeparty_host && $homeparty->homeparty_host->isAddress())
<div class="float-right">
<button type="submit" class="btn btn-secondary"><i class="ion ion-ios-redo"></i> bestätigen und weiter zur Kasse</button>
</div>
<br><br>
<em class="small text-center"> <i class="fa fa-lock"></i> Du wirst auf unseren checkout Server weitergeletet, die Verbindung ist SSL verschlüsselt.</em>
@else
<div class="alert alert-warning">
Die Bestellung kann erst abgesendet werden, wenn die Lieferadresse Gastgeber/in angelegt ist. <a href="{{route('user_homeparty_guest_detail', [$homeparty->id, $homeparty->homeparty_host->id])}}"><i class="fa fa-edit"></i> </a></h6>
</div>
@endif
@endif
</div>
</div>
<div class="text-left mt-3">
@if(!$homeparty->completed)
<a href="{{route('user_homeparty_detail', [$homeparty->id])}}" class="btn btn-sm btn-secondary mr-2 mb-2"><i class="ion ion-ios-cog"></i> Homparty verwalten</a>
@endif
<a href="{{route('user_homepartys')}}" class="btn btn-sm btn-default mb-2">zurück zur Übersicht</a>
</div>
{!! Form::close() !!}
@endsection
@section('scripts')
<script src="{{ asset('/js/iq-homeparty-cart.js') }}?v=1{{ get_file_last_time('/js/iq-homeparty-cart.js') }}"></script>
<script type="application/javascript">
var iqHomepartyCart = IqHomepartyCart.init();
$( document ).ready(function() {
});
</script>
@endsection

View file

@ -1,278 +0,0 @@
@extends('layouts.layout-2')
@section('content')
<div class="card">
<div class="card-body p-2 p-md-4">
@if($is_abo)
<h4>{{ __('order.order_abo_was_placed_successfully') }}</h4>
@else
<h4>{{ __('order.order_was_placed_successfully') }}</h4>
@endif
<h6 class="small font-weight-semibold">
{{ __('order.payment_link_for_your_customer') }}
</h6>
<div class="mt-2">
<a target="_blank" class="btn btn-secondary" href="{{ route('checkout.checkout_card', ['identifier'=>$identifier]) }}">
{{ route('checkout.checkout_card', ['identifier'=>$identifier]) }}
</a>
</div>
</div>
<hr class="m-0">
<div class="card-body">
<h6 class="small font-weight-semibold">
{{ __('customer.customer_billing_address') }}
</h6>
<div class="row">
@if($shopping_user->billing_company)
<div class="col-md-12 mb-3">
<div class="text-muted small">{{ __('Company') }}</div>
{{ $shopping_user->billing_company }}
</div>
@endif
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Salutation') }}</div>
{{ \App\Services\HTMLHelper::getSalutationLang($shopping_user->billing_salutation) }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('First name') }}</div>
{{ $shopping_user->billing_firstname }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Last name') }}</div>
{{ $shopping_user->billing_lastname }}
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Street') }}</div>
{{ $shopping_user->billing_address }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Addition') }}</div>
{{ $shopping_user->billing_address_2 }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Postcode') }}</div>
{{ $shopping_user->billing_zipcode }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('City') }}</div>
{{ $shopping_user->billing_city }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Country') }}</div>
{{ $shopping_user->billing_country->getLocated() }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Phone') }}</div>
{{ $shopping_user->billing_phone }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('E-Mail') }}</div>
@if($shopping_user->faker_mail) "-" @else {{ $shopping_user->billing_email }} @endif
</div>
</div>
</div>
<hr class="m-0">
<!-- / Billing -->
<!-- Shipping -->
<div class="card-body">
<h6 class="small font-weight-semibold">
{{ __('Delivery address') }}
</h6>
@if($shopping_user->same_as_billing)
{{__('email.checkout_mail_same_address')}}
@else
<div class="row">
@if($shopping_user->shipping_company)
<div class="col-md-12 mb-3">
<div class="text-muted small">{{ __('Company') }}</div>
{{ $shopping_user->shipping_company }}
</div>
@endif
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Salutation') }}</div>
{{ \App\Services\HTMLHelper::getSalutationLang($shopping_user->shipping_salutation) }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('First name') }}</div>
{{ $shopping_user->shipping_firstname }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Last name') }}</div>
{{ $shopping_user->shipping_lastname }}
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Street') }}</div>
{{ $shopping_user->shipping_address }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Addition') }}</div>
{{ $shopping_user->shipping_address_2 }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Postcode') }}</div>
{{ $shopping_user->shipping_zipcode }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('City') }}</div>
{{ $shopping_user->shipping_city }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Country') }}</div>
{{ $shopping_user->shipping_country->getLocated() }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('Phone') }}</div>
{{ $shopping_user->shipping_phone }}
</div>
</div>
@endif
</div>
<div class="card-body">
<h6 class="small font-weight-semibold">
{{ __('tables.order') }}
</h6>
@if(isset($yard_shopping_items))
<div class="table-responsive">
<table class="table table-product m-0" style="min-width:550px;">
<tbody>
<tr>
<th>{{ __('tables.product') }}</th>
<th> @if($yard_shopping_items['tax_free'])
{{ __('tables.net_price') }}
@else
{{ __('tables.price') }}
@endif
</th>
<th>{{ __('tables.quantity') }}</th>
<th>{{ __('tables.sum') }}</th>
</tr>
@foreach($yard_shopping_items['items'] as $item)
<tr>
<td class="px-3 py-2">
<div class="media align-item-center">
@if($item->image)
<img src="{{ route('product_image', [$item->image]) }}" class="d-block ui-w-80 mr-4" alt>
@endif
<div class="media-body">
<div class="d-block text-body"><strong>{{ $item->name }}</strong>
{!! get_abo_type_badge($item->abo_type) !!}</div>
<div class="text-body">
<div>{{ __('order.content') }}: {{ $item->contents }}</div>
<div>{{ __('order.art_no') }}: {{ $item->number }}</div>
</div>
</div>
</div>
</td>
<td class="text-right font-weight-semibold align-middle px-3 py-2">
@if($yard_shopping_items['tax_free'])
{{ formatNumber($item->price_net, 2) }} &euro;
@else
{{ formatNumber($item->price, 2) }} &euro;
@endif
</td>
<td class="align-middle px-3 py-2" style="width: 66px;">
{{ $item->qty }}
</td>
<td class="text-right font-weight-semibold align-middle px-3 py-2">
@if($yard_shopping_items['tax_free'])
{{ formatNumber($item->price_net_total, 2) }} &euro;
@else
{{ formatNumber($item->price_total, 2) }} &euro;
@endif
</td>
</tr>
@endforeach
<tr>
<td colspan="3">
{{__('order.subtotal')}}
</td>
<td style="color:#37302d; text-align: right; vertical-align: top;line-height:1.6em;">
{{ $yard_shopping_items['total']['subtotal'] }} &euro;
</td>
</tr>
<tr>
<td colspan="3">
{{__('Delivery country')}}
</td>
<td class="text-right">
{{ $yard_shopping_items['total']['shippingCountryName'] }}
</td>
</tr>
<tr>
<td colspan="3">
{{__('order.shipping_costs')}}
</td>
<td class="text-right">
{{ $yard_shopping_items['total']['shippingNet'] }} &euro;
</td>
</tr>
<tr>
<td colspan="3">
{{__('order.total_without_VAT')}}
</td>
<td class="text-right">
{{ $yard_shopping_items['total']['subtotalWithShipping'] }} &euro;
</td>
</tr>
<tr>
<td colspan="3">
{{__('order.plus_VAT')}}
</td>
<td class="text-right">
{{ $yard_shopping_items['total']['taxWithShipping'] }} &euro;
</td>
</tr>
<tr>
<td colspan="3">
{{__('order.total_net')}}
</td>
<td class="text-right">
{{ $yard_shopping_items['total']['totalWithShipping'] }} &euro;
</td>
</tr>
@if($yard_shopping_items['tax_free'])
<tr>
<td colspan="3">
<b>{{__('order.total_net')}}</b>
</td>
<td class="text-right">
<b>{{ $yard_shopping_items['total']['totalWithShipping'] }} &euro;</b>
<br>
<span style="font-size: 0.8em">{{__('email.checkout_mail_subtotal_ws')}}</span>
</td>
</tr>
@else
<tr>
<td colspan="3">
<b>{{__('order.total_gross')}}</b>
</td>
<td class="text-right">
<b>{{ $yard_shopping_items['total']['totalWithShipping'] }} &euro;</b>
<br>
<span style="font-size: 0.8em">{{__('email.checkout_mail_tax_info')}}</span>
</td>
</tr>
@endif
</tbody>
</table>
</div>
@endif
</div>
</div>
@endsection

View file

@ -1,103 +0,0 @@
<!-- Shopping cart table -->
<div class="table-responsive">
<table class="table table-bordered m-0">
<thead>
<tr>
<!-- Set columns width -->
<th class="text-center py-3 px-4" style="min-width: 400px;">Produkt</th>
<th class="text-right py-3 px-4" style="width: 100px;">Preis</th>
<th class="text-center py-3 px-4" style="width: 120px;">Anzahl</th>
<th class="text-right py-3 px-4" style="width: 100px;">Summe</th>
<th class="py-3 px-4" style="width: 40px;"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="p-4">
<div class="media align-items-center">
<img src="/products/appwork/v152/assets_/img/uikit/nike-1.jpg" class="d-block ui-w-40 ui-bordered mr-4" alt>
<div class="media-body">
<a href="#" class="d-block text-body">Nike Men Black Liteforce III Sneakers</a>
<small>
<span class="text-muted">Color:</span>
<span class="ui-product-color ui-product-color-sm align-text-bottom" style="background:#e81e2c;"></span> &nbsp;
<span class="text-muted">Size: </span> EU 37 &nbsp;
<span class="text-muted">Ships from: </span> China
</small>
</div>
</div>
</td>
<td class="text-right font-weight-semibold align-middle p-4">
$57.55
</td>
<td class="align-middle p-4">
<input type="text" class="form-control text-center" value="2">
</td>
<td class="text-right font-weight-semibold align-middle p-4">
<span class="price">115.1</span> &euro;
</td>
<td class="text-center align-middle px-0">
<a href="#" class="close float-none" data-toggle="tooltip" title data-original-title="Remove">×</a>
</td>
</tr>
<tr>
<td class="p-4">
<div class="media align-items-center">
<img src="/products/appwork/v152/assets_/img/uikit/sunglasses.jpg" class="d-block ui-w-40 ui-bordered mr-4" alt>
<div class="media-body">
<a href="#" class="d-block text-body">WALKING 400 BLUE CAT3</a>
<small>
<span class="text-muted">Ships from: </span> Germany
</small>
</div>
</div>
</td>
<td class="text-right font-weight-semibold align-middle p-4">
$20.55
</td>
<td class="align-middle p-4">
<input type="text" class="form-control text-center" value="1">
</td>
<td class="text-right font-weight-semibold align-middle p-4">
$20.55
</td>
<td class="text-center align-middle px-0">
<a href="#" class="close float-none" data-toggle="tooltip" title data-original-title="Remove">×</a>
</td>
</tr>
</tbody>
</table>
</div>
<!-- / Shopping cart table -->
<div class="d-flex flex-wrap justify-content-between align-items-center pb-4">
<div class="mt-4">
{{-- <label class="text-muted font-weight-normal">Promocode</label>
<input type="text" placeholder="ABC" class="form-control">
--}}
</div>
<div class="d-flex">
<div class="text-right mt-4 mr-5">
<label class="text-muted font-weight-normal m-0">{{ __('order.points') }}</label>
<div class="text-large"><strong>$20</strong></div>
</div>
<div class="text-right mt-4">
<label class="text-muted font-weight-normal m-0">{{ __('order.total_sum') }}</label>
<div class="text-large"><strong>$1164.65</strong></div>
</div>
</div>
</div>
<hr>
<div class="float-right">
<button type="submit" class="btn btn-secondary">{{ __('order.confirm_and_proceed_to_checkout') }}</button>
</div>

View file

@ -1,23 +0,0 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
{{ __('Bestellung Kunde') }} <span class="text-muted">#{{$shopping_order->id}}</span>
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
@include('admin.sales._detail')
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">schließen</button>
</div>
<script>
$( document ).ready(function() {
});
</script>
</div>

View file

@ -1,110 +0,0 @@
@extends('layouts.layout-2')
@section('content')
@if ($errors->any())
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<h4 class="font-weight-bold py-2 mb-2">
{{ __('navigation.my_team') }}
</h4>
<div class="card">
<h5 class="card-header">
{{__('Points')}}
</h5>
<div class="card-body">
{!! Form::open(['url' => route('user_team_points'), 'class' => 'form-horizontal', 'id'=>'form_filter_user_points']) !!}
<div class="form-row align-items-center px-0 pb-2 pt-0">
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
<select class="custom-select on_change_select_filter" name="team_user_points_filter_month">
@foreach($filter_months as $key=>$value)
<option value="{{$key}}" @if(session('team_user_points_filter_month') == $key) selected @endif>{{$value}}</option>
@endforeach
</select>
</div>
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
<select class="custom-select on_change_select_filter" name="team_user_points_filter_year">
@foreach($filter_years as $key=>$value)
<option value="{{$value}}" @if(session('team_user_points_filter_year') == $value) selected @endif>{{$value}}</option>
@endforeach
</select>
</div>
</div>
{!! Form::close() !!}
<hr class="container-m-nx border-light mt-0">
<div class="card">
<div class="card-datatable table-responsive">
<table class="table table-striped table-bordered" id="datatable-user-points">
<thead>
<tr>
<th>{{__('Datum') }}</th>
<th>{{__('Points')}}</th>
<th>{{__('Umsatz netto')}}</th>
<th>{{__('Art')}}</th>
<th>{{__('Bestellung')}}</th>
<th>{{__('Info') }}</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
<script>
$( document ).ready(function() {
var oTable = $('#datatable-user-points').DataTable({
"processing": true,
"serverSide": true,
"stateSave": true,
"searching": false,
ajax: {
url: '{!! route('user_team_datatable_points') !!}',
data: function(d) {
d.team_user_points_filter_month = $('select[name=team_user_points_filter_month]').val();
d.team_user_points_filter_year = $('select[name=team_user_points_filter_year]').val();
}
},
"order": [[0, "desc" ]],
"columns": [
{ data: 'date', name: 'date' },
{ data: 'points', name: 'points' },
{ data: 'total_net', name: 'total_net' },
{ data: 'status', name: 'status', searchable: false },
{ data: 'order', name: 'order', orderable: false },
{ data: 'message', name: 'message', searchable: false },
],
"bLengthChange": false,
"iDisplayLength": 100,
"language": {
"url": "/js/German.json"
},
"drawCallback": function( settings ) {
alert( 'DataTables has redrawn the table' );
}
});
$('select.on_change_select_filter').on('change', function(){
oTable.draw();
});
$('input.on_keyup_input_filter').on('keyup', function(){
oTable.draw();
});
});
</script>
@endsection

View file

@ -1,383 +0,0 @@
@extends($user_shop ?'web.user.layouts.layout' : 'web.layouts.layout')
@section('content')
<section class="page-header page-header-xlg parallax parallax-3"
style="background-image:url('/assets/images/vision-min.jpg')">
<div class="overlay dark-1"><!-- dark overlay [1 to 9 opacity] --></div>
<div class="container">
</div>
</section>
<!-- /PAGE HEADER -->
<style>
/* div.shop-item {
margin-bottom:30px;
border: 1px solid #ddd;
}
div.shop-item > .thumbnail, .thumbnail {
border: none;
}
div.shop-item-summary {
padding: 8px;
}
div.shop-item-summary h2 a {
color: #9aa983;
font-size: 1.2em;
margin: 0 0 10px 0;
}
div.shop-item-buttons {
padding: 0 8px 10px 8px;
}
div.shop-item-buttons .btn-xs{
padding: 4px;
}
.cartContent a.remove_item {
background: transparent;
}
.cartContent .product_name {
font-size: 1.15em;
}
.cartContent .product_name > small {
line-height: 20px;
}
.cartContent .head .product_name {
min-height: auto;
padding-left: 20px;
}
a.shop-item-hl {
color: #9aa983;
font-size: 1.2em;
}
.table-mi-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {
border: 1px solid #ddd !important;
}
@media only screen and (max-width: 1200px) {
.cartContent .yard .product_name {
padding-bottom: 0;
min-height: 60px;
width: 60%;
}
.cartContent .yard .remove_item {
clear: right;
}
.cartContent .yard .total_price {
width: auto;
padding-top: 30px;
clear: right;
}
.cartContent .yard .item .qty {
float: left;
text-align: left;
}
.cartContent .yard .item.head {
display: none;
}
}
@media only screen and (min-width: 768px) {
.cartContent .yard .total_price {
padding-top: 10px;
}
}
@media only screen and (min-width: 992px) {
.cartContent .yard .total_price {
padding-top: 30px;
}
}
@media only screen and (min-width: 1200px) {
.cartContent .yard .total_price {
padding-top: 10px;
}
}
*/
select.form-control:not([size]):not([multiple]) {
height: 38px;
color: #6f6f6f;
font-weight: 600;
}
.yard-items-head {
border-bottom: 1px solid #ddd;
padding-bottom: 8px;
margin-bottom: 8px;
}
.yard-item {
position: relative;
border-bottom: 1px solid #ddd;
padding-bottom: 8px;
}
.yard-item a.shop-item-hl {
color: #9aa983;
font-size: 1.1em;
font-weight: bold;
}
.yard-item .options {
margin-top: 4px;
}
.yard-item a.auto-delete-product {
font-size: 0.7em;
font-weight: bold;
text-transform: uppercase;
}
.yard-item .quantity {
position: relative;
}
.quantity-select {
text-align: right;
}
.quantity-select select.form-control:not([size]):not([multiple]) {
width: auto;
min-width: 5em;
display: inline-block;
}
.yard-item .price-total {
margin-top: 6px;
white-space: nowrap;
}
.yard-item .font-semi-bold {
color: #393939;
font-weight: 500;
}
.yard-item .font-semi-bold .small {
font-size: 1rem;
}
.yard-item .font-bold {
color:#393939;
font-weight: bold;
}
.price-single {
white-space: nowrap;
}
.btn-default {
border: none;
font-size: 0.9em;
}
</style>
<!-- -->
<section>
<div class="container">
<h1 class="mb-0">Warenkorb</h1>
<!-- EMPTY CART -->
<!-- <div class="panel panel-default">
<div class="panel-body">
<strong>Shopping cart is empty!</strong><br />
You have no items in your shopping cart.<br />
Click <a href="index.html">here</a> to continue shopping. <br />
<span class="label label-warning">this is just an empty cart example</span>
</div>
</div>-->
<!-- /EMPTY CART -->
<!-- CART -->
<div class="row">
<!-- LEFT -->
<div class="col-lg-9 col-md-8 col-sm-12">
<h4 class="weight-400">Du hast {{ Yard::instance('shopping')->count() }} Artikel in Deinem Warenkorb</h4>
@if(Yard::instance('shopping')->getShippingFree())
<div class="alert alert-success">Versandkostenfrei ab {{ formatNumber(Yard::instance('shopping')->getShippingFree()) }} &euro;**</div>
@endif
@if(Yard::instance('shopping')->content()->count())
<!-- CART -->
{!! Form::open(['url' => url(Util::getPostRoute().'card/update'), 'class' => 'cartContent clearfix', 'id'=>'']) !!}
<!-- cart content -->
<div id="cartContent">
<div class="yard-items-head">
<div class="row hidden-sm-down">
<div class="col-xs-3 col-sm-2">
</div>
<div class="col-xs-9 col-sm-10">
<div class="row">
<div class="col-sm-6 col-md-7">
Artikel
</div>
<div class="col-sm-3 col-md-2 text-left">
Einzelpreis
</div>
<div class="ol-sm-3 col-md-3 text-right">
Anzahl
</div>
</div>
</div>
</div>
</div>
@foreach(Yard::instance('shopping')->content() as $row)
@php($product = \App\Models\Product::find($row->id))
<div class="row yard-item">
<div class="col-xs-3 col-sm-2">
<a href="{{ url('/produkte/alle-produkte/'.$row->options->slug) }}" title="" class="image">
@if($row->options->has('image'))
<img src="{{ route('product_image', [$row->options->image]) }}" class="img-responsive" alt="">
@else
<img src="{{ asset('/assets/images/1x1.png') }}" width="80" alt="">
@endif
</a>
</div>
<div class="col-xs-9 col-sm-10">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-7 description">
<a href="{{ url('/produkte/alle-produkte/'.$row->options->slug) }}" class="shop-item-hl"><span>{{ $row->name }}</span></a>
<div style="font-size: 13px; color:#1d1d1d; font-weight: 500;">Inhalt: {{ $product->contents }}</div>
<div style="font-size: 13px; color:#1d1d1d; font-weight: 500;">Art.-Nr.: {{ $product->number }}</div>
<div style="font-size: 13px; color:#6e6e6e; font-weight: 400;"><em>Lieferzeit: 1-3 Werktage</em></div>
<div class="options">
<a class="auto-delete-product" href="{{ url(Util::getPostRoute().'card/remove', $row->rowId) }}"><i class="fa fa-times"></i> Artikel entfernen</a>
</div>
</div>
<div class="col-xs-6 col-sm-3 col-md-2 text-left font-semi-bold price-single">
<div style="">{{ $row->price() }} &euro;</div>
@if(Yard::instance('shopping')->isPriceCurrency())
<span class="small">~{{ Yard::instance('shopping')->getCurrencyByKey('price', $row, 2) }} {{ Yard::instance('shopping')->getPriceCurrencyUnit() }} </span>
@endif
<div class="small">{{ $product->getBasePriceFormattedFullWith(Yard::instance('shopping')->getUserTaxFree(), false, Yard::instance('shopping')->getUserCountry()) }}</div>
<div class="small">
@if(Yard::instance('shopping')->getUserTaxFree())
* Preis netto
@else
* inkl. {{ number_format($row->taxRate, 0)}}% MwSt.% MwSt.
@endif
</div>
</div>
<div class="col-xs-6 col-sm-3 col-md-3 quantity">
<div class="quantity-select">
<select class="form-control" name="quantity[{{$row->rowId}}]" onchange="this.form.submit()">
{!! HTMLHelper::getOptionRange($row->qty, 1, 50) !!}
</select>
</div>
<div class="price-total text-right">
<span class="font-bold text-price-total">{{ $row->subtotal() }}</span> &euro;
@if(Yard::instance('shopping')->isPriceCurrency())
<br>
<span class="small">~{{ Yard::instance('shopping')->getCurrencyByKey('subtotal', $row, 2) }} {{ Yard::instance('shopping')->getPriceCurrencyUnit() }} </span>
@endif
</div>
</div>
</div>
</div>
</div>
@endforeach
<a href="{{url(Util::getPostRoute().'card/delete')}}" class="btn btn-default btn-xs pull-left"><i class="glyphicon glyphicon-remove"></i> Warenkorb löschen</a>
<button type="submit" class="btn btn-xs btn-default pull-right "><i class="glyphicon glyphicon-refresh"></i> Warenkorb aktualisieren</button>
<div class="clearfix"></div>
</div>
{!! Form::close() !!}
<!-- /CART -->
@endif
</div>
<!-- RIGHT -->
<div class="col-sm-8 col-sm-offset-4 col-md-4 col-md-offset-0 col-lg-3 col-lg-offset-0">
@if(Yard::instance('shopping')->content()->count())
<h3>Warenkorb Summe</h3>
<div class="toggle-transparent toggle-bordered-full clearfix">
<div class="toggle active cart-content">
<div class="toggle-content">
<div class="clearfix mb-2">
<span class="pull-right">{{ Yard::instance('shopping')->total() }} €</span>
<strong class="pull-left">Zwischensumme:</strong>
</div>
<hr class="mt-4 mb-4">
<div class="clearfix mb-2">
<span class="pull-right small"> {{ Yard::instance('shopping')->getShippingCountryName() }}</span>
<span class="pull-left small">Lieferland:</span>
</div>
{{-- <div class="clearfix mb-2">
<div class=" small">Lieferland:</div>
<div class="small">
<form action="{{ url(Util::getPostRoute().'card/show') }}" method="GET" style="margin-bottom: 0;">
<select name="selected_country" class="form-control" onchange="this.form.submit()">
{!! HTMLHelper::getCountriesForShipping(Yard::instance('shopping')->getShippingCountryId(), false) !!}
</select>
</form>
</div>
</div>--}}
<div class="clearfix mb-2">
<span class="pull-right small">{{ Yard::instance('shopping')->shipping() }} € </span>
<span class="pull-left small"><a href="{{ url('/versandkosten') }}" style="color:#666666;text-decoration: underline">Versandkosten</a>:</span>
</div>
<hr class="mt-4 mb-4">
@if(Yard::instance('shopping')->getUserTaxFree())
<div class="clearfix mb-2" style="font-size: 90%">
<span class="pull-right small">{{ Yard::instance('shopping')->subtotalWithShipping() }} €</span>
<span class="pull-left small">Summe netto:</span>
</div>
@else
<div class="clearfix mb-2" style="font-size: 90%">
<span class="pull-right small">{{ Yard::instance('shopping')->subtotalWithShipping() }} €</span>
<span class="pull-left small">Summe ohne MwSt:</span>
</div>
<div class="clearfix mb-2" style="font-size: 90%">
<span class="pull-right small">{{ Yard::instance('shopping')->taxWithShipping() }} €</span>
<span class="pull-left small"> zzgl. {{-- Yard::getTaxRate() --}} MwSt:</span>
</div>
@endif
<hr />
<span class="clearfix ">
<span class="pull-right size-20"><strong>{{ Yard::instance('shopping')->totalWithShipping() }} €</strong></span>
<strong class="pull-left">Gesamtsumme:</strong>
</span>
<a href="{{ url(Util::getPostRoute().'card/checkout/server') }}" class="btn btn-primary btn-lg btn-block mt-4 btn-text-500 faa-parent animated-hover"><i class="fa fa-mail-forward faa-horizontal"></i> zur Kasse</a>
<hr>
<p class="text-center" style="line-height: 1.2em;"><em class="small text-center"> <i class="fa fa-lock"></i> Sie werden auf unseren checkout Server weitergeletet, die Verbindung ist mit SSL verschlüsselt.</em></p>
</div>
</div>
</div>
@endif
</div>
</div>
<br><br>
<hr>
<p><em class="small" style="color: #828282">Alle Preise inkl. gesetzl. Mehrwertsteuer <a href="{{ url('/versandkosten') }}" style="text-decoration: underline">zzgl. Versandkosten</a>, wenn nicht anders beschrieben</em></p>
<!-- /CART -->
</div>
</section>
@endsection

View file

@ -1,83 +0,0 @@
@extends($user_shop ?'web.user.layouts.layout' : 'web.layouts.layout')
@section('content')
<section>
<div class="container">
<div class="white-box">
<h3 class="box-title m-b-0">Allgemeinen Geschäftsbedingungen</h3>
<hr>
<br>
<strong>Grundlegendes</strong><br>
1) Die nachstehenden Geschäftsbedingungen gelten für alle Verträge, die Sie mit uns als Anbieter (mivita e.K.) über die Internetseite www.mivita.care schließen. Das Warenangebot in unserem Online-Shop richtet sich ausschließlich an volljährige Kunden. Der Einbeziehung von Allgemeinen Geschäftsbedingungen von Kunden, die diesen Geschäftsbedingungen widersprechen, wird bereits jetzt widersprochen. Die Vertragssprache ist deutsch. Sie können diese Geschäfts-bedingungen auf unserer Website abrufen und ausdrucken.
<br>
<br>
2) Den vollständigen Vertragstext speichern wir nicht. Die Vertragsdaten können Sie vor Absendung Ihrer Bestellung über das Online - Warenkorbsystem ausdrucken oder elektronisch sichern. Nach Zugang Ihrer Bestellung schicken wir Ihnen die Bestelldaten, die gesetzlich vorgeschriebenen Informationen bei Fernabsatzverträgen und die Allgemeinen Geschäftsbedingungen nochmals per Mail zu.
<br><br>
<strong>Grundlegendes</strong><br>
1) Unsere Warenangebote im Internet sind unverbindlich und stellen kein verbindliches Angebot zum Abschluss eines Vertrages dar. Sie können über unser Online - Warenkorbsystem eine Bestellung, also ein verbindliches Kaufangebot abgeben. Hierzu legen Sie die zum Kauf beabsichtigten Waren im „Warenkorb” ab. Über die entsprechende Schaltfläche in der Navigationsleiste können Sie den „Warenkorb” aufrufen und dort jederzeit Änderungen vornehmen. Nach Aufrufen der Seite „Kasse” und der Eingabe Ihrer persönlichen Daten sowie der Zahlungs- und Versandbedingungen werden abschließend nochmals alle Bestelldaten in einer Bestellübersicht angezeigt. Sie haben hier die Möglichkeit, vor der Absendung Ihrer Bestellung sämtliche Angaben nochmals zu überprüfen, zu ändern (auch über die Funktion „zurück” des Internetbrowsers) bzw. den Kauf abzubrechen. Durch Absendung der Bestellung über die Schaltfläche “Kaufen” geben Sie ein verbindliches Angebot zum Abschluss des Vertrages ab. Sie erhalten dann eine automatische Eingangsbestätigung per Mail, die noch nicht zum Vertragsschluss führt.
<br><br>
(2) Wir können Ihr Angebot innerhalb von 2 Tagen durch Übermittlung einer Bestellbestätigung per Mail annehmen. Sofern Sie innerhalb dieser Frist keine entsprechende Nachricht erhalten sollten, sind Sie nicht mehr an Ihre Bestellung gebunden. Gegebenenfalls bereits erbrachte Leistungen erstatten wir Ihnen in diesem Fall unverzüglich zurück.
<br><br>
(3) Die Abwicklung der Bestellung und Übermittlung aller im Zusammenhang mit dem Vertragsschluss erforderlichen Informationen erfolgt per Mail zum Teil automatisiert. Sie haben deshalb sicherzustellen, dass die von Ihnen bei uns hinterlegte Mail-Adresse zutreffend ist, der Empfang der Mails technisch sichergestellt und insbesondere nicht durch SPAM-Filter verhindert wird.
<br><br>
<strong>§ 3 Preise/Zahlungsmodalitäten</strong><br>
(1) Die in unseren Angeboten genannten Preise sowie die Versandkosten stellen Gesamtpreise dar. Sie beinhalten alle Preisbestandteile einschließlich aller anfallenden Steuern.
<br><br>
(2) Die Versandkosten sind nicht im Kaufpreis enthalten. Sie können über eine entsprechend bezeichnete Schaltfläche auf unserer Website oder in der jeweiligen Artikelbeschreibung abgerufen werden. Die Versandkosten werden weiterhin im Laufe des Bestellvorganges gesondert ausgewiesen und sind von Ihnen zusätzlich zu tragen, soweit nicht die versandkostenfreie Lieferung zugesagt ist.
<br><br>
(3) Wir bieten Ihnen verschiedene Zahlungsarten an. Diese sind unter einer entsprechend bezeichneten Schaltfläche auf unserer Website oder in der jeweiligen Artikelbeschreibung ausgewiesen. Soweit nicht anders angegeben, sind die Zahlungsansprüche aus dem geschlossenen Vertrag sofort zur Zahlung fällig.
<br><br>
<strong>§ 4 Lieferbedingungen</strong><br>
(1) Lieferbedingungen, Liefertermin und gegebenenfalls bestehende Lieferbeschränkungen können Sie auf einer entsprechend bezeichneten Schaltfläche auf unserer Website oder in der jeweiligen Artikelbeschreibung abrufen.
<br><br>
(2) Bei Verbrauchern geht die Gefahr des zufälligen Untergangs und der zufälligen Verschlechterung der verkauften Sache während der Versendung erst mit der Übergabe der Ware an diese über. Dies unabhängig davon, ob die Versendung versichert oder unversichert erfolgt. Dies gilt allerdings nicht, wenn Sie eigenständig ein nicht vom Unternehmer benanntes Transportunternehmen oder eine sonst zur Ausführung der Versendung bestimmte Person beauftragt haben.
<br><br>
(3) Bei Unternehmern erfolgt die Lieferung und Versendung auf eigene Gefahr.
<br><br>
<strong>§ 5 Zurückbehaltungsrecht, Eigentumsvorbehalt</strong><br>
(1) Ein Zurückbehaltungsrecht können Sie nur ausüben, soweit es sich um Forderungen aus demselben Vertragsverhältnis handelt.
<br><br>
(2) Die Ware bleibt bis zur vollständigen Zahlung des Kaufpreises unser Eigentum.
<br><br>
(3) Bei Unternehmern gilt ergänzend Folgendes:
<br><br>
- Wir behalten uns das Eigentum an der Ware bis zum vollständigen Ausgleich aller Forderungen aus der laufenden Geschäftsbeziehung vor. Vor Übergang des Eigentums an der Vorbehaltsware ist eine Verpfändung oder Sicherheitsübereignung nicht zulässig.
<br>
- Sie dürfen die Ware im ordentlichen Geschäftsgang weiterverkaufen. Für diesen Fall treten Sie bereits jetzt alle Forderungen in Höhe des Rechnungsbetrages, die Ihnen aus dem Weiterverkauf erwachsen, an uns ab. Wir nehmen die Abtretung an, Sie sind jedoch zur Einziehung der Forderungen ermächtigt. Soweit Sie Ihren Zahlungsverpflichtungen nicht ordnungsgemäß nachkommen, behalten wir uns das Recht vor, Forderungen selbst einzuziehen.
<br>
- Bei Verbindung und Vermischung der Vorbehaltsware erwerben wir Miteigentum an der neuen Sache im Verhältnis des Rechnungswertes der Vorbehaltsware zu den anderen verarbeiteten Gegenständen zum Zeitpunkt der Verarbeitung.
<br>
- Wir verpflichteten uns, die uns zustehenden Sicherheiten auf Verlangen insoweit freizugeben, als der realisierbare Wert unserer Sicherheiten die zu sichernden Forderungen um mehr als 10 % übersteigt. Die Auswahl der freizugebenden Sicherheiten obliegt uns.
<br><br>
<strong>§ 6 Gewährleistung</strong><br>
(1) Es bestehen die gesetzlichen Mängelhaftungsrechte.
<br><br>
(2) Bei Unternehmern gilt abweichend von Abs.1:
<br><br>
- als Unternehmer haben Sie die Ware unverzüglich und mit der gebotenen Sorgfalt auf Qualitäts- und Mengenabweichungen zu untersuchen und uns offensichtliche Mängel binnen 7 Tagen ab Empfang der Ware schriftlich anzuzeigen. Zur Fristwahrung genügt die rechtzeitige Absendung. Dies gilt auch für später festgestellte verdeckte Mängel ab Entdeckung. Sollten Sie Ihrer Untersuchungs- und Rügepflicht nicht nachkommen, ist die Geltendmachung von Gewährleistungsansprüchen ausgeschlossen.
<br>
- beim Vorliegen von Mängeln können wir nach unserer Wahl Gewähr durch Nachbesserung oder Ersatzlieferung leisten. Bei einem Fehlschlagen der Mängelbeseitigung können Sie nach Ihrer Wahl Minderung verlangen oder vom Vertrag zurücktreten. Die Mängelbeseitigung gilt nach erfolglosem zweiten Versuch als fehlgeschlagen, wenn sich nicht insbesondere aus der Art der Sache oder des Mangels oder den sonstigen Umständen etwas anderes ergibt. Im Falle der Nachbesserung müssen wir nicht die erhöhten Kosten tragen, die durch die Verbringung der Ware an einen anderen Ort als den Erfüllungsort entstehen, sofern die Verbringung nicht dem bestimmungsgemäßen Gebrauch der Ware entspricht.
<br>
- die Gewährleistungsfrist beträgt ein Jahr ab Ablieferung der Ware. Die verkürzte Gewährleistungsfrist gilt nicht für uns zurechenbare schuldhaft verursachte Schäden aus der Verletzung des Lebens, des Körpers oder der Gesundheit und grob fahrlässig oder vorsätzlich verursachte Schäden bzw. Arglist, sowie bei Rückgriffsansprüchen gemäß §§ 478, 479 BGB.
<br>
<strong>§ 7 Haftung</strong><br>
(1) Wir haften uneingeschränkt für Schäden aus der Verletzung des Lebens, des Körpers oder der Gesundheit. Weiterhin haften wir ohne Einschränkung in allen Fällen des Vorsatzes und grober Fahrlässigkeit, bei arglistigem Verschweigen eines Mangels, bei Übernahme der Garantie für die Beschaffenheit des Kaufgegenstandes und in allen anderen gesetzlich geregelten Fällen.
<br>
(2) Sofern wesentliche Vertragspflichten betroffen sind, ist unsere Haftung bei leichter Fahrlässigkeit auf den vertragstypischen, vorhersehbaren Schaden beschränkt. Wesentliche Vertragspflichten sind wesentliche Pflichten, die sich aus der Natur des Vertrages ergeben und deren Verletzung die Erreichung des Vertragszweckes gefährden würde sowie Pflichten, die der Vertrag uns nach seinem Inhalt zur Erreichung des Vertragszwecks auferlegt, deren Erfüllung die ordnungsgemäße Durchführung des Vertrags überhaupt erst möglich machen und auf deren Einhaltung Sie regelmäßig vertrauen dürfen.
<br>
<strong>§ 8 Schlussbestimmungen</strong><br>
(1) Es gilt deutsches Recht. Bei Verbrauchern gilt diese Rechtswahl nur, soweit hierdurch der durch zwingende Bestimmungen des Rechts des Staates des gewöhnlichen Aufenthaltes des Verbrauchers gewährte Schutz nicht entzogen wird (Günstigkeitsprinzip). Die Bestimmungen des UN-Kaufrechts finden ausdrücklich keine Anwendung.
<br><br>
(2) Erfüllungsort für alle Leistungen aus den mit uns bestehenden Geschäftsbeziehungen sowie Gerichtsstand ist unser Sitz, soweit Sie nicht Verbraucher, sondern Kaufmann, juristische Person des öffentlichen Rechts oder öffentlich-rechtliches Sondervermögen sind. Dasselbe gilt, wenn Sie keinen allgemeinen Gerichtsstand in Deutschland oder der EU haben oder der Wohnsitz oder gewöhnliche Aufenthalt im Zeitpunkt der Klageerhebung nicht bekannt ist. Die Befugnis, auch das Gericht an einem anderen gesetzlichen Gerichtsstand anzurufen, bleibt hiervon unberührt.
<br><br>
Stand: 05.10.2018
<br><br>
</div>
</div>
</section>
@endsection

View file

@ -1,231 +0,0 @@
@extends($user_shop ?'web.user.layouts.layout' : 'web.layouts.layout')
@section('content')
<section>
<div class="container">
<div class="white-box">
<h3 class="box-title m-b-0">Datenschutzerklärung</h3>
<hr>
<br>
Unsere Website kann grundsätzlich ohne Angabe personenbezogener Daten genutzt werden. Sofern Sie bestimmte Leistungen über unsere Website in Anspruch nehmen wollen, kann eine Verarbeitung Ihrer personenbezogenen Daten erforderlich werden.
<br>
Die Verarbeitung Ihrer personenbezogener Daten erfolgt stets in Übereinstimmung mit der Datenschutz-Grundverordnung (DSGVO) und den für uns geltenden landesspezifischen Datenschutzbestimmungen.
<br>
Wir haben nach Maßgabe des Art. 32 DSGVO geeignete technische und organisatorische Maßnahmen getroffen, um ein angemessenes Schutzniveau zu gewährleisten. Weiterhin haben wir Verfahren eingerichtet, die eine Wahrnehmung Ihrer Rechte, die Löschung von Daten und die Reaktion auf eine Gefährdung der Daten gewährleisten. Den Schutz Ihrer personenbezogenen Daten haben wir bereits bei der Entwicklung und Auswahl der verwendeten Hardware und Software berücksichtigt. Hiermit kommen wir dem Prinzip des Datenschutzes durch Technikgestaltung/durch datenschutzfreundliche Voreinstellungen nach, Art. 25 DSGVO. Zu unseren Sicherheitsmaßnahmen gehören insbesondere die verschlüsselte Übertragung (SSL-Verschlüsselung) von Daten zwischen Ihrem Browser und unserem Server.
<br><br>
<strong>I. Definitionen</strong>
<br>
Zur besseren Verständlichkeit unserer Datenschutzerklärung möchten wir Ihnen zunächst einige der verwendeten Begriffe erläutern. Im Sinne dieser Datenschutzerklärung bezeichnet der Ausdruck:
<br><br>
1) „personenbezogene Daten“ alle Informationen, die sich auf eine identifizierte oder identifizierbare natürliche Person (im Folgenden "betroffene Person") beziehen; als identifizierbar wird eine natürliche Person angesehen, die direkt oder indirekt, insbesondere mittels Zuordnung zu einer Kennung wie einem Namen, zu einer Kennnummer, zu Standortdaten, zu einer Online-Kennung oder zu einem oder mehreren besonderen Merkmalen identifiziert werden kann, die Ausdruck der physischen, physiologischen, genetischen, psychischen, wirtschaftlichen, kulturellen oder sozialen Identität dieser natürlichen Person sind;
<br><br>
2) „Verarbeitung“ jeden mit oder ohne Hilfe automatisierter Verfahren ausgeführten Vorgang oder jede solche Vorgangsreihe im Zusammenhang mit personenbezogenen Daten wie das Erheben, das Erfassen, die Organisation, das Ordnen, die Speicherung, die Anpassung oder Veränderung, das Auslesen, das Abfragen, die Verwendung, die Offenlegung durch Übermittlung, Verbreitung oder eine andere Form der Bereitstellung, den Abgleich oder die Verknüpfung, die Einschränkung, das Löschen oder die Vernichtung;
<br><br>
3) "Einschränkung der Verarbeitung" die Markierung gespeicherter personenbezogener Daten mit dem Ziel, ihre künftige Verarbeitung einzuschränken;
<br><br>
4) "Profiling" jede Art der automatisierten Verarbeitung personenbezogener Daten, die darin besteht, dass diese personenbezogenen Daten verwendet werden, um bestimmte persönliche Aspekte, die sich auf eine natürliche Person beziehen, zu bewerten, insbesondere um Aspekte bezüglich Arbeitsleistung, wirtschaftliche Lage, Gesundheit, persönliche Vorlieben, Interessen, Zuverlässigkeit, Verhalten, Aufenthaltsort oder Ortswechsel dieser natürlichen Person zu analysieren oder vorherzusagen;
<br><br>
5) "Pseudonymisierung" die Verarbeitung personenbezogener Daten in einer Weise, dass die personenbezogenen Daten ohne Hinzuziehung zusätzlicher Informationen nicht mehr einer spezifischen betroffenen Person zugeordnet werden können, sofern diese zusätzlichen Informationen gesondert aufbewahrt werden und technischen und organisatorischen Maßnahmen unterliegen, die gewährleisten, dass die personenbezogenen Daten nicht einer identifizierten oder identifizierbaren natürlichen Person zugewiesen werden;
<br><br>
6) „Verantwortliche“ die natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, die allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten entscheidet; sind die Zwecke und Mittel dieser Verarbeitung durch das Unionsrecht oder das Recht der Mitgliedstaaten vorgegeben, so kann der Verantwortliche beziehungsweise können die bestimmten Kriterien seiner Benennung nach dem Unionsrecht oder dem Recht der Mitgliedstaaten vorgesehen werden
<br><br>
7) „Auftragsverarbeiter“ eine natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, die personenbezogene Daten im Auftrag des Verantwortlichen verarbeitet;
<br><br>
8) „Empfänger“ eine natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, der personenbezogene Daten offengelegt werden, unabhängig davon, ob es sich bei ihr um einen Dritten handelt oder nicht. Behörden, die im Rahmen eines bestimmten Untersuchungsauftrags nach dem Unionsrecht oder dem Recht der Mitgliedstaaten möglicherweise personenbezogene Daten erhalten, gelten jedoch nicht als Empfänger; die Verarbeitung dieser Daten durch die genannten Behörden erfolgt im Einklang mit den geltenden Datenschutzvorschriften gemäß den Zwecken der Verarbeitung;
<br><br>
9) „Dritter“ eine natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, außer der betroffenen Person, dem Verantwortlichen, dem Auftragsverarbeiter und den Personen, die unter der unmittelbaren Verantwortung des Verantwortlichen oder des Auftragsverarbeiters befugt sind, die personenbezogenen Daten zu verarbeiten;
<br><br>
10) „Einwilligung“ der betroffenen Person jede freiwillig für den bestimmten Fall, in informierter Weise und unmissverständlich abgegebene Willensbekundung in Form einer Erklärung oder einer sonstigen eindeutigen bestätigenden Handlung, mit der die betroffene Person zu verstehen gibt, dass sie mit der Verarbeitung der sie betreffenden personenbezogenen Daten einverstanden ist;
<br><br>
11) „Verletzung des Schutzes personenbezogener Daten“ eine Verletzung der Sicherheit, die, ob unbeabsichtigt oder unrechtmäßig, zur Vernichtung, zum Verlust, zur Veränderung, oder zur unbefugten Offenlegung von beziehungsweise zum unbefugten Zugang zu personenbezogenen Daten führt, die übermittelt, gespeichert oder auf sonstige Weise verarbeitet wurden.
<br><br>
<strong>II. Verantwortlicher</strong>
<br>
Verantwortlicher im Sinne der Datenschutz-Grundverordnung sowie der in den Mitgliedstaaten der Europäischen Union geltenden Datenschutzgesetze und anderer datenschutzrechtlicher Bestimmungen ist:
<br><br>
<strong>mivita e.K.</strong><br>
Herr Alois Ried<br>
Leinfeld 2<br>
87755 Kirchhaslach<br>
Telefon: +49 (0) 8333 946 17 67<br>
Mail: info@mivita.care<br>
<br><br>
<strong>III. Cookies</strong>
<br>
Unsere Website verwendet Cookies. Cookies sind kleine Textdateien, die über einen Internetbrowser auf einem Computersystem abgelegt und gespeichert werden.
<br>
Zahlreiche Websites und Server verwenden Cookies. Viele Cookies enthalten eine sogenannte Cookie-ID. Eine Cookie-ID ist eine eindeutige Kennung des Cookies. Sie besteht aus einer Zeichenfolge, durch die Websites und Server dem konkreten Internetbrowser zugeordnet werden können, in dem das Cookie gespeichert wurde. Dies ermöglicht es den besuchten Websites und Servern, den individuellen Browser der betroffenen Person von anderen Internetbrowsern, die andere Cookies enthalten, zu unterscheiden. Ein bestimmter Internetbrowser kann über die eindeutige Cookie-ID wiedererkannt und identifiziert werden.
<br>
Durch den Einsatz von Cookies können wir Ihnen nutzerfreundlichere Services bereitstellen, die ohne die Cookie-Setzung nicht möglich wären.
<br>
Mittels eines Cookies können die Informationen und Angebote auf unserer Website im Sinne des Benutzers optimiert werden. Cookies ermöglichen uns, wie bereits erwähnt, die Benutzer unserer Website wiederzuerkennen. Zweck dieser Wiedererkennung ist es, Ihnen die Verwendung unserer Websites zu erleichtern. Der Benutzer einer Website, die Cookies verwendet, muss beispielsweise nicht bei jedem Besuch der Internetseite erneut seine Zugangsdaten eingeben, weil dies von der Internetseite und dem auf dem Computersystem des Benutzers abgelegten Cookie übernommen wird.
<br>
Die durch Cookies verarbeiteten Daten sind für die genannten Zwecke zur Wahrung unserer berechtigten Interessen nach Art. 6 Abs. 1 S. 1 lit. f DSGVO erforderlich.
<br>
Sie können die Setzung von Cookies durch unsere Website jederzeit mittels einer entsprechenden Einstellung des genutzten Internetbrowsers verhindern und damit der Setzung von Cookies dauerhaft widersprechen. Ferner können bereits gesetzte Cookies jederzeit über einen Internetbrowser oder andere Softwareprogramme gelöscht werden. Dies ist in allen gängigen Internetbrowsern möglich. Sollten Sie die Setzung von Cookies in dem von Ihnen genutzten Internetbrowser deaktiveren, sind unter Umständen nicht alle Funktionen unserer Website vollumfänglich nutzbar.
<br><br>
IV. Daten und Informationen, die beim Aufruf unserer Website gespeichert werden
<br>
Bei jedem Aufruf unserer Website werden allgemeine Daten und Informationen erfasst, die in den Logfiles des Servers gespeichert werden.
<br><br>
<strong>Folgende Daten/Informationen können erfasst werden:</strong>
<br>
- die verwendeten Browsertypen und Versionen
- das verwendete Betriebssystem,
- die Website, von der Sie auf unsere Website gelangen
- die Unterwebsites, die auf unserer Website angesteuert werden
- das Datum und die Uhrzeit des Zugriffs auf unsere Website,
- Ihre IP-Adresse
- Ihr Internet-Service-Provider
- sonstige ähnliche Daten und Informationen, die der Gefahrenabwehr im Falle von Angriffen auf unsere IT-Systeme dienen.
<br><br>
Wir benötigen diese Informationen, um die Inhalte unserer Website zutreffend bereitstellen zu können. die dauerhafte Funktionsfähigkeit unseres IT-Systems gewährleisten zu können und um im Falle eines Cyberangriffes den Behörden die zu einer Strafverfolgung notwendigen Informationen bereitstellen zu können. Hierin liegt auch unser berechtigtes Interesse im Rahmen der Rechtsgrundlage für die Verarbeitung dieser Daten gemäß Art. 6 Abs. 1 lit. f DSGVO. Bei der Nutzung dieser allgemeinen Daten und Informationen ziehen wir keine Rückschlüsse auf die betroffene Person. Die anonymen Daten der Server-Logfiles speichern wir getrennt von allen personenbezogenen Daten.
V. Elektronische Kontaktaufnahme mit uns
<br><br>
Aufgrund der Regelungen des Telemediengesetzes (TMG) sind wir zur Angabe einer allgemeinen Mailadresse im Impressum unserer Website verpflichtet, über die Sie uns per Mail kontaktieren können. Weiterhin haben Sie die Möglichkeit, über Kontaktformulare auf unserer Website Kontakt mit uns aufzunehmen. Über die Kontaktformulare können Sie u.a. Anfragen zu den Produkten oder unserem Geschäft stellen bzw. sich als Berater bei uns bewerben. Die von Ihnen per Mail oder unsere Kontaktformulare an uns übermittelten personenbezogenen Daten werden automatisch für Zwecke der Bearbeitung oder der Kontaktaufnahme zu Ihnen gespeichert.
<br><br>
Mit Absenden Ihrer Nachricht willigen Sie in die Verarbeitung der übermittelten Daten ein. Die Verarbeitung erfolgt auf Grundlage des Art. 6 Abs. 1 lit. a DSGVO mit Ihrer Einwilligung. Sie können Ihre Einwilligung jederzeit durch Mitteilung an uns widerrufen, ohne dass die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Verarbeitung berührt wird. Ihre E-Mail-Adresse nutzen wir nur zur Bearbeitung Ihrer Anfrage. Ihre Daten werden anschließend gelöscht, sofern Sie der weitergehenden Verarbeitung und Nutzung nicht zugestimmt haben.
<br><br>
<strong>VI. Rechtsgrundlagen der Verarbeitung</strong>
<br>
Sofern wir bei Ihnen eine Einwilligung für einen bestimmten Verarbeitungszweck einholen, dient uns Art. 6 I lit. a DSGVO als Rechtsgrundlage für den Verarbeitungsvorgang.
<br><br>
Sofern die Verarbeitung personenbezogener Daten zur Erfüllung eines Vertrags erforderlich ist, beruht die Verarbeitung auf Art. 6 I lit. b DSGVO. Dies gilt ebenfalls für Verarbeitungsvorgänge, die zur Durchführung vorvertraglicher Maßnahmen erforderlich sind, etwa bei Anfragen zur unseren Produkten oder sonstigen Leistungen.
<br><br>
Sofern wir einer rechtlichen Verpflichtung unterliegen, durch die eine Verarbeitung von personenbezogenen Daten erforderlich wird, wie beispielsweise zur Erfüllung steuerlicher Pflichten, so ist Rechtsgrundlage für die Verarbeitung Art. 6 I lit. c DSGVO.
<br><br>
Sofern die Verarbeitung von personenbezogenen Daten erforderlich wird, um lebenswichtige Interessen der betroffenen Person oder einer anderen natürlichen Person zu schützen, würde die Verarbeitung auf Art. 6 I lit. d DSGVO beruhen.
<br><br>
Letztlich kann Art. 6 I lit. f DSGVO Rechtsgrundlage für einen Verarbeitungsvorgang sein. Dies ist dann der Fall, wenn der Verarbeitungsvorgang von keiner der vorgenannten Rechtsgrundlagen erfasst wird und die Verarbeitung zur Wahrung eines berechtigten Interesses unseres Unternehmens oder eines Dritten erforderlich ist, sofern die Interessen, Grundrechte und Grundfreiheiten des Betroffenen nicht überwiegen. Basiert die Verarbeitung personenbezogener Daten auf Artikel 6 I lit. f DSGVO ist unser berechtigtes Interesse die Durchführung unserer Geschäftstätigkeit zugunsten des Wohlergehens unserer Mitarbeiter/Anteilseigner.
<br><br>
<strong>VII. Gesetzliche oder vertragliche Vorschriften zur Bereitstellung der personenbezogenen Daten</strong>
<br>
Die Bereitstellung personenbezogener Daten ist zum Teil gesetzlich vorgeschrieben ist (z.B. Steuervorschriften) und kann sich auch aus vertraglichen Regelungen (z.B. Angaben zum Vertragspartner) ergeben. Für den Fall, dass Sie einen Vertrag mit uns abschließen wollen, ist es erforderlich, dass Sie uns personenbezogene Daten zur Verfügung stellen, die in der Folge durch uns verarbeitet werden. Eine Nichtbereitstellung der personenbezogenen Daten hätte zur Folge, dass wir keinen Vertrag mit Ihnen schließen können.
<br><br>
<strong>VIII. Routinemäßige Löschung/Sperrung von personenbezogenen Daten</strong>
<br>
Wir verarbeiten und speichern personenbezogene Daten nur für den Zeitraum, der zur Erreichung des Speicherungszwecks erforderlich ist oder sofern dies durch den Europäischen Richtlinien- und Verordnungsgeber oder einen anderen Gesetzgeber in Gesetzen oder Vorschriften vorgesehen wurde. Entfällt der Speicherungszweck oder läuft eine vom Europäischen Richtlinien- und Verordnungsgeber oder einem anderen zuständigen Gesetzgeber vorgeschriebene Speicherfrist ab, werden die personenbezogenen Daten routinemäßig und entsprechend den gesetzlichen Vorschriften gesperrt oder gelöscht.
<br><br>
Nach Ablauf der jeweiligen gesetzlichen Aufbewahrungsfrist werden die entsprechenden Daten routi-nemäßig gelöscht, sofern sie nicht mehr zur Vertragserfüllung oder Vertragsanbahnung erforderlich sind. Nach den gesetzlichen Vorgaben in Deutschland erfolgt die Aufbewahrung insbesondere für 10 Jahre gemäß §§ 147 Abs. 1 AO, 257 Abs. 1 Nr. 1 und 4, Abs. 4 HGB (Bücher, Aufzeichnungen, Lageberichte, Buchungsbelege, Handelsbücher, für Besteuerung relevanter Unterlagen, etc.) und 6 Jahre gemäß § 257 Abs. 1 Nr. 2 und 3, Abs. 4 HGB (Handelsbriefe).
<br><br>
<strong>IX. Ihre Rechte</strong>
<br>
<strong>1) Bestätigungs- und Auskunftsrecht</strong>
<br>
Sie haben das Recht, von uns eine Bestätigung darüber zu verlangen, ob betreffende personenbezogene Daten verarbeitet werden. Möchten Sie Recht in Anspruch nehmen, können sie sich hierzu jederzeit an uns wenden.
<br><br>
Sie haben weiterhin das Recht, von uns unentgeltliche Auskunft über die zu Ihrer Person gespeicherten personenbezogenen Daten und eine Kopie dieser Auskunft zu erhalten. Ferner steht Ihnen ein Auskunftsanspruch über folgende Informationen zu:
<br>
- die Verarbeitungszwecke
- die Kategorien personenbezogener Daten, die verarbeitet werden
- die Empfänger oder Kategorien von Empfängern, gegenüber denen die personenbezogenen Daten offengelegt worden sind oder noch offengelegt werden, insbesondere bei Empfängern in Drittländern oder bei internationalen Organisationen
- falls möglich die geplante Dauer, für die die personenbezogenen Daten gespeichert werden, oder, falls dies nicht möglich ist, die Kriterien für die Festlegung dieser Dauer
- das Bestehen eines Rechts auf Berichtigung oder Löschung der sie betreffenden personenbezogenen Daten oder auf Einschränkung der Verarbeitung durch den Verantwortlichen oder eines Widerspruchsrechts gegen diese Verarbeitung
- das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde
- wenn die personenbezogenen Daten nicht bei der betroffenen Person erhoben werden: Alle verfügbaren Informationen über die Herkunft der Daten
- das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling gemäß Artikel 22 Abs.1 und 4 DSGVO und - zumindest in diesen Fällen - aussagekräftige Informationen über die involvierte Logik sowie die Tragweite und die angestrebten Auswirkungen einer derartigen Verarbeitung für die betroffene Person
<br><br>
Ferner steht Ihnen ein Auskunftsrecht darüber zu, ob personenbezogene Daten an ein Drittland oder an eine internationale Organisation übermittelt wurden. Sofern dies der Fall ist, so steht Ihnen im Übrigen das Recht zu, Auskunft über die geeigneten Garantien im Zusammenhang mit der Übermittlung zu erhalten.
<br><br>
Möchten Sie dieses Auskunftsrecht in Anspruch nehmen, können sie sich hierzu jederzeit an uns wenden.
<br><br>
<strong>2) Recht auf Berichtigung</strong>
<br>
Sie haben das Recht, die unverzügliche Berichtigung sie betreffender unrichtiger personenbezogener Daten zu verlangen. Ferner steht Ihnen das Recht zu, unter Berücksichtigung der Zwecke der Verarbeitung, die Vervollständigung unvollständiger personenbezogener Daten - auch mittels einer ergänzenden Erklärung - zu verlangen.
<br><br>
Möchten Sie dieses Berichtigungsrecht in Anspruch nehmen, können sie sich hierzu jederzeit an uns wenden.
<br><br>
<strong>3) Recht auf Löschung („Recht auf „Vergessenwerden“)</strong>
<br>
Sie haben das Recht, von uns zu verlangen, dass die sie betreffenden personenbezogenen Daten unverzüglich gelöscht werden, sofern einer der folgenden Gründe zutrifft und soweit die Verarbeitung nicht erforderlich ist:
<br>
- Die personenbezogenen Daten wurden für solche Zwecke erhoben oder auf sonstige Weise verarbeitet, für welche sie nicht mehr notwendig sind;
- Sie widerrufen ihre Einwilligung, auf die sich die Verarbeitung gemäß Art. 6 Abs. 1 Buchstabe a DSGVO oder Art. 9 Abs. 2 Buchstabe a DSGVO stützte, und es fehlt an einer anderweitigen Rechtsgrundlage für die Verarbeitung;
- Sie legen gemäß Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung ein, und es liegen keine vorrangigen berechtigten Gründe für die Verarbeitung vor, oder Sie legen gemäß Art. 21 Abs. 2 DSGVO Widerspruch gegen die Verarbeitung ein;
- Die personenbezogenen Daten wurden unrechtmäßig verarbeitet;
- Die Löschung der personenbezogenen Daten ist zur Erfüllung einer rechtlichen Verpflichtung nach dem Unionsrecht oder dem Recht der Mitgliedstaaten erforderlich, dem wir unterliegen.
- Die personenbezogenen Daten wurden in Bezug auf angebotene Dienste der Informationsgesellschaft gemäß Art. 8 Abs. 1 DSGVO erhoben.
<br><br>
Sofern einer der oben genannten Gründe zutrifft und Sie die Löschung von personenbezogenen Daten, die bei uns gespeichert sind, veranlassen möchten, können sie sich hierzu jederzeit an uns wenden. Wir werden veranlassen, dass dem Löschverlangen unverzüglich nachgekommen wird.
<br>
Wurden die personenbezogenen Daten von uns öffentlich gemacht und sind wir als Verantwortlicher gemäß Art. 17 Abs. 1 DSGVO zur Löschung der personenbezogenen Daten verpflichtet, so treffen wir unter Berücksichtigung der verfügbaren Technologie und der Implementierungskosten angemessene Maßnahmen, auch technischer Art, um andere für die Datenverarbeitung Verantwortliche, welche die veröffentlichten personenbezogenen Daten verarbeiten, darüber in Kenntnis zu setzen, dass Sie von diesen anderen für die Datenverarbeitung Verantwortlichen die Löschung sämtlicher Links zu diesen personenbezogenen Daten oder von Kopien oder Replikationen dieser personenbezogenen Daten verlangt haben, soweit die Verarbeitung nicht erforderlich ist. Wir werden im Einzelfall das Notwendige veranlassen.
<br><br>
<strong>4) Recht auf Einschränkung der Verarbeitung</strong>
<br>
Sie haben das Recht, von uns die Einschränkung der Verarbeitung zu verlangen, wenn eine der folgenden Voraussetzungen gegeben ist:
<br>
- Die Richtigkeit der personenbezogenen Daten wird von Ihnen bestritten, und zwar für eine Dauer, die es uns ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen;
- Die Verarbeitung ist unrechtmäßig, Sie lehnen die Löschung der personenbezogenen Daten ab und verlangen stattdessen die Einschränkung der Nutzung der personenbezogenen Daten;
- Wir benötigen die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger, Sie benötigen sie jedoch zur Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen;
- Sie haben Widerspruch gegen die Verarbeitung gem. Art. 21 Abs. 1 DSGVO eingelegt und es steht noch nicht fest, ob unsere berechtigten Gründe gegenüber Ihren überwiegen.
<br>
Sofern eine der oben genannten Voraussetzungen gegeben ist und Sie die Einschränkung von personenbezogenen Daten, die bei uns gespeichert sind, verlangen möchten, können Sie sich hierzu jederzeit an uns wenden. Wir werden die Einschränkung der Verarbeitung veranlassen.
<br><br>
<strong>5) Recht auf Datenübertragbarkeit</strong>
<br>
Sie haben das Recht, von uns die sie betreffenden personenbezogenen Daten, welche von Ihnen bereitgestellt wurden, in einem strukturierten, gängigen und maschinenlesbaren Format zu erhalten. Sie haben außerdem das Recht, diese Daten einem anderen Verantwortlichen ohne Behinderung durch uns zu übermitteln, sofern die Verarbeitung auf der Einwilligung gemäß Art. 6 Abs. 1 Buchstabe a DSGVO oder Art. 9 Abs. 2 Buchstabe a DSGVO oder auf einem Vertrag gemäß Art. 6 Abs. 1 Buchstabe b DSGVO beruht und die Verarbeitung mithilfe automatisierter Verfahren erfolgt, sofern die Verarbeitung nicht für die Wahrnehmung einer Aufgabe erforderlich ist, die im öffentlichen Interesse liegt oder in Ausübung öffentlicher Gewalt erfolgt, welche uns übertragen wurde.
<br><br>
Ferner haben Sie bei der Ausübung ihres Rechts auf Datenübertragbarkeit gemäß Art. 20 Abs. 1 DSGVO das Recht, zu erwirken, dass die personenbezogenen Daten direkt von uns an einen anderen Verantwortlichen übermittelt werden, soweit dies technisch machbar ist und sofern hiervon nicht die Rechte und Freiheiten anderer Personen beeinträchtigt werden.
<br><br>
Zur Geltendmachung des Rechts auf Datenübertragbarkeit können Sie sich jederzeit an uns wenden.
<br><br>
<strong>6) Recht auf Widerspruch</strong>
<br>
Sie haben das Recht, aus Gründen, die sich aus ihrer besonderen Situation ergeben, jederzeit gegen die Verarbeitung sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 Buchstaben e oder f DSGVO erfolgt, Widerspruch einzulegen. Dies gilt auch für ein auf diese Bestimmungen gestütztes Profiling.
<br><br>
Wir verarbeiten die personenbezogenen Daten im Falle des Widerspruchs nicht mehr, es sei denn, wir können zwingende schutzwürdige Gründe für die Verarbeitung nachweisen, die Ihre Interessen, Rechte und Freiheiten überwiegen, oder die Verarbeitung dient der Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen.
<br>
Verarbeiten wir personenbezogene Daten, um Direktwerbung zu betreiben, so haben Sie das Recht, jederzeit Widerspruch gegen die Verarbeitung der personenbezogenen Daten zum Zwecke derartiger Werbung einzulegen. Dies gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht. Widersprechen Sie der Verarbeitung für Zwecke der Direktwerbung, so werden wir die personenbezogenen Daten nicht mehr für diese Zwecke verarbeiten.
<br><br>
Zudem haben Sie das Recht, aus Gründen, die sich aus ihrer besonderen Situation ergeben, gegen die sie betreffende Verarbeitung personenbezogener Daten, die bei uns zu wissenschaftlichen oder historischen Forschungszwecken oder zu statistischen Zwecken gemäß Art. 89 Abs. 1 DSGVO erfolgen, Widerspruch einzulegen, es sei denn, eine solche Verarbeitung ist zur Erfüllung einer im öffentlichen Interesse liegenden Aufgabe erforderlich.
<br><br>
Zur Ausübung des Rechts auf Widerspruch können Sie sich an uns wenden. Es steht Ihnen frei, im Zusammenhang mit der Nutzung von Diensten der Informationsgesellschaft, ungeachtet der Richtlinie 2002/58/EG, ihr Widerspruchsrecht mittels automatisierter Verfahren auszuüben, bei denen technische Spezifikationen verwendet werden.
<br><br>
<strong>7) Automatisierte Entscheidungen im Einzelfall einschließlich Profiling</strong>
<br>
Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung - einschließlich Profiling - beruhenden Entscheidung unterworfen zu werden, die Ihnen gegenüber rechtliche Wirkung entfaltet oder sie in ähnlicher Weise erheblich beeinträchtigt, sofern die Entscheidung nicht für den Abschluss oder die Erfüllung eines Vertrags zwischen Ihnen und uns erforderlich ist, oder aufgrund von Rechtsvorschriften der Union oder der Mitgliedstaaten, denen wir unterliegen, zulässig ist und diese Rechtsvorschriften angemessene Maßnahmen zur Wahrung Ihrer Rechte und Freiheiten enthalten oder mit Ihrer ausdrücklicher Einwilligung erfolgt.
<br><br>
Ist die Entscheidung für den Abschluss oder die Erfüllung eines Vertrags zwischen Ihnen und uns erforderlich oder erfolgt sie mit Ihrer ausdrücklicher Einwilligung, treffen wir angemessene Maßnahmen, um Ihre Rechte und Freiheiten sowie Ihre berechtigten Interessen zu wahren, wozu mindestens das Recht auf Erwirkung des Eingreifens einer Person seitens des Verantwortlichen, auf Darlegung des eigenen Standpunkts und auf Anfechtung der Entscheidung gehört.
<br><br>
Möchten Sie Rechte mit Bezug auf automatisierte Entscheidungen geltend machen, können Sie sich hierzu jederzeit an uns wenden.
<br><br>
<strong>8) Recht auf Widerruf einer datenschutzrechtlichen Einwilligung</strong>
<br>
Sie haben das Recht, eine Einwilligung zur Verarbeitung personenbezogener Daten jederzeit zu widerrufen.
Möchten Sie Ihr Recht auf Widerruf einer Einwilligung geltend machen, können Sie sich hierzu jederzeit an uns wenden.
<br><br>
<strong>9) Beschwerderecht bei der Aufsichtsbehörde</strong>
<br>
Sie haben gemäß Art. 77 DSGVO das Recht, sich bei der Aufsichtsbehörde zu beschweren, wenn Sie der Ansicht sind, dass die Verarbeitung Ihrer personenbezogenen Daten nicht rechtmäßig erfolgt.
<br><br>
<strong>X. Zusammenarbeit mit Auftragsverarbeitern/Dritten</strong>
<br>
Soweit wir im Rahmen unserer Datenverarbeitung Ihre Daten gegenüber anderen Personen/Unternehmen offenbaren, an diese übermitteln oder diesen Zugriff auf Ihre Daten gewähren, erfolgt dies ausschließlich auf Grundlage einer gesetzlichen Erlaubnis, Ihrer Einwilligung, einer rechtlichen Verpflichtung oder auf Grundlage unserer berechtigten Interessen. Wenn Dritte von uns mit der Verarbeitung von Daten auf Grundlage eines so genannten „Auftragsverarbeitungsvertrages“ beauftragt worden sind bzw. werden, geschieht dies auf Grundlage des Art. 28 DSGVO.
<br><br>
<strong>XI. Übermittlungen in Drittländer</strong>
<br>
Soweit wir Daten in einem Drittland verarbeiten oder dies im Rahmen der Inanspruchnahme von Diensten Dritter geschieht, erfolgt dies nur, wenn es zur Erfüllung unserer (vor)vertraglichen Pflichten, auf Grundlage Ihrer Einwilligung, aufgrund einer rechtlichen Verpflichtung oder auf Grundlage unserer berechtigten Interessen geschieht. Vorbehaltlich gesetzlicher oder vertraglicher Erlaubnisse verarbeiten oder lassen wir die Daten in einem Drittland nur beim Vorliegen der besonderen Voraussetzungen der Art. 44 ff. DSGVO verarbeiten. Dementsprechend erfolgt die Verarbeitung z.B. auf Grundlage besonderer Garantien, wie der offiziell anerkannten Feststellung eines der EU entsprechenden Datenschutzniveaus (z.B. für die USA durch das „Privacy Shield“) oder Beachtung offiziell anerkannter spezieller vertraglicher Verpflichtungen (so genannte „Standardvertragsklauseln“).
<br><br>
<strong>XII. Einbindung von Diensten und Inhalten Dritter</strong>
<br>
Wir setzen auf unserer Website basierend auf unseren berechtigten Interessen im Sinne des Art. 6 Abs. 1 lit. f. DSGVO Angebote von Drittanbietern ein, um deren Inhalte einbinden zu können. Die Anbieter dieser Inhalte erhalten Kenntnis über Ihre IP-Adresse, da ohne die Kenntnis über die IP-Adresse die Inhalte nicht an Ihren Browser übermittelt werden können. Hierbei bemühen wir uns, nur solche Inhalte von Drittanbietern zu verwenden, bei denen Ihre IP-Adresse ausschließlich zur Auslieferung der Inhalte verwendet wird. Es besteht weiterhin die Möglichkeit, dass Drittanbieter so genannte „Pixel-Tags“ - dies sind unsichtbare Grafiken, die auch als "Web Beacons" bezeichnet werden - für statistische oder Marketingzwecke verwenden. "Pixel-Tags" können Informationen, wie zum Beispiel den Besucherverkehr auf unserer Website, auswerten.
<br><br>
Nachfolgend geben wir Ihren eine Übersicht zu den von uns verwendeten Angeboten von Drittanbietern nebst Links zu deren Datenschutzerklärungen:
<br><br>
Externe Schriftarten von Google, LLC., https://www.google.com/fonts („Google Fonts“). Die Einbindung der Google Fonts erfolgt durch einen Serveraufruf bei Google (in der Regel in den USA). Die Datenschutzerklärung finden Sie hier: https://policies.google.com/privacy, Opt-Out: https://adssettings.google.com/authenticated
<br><br>
Videos der Plattform “YouTube” des Drittanbieters Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA. Die Datenschutzerklärung finden Sie hier: https://policies.google.com/privacy, Opt-Out: https://adssettings.google.com/authenticated
<br><br>
Stand: 01.10.2018
<br><br>
</div>
</div>
</section>
@endsection

View file

@ -1,80 +0,0 @@
@extends($user_shop ?'web.user.layouts.layout' : 'web.layouts.layout')
@section('content')
<section class="page-header page-header-xlg parallax parallax-3" style="background-image:url('/assets/images/vision-min.jpg')">
<div class="overlay dark-1"><!-- dark overlay [1 to 9 opacity] --></div>
<div class="container">
</div>
</section>
<!-- /PAGE HEADER -->
<section>
<div class="container">
<div class="row">
<!-- LEFT COLUMNS -->
<div class="col-md-9 col-sm-9 col-md-push-3 col-sm-push-3">
<h1>Erreichbarkeit mit Familie & Privatem</h1>
<div class="row">
<div class="col-md-4 col-sm-4">
<img class="img-fluid" src="/assets/images/1-min.jpg" alt="service" />
<p class="small"><em>Nesciunt tofu stumptown aliqua, retro synth master cleanse.</em></p>
</div>
<div class="col-md-8 col-sm-8">
<table class="table">
<tr>
<td><img class="" src="/assets/images/icons/icon_1.png" height="40px" width="40px" alt="" /></td>
<td><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p></td>
</tr>
<tr>
<td><img class="" src="/assets/images/icons/icon_2.png" height="40px" width="40px" alt="" /></td>
<td><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p></td>
</tr>
<tr>
<td><img class="" src="/assets/images/icons/icon_3.png" height="40px" width="40px" alt="" /></td>
<td><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p></td>
</tr>
<tr>
<td><img class="" src="/assets/images/icons/icon_4.png" height="40px" width="40px" alt="" /></td>
<td><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p></td>
</tr>
<tr>
<td><img class="" src="/assets/images/icons/icon_5.png" height="40px" width="40px" alt="" /></td>
<td><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p></td>
</tr>
</table>
</div>
</div>
<div class="col-md-12">
<hr>
</div>
<div class="col-md-12">
<h2>Mache Menschen glücklich ....</h2>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
<img class="img-fluid" src="/assets/images/produktfamilie.jpg" alt="" />
</div>
@include('web.templates._content_contact')
</div>
<!-- /LEFT COLUMNS -->
<!-- RIGHT COLUMNS -->
<div class="col-md-3 col-sm-3 col-md-pull-9 col-sm-pull-9">
@include('web.templates._bcategories')
</div>
<!-- /RIGHT COLUMNS -->
</div>
</div>
</section>
@endsection

Some files were not shown because too many files have changed in this diff Show more