Abo Einmalprodukte: Phasen 5-7, konfigurierbare Sperrfristen, Lokalisierung & Dashboard
Rechnung/Lieferschein: - PDF-Gruppierung Abo- vs. Einmal-Artikel (is_abo_addon), rueckwaertskompatibel - Vorschau-Command sales:preview-invoice (umgeht Test-System-Gate, ohne Rechnungsnummer) Reminder-Mail (vorbereitet, Cron inaktiv): - MailAboExecutionReminder + Template, abo:send-execution-reminder, Spalte onetime_reminder_sent_for - Berater -> Sales Center, Kunde -> Portal; Vorschau abo:preview-reminder - Datum-Fix: formatDateDB() statt formatDate() (ICU-Format) Sperrfristen konfigurierbar (Admin-Settings): - abo-lock-days-change (Liefertag + Abo-Produkte), abo-lock-days-pause-cancel - Meldungen mit :lock-Platzhalter; Pausieren/Kuendigen vom Change-Lock entkoppelt - Abo-Produkt-Aenderungen im Lock-Fenster server- + clientseitig eingefroren - Selbstbedienung: Add-only/Lock nach $view (kein Admin-Bypass), Stale-Cache-Fix beim Mengen-Update Dashboard: - Einmalprodukte-Card + Team-Abo-KPI-Card, News-Card responsiv (col-xl-6) Lokalisierung: - Sprachdateien en/es/fr vollstaendig mit de synchronisiert (inkl. marketingplan/portal) - LocalizationSyncTest sichert Key-Gleichheit ab Tests: AboOneTimeInvoiceGrouping, AboExecutionReminder, AboLockDaysSetting, AboOnetimeDashboardAndMail, PreviewInvoiceCommand, TeamAboOverview + erweiterte View-Tests Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9f996a7f1b
commit
65b867f8ee
96 changed files with 4154 additions and 1189 deletions
110
app/Console/Commands/AboSendExecutionReminder.php
Normal file
110
app/Console/Commands/AboSendExecutionReminder.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Mail\MailAboExecutionReminder;
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\AboHelper;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class AboSendExecutionReminder extends Command
|
||||
{
|
||||
/**
|
||||
* Reminder vor der Abo-Ausführung: weist auf das Zeitfenster für einmalige
|
||||
* Zusatzprodukte hin. Berater erhalten den Link ins Sales Center, Endkunden
|
||||
* ins Kundenportal.
|
||||
*/
|
||||
protected $signature = 'abo:send-execution-reminder {--dry-run : Nur zählen, nichts versenden}';
|
||||
|
||||
protected $description = 'Versendet Reminder-Mails für anstehende Abo-Lieferungen (Einmalprodukte-Fenster)';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$windowDays = AboHelper::getOneTimeWindowDays();
|
||||
$targetDate = Carbon::today()->addDays($windowDays);
|
||||
$dryRun = (bool) $this->option('dry-run');
|
||||
|
||||
$abos = UserAbo::query()
|
||||
->with(['user', 'shopping_user'])
|
||||
->where('active', true)
|
||||
->where('status', 2)
|
||||
->whereIn('is_for', ['me', 'ot'])
|
||||
->whereDate('next_date', $targetDate->toDateString())
|
||||
->where(function ($query) use ($targetDate): void {
|
||||
$query->whereNull('onetime_reminder_sent_for')
|
||||
->orWhereDate('onetime_reminder_sent_for', '!=', $targetDate->toDateString());
|
||||
})
|
||||
->get();
|
||||
|
||||
$sent = 0;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($abos as $abo) {
|
||||
$email = $this->recipientEmail($abo);
|
||||
|
||||
if (! $email) {
|
||||
$skipped++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$sent++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Mail::to($email)
|
||||
->locale($this->recipientLocale($abo))
|
||||
->send(new MailAboExecutionReminder($abo));
|
||||
|
||||
$abo->onetime_reminder_sent_for = $abo->next_date;
|
||||
$abo->save();
|
||||
$sent++;
|
||||
} catch (\Throwable $e) {
|
||||
$skipped++;
|
||||
Log::channel('abo_order')->error('AboSendExecutionReminder: Versand fehlgeschlagen', [
|
||||
'abo_id' => $abo->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->info(sprintf(
|
||||
'Reminder %s: %d versendet, %d übersprungen (Zieldatum %s, Fenster %d Tage).',
|
||||
$dryRun ? '(dry-run)' : '',
|
||||
$sent,
|
||||
$skipped,
|
||||
$targetDate->toDateString(),
|
||||
$windowDays
|
||||
));
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function recipientEmail(UserAbo $abo): ?string
|
||||
{
|
||||
if ($abo->email) {
|
||||
return $abo->email;
|
||||
}
|
||||
|
||||
if ($abo->is_for === 'me') {
|
||||
return $abo->user?->email;
|
||||
}
|
||||
|
||||
return $abo->shopping_user?->billing_email;
|
||||
}
|
||||
|
||||
private function recipientLocale(UserAbo $abo): string
|
||||
{
|
||||
$locale = $abo->is_for === 'me'
|
||||
? $abo->user?->getLocale()
|
||||
: $abo->shopping_user?->getLocale();
|
||||
|
||||
return $locale ?: 'de';
|
||||
}
|
||||
}
|
||||
67
app/Console/Commands/PreviewAboReminder.php
Normal file
67
app/Console/Commands/PreviewAboReminder.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Mail\MailAboExecutionReminder;
|
||||
use App\Models\UserAbo;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PreviewAboReminder extends Command
|
||||
{
|
||||
/**
|
||||
* Rendert die Abo-Ausführungs-Reminder-Mail für ein Abo als HTML-Vorschau
|
||||
* (und sendet sie optional via --send an eine Adresse, z. B. zum Test in Mailpit).
|
||||
* Verbraucht/ändert nichts am Abo.
|
||||
*/
|
||||
protected $signature = 'abo:preview-reminder {abo : UserAbo-ID} {--send= : Mail zusätzlich an diese Adresse senden (Mailpit-Test)}';
|
||||
|
||||
protected $description = 'Vorschau der Abo-Reminder-Mail erzeugen (HTML) und optional testweise versenden';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$abo = UserAbo::with(['user', 'shopping_user'])->find((int) $this->argument('abo'));
|
||||
|
||||
if (! $abo) {
|
||||
$this->error('UserAbo '.$this->argument('abo').' nicht gefunden.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$locale = $this->recipientLocale($abo);
|
||||
$originalLocale = App::getLocale();
|
||||
|
||||
App::setLocale($locale);
|
||||
try {
|
||||
$html = (new MailAboExecutionReminder($abo))->render();
|
||||
} finally {
|
||||
App::setLocale($originalLocale);
|
||||
}
|
||||
|
||||
$path = 'preview/abo-reminder-'.$abo->id.'.html';
|
||||
Storage::disk('public')->put($path, $html);
|
||||
|
||||
$url = preg_replace('#(?<!:)//+#', '/', Storage::disk('public')->url($path));
|
||||
$this->info("Reminder-Vorschau für Abo {$abo->id} (Locale {$locale}, ".($abo->is_for === 'me' ? 'Berater → Sales Center' : 'Endkunde → Portal').'):');
|
||||
$this->line(' HTML: '.$url);
|
||||
$this->line(' Datei: '.Storage::disk('public')->path($path));
|
||||
|
||||
if ($send = $this->option('send')) {
|
||||
Mail::to($send)->locale($locale)->send(new MailAboExecutionReminder($abo));
|
||||
$this->info(" Mail an {$send} versendet (siehe Mailpit).");
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function recipientLocale(UserAbo $abo): string
|
||||
{
|
||||
$locale = $abo->is_for === 'me'
|
||||
? $abo->user?->getLocale()
|
||||
: $abo->shopping_user?->getLocale();
|
||||
|
||||
return $locale ?: 'de';
|
||||
}
|
||||
}
|
||||
53
app/Console/Commands/PreviewInvoice.php
Normal file
53
app/Console/Commands/PreviewInvoice.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PreviewInvoice extends Command
|
||||
{
|
||||
/**
|
||||
* Erzeugt eine Vorschau der Rechnungs-/Lieferschein-PDFs einer Bestellung,
|
||||
* ohne eine offizielle Rechnung anzulegen (keine Rechnungsnummer, kein Tracking).
|
||||
* Nützlich auf Testsystemen, wo die reguläre Rechnungserzeugung deaktiviert ist.
|
||||
*/
|
||||
protected $signature = 'sales:preview-invoice {order : ShoppingOrder-ID}';
|
||||
|
||||
protected $description = 'Vorschau-PDFs (Rechnung + Lieferschein) einer Bestellung erzeugen – ohne offizielle Rechnung';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$orderId = (int) $this->argument('order');
|
||||
$order = ShoppingOrder::with('shopping_order_items.product')->find($orderId);
|
||||
|
||||
if (! $order) {
|
||||
$this->error("ShoppingOrder {$orderId} nicht gefunden.");
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
try {
|
||||
$paths = (new InvoiceRepository($order))->makePreview();
|
||||
} catch (\Throwable $e) {
|
||||
$this->error('Fehler bei der Vorschau-Erzeugung: '.$e->getMessage());
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info("Vorschau für Bestellung {$orderId} erzeugt (keine offizielle Rechnung, keine Nummer verbraucht):");
|
||||
foreach ($paths as $type => $path) {
|
||||
$label = $type === 'invoice' ? 'Rechnung ' : 'Lieferschein';
|
||||
$url = preg_replace('#(?<!:)//+#', '/', Storage::disk('public')->url($path));
|
||||
$this->line(" {$label}: ".$url);
|
||||
$this->line(" {$label} (Datei): ".Storage::disk('public')->path($path));
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->comment('Hinweis: Der Umsatzpunkte-Block entfällt in der Vorschau (kein Tracking).');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,9 @@ class UserMakeAboOrder extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:make_abo_order';
|
||||
protected $signature = 'user:make_abo_order
|
||||
{--abo= : Nur dieses eine Abo (ID) ausführen}
|
||||
{--force : Datums- und Duplikatsprüfung überspringen (manueller Testlauf)}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
|
|
@ -89,17 +91,38 @@ class UserMakeAboOrder extends Command
|
|||
private function checkAbosToOrder()
|
||||
{
|
||||
$dateNow = Carbon::now()->format('Y-m-d');
|
||||
$forceAboId = $this->option('abo') !== null ? (int) $this->option('abo') : null;
|
||||
$force = (bool) $this->option('force');
|
||||
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', ['date' => $dateNow]);
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', [
|
||||
'date' => $dateNow,
|
||||
'force_abo_id' => $forceAboId,
|
||||
'force' => $force,
|
||||
]);
|
||||
|
||||
// Prüfe auf bereits verarbeitete Abos am heutigen Tag (Duplikatsprüfung)
|
||||
$userAbos = UserAbo::where('next_date', '=', $dateNow)
|
||||
->where('active', true)
|
||||
->where('status', '=', 2) // abo_okay
|
||||
->whereDoesntHave('user_abo_orders', function ($query) use ($dateNow) {
|
||||
$query->whereDate('created_at', $dateNow);
|
||||
})
|
||||
->get();
|
||||
if ($force) {
|
||||
$this->warn('FORCE-Modus aktiv: Datums-/Duplikatsprüfung wird übersprungen (echte Bestellung + Zahlung!).');
|
||||
}
|
||||
|
||||
$query = UserAbo::query();
|
||||
|
||||
if ($forceAboId !== null) {
|
||||
$query->where('id', $forceAboId);
|
||||
} else {
|
||||
$query->where('next_date', '=', $dateNow);
|
||||
}
|
||||
|
||||
// Im Force-Modus werden die regulären Filter (fällig/aktiv/status/Duplikat) übersprungen,
|
||||
// damit ein einzelnes Abo on-demand getestet werden kann.
|
||||
if (! $force) {
|
||||
$query->where('active', true)
|
||||
->where('status', '=', 2) // abo_okay
|
||||
->whereDoesntHave('user_abo_orders', function ($query) use ($dateNow) {
|
||||
$query->whereDate('created_at', $dateNow);
|
||||
});
|
||||
}
|
||||
|
||||
$userAbos = $query->get();
|
||||
|
||||
$count = $userAbos->count();
|
||||
\Log::channel('abo_order')->info("UserMakeAboOrder: {$count} fällige Abos gefunden (ohne bereits verarbeitete)");
|
||||
|
|
@ -115,14 +138,15 @@ class UserMakeAboOrder extends Command
|
|||
|
||||
try {
|
||||
// Locking-Mechanismus: Verhindert Race Conditions bei paralleler Ausführung
|
||||
$shoppingOrder = DB::transaction(function () use ($userAbo, $dateNow) {
|
||||
$shoppingOrder = DB::transaction(function () use ($userAbo, $dateNow, $force) {
|
||||
// Lock das Abo für Update, um Race Conditions zu vermeiden
|
||||
$lockedAbo = UserAbo::where('id', $userAbo->id)
|
||||
->where('next_date', '=', $dateNow)
|
||||
->where('active', true)
|
||||
->where('status', '=', 2) // abo_okay
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
$lockQuery = UserAbo::where('id', $userAbo->id);
|
||||
if (! $force) {
|
||||
$lockQuery->where('next_date', '=', $dateNow)
|
||||
->where('active', true)
|
||||
->where('status', '=', 2); // abo_okay
|
||||
}
|
||||
$lockedAbo = $lockQuery->lockForUpdate()->first();
|
||||
|
||||
if (! $lockedAbo) {
|
||||
\Log::channel('abo_order')->warning('UserMakeAboOrder: Abo wurde bereits verarbeitet oder ist nicht mehr aktiv', [
|
||||
|
|
@ -132,18 +156,20 @@ class UserMakeAboOrder extends Command
|
|||
return null;
|
||||
}
|
||||
|
||||
// Nochmalige Prüfung auf Duplikat innerhalb der Transaktion
|
||||
$existingOrder = UserAboOrder::where('user_abo_id', $lockedAbo->id)
|
||||
->whereDate('created_at', $dateNow)
|
||||
->first();
|
||||
// Nochmalige Prüfung auf Duplikat innerhalb der Transaktion (im Force-Modus übersprungen)
|
||||
if (! $force) {
|
||||
$existingOrder = UserAboOrder::where('user_abo_id', $lockedAbo->id)
|
||||
->whereDate('created_at', $dateNow)
|
||||
->first();
|
||||
|
||||
if ($existingOrder) {
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Abo wurde bereits heute verarbeitet', [
|
||||
'abo_id' => $lockedAbo->id,
|
||||
'existing_order_id' => $existingOrder->shopping_order_id,
|
||||
]);
|
||||
if ($existingOrder) {
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Abo wurde bereits heute verarbeitet', [
|
||||
'abo_id' => $lockedAbo->id,
|
||||
'existing_order_id' => $existingOrder->shopping_order_id,
|
||||
]);
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->makeOrder($lockedAbo);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ class Kernel extends ConsoleKernel
|
|||
$schedule->command('user:cleanup')->dailyAt('03:30');
|
||||
$schedule->command('user:make_abo_order')->dailyAt('04:00');
|
||||
|
||||
// Abo-Einmalprodukte: Reminder-Mail vor der Ausführung (Einmalprodukte-Fenster).
|
||||
// BEWUSST INAKTIV bis zum Abschluss des Review-Gates (Feature aktuell nur VIP
|
||||
// im Sales Center, Portal ausgeblendet). Nach Freigabe einkommentieren:
|
||||
// $schedule->command('abo:send-execution-reminder')->dailyAt('06:00');
|
||||
|
||||
// Abo-Chart-Snapshots: vergangene Monate einfrieren (nach allen Abo-Jobs)
|
||||
$schedule->command('abo:store-chart-snapshots')->dailyAt('04:30');
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ use App\Models\DashboardNews;
|
|||
use App\Models\Incentive;
|
||||
use App\Models\IncentiveParticipant;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\AboHelper;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -61,12 +63,36 @@ class HomeController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
// Eigenes Abo des Beraters für die Einmalprodukte-Dashboard-Card (nur wenn
|
||||
// das Zeitfenster offen ist und das Feature für den User sichtbar ist).
|
||||
$oneTimeAbo = null;
|
||||
$aboOneTimeId = UserAbo::where('user_id', $user->id)
|
||||
->where('is_for', 'me')
|
||||
->where('active', true)
|
||||
->where('status', 2)
|
||||
->value('id');
|
||||
|
||||
if ($aboOneTimeId) {
|
||||
$abo = UserAbo::find($aboOneTimeId);
|
||||
if ($abo && AboHelper::isOneTimeWindowOpen($abo) && AboHelper::isOneTimeFeatureVisible($abo)) {
|
||||
$oneTimeAbo = $abo;
|
||||
}
|
||||
}
|
||||
|
||||
$teamAboKpis = null;
|
||||
if ($user->isActiveAccount()) {
|
||||
$teamAboKpis = app(\App\Services\Abo\TeamAboOverviewService::class)
|
||||
->teamKpis($user, (int) Carbon::now()->month, (int) Carbon::now()->year);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'user' => $user,
|
||||
'now' => Carbon::now(),
|
||||
'dashboardNews' => DashboardNews::getActiveNews(),
|
||||
'activeIncentive' => $activeIncentive,
|
||||
'incentiveParticipant' => $incentiveParticipant,
|
||||
'oneTimeAbo' => $oneTimeAbo,
|
||||
'teamAboKpis' => $teamAboKpis,
|
||||
];
|
||||
|
||||
return view('home', $data);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class AboController extends Controller
|
|||
|
||||
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
|
||||
$user_abo = UserAbo::where('email', $shopping_user->billing_email)
|
||||
->where('status', '>', 1)
|
||||
->where('status', '>=', 1)
|
||||
->first();
|
||||
|
||||
if (! $user_abo) {
|
||||
|
|
@ -99,6 +99,8 @@ class AboController extends Controller
|
|||
$user_abo = UserAbo::findOrFail($id);
|
||||
$this->checkPortalPermission($user_abo);
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
// Sperrfrist (Liefertag/Abo-Produkte): innerhalb des Fensters keine Produktänderungen.
|
||||
$changeLocked = AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'abo_update_settings') {
|
||||
|
|
@ -116,8 +118,15 @@ class AboController extends Controller
|
|||
// Yard für Gewichts-/Versandprüfung initialisieren (Versandland setzen)
|
||||
AboOrderCart::initYard($user_abo);
|
||||
|
||||
if ($changeLocked) {
|
||||
$message = __('abo.error_change_locked', [
|
||||
'days' => (int) now()->diffInDays(\Carbon\Carbon::parse($user_abo->next_date), false),
|
||||
'lock' => \App\Repositories\AboRepository::getLockDaysChange(),
|
||||
]);
|
||||
}
|
||||
|
||||
// addProduct
|
||||
if ($data['action'] === 'addProduct') {
|
||||
if (! $changeLocked && $data['action'] === 'addProduct') {
|
||||
if ($product = Product::find($data['product_id'])) {
|
||||
if (AboOrderCart::exceedsMaxWeight($user_abo, (int) $product->weight)) {
|
||||
$message = __('msg.cart_max_weight_reached');
|
||||
|
|
@ -140,7 +149,7 @@ class AboController extends Controller
|
|||
}
|
||||
|
||||
// updateCart
|
||||
if ($data['action'] === 'updateCart') {
|
||||
if (! $changeLocked && $data['action'] === 'updateCart') {
|
||||
if (isset($data['product_id']) && $product = Product::find($data['product_id'])) {
|
||||
if (isset($data['order_item_id']) && $UserAboItem = UserAboItem::find($data['order_item_id'])) {
|
||||
if (isset($data['qty'])) {
|
||||
|
|
@ -165,7 +174,7 @@ class AboController extends Controller
|
|||
}
|
||||
|
||||
// removeFromCart
|
||||
if ($data['action'] === 'removeFromCart') {
|
||||
if (! $changeLocked && $data['action'] === 'removeFromCart') {
|
||||
if ($isAddOnlyMode) {
|
||||
return response()->json([
|
||||
'response' => false,
|
||||
|
|
@ -190,7 +199,7 @@ class AboController extends Controller
|
|||
}
|
||||
|
||||
// updateCompProduct
|
||||
if ($data['action'] === 'updateCompProduct') {
|
||||
if (! $changeLocked && $data['action'] === 'updateCompProduct') {
|
||||
if ($UserAboItem = UserAboItem::where('user_abo_id', $user_abo->id)->where('comp', $data['comp_num'])->first()) {
|
||||
$oldProduct = $UserAboItem->product;
|
||||
$UserAboItem->product_id = $data['comp_product_id'];
|
||||
|
|
@ -217,6 +226,10 @@ class AboController extends Controller
|
|||
}
|
||||
AboOrderCart::checkNumOfCompProducts($user_abo);
|
||||
|
||||
// Relation neu laden, damit die gerenderte Menge dem gespeicherten Stand entspricht
|
||||
// (sonst zeigt _order_abo_show die gecachte alte Menge → Feld „springt" zurück).
|
||||
$user_abo->load('user_abo_items');
|
||||
|
||||
$summary = AboOrderCart::getSplitSummary();
|
||||
$error_message = $message ? $message : false;
|
||||
$html_cart = view('admin.abo._order_abo_show', [
|
||||
|
|
@ -225,6 +238,7 @@ class AboController extends Controller
|
|||
'split_mode' => AboHelper::isOneTimeFeatureVisible($user_abo),
|
||||
'summary' => $summary,
|
||||
'add_only_mode' => $isAddOnlyMode,
|
||||
'change_locked' => $changeLocked,
|
||||
])->render();
|
||||
$html_comp = view('user.order.comp_product', array_merge($data, [
|
||||
'cart_instance' => AboOrderCart::INSTANCE,
|
||||
|
|
@ -353,6 +367,7 @@ class AboController extends Controller
|
|||
$user_abo = UserAbo::findOrFail($id);
|
||||
$this->checkPortalPermission($user_abo);
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
$changeLocked = AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
|
||||
if (! AboHelper::isOneTimeFeatureVisible($user_abo)) {
|
||||
return response()->json([
|
||||
|
|
@ -389,6 +404,7 @@ class AboController extends Controller
|
|||
'summary' => $summary,
|
||||
'only_show_products' => false,
|
||||
'add_only_mode' => $isAddOnlyMode,
|
||||
'change_locked' => $changeLocked,
|
||||
])->render(),
|
||||
'html_summary' => view('admin.abo._order_combined_summary', [
|
||||
'summary' => $summary,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers\User;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Abo\AboOneTimeItemRequest;
|
||||
use App\Models\Product;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboItem;
|
||||
use App\Models\UserAboOneTimeItem;
|
||||
|
|
@ -13,6 +14,7 @@ use App\Services\AboHelper;
|
|||
use App\Services\AboItemHistoryService;
|
||||
use App\Services\AboOrderCart;
|
||||
use App\Services\AboRetryPaymentService;
|
||||
use App\Services\OrderPaymentService;
|
||||
use App\Services\Shop;
|
||||
use App\User;
|
||||
use Request;
|
||||
|
|
@ -33,15 +35,25 @@ class AboController extends Controller
|
|||
|
||||
if ($view === 'me') {
|
||||
// Nur Abos des aktuellen Benutzers
|
||||
$user_abos = UserAbo::where('user_id', \Auth::user()->id)
|
||||
->where('status', '>', 1);
|
||||
$baseQuery = UserAbo::where('user_id', \Auth::user()->id)
|
||||
->where('status', '>=', 1)
|
||||
->where('is_for', 'me');
|
||||
|
||||
if ((clone $baseQuery)->where('status', 1)->exists()) {
|
||||
return view('user.abo.index', [
|
||||
'user_abos' => (clone $baseQuery)->orderBy('id', 'desc')->get(),
|
||||
'view' => 'me',
|
||||
'isAdmin' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
$user_abos = (clone $baseQuery)->orderBy('id', 'desc')->get();
|
||||
if ($user_abos->count() > 0) {
|
||||
return redirect(route('user_abos_detail', ['me', $user_abos->first()->id]));
|
||||
}
|
||||
|
||||
return view('user.abo.index', [
|
||||
'user_abos' => [],
|
||||
'user_abos' => $user_abos,
|
||||
'view' => 'me',
|
||||
'isAdmin' => false,
|
||||
]);
|
||||
|
|
@ -49,23 +61,28 @@ class AboController extends Controller
|
|||
|
||||
if ($view === 'ot') {
|
||||
$selectedYear = (int) \Request::get('year', now()->year);
|
||||
$selectedMonth = (int) \Request::get('month', 0);
|
||||
$baseQuery = UserAbo::where('member_id', \Auth::user()->id)
|
||||
->where('status', '>', 1)
|
||||
->where('status', '>=', 1)
|
||||
->where('is_for', 'ot');
|
||||
|
||||
$user_abos = (clone $baseQuery)
|
||||
->with(['user_abo_items', 'user_abo_items.product', 'shopping_user'])
|
||||
->addedInMonth($selectedYear, $selectedMonth)
|
||||
->orderBy('id', 'desc')
|
||||
->get();
|
||||
|
||||
return view('user.abo.index', [
|
||||
'user_abos' => $user_abos,
|
||||
'abo_payment_links' => $this->getAboPaymentLinks(),
|
||||
'view' => 'ot',
|
||||
'isAdmin' => false,
|
||||
'chartData' => AboHelper::getMonthlyAboCounts($baseQuery, $selectedYear, 'ot', \Auth::user()->id),
|
||||
'chartYear' => $selectedYear,
|
||||
'chartYears' => \App\Services\HTMLHelper::getYearRange(2026),
|
||||
'chartMonths' => \App\Services\HTMLHelper::getTransMonths(),
|
||||
'filterMonth' => $selectedMonth,
|
||||
'filterYear' => $selectedYear,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +140,11 @@ class AboController extends Controller
|
|||
$user_abo = UserAbo::findOrFail($id);
|
||||
$this->checkPermissions($view, $user_abo);
|
||||
$editView = \Auth::user()?->isAdmin() ? 'admin' : $view;
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $editView);
|
||||
// Add-only (Mindestlaufzeit) und Change-Lock richten sich nach der Abo-Sicht ($view),
|
||||
// NICHT nach Admin-Status – auf der Selbstbedienungs-Seite gelten für alle (auch VIP/Admin)
|
||||
// die Berater-Regeln. $editView dient nur dem History-Logging.
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
$changeLocked = AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'abo_update_settings') {
|
||||
|
|
@ -138,8 +159,15 @@ class AboController extends Controller
|
|||
$message = false;
|
||||
// Yard für Gewichts-/Versandprüfung initialisieren (Versandland setzen)
|
||||
AboOrderCart::initYard($user_abo);
|
||||
|
||||
if ($changeLocked) {
|
||||
$message = __('abo.error_change_locked', [
|
||||
'days' => (int) now()->diffInDays(\Carbon\Carbon::parse($user_abo->next_date), false),
|
||||
'lock' => \App\Repositories\AboRepository::getLockDaysChange(),
|
||||
]);
|
||||
}
|
||||
// addProduct
|
||||
if ($data['action'] === 'addProduct') {
|
||||
if (! $changeLocked && $data['action'] === 'addProduct') {
|
||||
if ($product = Product::find($data['product_id'])) {
|
||||
if (AboOrderCart::exceedsMaxWeight($user_abo, (int) $product->weight)) {
|
||||
$message = __('msg.cart_max_weight_reached');
|
||||
|
|
@ -162,7 +190,7 @@ class AboController extends Controller
|
|||
}
|
||||
|
||||
// updateCart
|
||||
if ($data['action'] === 'updateCart') {
|
||||
if (! $changeLocked && $data['action'] === 'updateCart') {
|
||||
// product_id | order_item_id | cart_order_id | qty
|
||||
if (isset($data['product_id']) && $product = Product::find($data['product_id'])) {
|
||||
if (isset($data['order_item_id']) && $UserAboItem = UserAboItem::find($data['order_item_id'])) {
|
||||
|
|
@ -188,7 +216,7 @@ class AboController extends Controller
|
|||
}
|
||||
|
||||
// removeFromCart
|
||||
if ($data['action'] === 'removeFromCart') {
|
||||
if (! $changeLocked && $data['action'] === 'removeFromCart') {
|
||||
if ($isAddOnlyMode) {
|
||||
return response()->json([
|
||||
'response' => false,
|
||||
|
|
@ -212,7 +240,7 @@ class AboController extends Controller
|
|||
}
|
||||
}
|
||||
// updateCompProduct
|
||||
if ($data['action'] === 'updateCompProduct') {
|
||||
if (! $changeLocked && $data['action'] === 'updateCompProduct') {
|
||||
if ($UserAboItem = UserAboItem::where('user_abo_id', $user_abo->id)->where('comp', $data['comp_num'])->first()) {
|
||||
$oldProduct = $UserAboItem->product;
|
||||
$UserAboItem->product_id = $data['comp_product_id'];
|
||||
|
|
@ -239,6 +267,10 @@ class AboController extends Controller
|
|||
}
|
||||
AboOrderCart::checkNumOfCompProducts($user_abo); // after reCalculateShippingPrice check it and remove or add comp product
|
||||
|
||||
// Relation neu laden, damit die gerenderte Menge dem gespeicherten Stand
|
||||
// entspricht (sonst zeigt _order_abo_show die gecachte alte Menge → Feld „springt" zurück).
|
||||
$user_abo->load('user_abo_items');
|
||||
|
||||
if ($user_abo->is_for === 'me') {
|
||||
$data['comp_products'] = Shop::getCompProducts('abo-me');
|
||||
}
|
||||
|
|
@ -250,6 +282,7 @@ class AboController extends Controller
|
|||
'split_mode' => AboHelper::isOneTimeFeatureVisible($user_abo),
|
||||
'summary' => $summary,
|
||||
'add_only_mode' => $isAddOnlyMode,
|
||||
'change_locked' => $changeLocked,
|
||||
])->render();
|
||||
$html_comp = view('user.order.comp_product', array_merge($data, [
|
||||
'cart_instance' => AboOrderCart::INSTANCE,
|
||||
|
|
@ -271,8 +304,9 @@ class AboController extends Controller
|
|||
{
|
||||
$user_abo = UserAbo::findOrFail($id);
|
||||
$this->checkPermissions($view, $user_abo);
|
||||
$editView = \Auth::user()?->isAdmin() ? 'admin' : $view;
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $editView);
|
||||
// Add-only/Change-Lock nach Abo-Sicht ($view), kein Admin-Bypass (siehe update()).
|
||||
$isAddOnlyMode = AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
$changeLocked = AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
|
||||
if (! AboHelper::isOneTimeFeatureVisible($user_abo)) {
|
||||
return response()->json([
|
||||
|
|
@ -310,6 +344,7 @@ class AboController extends Controller
|
|||
'summary' => $summary,
|
||||
'only_show_products' => false,
|
||||
'add_only_mode' => $isAddOnlyMode,
|
||||
'change_locked' => $changeLocked,
|
||||
])->render(),
|
||||
'html_summary' => view('admin.abo._order_combined_summary', [
|
||||
'summary' => $summary,
|
||||
|
|
@ -520,6 +555,67 @@ class AboController extends Controller
|
|||
return redirect(route('user_abos_detail', [$view, $id]));
|
||||
}
|
||||
|
||||
public function deletePending($view, $id)
|
||||
{
|
||||
$user_abo = UserAbo::findOrFail($id);
|
||||
$this->checkPermissions($view, $user_abo);
|
||||
|
||||
if (! $user_abo->canDeletePendingInitialPayment()) {
|
||||
\Session()->flash('alert-error', __('abo.pending_delete_not_allowed'));
|
||||
|
||||
return redirect(route('user_abos', [$view]));
|
||||
}
|
||||
|
||||
\DB::transaction(function () use ($user_abo) {
|
||||
$user_abo->delete();
|
||||
});
|
||||
|
||||
\Session()->flash('alert-success', __('abo.pending_delete_success'));
|
||||
|
||||
return redirect(route('user_abos', [$view]));
|
||||
}
|
||||
|
||||
public function deletePaymentLink($identifier)
|
||||
{
|
||||
$shoppingInstance = ShoppingInstance::where('identifier', $identifier)->firstOrFail();
|
||||
$user = \Auth::user();
|
||||
$userShopId = $user && $user->shop ? $user->shop->id : null;
|
||||
|
||||
if ((int) $shoppingInstance->user_shop_id !== (int) $userShopId || ! OrderPaymentService::isAboCustomerPaymentLink($shoppingInstance)) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
if (! OrderPaymentService::canDeleteInstance($shoppingInstance)) {
|
||||
\Session()->flash('alert-error', __('abo.payment_link_delete_not_allowed'));
|
||||
|
||||
return redirect(route('user_abos', ['ot']));
|
||||
}
|
||||
|
||||
OrderPaymentService::deleteInstance($identifier);
|
||||
\Session()->flash('alert-success', __('abo.payment_link_delete_success'));
|
||||
|
||||
return redirect(route('user_abos', ['ot']));
|
||||
}
|
||||
|
||||
private function getAboPaymentLinks()
|
||||
{
|
||||
$user = \Auth::user();
|
||||
$userShopId = $user && $user->shop ? $user->shop->id : null;
|
||||
|
||||
if (! $userShopId) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return ShoppingInstance::where('user_shop_id', $userShopId)
|
||||
->where('payment', 6)
|
||||
->where('status', '<', 10)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
->filter(fn (ShoppingInstance $shoppingInstance) => OrderPaymentService::isAboCustomerPaymentLink($shoppingInstance))
|
||||
->reject(fn (ShoppingInstance $shoppingInstance) => OrderPaymentService::hasUserAboForPaymentLink($shoppingInstance, $user))
|
||||
->values();
|
||||
}
|
||||
|
||||
private function checkPermissions($view, $user_abo)
|
||||
{
|
||||
\Log::info('checkPermissions', ['view' => $view, 'user_abo' => $user_abo]);
|
||||
|
|
|
|||
69
app/Mail/MailAboExecutionReminder.php
Normal file
69
app/Mail/MailAboExecutionReminder.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\AboHelper;
|
||||
use App\Services\Util;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class MailAboExecutionReminder extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public UserAbo $userAbo) {}
|
||||
|
||||
public function build(): self
|
||||
{
|
||||
$isConsultant = $this->userAbo->is_for === 'me';
|
||||
|
||||
$salutation = __('email.hello');
|
||||
$firstname = $this->userAbo->shopping_user?->billing_firstname;
|
||||
if ($firstname) {
|
||||
$salutation = __('email.hello').' '.$firstname;
|
||||
}
|
||||
|
||||
$days = $this->daysUntilExecution();
|
||||
|
||||
return $this->subject(__('email.abo_reminder_subject'))
|
||||
->view('emails.abo_execution_reminder')
|
||||
->with([
|
||||
'salutation' => $salutation,
|
||||
'isConsultant' => $isConsultant,
|
||||
'days' => $days,
|
||||
'nextDate' => $this->userAbo->next_date
|
||||
? Carbon::parse($this->userAbo->next_date)->format(\Util::formatDateDB())
|
||||
: '',
|
||||
'link' => $this->buildLink($isConsultant),
|
||||
'greetings' => __('email.greetings'),
|
||||
'sender' => __('email.sender'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Berater erhalten den Link ins Sales Center (my.mivita.care), Endkunden ins
|
||||
* Kundenportal (in.mivita.care) – jeweils zur Abo-Detail-/Übersichtsseite.
|
||||
*/
|
||||
private function buildLink(bool $isConsultant): string
|
||||
{
|
||||
if ($isConsultant) {
|
||||
return rtrim(Util::getMyMivitaUrl(), '/').'/user/abos/detail/me/'.$this->userAbo->id;
|
||||
}
|
||||
|
||||
return rtrim(Util::getMyMivitaPortalUrl(), '/').'/portal/my-subscriptions';
|
||||
}
|
||||
|
||||
private function daysUntilExecution(): int
|
||||
{
|
||||
if (! $this->userAbo->next_date) {
|
||||
return AboHelper::getOneTimeWindowDays();
|
||||
}
|
||||
|
||||
$days = Carbon::today()->diffInDays(Carbon::parse($this->userAbo->next_date)->startOfDay(), false);
|
||||
|
||||
return (int) max(0, $days);
|
||||
}
|
||||
}
|
||||
|
|
@ -98,6 +98,7 @@ class UserAbo extends Model
|
|||
'start_date' => 'datetime',
|
||||
'last_date' => 'datetime',
|
||||
'next_date' => 'datetime',
|
||||
'onetime_reminder_sent_for' => 'date',
|
||||
'cancel_date' => 'datetime',
|
||||
'user_deleted_at' => 'datetime',
|
||||
'carddata' => 'array',
|
||||
|
|
@ -121,6 +122,7 @@ class UserAbo extends Model
|
|||
'start_date',
|
||||
'last_date',
|
||||
'next_date',
|
||||
'onetime_reminder_sent_for',
|
||||
'cancel_date',
|
||||
'user_deleted_at',
|
||||
];
|
||||
|
|
@ -151,6 +153,34 @@ class UserAbo extends Model
|
|||
8 => 'success',
|
||||
];
|
||||
|
||||
/**
|
||||
* Aktive Abos (laufend): active=true und kein terminaler/inaktiver Status
|
||||
* (4 = storniert, 5 = beendet, 6 = inaktiv). Spiegelt die Definition aus
|
||||
* {@see \App\Services\Backoffice\BackofficeDashboardService}.
|
||||
*/
|
||||
public function scopeActiveAbo(\Illuminate\Database\Eloquent\Builder $query): \Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where('active', true)
|
||||
->whereNotIn('status', [4, 5, 6]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schränkt die Abfrage auf Abos ein, die im angegebenen Monat/Jahr hinzugekommen
|
||||
* sind (Eingangsmonat = start_date). Bei month=0 (oder außerhalb 1–12) bleibt die
|
||||
* Abfrage unverändert.
|
||||
*/
|
||||
public function scopeAddedInMonth(\Illuminate\Database\Eloquent\Builder $query, int $year, int $month): \Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
if ($month < 1 || $month > 12) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
return $query
|
||||
->whereYear('start_date', $year)
|
||||
->whereMonth('start_date', $month);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
|
|
@ -171,6 +201,55 @@ class UserAbo extends Model
|
|||
return $this->hasMany(UserAboOrder::class);
|
||||
}
|
||||
|
||||
public function initialUserAboOrder(): ?UserAboOrder
|
||||
{
|
||||
return $this->user_abo_orders()
|
||||
->orderBy('id')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function initialShoppingOrder(): ?ShoppingOrder
|
||||
{
|
||||
return $this->initialUserAboOrder()?->shopping_order;
|
||||
}
|
||||
|
||||
public function initialShoppingPayment(): ?ShoppingPayment
|
||||
{
|
||||
return $this->initialShoppingOrder()?->shopping_payments()
|
||||
->orderBy('id')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function isPendingInitialPayment(): bool
|
||||
{
|
||||
return (int) $this->status === 1;
|
||||
}
|
||||
|
||||
public function hasInitialPaymentStatus(): bool
|
||||
{
|
||||
$payment = $this->initialShoppingPayment();
|
||||
$order = $this->initialShoppingOrder();
|
||||
|
||||
return filled($payment?->txaction)
|
||||
|| filled($payment?->status)
|
||||
|| filled($order?->txaction);
|
||||
}
|
||||
|
||||
public function hasFailedInitialPayment(): bool
|
||||
{
|
||||
$payment = $this->initialShoppingPayment();
|
||||
$order = $this->initialShoppingOrder();
|
||||
|
||||
return in_array($payment?->txaction, ['failed'], true)
|
||||
|| in_array($payment?->status, ['error', 'cancel'], true)
|
||||
|| in_array($order?->txaction, ['failed'], true);
|
||||
}
|
||||
|
||||
public function canDeletePendingInitialPayment(): bool
|
||||
{
|
||||
return $this->isPendingInitialPayment() && $this->hasFailedInitialPayment();
|
||||
}
|
||||
|
||||
public function user_abo_items()
|
||||
{
|
||||
return $this->hasMany(UserAboItem::class);
|
||||
|
|
|
|||
|
|
@ -8,9 +8,33 @@ use Carbon\Carbon;
|
|||
|
||||
class AboRepository extends BaseRepository
|
||||
{
|
||||
private const LOCK_DAYS_CHANGE = 10;
|
||||
private const DEFAULT_LOCK_DAYS_CHANGE = 10;
|
||||
|
||||
private const LOCK_DAYS_PAUSE_CANCEL = 3;
|
||||
private const DEFAULT_LOCK_DAYS_PAUSE_CANCEL = 3;
|
||||
|
||||
/**
|
||||
* Sperrfrist (Kalendertage) vor der Ausführung, ab der das Bearbeiten des Abos
|
||||
* (Intervall/Produkte) blockiert wird. Konfigurierbar über das Setting
|
||||
* `abo-lock-days-change`; Fallback auf den Default, wenn leer/0.
|
||||
*/
|
||||
public static function getLockDaysChange(): int
|
||||
{
|
||||
$days = (int) \App\Models\Setting::getContentBySlug('abo-lock-days-change');
|
||||
|
||||
return $days > 0 ? $days : self::DEFAULT_LOCK_DAYS_CHANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sperrfrist (Kalendertage) vor der Ausführung, ab der das Pausieren/Kündigen
|
||||
* des Abos blockiert wird. Konfigurierbar über das Setting
|
||||
* `abo-lock-days-pause-cancel`; Fallback auf den Default, wenn leer/0.
|
||||
*/
|
||||
public static function getLockDaysPauseCancel(): int
|
||||
{
|
||||
$days = (int) \App\Models\Setting::getContentBySlug('abo-lock-days-pause-cancel');
|
||||
|
||||
return $days > 0 ? $days : self::DEFAULT_LOCK_DAYS_PAUSE_CANCEL;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -59,8 +83,8 @@ class AboRepository extends BaseRepository
|
|||
// Sperre: 3 Tage vor Ausführung kann nicht mehr pausiert/gekündigt werden
|
||||
if (! $isAdminUpdate && $this->model->next_date) {
|
||||
$daysUntil = (int) now()->diffInDays(\Carbon\Carbon::parse($this->model->next_date), false);
|
||||
if ($daysUntil >= 0 && $daysUntil < self::LOCK_DAYS_PAUSE_CANCEL) {
|
||||
\Session()->flash('alert-error', __('abo.error_cancel_locked', ['days' => $daysUntil]));
|
||||
if ($daysUntil >= 0 && $daysUntil < self::getLockDaysPauseCancel()) {
|
||||
\Session()->flash('alert-error', __('abo.error_cancel_locked', ['days' => $daysUntil, 'lock' => self::getLockDaysPauseCancel()]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -79,8 +103,8 @@ class AboRepository extends BaseRepository
|
|||
// Sperre: 3 Tage vor Ausführung kann nicht mehr pausiert werden
|
||||
if (! $isAdminUpdate && $this->model->active && ! $active && $this->model->next_date) {
|
||||
$daysUntil = (int) now()->diffInDays(\Carbon\Carbon::parse($this->model->next_date), false);
|
||||
if ($daysUntil >= 0 && $daysUntil < self::LOCK_DAYS_PAUSE_CANCEL) {
|
||||
\Session()->flash('alert-error', __('abo.error_pause_locked', ['days' => $daysUntil]));
|
||||
if ($daysUntil >= 0 && $daysUntil < self::getLockDaysPauseCancel()) {
|
||||
\Session()->flash('alert-error', __('abo.error_pause_locked', ['days' => $daysUntil, 'lock' => self::getLockDaysPauseCancel()]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -149,26 +173,33 @@ class AboRepository extends BaseRepository
|
|||
return true;
|
||||
}
|
||||
|
||||
// Sperre: 10 Tage vor nächster Ausführung keine Änderungen mehr (Pakete werden vorgepackt)
|
||||
if ($this->model->next_date) {
|
||||
$daysUntilExecution = (int) now()->diffInDays(\Carbon\Carbon::parse($this->model->next_date), false);
|
||||
if ($daysUntilExecution >= 0 && $daysUntilExecution < self::LOCK_DAYS_CHANGE) {
|
||||
\Session()->flash('alert-error', __('abo.error_change_locked', ['days' => $daysUntilExecution]));
|
||||
// Die Change-Sperre (Liefertag/Intervall) greift NUR, wenn der Liefertag tatsächlich
|
||||
// geändert wird. Reines Pausieren/Kündigen (Intervall unverändert) unterliegt
|
||||
// ausschließlich der eigenen Sperrfrist in updateStatus() + der Mindestlaufzeit.
|
||||
$intervalChanged = (int) $data['abo_interval'] !== (int) $this->model->abo_interval;
|
||||
|
||||
if ($intervalChanged) {
|
||||
// Sperre: X Tage vor nächster Ausführung kein Liefertag-Wechsel mehr (Pakete werden vorgepackt)
|
||||
if ($this->model->next_date) {
|
||||
$daysUntilExecution = (int) now()->diffInDays(\Carbon\Carbon::parse($this->model->next_date), false);
|
||||
if ($daysUntilExecution >= 0 && $daysUntilExecution < self::getLockDaysChange()) {
|
||||
\Session()->flash('alert-error', __('abo.error_change_locked', ['days' => $daysUntilExecution, 'lock' => self::getLockDaysChange()]));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfung: Das neue berechnete Ausführungsdatum muss mindestens getLockDaysChange() Tage entfernt sein.
|
||||
// Falls next_date bereits in einem zukünftigen Monat liegt, wird das neue Datum in diesem Monat berechnet.
|
||||
$newNextDate = $this->calculateNewNextDate($data['abo_interval']);
|
||||
$daysUntilNewDate = (int) now()->diffInDays($newNextDate, false);
|
||||
if ($daysUntilNewDate < self::getLockDaysChange()) {
|
||||
\Session()->flash('alert-error', __('abo.error_abo_interval_too_soon', ['days' => $daysUntilNewDate, 'lock' => self::getLockDaysChange()]));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfung: Das neue berechnete Ausführungsdatum muss mindestens LOCK_DAYS_CHANGE Tage entfernt sein.
|
||||
// Falls next_date bereits in einem zukünftigen Monat liegt, wird das neue Datum in diesem Monat berechnet.
|
||||
$newNextDate = $this->calculateNewNextDate($data['abo_interval']);
|
||||
$daysUntilNewDate = (int) now()->diffInDays($newNextDate, false);
|
||||
if ($daysUntilNewDate < self::LOCK_DAYS_CHANGE) {
|
||||
\Session()->flash('alert-error', __('abo.error_abo_interval_too_soon', ['days' => $daysUntilNewDate]));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,40 @@ class InvoiceRepository extends BaseRepository
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine reine VORSCHAU der Rechnungs- und Lieferschein-PDFs – ohne
|
||||
* `UserInvoice` anzulegen, ohne eine Rechnungsnummer zu verbrauchen und ohne
|
||||
* Umsatz-/Incentive-Tracking. Dient der visuellen Prüfung des Layouts (z. B. auf
|
||||
* Testsystemen, wo die reguläre Erzeugung in {@see createAndSalesVolume()}
|
||||
* bewusst deaktiviert ist).
|
||||
*
|
||||
* @return array<string, string> Storage-Pfade (disk "public") der erzeugten PDFs
|
||||
*/
|
||||
public function makePreview(): array
|
||||
{
|
||||
$invoiceDate = now()->format('d.m.Y');
|
||||
if ($payt = $this->model->getLastShoppingPaymentTransaction()) {
|
||||
$invoiceDate = $payt->created_at->format('d.m.Y');
|
||||
}
|
||||
|
||||
$this->invoice_date = $invoiceDate;
|
||||
$this->invoice_number = 'VORSCHAU-'.$this->model->id;
|
||||
$this->dir = 'invoice/preview/';
|
||||
$this->delivery_dir = 'delivery/preview/';
|
||||
$this->filename = Invoice::makeInvoiceFilename($this->invoice_number);
|
||||
$this->delivery_filename = Invoice::makeDeliveryFilename($this->invoice_number);
|
||||
$this->user_sales_volume = null; // Vorschau: kein Umsatz-Tracking, Punkte-Block entfällt
|
||||
|
||||
$this->makePDF();
|
||||
|
||||
$paths = ['invoice' => $this->dir.Invoice::makeInvoiceFilenameLocale($this->invoice_number, 'de')];
|
||||
if (! $this->model->shopping_collect_order) {
|
||||
$paths['delivery'] = $this->delivery_dir.Invoice::makeDeliveryFilenameLocale($this->invoice_number, 'de');
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt die PDFs für Rechnung und Lieferschein.
|
||||
* Das deutsche Original wird immer erstellt (Finanzamt-Anforderung).
|
||||
|
|
|
|||
391
app/Services/Abo/TeamAboOverviewService.php
Normal file
391
app/Services/Abo/TeamAboOverviewService.php
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Abo;
|
||||
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\Backoffice\BackofficeDashboardService;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Abo-fokussierte Team-Übersicht (für alle aktiven Berater, nicht nur VIP).
|
||||
*
|
||||
* Gruppiert die Downline nach Linien/Ebenen und liefert pro Ebene die Abo-Kennzahlen:
|
||||
* wer hat selbst ein Abo, wie viele Kundenabos, sowie die im gewählten Monat neu
|
||||
* hinzugekommenen Abos. Wiederverwendet die Linien-Logik aus
|
||||
* {@see BackofficeDashboardService} (keine Duplizierung der Baum-Traversierung).
|
||||
*/
|
||||
class TeamAboOverviewService
|
||||
{
|
||||
public function __construct(private BackofficeDashboardService $dashboardService) {}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* month: int,
|
||||
* year: int,
|
||||
* lines: array<int, array<string, mixed>>,
|
||||
* totals: array<string, mixed>
|
||||
* }
|
||||
*/
|
||||
public function linesOverview(User $user, int $month, int $year): array
|
||||
{
|
||||
$lineBuckets = $this->dashboardService->lineBuckets($user->id);
|
||||
|
||||
$lines = [];
|
||||
$totals = $this->emptyLine(0);
|
||||
$totals['label'] = __('abo.team_total');
|
||||
|
||||
foreach ($lineBuckets as $line => $users) {
|
||||
$row = $this->buildLineRow((int) $line, $users, $month, $year);
|
||||
$lines[$line] = $row;
|
||||
$totals = $this->addToTotals($totals, $row);
|
||||
}
|
||||
|
||||
return [
|
||||
'month' => $month,
|
||||
'year' => $year,
|
||||
'lines' => $lines,
|
||||
'totals' => $totals,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Leichtgewichtige Kennzahlen für das Dashboard (ohne Punkte-/Mitglieder-Details).
|
||||
*
|
||||
* @return array{team_total_abos: int, team_partner_abos: int, team_customer_abos: int, shop_1000: int}
|
||||
*/
|
||||
public function teamKpis(User $user, int $month, int $year): array
|
||||
{
|
||||
$teamUserIds = $this->dashboardService->teamUserIds($user->id);
|
||||
|
||||
if ($teamUserIds === []) {
|
||||
return [
|
||||
'team_total_abos' => 0,
|
||||
'team_partner_abos' => 0,
|
||||
'team_customer_abos' => 0,
|
||||
'shop_1000' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$partnerAbos = UserAbo::query()->activeAbo()->where('is_for', 'me')->whereIn('user_id', $teamUserIds)->count();
|
||||
$customerAbos = UserAbo::query()->activeAbo()->where('is_for', 'ot')->whereIn('member_id', $teamUserIds)->count();
|
||||
|
||||
return [
|
||||
'team_total_abos' => $partnerAbos + $customerAbos,
|
||||
'team_partner_abos' => $partnerAbos,
|
||||
'team_customer_abos' => $customerAbos,
|
||||
'shop_1000' => $this->dashboardService->shop1000Count($teamUserIds, $month, $year),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Monatliches Abo-Wachstum des Teams für ein Jahr: je Monat die Anzahl neu
|
||||
* hinzugekommener (aktiver) Eigen- und Kunden-Abos anhand des Eingangsmonats
|
||||
* (start_date). Dient der separaten Wachstums-Tabelle unter der Bestandsübersicht.
|
||||
*
|
||||
* @return array{
|
||||
* year: int,
|
||||
* months: array<int, array{month: int, label: string, own_new: int, customer_new: int, total_new: int}>,
|
||||
* totals: array{own_new: int, customer_new: int, total_new: int}
|
||||
* }
|
||||
*/
|
||||
public function monthlyGrowth(User $user, int $year): array
|
||||
{
|
||||
$teamUserIds = $this->dashboardService->teamUserIds($user->id);
|
||||
$monthNames = \App\Services\HTMLHelper::getTransMonths();
|
||||
|
||||
$ownByMonth = $teamUserIds === [] ? [] : $this->newAbosByMonth($teamUserIds, 'user_id', 'me', $year);
|
||||
$customerByMonth = $teamUserIds === [] ? [] : $this->newAbosByMonth($teamUserIds, 'member_id', 'ot', $year);
|
||||
|
||||
$months = [];
|
||||
$totals = ['own_new' => 0, 'customer_new' => 0, 'total_new' => 0];
|
||||
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$own = $ownByMonth[$month] ?? 0;
|
||||
$customer = $customerByMonth[$month] ?? 0;
|
||||
|
||||
$months[] = [
|
||||
'month' => $month,
|
||||
'label' => $monthNames[$month] ?? (string) $month,
|
||||
'own_new' => $own,
|
||||
'customer_new' => $customer,
|
||||
'total_new' => $own + $customer,
|
||||
];
|
||||
|
||||
$totals['own_new'] += $own;
|
||||
$totals['customer_new'] += $customer;
|
||||
$totals['total_new'] += $own + $customer;
|
||||
}
|
||||
|
||||
return [
|
||||
'year' => $year,
|
||||
'months' => $months,
|
||||
'totals' => $totals,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Zählt neue (aktive) Abos je Monat eines Jahres anhand start_date.
|
||||
* DB-agnostisch (kein MONTH()/strftime): rohe Datumswerte werden in PHP gruppiert.
|
||||
*
|
||||
* @param int[] $userIds
|
||||
* @return array<int, int>
|
||||
*/
|
||||
private function newAbosByMonth(array $userIds, string $userColumn, string $isFor, int $year): array
|
||||
{
|
||||
$dates = UserAbo::query()
|
||||
->activeAbo()
|
||||
->where('is_for', $isFor)
|
||||
->whereIn($userColumn, $userIds)
|
||||
->whereYear('start_date', $year)
|
||||
->toBase()
|
||||
->pluck('start_date');
|
||||
|
||||
$byMonth = [];
|
||||
foreach ($dates as $date) {
|
||||
if (! $date) {
|
||||
continue;
|
||||
}
|
||||
$month = (int) Carbon::parse($date)->month;
|
||||
$byMonth[$month] = ($byMonth[$month] ?? 0) + 1;
|
||||
}
|
||||
|
||||
return $byMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abo-Zusammenfassung eines einzelnen Team-Mitglieds für das Detail-Modal.
|
||||
* Liefert null, wenn das Mitglied nicht in der Downline des Owners liegt.
|
||||
*
|
||||
* @return array{
|
||||
* name: string,
|
||||
* email: string,
|
||||
* own_abo: array<string, mixed>|null,
|
||||
* customer_abos: array{count: int, total_points: float, items: array<int, array<string, mixed>>}
|
||||
* }|null
|
||||
*/
|
||||
public function memberAboSummary(User $owner, int $memberId): ?array
|
||||
{
|
||||
if (! \App\Services\AboHelper::isUserInTeam($owner->id, $memberId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$member = User::with('account')->find($memberId);
|
||||
|
||||
if (! $member) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ownAbo = UserAbo::query()
|
||||
->activeAbo()
|
||||
->where('is_for', 'me')
|
||||
->where('user_id', $memberId)
|
||||
->with(['user_abo_items.product', 'user_abo_orders'])
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
$customerAbos = UserAbo::query()
|
||||
->activeAbo()
|
||||
->where('is_for', 'ot')
|
||||
->where('member_id', $memberId)
|
||||
->with(['user_abo_items.product', 'user_abo_orders'])
|
||||
->orderBy('start_date')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'name' => $this->memberName($member),
|
||||
'email' => $member->email ?? '',
|
||||
'own_abo' => $ownAbo ? $this->aboSummary($ownAbo) : null,
|
||||
'customer_abos' => [
|
||||
'count' => $customerAbos->count(),
|
||||
'total_points' => (float) $customerAbos->sum(fn (UserAbo $abo) => $abo->getTotalPoints()),
|
||||
'items' => $customerAbos->map(fn (UserAbo $abo) => $this->aboSummary($abo))->all(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{points: float, start_date: string, next_date: string, executions: int, amount: string, interval: int}
|
||||
*/
|
||||
private function aboSummary(UserAbo $abo): array
|
||||
{
|
||||
return [
|
||||
'points' => (float) $abo->getTotalPoints(),
|
||||
'start_date' => $abo->start_date,
|
||||
'next_date' => $abo->next_date,
|
||||
'executions' => $abo->getCountPaidOrders(),
|
||||
'amount' => $abo->getFormattedAmount(),
|
||||
'interval' => (int) $abo->abo_interval,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Support\Collection<int, \App\User> $users
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function buildLineRow(int $line, Collection $users, int $month, int $year): array
|
||||
{
|
||||
$userIds = $users->pluck('id')->map(fn ($id) => (int) $id)->all();
|
||||
|
||||
if ($userIds === []) {
|
||||
return $this->emptyLine($line);
|
||||
}
|
||||
|
||||
$users->loadMissing('user_level');
|
||||
|
||||
$ownAbos = $this->ownAbosByUser($userIds);
|
||||
$customerAbos = $this->customerAbosByMember($userIds);
|
||||
|
||||
$members = [];
|
||||
$membersWithOwnAbo = 0;
|
||||
$ownAbosCount = 0;
|
||||
$ownAboPoints = 0.0;
|
||||
$customerAbosCount = 0;
|
||||
$customerAboPoints = 0.0;
|
||||
|
||||
foreach ($users as $teamUser) {
|
||||
$uid = (int) $teamUser->id;
|
||||
$ownAbo = $ownAbos->get($uid);
|
||||
$custList = $customerAbos->get($uid, collect());
|
||||
|
||||
$hasOwnAbo = $ownAbo !== null;
|
||||
$memberOwnPoints = $hasOwnAbo ? (float) $ownAbo->getTotalPoints() : 0.0;
|
||||
$memberCustomerCount = $custList->count();
|
||||
$memberCustomerPoints = (float) $custList->sum(fn (UserAbo $abo) => $abo->getTotalPoints());
|
||||
|
||||
if ($hasOwnAbo) {
|
||||
$membersWithOwnAbo++;
|
||||
$ownAbosCount++;
|
||||
$ownAboPoints += $memberOwnPoints;
|
||||
}
|
||||
$customerAbosCount += $memberCustomerCount;
|
||||
$customerAboPoints += $memberCustomerPoints;
|
||||
|
||||
$members[] = [
|
||||
'user_id' => $uid,
|
||||
'name' => $this->memberName($teamUser),
|
||||
'career_level' => $teamUser->user_level?->getLang('name') ?? '',
|
||||
'has_own_abo' => $hasOwnAbo,
|
||||
'own_abo_points' => $memberOwnPoints,
|
||||
'customer_abo_count' => $memberCustomerCount,
|
||||
'customer_abo_points' => $memberCustomerPoints,
|
||||
'total_abos' => ($hasOwnAbo ? 1 : 0) + $memberCustomerCount,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'line' => $line,
|
||||
'label' => __('abo.team_line', ['line' => $line]),
|
||||
'consultants' => $users->count(),
|
||||
'members_total' => $users->count(),
|
||||
'members_with_own_abo' => $membersWithOwnAbo,
|
||||
'own_abos' => $ownAbosCount,
|
||||
'own_abos_new' => $this->newAboCount($userIds, 'user_id', 'me', $month, $year),
|
||||
'own_abo_points' => $ownAboPoints,
|
||||
'customer_abos' => $customerAbosCount,
|
||||
'customer_abos_new' => $this->newAboCount($userIds, 'member_id', 'ot', $month, $year),
|
||||
'customer_abo_points' => $customerAboPoints,
|
||||
'total_abos' => $ownAbosCount + $customerAbosCount,
|
||||
'members' => $members,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Eigene (me) aktive Abos je Berater, indiziert nach user_id (ein Abo pro Berater).
|
||||
*
|
||||
* @param int[] $userIds
|
||||
* @return \Illuminate\Support\Collection<int, \App\Models\UserAbo>
|
||||
*/
|
||||
private function ownAbosByUser(array $userIds): Collection
|
||||
{
|
||||
return UserAbo::query()
|
||||
->activeAbo()
|
||||
->where('is_for', 'me')
|
||||
->whereIn('user_id', $userIds)
|
||||
->with('user_abo_items.product')
|
||||
->get()
|
||||
->keyBy(fn (UserAbo $abo) => (int) $abo->user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kundenabos (ot) je Berater, gruppiert nach member_id.
|
||||
*
|
||||
* @param int[] $userIds
|
||||
* @return \Illuminate\Support\Collection<int, \Illuminate\Support\Collection<int, \App\Models\UserAbo>>
|
||||
*/
|
||||
private function customerAbosByMember(array $userIds): Collection
|
||||
{
|
||||
return UserAbo::query()
|
||||
->activeAbo()
|
||||
->where('is_for', 'ot')
|
||||
->whereIn('member_id', $userIds)
|
||||
->with('user_abo_items.product')
|
||||
->get()
|
||||
->groupBy(fn (UserAbo $abo) => (int) $abo->member_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $userIds
|
||||
*/
|
||||
private function newAboCount(array $userIds, string $userColumn, string $isFor, int $month, int $year): int
|
||||
{
|
||||
$startDate = Carbon::create($year, $month, 1)->startOfMonth();
|
||||
$endDate = Carbon::create($year, $month, 1)->endOfMonth();
|
||||
|
||||
return UserAbo::query()
|
||||
->activeAbo()
|
||||
->whereIn($userColumn, $userIds)
|
||||
->where('is_for', $isFor)
|
||||
->whereBetween('start_date', [$startDate, $endDate])
|
||||
->count();
|
||||
}
|
||||
|
||||
private function memberName(User $user): string
|
||||
{
|
||||
if ($user->account) {
|
||||
$name = trim($user->account->first_name.' '.$user->account->last_name);
|
||||
if ($name !== '') {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $user->email ?? ('#'.$user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function emptyLine(int $line): array
|
||||
{
|
||||
return [
|
||||
'line' => $line,
|
||||
'label' => $line > 0 ? __('abo.team_line', ['line' => $line]) : __('abo.team_total'),
|
||||
'consultants' => 0,
|
||||
'members_total' => 0,
|
||||
'members_with_own_abo' => 0,
|
||||
'own_abos' => 0,
|
||||
'own_abos_new' => 0,
|
||||
'own_abo_points' => 0.0,
|
||||
'customer_abos' => 0,
|
||||
'customer_abos_new' => 0,
|
||||
'customer_abo_points' => 0.0,
|
||||
'total_abos' => 0,
|
||||
'members' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $totals
|
||||
* @param array<string, mixed> $row
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function addToTotals(array $totals, array $row): array
|
||||
{
|
||||
foreach (['consultants', 'members_total', 'members_with_own_abo', 'own_abos', 'own_abos_new', 'own_abo_points', 'customer_abos', 'customer_abos_new', 'customer_abo_points', 'total_abos'] as $key) {
|
||||
$totals[$key] += $row[$key];
|
||||
}
|
||||
|
||||
return $totals;
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ class AboHelper
|
|||
{
|
||||
$user = $user ? $user : \Auth::user();
|
||||
|
||||
return UserAbo::where('user_id', $user->id)->where('is_for', 'me')->where('status', '>', 1)->first() === null ? false : true;
|
||||
return UserAbo::where('user_id', $user->id)->where('is_for', 'me')->where('status', '>=', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function memberHasAbo(ShoppingUser $shopping_user)
|
||||
|
|
@ -52,12 +52,12 @@ class AboHelper
|
|||
return false;
|
||||
}
|
||||
|
||||
return UserAbo::where('email', $shopping_user->billing_email)->where('is_for', 'ot')->where('status', '>', 1)->first() === null ? false : true;
|
||||
return UserAbo::where('email', $shopping_user->billing_email)->where('is_for', 'ot')->where('status', '>=', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function hasAboByEmail($email)
|
||||
{
|
||||
return UserAbo::where('email', $email)->where('status', '>', 1)->first() === null ? false : true;
|
||||
return UserAbo::where('email', $email)->where('status', '>=', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function setAboStatus(ShoppingOrder $shopping_order, $status, $paid = false)
|
||||
|
|
@ -115,6 +115,23 @@ class AboHelper
|
|||
return ! self::canCancelAbo($user_abo, $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob das Bearbeiten des Abos (Liefertag/Intervall) aktuell durch die
|
||||
* Sperrfrist vor der Ausführung blockiert ist. Admins umgehen die Sperre.
|
||||
* Spiegelt die serverseitige Prüfung in {@see \App\Repositories\AboRepository::validate()}
|
||||
* für die UI (Feld/Button deaktivieren).
|
||||
*/
|
||||
public static function isAboChangeLocked(UserAbo $userAbo, string $view = 'user'): bool
|
||||
{
|
||||
if ($view === 'admin' || ! $userAbo->next_date) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$daysUntil = (int) Carbon::now()->diffInDays(Carbon::parse($userAbo->next_date), false);
|
||||
|
||||
return $daysUntil >= 0 && $daysUntil < \App\Repositories\AboRepository::getLockDaysChange();
|
||||
}
|
||||
|
||||
public static function canEditAbo($user_abo, $view = 'user')
|
||||
{
|
||||
if ($view === 'portal') {
|
||||
|
|
@ -157,10 +174,10 @@ class AboHelper
|
|||
public static function getAboTypeBadge($abo_type)
|
||||
{
|
||||
if ($abo_type === 'base') {
|
||||
return '<span class="badge badge-pill badge-warning"><i class="fas fa-star"></i> ' . __('abo.' . $abo_type) . '</span></a>';
|
||||
return '<span class="badge badge-pill badge-warning"><i class="fas fa-star"></i> '.__('abo.'.$abo_type).'</span></a>';
|
||||
}
|
||||
if ($abo_type === 'upgrade') {
|
||||
return '<span class="badge badge-pill badge-info"><i class="far fa-star"></i> ' . __('abo.' . $abo_type) . '</span></a>';
|
||||
return '<span class="badge badge-pill badge-info"><i class="far fa-star"></i> '.__('abo.'.$abo_type).'</span></a>';
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
@ -210,24 +227,14 @@ class AboHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Sichtbarkeit des Einmalprodukte-Features während der Live-Abstimmung.
|
||||
*
|
||||
* Temporäre Einschränkung: Das Feature wird vorerst nur VIP-Usern (Admins)
|
||||
* im Sales Center angezeigt. Das Endkunden-Portal läuft über den
|
||||
* `customers`-Guard und hat keinen VIP-User auf dem `user`-Guard, daher
|
||||
* bleibt das Feature dort vollständig ausgeblendet. Nach Abschluss der
|
||||
* Abstimmung kann diese Methode wieder auf reines isOneTimeWindowOpen()
|
||||
* zurückgesetzt werden, um das Feature für alle freizuschalten.
|
||||
* Sichtbarkeit des Einmalprodukte-Features. Maßgeblich ist allein das
|
||||
* konfigurierte Zeitfenster vor der Ausführung (Sales Center und Portal
|
||||
* gleichermaßen). Das frühere Review-Gate (nur VIP, Portal ausgeblendet)
|
||||
* wurde nach Abschluss der Abstimmung aufgehoben.
|
||||
*/
|
||||
public static function isOneTimeFeatureVisible(UserAbo $userAbo): bool
|
||||
{
|
||||
/* if (! self::isOneTimeWindowOpen($userAbo)) {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
$user = \Auth::guard('user')->user();
|
||||
|
||||
return $user instanceof User && $user->isVIP();
|
||||
return self::isOneTimeWindowOpen($userAbo);
|
||||
}
|
||||
|
||||
public static function getFirstAboDate($date, $abo_interval)
|
||||
|
|
@ -412,7 +419,7 @@ class AboHelper
|
|||
{
|
||||
$ret = [];
|
||||
foreach (self::$txaction_filter_text as $key => $val) {
|
||||
$ret[$key] = trans('payment.' . $val);
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Speichert das `next_date`, für das zuletzt eine Einmalprodukte-Reminder-Mail
|
||||
* verschickt wurde (Duplikat-Schutz pro Ausführungszyklus).
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('user_abos', function (Blueprint $table) {
|
||||
$table->date('onetime_reminder_sent_for')->nullable()->after('next_date');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('user_abos', function (Blueprint $table) {
|
||||
$table->dropColumn('onetime_reminder_sent_for');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -262,37 +262,62 @@ Neuer Slug **`abo-onetime-window-days`** (Typ `int`, Default `4`) in der „Abo
|
|||
|
||||
---
|
||||
|
||||
### Phase 5 – Rechnung & Lieferschein · `OFFEN`
|
||||
### Phase 5 – Rechnung & Lieferschein · `ERLEDIGT (2026-06-12)`
|
||||
|
||||
- [ ] 5.1 `invoice-detail.blade.php`: Positionen nach `is_abo_addon` gruppieren – Abo oben, abgegrenzter Block „Einmalig hinzugefügte Artikel" darunter.
|
||||
- [ ] 5.2 `delivery-detail.blade.php`: gleiche Gruppierung/Abgrenzung.
|
||||
- [ ] 5.3 Übersetzungen DE/EN/ES/FR für Block-Überschriften.
|
||||
- [ ] 5.4 Tests/Sichtprüfung: PDF mit gemischter Bestellung (Abo + Einmal) korrekt gruppiert.
|
||||
- [x] 5.1 `invoice-detail.blade.php`: Positionen nach `is_abo_addon` gruppieren – Abo oben, abgegrenzter Block „Einmalig hinzugefügte Artikel" darunter.
|
||||
- [x] 5.2 `delivery-detail.blade.php`: gleiche Gruppierung/Abgrenzung.
|
||||
- [x] 5.3 Übersetzungen DE/EN/ES/FR für Block-Überschriften.
|
||||
- [x] 5.4 Tests/Sichtprüfung: PDF mit gemischter Bestellung (Abo + Einmal) korrekt gruppiert.
|
||||
|
||||
**Doku:** _(nach Umsetzung ausfüllen)_
|
||||
**Doku (2026-06-12):**
|
||||
|
||||
- **5.1 + 5.2 Gruppierung (rückwärtskompatibel):** In beiden PDF-Templates wird die Positionsliste vor der Ausgabe per `sortBy(is_abo_addon ? 1 : 0)` stabil sortiert (Abo-Items zuerst, Einmal-Artikel danach – PHP 8.4 `sortBy` ist stabil, Reihenfolge innerhalb der Gruppen bleibt erhalten). Zwei Überschriften-Zeilen (`<tr>` mit `colspan` + grauem Hintergrund `#f2f2f2`) werden **nur dann** eingefügt, wenn die Bestellung tatsächlich Einmal-Artikel enthält (`$hasAddonItems`). Bestellungen ohne Einmal-Artikel (= alle regulären Bestellungen/Abos) rendern damit **unverändert** ohne zusätzliche Überschriften. `colspan` = 6 bei `payment_for === 6` (Kunde-Shop), sonst 7 (Berater); Lieferschein fest 3.
|
||||
- **5.3 Übersetzungen:** Neue Keys `pdf.abo_items_heading` („Abo-Produkte") und `pdf.abo_addon_items_heading` („Einmalig hinzugefügte Artikel") in `resources/lang/{de,en,es,fr}/pdf.php`.
|
||||
- **5.4 Tests:** `tests/Feature/AboOneTimeInvoiceGroupingTest.php` (4 Tests grün): Rechnung **und** Lieferschein zeigen bei gemischter Bestellung beide Block-Überschriften und Abo-Block **vor** Einmal-Block (`strpos`-Reihenfolge); reine Bestellung ohne Einmal-Artikel zeigt **keine** Überschriften (Backward-Compat-Beleg). Gesamt-Suite Einmalprodukte: **52 grün** (+ 1 erwartet rot = Review-Gate, s. Phase 4).
|
||||
- **Snapshot-Sicherheit (vgl. 9.4):** Da `is_abo_addon` und alle Preis-Snapshots dauerhaft in `shopping_order_items` liegen, bleibt die Gruppierung korrekt, auch nachdem `user_abo_one_time_items` per Purge gelöscht wurden.
|
||||
- **Pint:** ausgeführt (`--dirty`), pass.
|
||||
|
||||
---
|
||||
|
||||
### Phase 6 – Reminder-E-Mail · `OFFEN`
|
||||
### Phase 6 – Reminder-E-Mail · `ERLEDIGT (2026-06-12)`
|
||||
|
||||
- [ ] 6.1 Mailable `MailAboExecutionReminder` + Template (DE/EN/ES/FR): Ausführung in X Tagen, Deckung prüfen, jetzt Produkte mitnehmen / Nachhaltigkeit.
|
||||
- [ ] 6.2 Link je `is_for`: `me` → `getMyMivitaUrl()` + `user/abos/detail/me/{id}`; `ot` → `getMyMivitaPortalUrl()` + Portal-Abo-Route.
|
||||
- [ ] 6.3 Command `abo:send-execution-reminder`: selektiert Abos mit `next_date = heute + abo-onetime-window-days`, `active`, `status=2`; Duplikat-Schutz pro Zyklus.
|
||||
- [ ] 6.4 Schedule-Eintrag in `app/Console/Kernel.php`.
|
||||
- [ ] 6.5 Tests: Selektion, Link-Wahl Berater/Endkunde, Duplikat-Schutz.
|
||||
- [x] 6.1 Mailable `MailAboExecutionReminder` + Template (DE/EN/ES/FR): Ausführung in X Tagen, Deckung prüfen, jetzt Produkte mitnehmen / Nachhaltigkeit.
|
||||
- [x] 6.2 Link je `is_for`: `me` → `getMyMivitaUrl()` + `user/abos/detail/me/{id}`; `ot` → `getMyMivitaPortalUrl()` + Portal-Abo-Route.
|
||||
- [x] 6.3 Command `abo:send-execution-reminder`: selektiert Abos mit `next_date = heute + abo-onetime-window-days`, `active`, `status=2`; Duplikat-Schutz pro Zyklus.
|
||||
- [x] 6.4 Schedule-Eintrag in `app/Console/Kernel.php` (**bewusst inaktiv/auskommentiert** – Review-Gate).
|
||||
- [x] 6.5 Tests: Selektion, Link-Wahl Berater/Endkunde, Duplikat-Schutz.
|
||||
|
||||
**Doku:** _(nach Umsetzung ausfüllen)_
|
||||
**Doku (2026-06-12):**
|
||||
|
||||
- **6.1 Mailable** `app/Mail/MailAboExecutionReminder.php` (Constructor-Promotion `public UserAbo $userAbo`): ermittelt Anrede aus `shopping_user->billing_firstname`, Tage bis Ausführung (`diffInDays`, min 0), Lieferdatum (`Util::formatDate()`) und den zielgruppenspezifischen Link. Subject `email.abo_reminder_subject`. **Hinweis:** Das ererbte `Mailable::$subject` darf **nicht** typisiert redeklariert werden (Fatal Error) → Subject wird in `build()` via `->subject(__())` gesetzt.
|
||||
- **Template** `resources/views/emails/abo_execution_reminder.blade.php` (am DHL-Tracking-Stil orientiert): Logo, Anrede, `trans_choice('email.abo_reminder_intro', $days, [...])` (Singular/Plural Tage + Datum), Einmalprodukte-Hinweis, hervorgehobene Box mit **Deckungs-Hinweis** + **Nachhaltigkeits-Hinweis** und CTA-Button (Text je `isConsultant`), Standard-Footer.
|
||||
- **6.2 Link-Wahl** (`MailAboExecutionReminder::buildLink()`): Berater (`is_for === 'me'`) → `Util::getMyMivitaUrl()` + `/user/abos/detail/me/{id}` (Sales Center my.mivita.care); Endkunde (`ot`) → `Util::getMyMivitaPortalUrl()` + `/portal/my-subscriptions` (Kundenportal in.mivita.care). Cross-Domain → bewusst String-Konkatenation statt `route()`.
|
||||
- **6.3 Command** `app/Console/Commands/AboSendExecutionReminder.php` (`abo:send-execution-reminder`, Option `--dry-run`): selektiert `active=true`, `status=2`, `is_for ∈ {me,ot}`, `next_date = heute + abo-onetime-window-days`. **Duplikat-Schutz:** neue Spalte `user_abos.onetime_reminder_sent_for` (date) – versendet nur, wenn `null` **oder** `!= next_date`; nach Erfolg wird sie auf `next_date` gesetzt. Empfänger-E-Mail: `abo->email` (Fallback `user->email` bzw. `shopping_user->billing_email`). Locale je Empfänger (`getLocale()`, Fallback `de`). Versandfehler → Log-Channel `abo_order`, kein Abbruch.
|
||||
- **Migration** `database/migrations/2026_06_12_124917_add_onetime_reminder_sent_for_to_user_abos_table.php` – `date onetime_reminder_sent_for nullable after('next_date')`; `UserAbo` um Fillable + Cast `date` ergänzt. **Hinweis:** Migration muss beim Deploy auf der echten DB ausgeführt werden (`php artisan migrate`).
|
||||
- **6.4 Schedule** in `app/Console/Kernel.php` als Kommentar hinterlegt (`// $schedule->command('abo:send-execution-reminder')->dailyAt('06:00');`) – **bewusst inaktiv**, bis das Review-Gate fällt (sonst würden Empfänger auf ein für sie ausgeblendetes Feature verlinkt). Nach Freigabe nur einkommentieren.
|
||||
- **Übersetzungen** (`{de,en,es,fr}/email.php`): `abo_reminder_subject`, `abo_reminder_title`, `abo_reminder_intro` (pluralisiert), `abo_reminder_onetime_hint`, `abo_reminder_coverage_hint`, `abo_reminder_sustainability_hint`, `abo_reminder_button_consultant`, `abo_reminder_button_customer`.
|
||||
- **6.5 Tests** `tests/Feature/AboExecutionReminderTest.php` (6 Tests grün, `Mail::fake()`): Selektion im Fenster, kein Versand außerhalb/inaktiv/falscher Status, Link-Wahl Berater (Sales Center) vs. Endkunde (Portal) über `->render()`, Duplikat-Schutz (zweiter Lauf versendet nicht, `onetime_reminder_sent_for` gesetzt). Gesamt Einmalprodukte: **58 grün** (+ 1 erwartet rot = Review-Gate).
|
||||
- **Pint:** ausgeführt (`--dirty`), pass.
|
||||
|
||||
---
|
||||
|
||||
### Phase 7 – Gesamttests & Abschluss · `OFFEN`
|
||||
### Phase 7 – Gesamttests & Abschluss · `ERLEDIGT (2026-06-12)`
|
||||
|
||||
- [ ] 7.1 End-to-End-Feature-Tests über alle Phasen.
|
||||
- [ ] 7.2 `./vendor/bin/pint` über alle geänderten Dateien.
|
||||
- [ ] 7.3 Vollständige Testsuite (nach Rücksprache) laufen lassen.
|
||||
- [ ] 7.4 Abschluss-Dokumentation in diesem File aktualisieren.
|
||||
- [x] 7.1 End-to-End-Feature-Tests über alle Phasen (je Phase eigene Test-Datei, s. u.).
|
||||
- [x] 7.2 `./vendor/bin/pint` über alle geänderten Dateien (pass).
|
||||
- [x] 7.3 Vollständige Testsuite (nach Rücksprache) laufen lassen.
|
||||
- [x] 7.4 Abschluss-Dokumentation in diesem File aktualisiert.
|
||||
|
||||
**Doku:** _(nach Umsetzung ausfüllen)_
|
||||
**Doku (2026-06-12):**
|
||||
|
||||
- **Feature-Tests Einmalprodukte (alle grün):** `AboOneTimeWindowTest`, `AboOneTimeServiceTest`, `AboOneTimeViewTest`, `AboMakeOrderOneTimeTest`, `AboUserRetryTest`, `AboOneTimeInvoiceGroupingTest` (Phase 5), `AboExecutionReminderTest` (Phase 6) → **58 grün** (+ 1 erwartet rot = Review-Gate `isOneTimeFeatureVisible`).
|
||||
- **Vollständige Suite (`php artisan test`):** 459 passed, 1 skipped, **93 failed** – Dauer ~97 s. **Alle 93 Fehler sind vorbestehend und NICHT durch Phase 5–7 verursacht** (verifiziert):
|
||||
- `Unit/Services/InvoiceServiceTest` → `no such table: settings` (Test nutzt reale DB-Tabelle, fehlt auf SQLite).
|
||||
- `Feature/ExampleTest` → `no such table: dbip_lookup` (Geo-IP-Tabelle nur in MySQL).
|
||||
- `Feature/Payment/ConcurrentPaymentTest` + `PayoneRaceConditionTest` → `QueryException` (SQLite kann die Concurrency-/Lock-Szenarien nicht abbilden; gehören zum Payment-Branch).
|
||||
- `Unit/BusinessPlan/*`, `Feature/BusinessPlan/*`, `Unit/Incentive/*`, `Feature/Incentive/*` → `BadMethodCallException`/`RouteNotFoundException`/`TypeError`/`ReflectionException` (unabhängige Altlasten).
|
||||
- `Feature/FrenchLocalizationTest` → `fr/abo.php` fehlen Keys, die `de/abo.php` hat (`abo_extern_done`, `abo_finish`, `abo_order_info_*`, Status-Typen). **Bereits auf committed HEAD rot** (Beleg: `git show HEAD:resources/lang/fr/abo.php` enthält `abo_extern_done` nicht, `de` schon). Stammt aus **fremden** Commits (u. a. „Bestellung extern als erledigt markieren"), nicht aus diesem Feature. Die Einmalprodukte-Keys selbst sind in allen vier Sprachen (de/en/es/fr) vollständig vorhanden; die in Phase 5/6 ergänzten `pdf.php`/`email.php`-Keys wurden in allen vier Sprachen synchron hinzugefügt.
|
||||
- **Offener Fremd-Befund (nicht Teil dieses Features):** `fr/abo.php` und `es/abo.php` sind gegenüber `de/abo.php` nicht synchron (fehlende Keys aus anderen Arbeitspaketen). Empfehlung: in einem eigenen Ticket nachziehen.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -408,4 +433,9 @@ Der bestehende Retry ist Admin-manuell (`AboRetryPaymentService`). Eine **automa
|
|||
| 2026-06-08 | Review-Gate | **Temporäre Live-Sichtbarkeit für Abstimmung:** Einmalprodukte-Feature über `AboHelper::isOneTimeFeatureVisible()` nur für VIP-User (`isVIP()` = `admin>=1`) im Sales Center sichtbar; Endkunden-Portal (customers-Guard, kein VIP) komplett ausgeblendet. Gates in `User\AboController` (detail/update/oneTime/oneTimeDatatable), `Portal\AboController` (myAbo/update/oneTime/oneTimeDatatable/modalLoad), `ModalController` (abo-add-onetime). Reversibel: Methode später auf reines `isOneTimeWindowOpen()` zurücksetzen + Portal reaktivieren. 4 neue Tests (47 gesamt grün) | ERLEDIGT |
|
||||
| 2026-06-08 | 4 (Schritt 1) | **Ausführung – Einmal-Artikel in die Bestellung:** `UserMakeOrder::makeShoppingOrder()` lädt nach `makeOrderYard()` zusätzlich `AboOrderCart::addOneTimeItemsToYard()` (nur verbindlich bestätigte Artikel); `ShoppingOrderItem` erhält `is_abo_addon` aus `options->abo_addon`. Reihenfolge sichert: `user_abos.amount` bleibt der **reine** Abo-Betrag, der Abbuchungsbetrag der Bestellung ist kombiniert (Abo + Einmal). 3 neue Tests (`AboMakeOrderOneTimeTest`) | ERLEDIGT |
|
||||
| 2026-06-08 | 4 (Schritt 2) | **Purge & Comp-Reset nur bei Erfolg:** Neue Methode `AboOneTimeService::purgeAfterExecution()` löscht nach erfolgreicher Ausführung **alle** Einmal-Artikel des Abos (bestätigt + offen + soft-deleted, `forceDelete`) und bewertet anschließend die Kompensationsprodukte des reinen Abos neu (Option A: `initYard`+`makeOrderYard`+`checkNumOfCompProducts`). Aufruf im Erfolgszweig von `UserMakeAboOrder::updateAbo()` (Cron) und `AboRetryPaymentService::markAboSuccess()`. Bei Zahlungsfehler bleiben die Einmal-Artikel erhalten. Fehler beim Purge rollen den erfolgreichen Lauf nicht zurück (nur Logging). 3 neue Tests (Purge inkl. soft-deleted, Comp-Reduktion, „behalten bei Fehler") | ERLEDIGT |
|
||||
| 2026-06-12 | Review-Gate | **Review-Gate AUFGEHOBEN:** `AboHelper::isOneTimeFeatureVisible()` delegiert wieder rein auf `isOneTimeWindowOpen()` (fensterbasiert, Sales Center + Portal gleichermaßen). VIP-Beschränkung und Portal-Ausblendung entfernt, Fensterprüfung reaktiviert. VIP-Gate-Tests in `AboOneTimeWindowTest` auf fensterbasiertes Verhalten umgeschrieben → **58 grün, kein erwartet-roter Test mehr**. **Hinweis:** Reminder-Cron bleibt weiterhin inaktiv (separate Entscheidung). | ERLEDIGT |
|
||||
| 2026-06-12 | Settings | **Sperrfristen konfigurierbar:** `AboRepository`-Konstanten → Settings `abo-lock-days-change` (Default 10, Abo bearbeiten) und `abo-lock-days-pause-cancel` (Default 3, Pausieren/Kündigen), zwei Felder in der Admin-Abo-Card. 4 neue Tests (`AboLockDaysSettingTest`). Keine Migration nötig (generisches Setting-K/V) | ERLEDIGT |
|
||||
| 2026-06-12 | 7 | **Gesamttests & Abschluss:** Vollständige Suite gelaufen (459 passed, 1 skipped, 93 failed). Alle 93 Fehler vorbestehend/fremd (SQLite-Infra: `settings`/`dbip_lookup`-Tabellen; Payment-Concurrency; BusinessPlan/Incentive-Altlasten; `fr/abo.php`-Sync aus Fremd-Commits – bereits auf HEAD rot). Einmalprodukte-Feature: 58 grün + 1 erwartet rot (Review-Gate). Pint pass | ERLEDIGT |
|
||||
| 2026-06-12 | 6 | **Reminder-E-Mail (vorbereitet, Cron inaktiv):** Mailable `MailAboExecutionReminder` + Template (DE/EN/ES/FR), Command `abo:send-execution-reminder` (Selektion `next_date = heute + Fenster`, `active`, `status=2`, Duplikat-Schutz über neue Spalte `user_abos.onetime_reminder_sent_for`). Link-Unterscheidung Berater → Sales Center (my.mivita), Endkunde → Portal (in.mivita). Schedule-Eintrag **bewusst auskommentiert** (Review-Gate). 6 neue Tests (`AboExecutionReminderTest`, 58 gesamt grün). **Deploy:** `php artisan migrate` nötig | ERLEDIGT |
|
||||
| 2026-06-12 | 5 | **Rechnung & Lieferschein – Gruppierung:** `invoice-detail.blade.php` + `delivery-detail.blade.php` gruppieren Positionen nach `is_abo_addon` (Abo oben, abgegrenzter Block „Einmalig hinzugefügte Artikel" darunter) – nur bei tatsächlich vorhandenen Einmal-Artikeln, sonst unveränderte Ausgabe. Neue Lang-Keys `pdf.abo_items_heading`/`pdf.abo_addon_items_heading` (DE/EN/ES/FR). 4 neue Tests (`AboOneTimeInvoiceGroupingTest`, 52 gesamt grün) | ERLEDIGT |
|
||||
| 2026-06-08 | 4 (Schritt 3) | **User-Retry (Sales Center + Portal):** Neue Methoden `User\AboController::retryPayment($view,$id)` (Permission via `checkPermissions`) und `Portal\AboController::retryPayment($id)` (Permission via `checkPortalPermission`), delegieren an `AboRetryPaymentService::retry()` (nutzt denselben `makeShoppingOrder`-Pfad → Einmal-Artikel automatisch enthalten). Routen `user_abos_retry_payment` (CRM) und `portal_abos_retry_payment` (Portal). Gemeinsames Confirm-Modal `_retry_payment_modal` (nur bei `status===3 && active`) in `user/abo/detail` und `portal/abo/my_abo` inkl. Erfolgsmeldung. 2 neue Tests (Erfolg + 403 bei fremdem Abo). **Hinweis:** Ein bestehender Test (`isOneTimeFeatureVisible außerhalb des Fensters → false`) schlägt erwartungsgemäß fehl, da die Fensterprüfung für die Review-Phase bewusst auskommentiert bleibt | ERLEDIGT |
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ return [
|
|||
'warning_next_date_soon_select' => 'Hinweis: Die nächste Abo-Ausführung ist bereits in :placeholder_days Tagen (:placeholder_date).',
|
||||
'warning_next_date_info' => 'Die nächste Abo-Ausführung ist in :days Tagen am :date.',
|
||||
'info_next_execution_select' => 'Nächste Ausführung: in :placeholder_days Tagen am :placeholder_date.',
|
||||
'error_change_locked' => 'Änderungen sind nicht mehr möglich. Die nächste Ausführung ist in :days Tagen. Änderungen müssen mindestens 10 Tage vorher erfolgen.',
|
||||
'error_abo_interval_too_soon' => 'Der gewählte Liefertag liegt nur :days Tage entfernt. Bitte wähle einen Liefertag, der mindestens 10 Tage in der Zukunft liegt.',
|
||||
'error_cancel_locked' => 'Eine Kündigung ist nicht mehr möglich. Die nächste Ausführung ist in :days Tagen. Kündigungen müssen mindestens 3 Tage vorher erfolgen.',
|
||||
'error_pause_locked' => 'Das Abo kann nicht mehr pausiert werden. Die nächste Ausführung ist in :days Tagen. Pausieren muss mindestens 3 Tage vorher erfolgen.',
|
||||
'error_change_locked' => 'Änderungen sind nicht mehr möglich. Die nächste Ausführung ist in :days Tagen. Änderungen müssen mindestens :lock Tage vorher erfolgen.',
|
||||
'error_abo_interval_too_soon' => 'Der gewählte Liefertag liegt nur :days Tage entfernt. Bitte wähle einen Liefertag, der mindestens :lock Tage in der Zukunft liegt.',
|
||||
'error_cancel_locked' => 'Eine Kündigung ist nicht mehr möglich. Die nächste Ausführung ist in :days Tagen. Kündigungen müssen mindestens :lock Tage vorher erfolgen.',
|
||||
'error_pause_locked' => 'Das Abo kann nicht mehr pausiert werden. Die nächste Ausführung ist in :days Tagen. Pausieren muss mindestens :lock Tage vorher erfolgen.',
|
||||
'error_next_date' => 'Das Datum für die nächste Ausführung nicht korrekt',
|
||||
'checkout_mail_abo_hl' => 'Dein Abo / regelmäßige Lieferung.',
|
||||
'checkout_mail_abo_start' => 'Dein Abo wurde erfolgreich mit folgenden Einstellungen angelegt:',
|
||||
|
|
@ -95,6 +95,22 @@ return [
|
|||
'product_prices_career_level_info' => 'Die Produktpreise werden entsprechend Deinem Karriere-Level <strong>:user_level_name</strong> abzüglich <strong>:user_level_margin %</strong> Marge angezeigt und brechnet.',
|
||||
'product_prices_career_level_cpay_info' => 'Die Produktpreise werden als Kunden VK-Preise angezeigt, nach Abschluss der Kundenzahlung erhälst du Deine Provision entsprechend Deinem Karriere-Level <strong>:user_level_name</strong> Provision <strong>:user_level_margin %</strong>.',
|
||||
'error_email_has_abo' => 'Für die E-Mail-Adresse :email ist bereits ein Abonnement vorhanden.',
|
||||
'error_user_has_initiated_abo' => 'Für dich ist bereits ein Abo angelegt oder die Zahlung dazu läuft noch. Bitte prüfe den Status unter "Meine Abos".',
|
||||
'pending_payment_waiting_title' => 'Abo angelegt - Zahlung noch nicht bestätigt',
|
||||
'pending_payment_waiting_copy' => 'Der Checkout wurde abgeschlossen. Wir warten noch auf den Zahlungsstatus des Zahlungsanbieters. Solange kein Status eingegangen ist, kann dieser Eintrag nicht gelöscht werden.',
|
||||
'pending_payment_processing_title' => 'Abo angelegt - Zahlung wird verarbeitet',
|
||||
'pending_payment_processing_copy' => 'Der Zahlungsanbieter hat bereits einen Status geliefert. Bitte warte auf die finale Zahlungsbestätigung.',
|
||||
'pending_payment_failed_title' => 'Zahlung fehlgeschlagen',
|
||||
'pending_payment_failed_copy' => 'Die Zahlung für dieses Abo konnte nicht abgeschlossen werden. Du kannst diesen Eintrag löschen und das Abo anschließend neu anlegen.',
|
||||
'pending_delete_button' => 'Eintrag löschen',
|
||||
'pending_delete_success' => 'Der nicht bestätigte Abo-Eintrag wurde gelöscht.',
|
||||
'pending_delete_not_allowed' => 'Dieser Abo-Eintrag kann noch nicht gelöscht werden, weil die Zahlung noch nicht final fehlgeschlagen ist.',
|
||||
'payment_link_sent_title' => 'Abo-Zahlungslink gesendet',
|
||||
'payment_link_sent_copy' => 'Der Zahlungslink wurde an den Kunden gesendet. Solange noch keine Zahlung gestartet wurde, kann dieser Eintrag gelöscht werden.',
|
||||
'payment_link_processing_copy' => 'Der Kunde hat die Zahlung gestartet. Wir warten auf den finalen Zahlungsstatus des Zahlungsanbieters. In diesem Zustand kann der Eintrag nicht gelöscht werden.',
|
||||
'payment_link_failed_copy' => 'Die Zahlung zu diesem Abo-Zahlungslink ist fehlgeschlagen oder wurde abgebrochen. Du kannst den Eintrag löschen und anschließend einen neuen Zahlungslink erstellen.',
|
||||
'payment_link_delete_success' => 'Der Abo-Zahlungslink wurde gelöscht.',
|
||||
'payment_link_delete_not_allowed' => 'Dieser Zahlungslink kann aktuell nicht gelöscht werden, weil die Zahlung bereits läuft oder abgeschlossen ist.',
|
||||
'abo_assigned' => 'Abo aktiv',
|
||||
'base' => 'Basis',
|
||||
'upgrade' => 'Upgrade',
|
||||
|
|
@ -175,6 +191,37 @@ return [
|
|||
'extern_done_error' => 'Die Bestellung konnte nicht als erledigt markiert werden: :error',
|
||||
'team_subscriptions' => 'Team Abos',
|
||||
'team_customer_abos' => 'Team Kunden-Abos',
|
||||
'team_total' => 'Gesamt',
|
||||
'team_line' => ':line. Ebene',
|
||||
'filter_period' => 'Zeitraum:',
|
||||
'team_total_abos' => 'Gesamtabos im Team',
|
||||
'team_own_abos' => 'Eigen-Abos',
|
||||
'team_members_with_abo' => 'Mit eigenem Abo',
|
||||
'team_by_level' => 'Abos nach Ebenen',
|
||||
'new_this_month' => 'neu im Monat',
|
||||
'with_own_abo' => 'Mit Eigen-Abo',
|
||||
'consultants' => 'Berater',
|
||||
'level' => 'Ebene',
|
||||
'own_abo' => 'Eigen-Abo',
|
||||
'customer_abos_count' => 'Kundenabos',
|
||||
'career_level' => 'Karriere-Level',
|
||||
'of' => 'von',
|
||||
'yes' => 'Ja',
|
||||
'no' => 'Nein',
|
||||
'shop_1000' => '1000-Punkte-Shops',
|
||||
'next_execution' => 'Nächste Ausführung',
|
||||
'executions_count' => 'Ausführungen',
|
||||
'abo_count_points' => 'Punkte',
|
||||
'no_own_abo' => 'Kein eigenes Abo vorhanden.',
|
||||
'no_customer_abos' => 'Keine Kunden-Abos vorhanden.',
|
||||
'team_growth' => 'Abo-Wachstum (Neuzugänge je Monat)',
|
||||
'month' => 'Monat',
|
||||
'new_own_abos' => 'Neue Eigen-Abos',
|
||||
'new_customer_abos' => 'Neue Kunden-Abos',
|
||||
'new_total' => 'Neu gesamt',
|
||||
'filter' => 'Filtern',
|
||||
'reset' => 'Zurücksetzen',
|
||||
'filter_added_period' => 'Hinzugekommen im Zeitraum:',
|
||||
'chart_monthly_abos' => 'Abos pro Monat',
|
||||
'chart_active_abos' => 'Aktive Abos',
|
||||
'chart_abos_label' => 'Abos',
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'' => '',
|
||||
'cancel' => 'abbrechen',
|
||||
'confirm' => 'bestätigen',
|
||||
'file_is_too_big' => 'Die Datei ist zu groß<br>max. $0 MB',
|
||||
'image_too_small ' => 'Bild zu klein<br>min. $0 Pixel',
|
||||
'invalid_file' => 'Ungültige Datei<br>bitte nur: $0',
|
||||
'really_delete_picture' => 'Bild wirklich löschen?',
|
||||
'rotate' => 'drehen',
|
||||
'save_image' => 'Bild speichern',
|
||||
'search_file_or_drag_drop' => 'Datei suchen oder Drag & Drop',
|
||||
'upload_photo' => 'Foto-Upload',
|
||||
'dictDefaultMessage' => 'Drop files here to upload',
|
||||
'dictFallbackMessage' => 'Your browser does not support drag n drop file uploads.',
|
||||
'dictFallbackText' => 'Please use the fallback form below to upload your files like in the olden days',
|
||||
'dictFileTooBig' => 'File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.',
|
||||
'dictInvalidFileType' => 'You cant upload files of this type.',
|
||||
'dictResponseError' => 'Server responded with {{statusCode}} code.',
|
||||
'dictCancelUpload' => 'Cancel upload',
|
||||
'dictRemoveFile' => 'Remove file',
|
||||
'dictMaxFilesExceeded' => 'You can not upload any more files.',
|
||||
);
|
||||
return [
|
||||
'' => '',
|
||||
'cancel' => 'abbrechen',
|
||||
'confirm' => 'bestätigen',
|
||||
'file_is_too_big' => 'Die Datei ist zu groß<br>max. $0 MB',
|
||||
'image_too_small' => 'Bild zu klein<br>min. $0 Pixel',
|
||||
'invalid_file' => 'Ungültige Datei<br>bitte nur: $0',
|
||||
'really_delete_picture' => 'Bild wirklich löschen?',
|
||||
'rotate' => 'drehen',
|
||||
'save_image' => 'Bild speichern',
|
||||
'search_file_or_drag_drop' => 'Datei suchen oder Drag & Drop',
|
||||
'upload_photo' => 'Foto-Upload',
|
||||
'dictDefaultMessage' => 'Drop files here to upload',
|
||||
'dictFallbackMessage' => 'Your browser does not support drag n drop file uploads.',
|
||||
'dictFallbackText' => 'Please use the fallback form below to upload your files like in the olden days',
|
||||
'dictFileTooBig' => 'File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.',
|
||||
'dictInvalidFileType' => 'You cant upload files of this type.',
|
||||
'dictResponseError' => 'Server responded with {{statusCode}} code.',
|
||||
'dictCancelUpload' => 'Cancel upload',
|
||||
'dictRemoveFile' => 'Remove file',
|
||||
'dictMaxFilesExceeded' => 'You can not upload any more files.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -130,4 +130,14 @@ Dein Team von MIVITA',
|
|||
'dhl_tracking_button' => 'Sendung bei DHL verfolgen',
|
||||
'dhl_tracking_info' => 'Du kannst den aktuellen Status Deiner Sendung jederzeit über den obigen Button bei DHL einsehen.',
|
||||
|
||||
// Abo-Einmalprodukte: Reminder vor der Ausführung
|
||||
'abo_reminder_subject' => 'Deine nächste Abo-Lieferung steht an – jetzt Produkte mitnehmen',
|
||||
'abo_reminder_title' => 'Deine nächste Abo-Lieferung steht bevor',
|
||||
'abo_reminder_intro' => '{1}Deine nächste Abo-Lieferung wird in :days Tag (am :date) ausgeführt.|[2,*]Deine nächste Abo-Lieferung wird in :days Tagen (am :date) ausgeführt.',
|
||||
'abo_reminder_onetime_hint' => 'Du kannst dieser Lieferung jetzt einmalig weitere Produkte aus unserem Sortiment hinzufügen – ohne zusätzliche Versandkosten und ohne zweiten Versandweg.',
|
||||
'abo_reminder_coverage_hint' => 'Bitte achte darauf, dass Deine hinterlegte Zahlungsweise den Gesamtbetrag (Abo + zusätzliche Produkte) deckt.',
|
||||
'abo_reminder_sustainability_hint' => 'Gemeinsam sparen wir so Verpackung und einen zweiten Transportweg – gut für die Umwelt.',
|
||||
'abo_reminder_button_consultant' => 'Produkte zur Lieferung hinzufügen',
|
||||
'abo_reminder_button_customer' => 'Produkte zur Lieferung hinzufügen',
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ return [
|
|||
'weight' => 'Gewicht',
|
||||
'you_has_article_in_shopping_cart' => 'Du hast :num Artikel in Deinem Warenkorb',
|
||||
'excl' => 'zzgl.',
|
||||
'VAT' => 'MwSt.',
|
||||
'ipay' => 'ich zahle',
|
||||
'cpay' => 'Kunde zahlt',
|
||||
'ipay_text' => 'Ich zahle abzüglich meiner Marge und rechne den VK mit meinem Kunden ab',
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ return [
|
|||
'shipping_costs' => 'Versandkosten',
|
||||
'total_amount' => 'Gesamtbetrag',
|
||||
|
||||
// Abo-Einmalprodukte (Gruppierung Rechnung/Lieferschein)
|
||||
'abo_items_heading' => 'Abo-Produkte',
|
||||
'abo_addon_items_heading' => 'Einmalig hinzugefügte Artikel',
|
||||
|
||||
];
|
||||
/*
|
||||
{{ __('pdf.') }}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,22 @@ return [
|
|||
'product_prices_career_level_info' => 'Product prices are displayed and calculated according to your career level <strong>:user_level_name</strong> minus <strong>:user_level_margin %</strong> margin.',
|
||||
'product_prices_career_level_cpay_info' => 'The product prices are displayed as customer retail prices. After the customer payment is completed, you will receive your commission according to your career level <strong>:user_level_name</strong> commission <strong>:user_level_margin %</strong>.',
|
||||
'error_email_has_abo' => 'A subscription already exists for the email address :email.',
|
||||
'error_user_has_initiated_abo' => 'A subscription has already been created for you or its payment is still being processed. Please check the status under "My subscriptions".',
|
||||
'pending_payment_waiting_title' => 'Subscription created - payment not confirmed yet',
|
||||
'pending_payment_waiting_copy' => 'Checkout has been completed. We are still waiting for the payment status from the payment provider. As long as no status has arrived, this entry cannot be deleted.',
|
||||
'pending_payment_processing_title' => 'Subscription created - payment is being processed',
|
||||
'pending_payment_processing_copy' => 'The payment provider has already sent a status. Please wait for the final payment confirmation.',
|
||||
'pending_payment_failed_title' => 'Payment failed',
|
||||
'pending_payment_failed_copy' => 'The payment for this subscription could not be completed. You can delete this entry and create the subscription again afterwards.',
|
||||
'pending_delete_button' => 'Delete entry',
|
||||
'pending_delete_success' => 'The unconfirmed subscription entry was deleted.',
|
||||
'pending_delete_not_allowed' => 'This subscription entry cannot be deleted yet because the payment has not finally failed.',
|
||||
'payment_link_sent_title' => 'Subscription payment link sent',
|
||||
'payment_link_sent_copy' => 'The payment link has been sent to the customer. As long as no payment has been started, this entry can be deleted.',
|
||||
'payment_link_processing_copy' => 'The customer has started the payment. We are waiting for the final payment status from the payment provider. This entry cannot be deleted in this state.',
|
||||
'payment_link_failed_copy' => 'The payment for this subscription payment link failed or was canceled. You can delete the entry and create a new payment link afterwards.',
|
||||
'payment_link_delete_success' => 'The subscription payment link was deleted.',
|
||||
'payment_link_delete_not_allowed' => 'This payment link cannot currently be deleted because the payment is already running or completed.',
|
||||
'abo_assigned' => 'Subscription active',
|
||||
'base' => 'Base',
|
||||
'upgrade' => 'Upgrade',
|
||||
|
|
@ -145,10 +161,10 @@ return [
|
|||
'warning_next_date_soon_select' => 'Note: The next subscription execution is in :placeholder_days days (:placeholder_date).',
|
||||
'warning_next_date_info' => 'The next subscription execution is in :days days on :date.',
|
||||
'info_next_execution_select' => 'Next execution: in :placeholder_days days on :placeholder_date.',
|
||||
'error_change_locked' => 'Changes are no longer possible. The next execution is in :days days. Changes must be made at least 10 days in advance.',
|
||||
'error_abo_interval_too_soon' => 'The selected delivery day is only :days days away. Please choose a delivery day at least 10 days in the future.',
|
||||
'error_cancel_locked' => 'Cancellation is no longer possible. The next execution is in :days days. Cancellations must be made at least 3 days in advance.',
|
||||
'error_pause_locked' => 'The subscription can no longer be paused. The next execution is in :days days. Pausing must be done at least 3 days in advance.',
|
||||
'error_change_locked' => 'Changes are no longer possible. The next execution is in :days days. Changes must be made at least :lock days in advance.',
|
||||
'error_abo_interval_too_soon' => 'The selected delivery day is only :days days away. Please choose a delivery day at least :lock days in the future.',
|
||||
'error_cancel_locked' => 'Cancellation is no longer possible. The next execution is in :days days. Cancellations must be made at least :lock days in advance.',
|
||||
'error_pause_locked' => 'The subscription can no longer be paused. The next execution is in :days days. Pausing must be done at least :lock days in advance.',
|
||||
'cancel_abo' => 'Cancel subscription',
|
||||
'confirm_cancel' => 'Do you really want to cancel the subscription?',
|
||||
'retry_payment' => 'Retry payment',
|
||||
|
|
@ -176,6 +192,37 @@ return [
|
|||
'back' => 'back',
|
||||
'team_subscriptions' => 'Team subscriptions',
|
||||
'team_customer_abos' => 'Team Customer Subscriptions',
|
||||
'team_total' => 'Total',
|
||||
'team_line' => 'Level :line',
|
||||
'filter_period' => 'Period:',
|
||||
'team_total_abos' => 'Total team subscriptions',
|
||||
'team_own_abos' => 'Own subscriptions',
|
||||
'team_members_with_abo' => 'With own subscription',
|
||||
'team_by_level' => 'Subscriptions by level',
|
||||
'new_this_month' => 'new this month',
|
||||
'with_own_abo' => 'With own subscription',
|
||||
'consultants' => 'Consultants',
|
||||
'level' => 'Level',
|
||||
'own_abo' => 'Own subscription',
|
||||
'customer_abos_count' => 'Customer subscriptions',
|
||||
'career_level' => 'Career level',
|
||||
'of' => 'of',
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
'shop_1000' => '1000-Point Shops',
|
||||
'next_execution' => 'Next execution',
|
||||
'executions_count' => 'Executions',
|
||||
'abo_count_points' => 'Points',
|
||||
'no_own_abo' => 'No own subscription.',
|
||||
'no_customer_abos' => 'No customer subscriptions.',
|
||||
'team_growth' => 'Subscription growth (new per month)',
|
||||
'month' => 'Month',
|
||||
'new_own_abos' => 'New own subscriptions',
|
||||
'new_customer_abos' => 'New customer subscriptions',
|
||||
'new_total' => 'New total',
|
||||
'filter' => 'Filter',
|
||||
'reset' => 'Reset',
|
||||
'filter_added_period' => 'Added during period:',
|
||||
'chart_monthly_abos' => 'Subscriptions per month',
|
||||
'chart_active_abos' => 'Active subscriptions',
|
||||
'chart_abos_label' => 'subscriptions',
|
||||
|
|
|
|||
|
|
@ -44,4 +44,5 @@ return [
|
|||
'language_settings' => 'Language settings',
|
||||
'preferred_language' => 'Preferred language',
|
||||
'language_hint' => 'This language will be used for your invoices, commission statements and delivery notes.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'cancel' => 'cancel',
|
||||
'confirm' => 'confirm',
|
||||
'file_is_too_big' => 'The file is too large<br>max. $0MB',
|
||||
'image_too_small' => 'Image too small <br>min. $0 pixels',
|
||||
'invalid_file' => 'Invalid file<br>please only: $0',
|
||||
'really_delete_picture' => 'Really delete an image?',
|
||||
'rotate' => 'turn',
|
||||
'save_image' => 'save image',
|
||||
'search_file_or_drag_drop' => 'Search file or drag & drop',
|
||||
'upload_photo' => 'photo upload',
|
||||
);
|
||||
return [
|
||||
'cancel' => 'cancel',
|
||||
'confirm' => 'confirm',
|
||||
'file_is_too_big' => 'The file is too large<br>max. $0MB',
|
||||
'image_too_small' => 'Image too small <br>min. $0 pixels',
|
||||
'invalid_file' => 'Invalid file<br>please only: $0',
|
||||
'really_delete_picture' => 'Really delete an image?',
|
||||
'rotate' => 'turn',
|
||||
'save_image' => 'save image',
|
||||
'search_file_or_drag_drop' => 'Search file or drag & drop',
|
||||
'upload_photo' => 'photo upload',
|
||||
'' => '',
|
||||
'dictDefaultMessage' => 'Drop files here to upload',
|
||||
'dictFallbackMessage' => 'Your browser does not support drag n drop file uploads.',
|
||||
'dictFallbackText' => 'Please use the fallback form below to upload your files like in the olden days',
|
||||
'dictFileTooBig' => 'File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.',
|
||||
'dictInvalidFileType' => 'You cant upload files of this type.',
|
||||
'dictResponseError' => 'Server responded with {{statusCode}} code.',
|
||||
'dictCancelUpload' => 'Cancel upload',
|
||||
'dictRemoveFile' => 'Remove file',
|
||||
'dictMaxFilesExceeded' => 'You can not upload any more files.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
);
|
||||
return [
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
'not_found' => 'This email is not registered.',
|
||||
'failed_customer' => 'This email was not found in our database.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -32,4 +32,7 @@ return [
|
|||
'select' => 'select',
|
||||
'under_review' => 'in examination',
|
||||
'language_hint' => 'Invoices and documents will be created in this language.',
|
||||
'delete_customer' => 'Delete customer',
|
||||
'deleted_successfully' => 'Customer was deleted successfully',
|
||||
'delete_customer_confirm' => 'Are you sure you want to delete this customer?',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -122,4 +122,14 @@ return [
|
|||
'dhl_tracking_order_ref' => 'Order number: :order',
|
||||
'dhl_tracking_button' => 'Track shipment with DHL',
|
||||
'dhl_tracking_info' => 'You can check the current status of your shipment at any time via the button above at DHL.',
|
||||
|
||||
// Subscription one-time products: reminder before execution
|
||||
'abo_reminder_subject' => 'Your next subscription delivery is coming up – add products now',
|
||||
'abo_reminder_title' => 'Your next subscription delivery is coming up',
|
||||
'abo_reminder_intro' => '{1}Your next subscription delivery will be processed in :days day (on :date).|[2,*]Your next subscription delivery will be processed in :days days (on :date).',
|
||||
'abo_reminder_onetime_hint' => 'You can now add further products from our range to this delivery on a one-time basis – without additional shipping costs and without a second delivery.',
|
||||
'abo_reminder_coverage_hint' => 'Please make sure your stored payment method covers the total amount (subscription + additional products).',
|
||||
'abo_reminder_sustainability_hint' => 'Together we save packaging and a second transport route – good for the environment.',
|
||||
'abo_reminder_button_consultant' => 'Add products to the delivery',
|
||||
'abo_reminder_button_customer' => 'Add products to the delivery',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'gtc' => 'General terms and conditions of business',
|
||||
'gtc_copy1' => '<strong>Basic information</strong><br> 1) The following terms and conditions apply to all contracts that you conclude with us as a provider (mivita care gmbh) via the website www.mivita.care. The range of goods in our online shop is aimed exclusively at adult customers. The inclusion of general terms and conditions of customers who contradict these terms and conditions is already objected to. The contract language is German. You can access and print out these terms and conditions on our website. <br> <br> 2) We do not save the complete text of the contract. You can print out the contract data or save it electronically using the online shopping cart system before sending your order. After receiving your order, we will send you the order details, the legally required information for distance selling contracts and the general terms and conditions again by email. <br><br>',
|
||||
'gtc_copy2' => '<strong>Basic information</strong><br> 1) Our product offers on the Internet are non-binding and do not represent a binding offer to conclude a contract. You can place an order, i.e. a binding purchase offer, via our online shopping cart system. To do this, place the goods you intend to purchase in the “shopping cart”. You can use the corresponding button in the navigation bar to access the “shopping cart” and make changes there at any time. After accessing the “Checkout” page and entering your personal data as well as the payment and shipping conditions, all order data will be displayed again in an order overview. Here you have the opportunity to check all information again before sending your order, to change it (also using the “back” function of the internet browser) or to cancel the purchase. By sending the order using the “Buy” button, you are making a binding offer to conclude the contract. You will then receive an automatic confirmation of receipt by email, which does not yet lead to the conclusion of the contract. <br><br> (2) We can accept your offer within 2 days by sending an order confirmation by email. If you do not receive a corresponding message within this period, you will no longer be bound to your order. In this case, we will immediately reimburse you for any services that have already been provided. <br><br> (3) The processing of the order and the transmission of all information required in connection with the conclusion of the contract is partly automated by email. You must therefore ensure that the email address you provide to us is correct, that receipt of emails is technically ensured and, in particular, that it is not prevented by SPAM filters. <br><br>',
|
||||
'gtc_copy3' => '<strong>§ 3 Prices/Payment Methods</strong><br> (1) The prices stated in our offers as well as the shipping costs represent total prices. They include all price components including all applicable taxes. <br><br> (2) Shipping costs are not included in the purchase price. They can be accessed via a correspondingly labeled button on our website or in the respective item description. The shipping costs will continue to be shown separately during the ordering process and must be borne additionally by you unless free shipping is guaranteed. <br><br> (3) We offer you various payment methods. These are shown under a correspondingly labeled button on our website or in the respective item description. Unless otherwise stated, payment claims arising from the concluded contract are due for payment immediately. <br><br>',
|
||||
'gtc_copy4' => '<strong>§ 4 Delivery conditions</strong><br> (1) Delivery conditions, delivery dates and any existing delivery restrictions can be accessed using a correspondingly labeled button on our website or in the respective item description. <br><br> (2) For consumers, the risk of accidental loss and accidental deterioration of the item sold during shipping only passes to the consumer when the goods are handed over to them. This is regardless of whether the shipment is insured or uninsured. However, this does not apply if you have independently commissioned a transport company not named by the entrepreneur or another person designated to carry out the shipment. <br><br> (3) For entrepreneurs, delivery and shipping takes place at their own risk. <br><br>',
|
||||
'gtc_copy5' => '<strong>§ 5 Right of retention, retention of title</strong><br> (1) You can only exercise a right of retention if it concerns claims from the same contractual relationship. <br><br> (2) The goods remain our property until the purchase price has been paid in full. <br><br> (3) The following also applies to entrepreneurs: <br><br> - We reserve ownership of the goods until all claims from the ongoing business relationship have been settled in full. Pledging or transfer of security is not permitted before ownership of the reserved goods is transferred. <br> - You may resell the goods in the ordinary course of business. In this case, you assign to us all claims in the amount of the invoice amount that arise from the resale. We accept the assignment, but you are authorized to collect the claims. If you do not properly meet your payment obligations, we reserve the right to collect claims ourselves. <br> - If the reserved goods are combined or mixed, we acquire co-ownership of the new item in the ratio of the invoice value of the reserved goods to the other processed items at the time of processing. <br> - We undertake to release the securities to which we are entitled upon request to the extent that the realizable value of our securities exceeds the claims to be secured by more than 10%. We are responsible for selecting the securities to be released. <br><br>',
|
||||
'gtc_copy6' => '<strong>§ 6 Warranty</strong><br> (1) The statutory liability rights for defects apply. <br><br> (2) For entrepreneurs, the following applies differently from paragraph 1: <br><br> - as an entrepreneur, you must inspect the goods immediately and with due care for deviations in quality and quantity and report any obvious defects to us within 7 days from receipt of the goods in writing. Deadline is sufficient for the timely dispatch. This also applies to hidden defects discovered later upon discovery. If you do not fulfill your obligation to inspect and give notice of complaints, the assertion of warranty claims is excluded. <br> - If there are defects, we can, at our discretion, provide a guarantee through repair or replacement delivery. If the removal of the defect fails, you can choose to demand a reduction in price or withdraw from the contract. The elimination of defects is deemed to have failed after an unsuccessful second attempt, unless the nature of the item or the defect or other circumstances indicate otherwise. In the event of repair, we do not have to bear the increased costs that arise from moving the goods to a location other than the place of performance if the delivery does not correspond to the intended use of the goods. <br> - the warranty period is one year from delivery of the goods. The shortened warranty period does not apply to culpably caused damages attributable to us resulting from injury to life, body or health and damages caused by gross negligence or intent or fraud, as well as for recourse claims in accordance with Sections 478 and 479 of the German Civil Code (BGB). <br><br>',
|
||||
'gtc_copy7' => '<strong>§ 7 Liability</strong><br> (1) We are fully liable for damages resulting from injury to life, body or health. Furthermore, we are liable without limitation in all cases of intent and gross negligence, in the case of fraudulent concealment of a defect, in the event of a guarantee for the quality of the purchased item and in all other cases regulated by law. <br> (2) If essential contractual obligations are affected, our liability in the event of slight negligence is limited to the foreseeable damage that is typical for the contract. Essential contractual obligations are essential obligations that arise from the nature of the contract and whose violation would jeopardize the achievement of the purpose of the contract as well as obligations that the contract imposes on us according to its content in order to achieve the purpose of the contract, the fulfillment of which makes the proper implementation of the contract possible in the first place and on whose compliance you can regularly rely. <br><br>',
|
||||
'gtc_copy8' => '<strong>§ 8 Final provisions</strong><br> (1) German law applies. For consumers, this choice of law only applies to the extent that the protection granted by mandatory provisions of the law of the consumer\'s country of habitual residence is not withdrawn (principle of favourability). The provisions of the UN Convention on Contracts for the International Sale of Goods expressly do not apply. <br><br> (2) The place of performance for all services from the existing business relationships with us and the place of jurisdiction is our registered office, provided you are not a consumer but a merchant, a legal entity under public law or a special fund under public law. The same applies if you do not have a general place of jurisdiction in Germany or the EU or your place of residence or habitual residence is not known at the time the action is filed. The right to appeal to the court at another legal place of jurisdiction remains unaffected by this. <br><br>',
|
||||
'gtc_copy9' => 'As of: October 5, 2018 <br><br>',
|
||||
);
|
||||
return [
|
||||
'gtc' => 'General terms and conditions of business',
|
||||
'gtc_copy1' => '<strong>Basic information</strong><br> 1) The following terms and conditions apply to all contracts that you conclude with us as a provider (mivita care gmbh) via the website www.mivita.care. The range of goods in our online shop is aimed exclusively at adult customers. The inclusion of general terms and conditions of customers who contradict these terms and conditions is already objected to. The contract language is German. You can access and print out these terms and conditions on our website. <br> <br> 2) We do not save the complete text of the contract. You can print out the contract data or save it electronically using the online shopping cart system before sending your order. After receiving your order, we will send you the order details, the legally required information for distance selling contracts and the general terms and conditions again by email. <br><br>',
|
||||
'gtc_copy2' => '<strong>Basic information</strong><br> 1) Our product offers on the Internet are non-binding and do not represent a binding offer to conclude a contract. You can place an order, i.e. a binding purchase offer, via our online shopping cart system. To do this, place the goods you intend to purchase in the “shopping cart”. You can use the corresponding button in the navigation bar to access the “shopping cart” and make changes there at any time. After accessing the “Checkout” page and entering your personal data as well as the payment and shipping conditions, all order data will be displayed again in an order overview. Here you have the opportunity to check all information again before sending your order, to change it (also using the “back” function of the internet browser) or to cancel the purchase. By sending the order using the “Buy” button, you are making a binding offer to conclude the contract. You will then receive an automatic confirmation of receipt by email, which does not yet lead to the conclusion of the contract. <br><br> (2) We can accept your offer within 2 days by sending an order confirmation by email. If you do not receive a corresponding message within this period, you will no longer be bound to your order. In this case, we will immediately reimburse you for any services that have already been provided. <br><br> (3) The processing of the order and the transmission of all information required in connection with the conclusion of the contract is partly automated by email. You must therefore ensure that the email address you provide to us is correct, that receipt of emails is technically ensured and, in particular, that it is not prevented by SPAM filters. <br><br>',
|
||||
'gtc_copy3' => '<strong>§ 3 Prices/Payment Methods</strong><br> (1) The prices stated in our offers as well as the shipping costs represent total prices. They include all price components including all applicable taxes. <br><br> (2) Shipping costs are not included in the purchase price. They can be accessed via a correspondingly labeled button on our website or in the respective item description. The shipping costs will continue to be shown separately during the ordering process and must be borne additionally by you unless free shipping is guaranteed. <br><br> (3) We offer you various payment methods. These are shown under a correspondingly labeled button on our website or in the respective item description. Unless otherwise stated, payment claims arising from the concluded contract are due for payment immediately. <br><br>',
|
||||
'gtc_copy4' => '<strong>§ 4 Delivery conditions</strong><br> (1) Delivery conditions, delivery dates and any existing delivery restrictions can be accessed using a correspondingly labeled button on our website or in the respective item description. <br><br> (2) For consumers, the risk of accidental loss and accidental deterioration of the item sold during shipping only passes to the consumer when the goods are handed over to them. This is regardless of whether the shipment is insured or uninsured. However, this does not apply if you have independently commissioned a transport company not named by the entrepreneur or another person designated to carry out the shipment. <br><br> (3) For entrepreneurs, delivery and shipping takes place at their own risk. <br><br>',
|
||||
'gtc_copy5' => '<strong>§ 5 Right of retention, retention of title</strong><br> (1) You can only exercise a right of retention if it concerns claims from the same contractual relationship. <br><br> (2) The goods remain our property until the purchase price has been paid in full. <br><br> (3) The following also applies to entrepreneurs: <br><br> - We reserve ownership of the goods until all claims from the ongoing business relationship have been settled in full. Pledging or transfer of security is not permitted before ownership of the reserved goods is transferred. <br> - You may resell the goods in the ordinary course of business. In this case, you assign to us all claims in the amount of the invoice amount that arise from the resale. We accept the assignment, but you are authorized to collect the claims. If you do not properly meet your payment obligations, we reserve the right to collect claims ourselves. <br> - If the reserved goods are combined or mixed, we acquire co-ownership of the new item in the ratio of the invoice value of the reserved goods to the other processed items at the time of processing. <br> - We undertake to release the securities to which we are entitled upon request to the extent that the realizable value of our securities exceeds the claims to be secured by more than 10%. We are responsible for selecting the securities to be released. <br><br>',
|
||||
'gtc_copy6' => '<strong>§ 6 Warranty</strong><br> (1) The statutory liability rights for defects apply. <br><br> (2) For entrepreneurs, the following applies differently from paragraph 1: <br><br> - as an entrepreneur, you must inspect the goods immediately and with due care for deviations in quality and quantity and report any obvious defects to us within 7 days from receipt of the goods in writing. Deadline is sufficient for the timely dispatch. This also applies to hidden defects discovered later upon discovery. If you do not fulfill your obligation to inspect and give notice of complaints, the assertion of warranty claims is excluded. <br> - If there are defects, we can, at our discretion, provide a guarantee through repair or replacement delivery. If the removal of the defect fails, you can choose to demand a reduction in price or withdraw from the contract. The elimination of defects is deemed to have failed after an unsuccessful second attempt, unless the nature of the item or the defect or other circumstances indicate otherwise. In the event of repair, we do not have to bear the increased costs that arise from moving the goods to a location other than the place of performance if the delivery does not correspond to the intended use of the goods. <br> - the warranty period is one year from delivery of the goods. The shortened warranty period does not apply to culpably caused damages attributable to us resulting from injury to life, body or health and damages caused by gross negligence or intent or fraud, as well as for recourse claims in accordance with Sections 478 and 479 of the German Civil Code (BGB). <br><br>',
|
||||
'gtc_copy7' => '<strong>§ 7 Liability</strong><br> (1) We are fully liable for damages resulting from injury to life, body or health. Furthermore, we are liable without limitation in all cases of intent and gross negligence, in the case of fraudulent concealment of a defect, in the event of a guarantee for the quality of the purchased item and in all other cases regulated by law. <br> (2) If essential contractual obligations are affected, our liability in the event of slight negligence is limited to the foreseeable damage that is typical for the contract. Essential contractual obligations are essential obligations that arise from the nature of the contract and whose violation would jeopardize the achievement of the purpose of the contract as well as obligations that the contract imposes on us according to its content in order to achieve the purpose of the contract, the fulfillment of which makes the proper implementation of the contract possible in the first place and on whose compliance you can regularly rely. <br><br>',
|
||||
'gtc_copy8' => '<strong>§ 8 Final provisions</strong><br> (1) German law applies. For consumers, this choice of law only applies to the extent that the protection granted by mandatory provisions of the law of the consumer\'s country of habitual residence is not withdrawn (principle of favourability). The provisions of the UN Convention on Contracts for the International Sale of Goods expressly do not apply. <br><br> (2) The place of performance for all services from the existing business relationships with us and the place of jurisdiction is our registered office, provided you are not a consumer but a merchant, a legal entity under public law or a special fund under public law. The same applies if you do not have a general place of jurisdiction in Germany or the EU or your place of residence or habitual residence is not known at the time the action is filed. The right to appeal to the court at another legal place of jurisdiction remains unaffected by this. <br><br>',
|
||||
'gtc_copy9' => 'As of: October 5, 2018 <br><br>',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -57,4 +57,5 @@ return [
|
|||
'own' => 'Own',
|
||||
'live_calculation_hint' => 'Live calculation (not yet finalized)',
|
||||
'live_calculation_hint_text' => 'Will be calculated at the end of the month.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,73 +1,74 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'acceptect_data_protection' => 'I hereby consent to the data processing mentioned under :data protection',
|
||||
'add_as_guest' => 'register as a guest',
|
||||
'add_product' => 'add product',
|
||||
'completed' => 'completed',
|
||||
'confirm_my_data_is_correct_and_complete' => 'I confirm that my data is correct and complete. After sending, a change is only possible via my personal MIVITA advisor.*',
|
||||
'copy' => 'Copied!',
|
||||
'copy_link' => 'copy link',
|
||||
'copy_link_info' => 'Share this link with the guests (e.g. WhatsApp or SMS) to take them to a landing page where they can fill out their data themselves. Use the “copy symbol” to copy the link straight to your clipboard.',
|
||||
'country_can_no_longer_be_changed_after_created' => 'The delivery country cannot be changed once it has been created. All shipping addresses must be in this country.',
|
||||
'create_delivery_address_host_info' => 'Delivery address and host have not yet been created.',
|
||||
'create_guest' => 'create guest',
|
||||
'create_guests' => 'create guests',
|
||||
'create_guests_info' => 'Guests can then be created and orders placed.',
|
||||
'create_new_homeparty' => 'create a new time-out party',
|
||||
'credit_bonus' => 'credit bonus',
|
||||
'credit_homeparty_voucher' => 'credit time-out party voucher',
|
||||
'current_bonus_view' => 'current bonus view',
|
||||
'data_protection' => 'data protection',
|
||||
'data_protection_reasons_your_personal_data_will_not_be_shown' => 'Note: For data protection reasons, your personal data will not be shown to other participants here. Once submitted, they can no longer be edited. If you would like to make a change later, please contact your personal MIVITA advisor.',
|
||||
'deduct_points_by_voucher' => 'deduction of points through voucher',
|
||||
'delivery_address_homeparty' => 'delivery address time out party',
|
||||
'delivery_directly_to_the_guest' => 'delivery directly to the guest',
|
||||
'delivery_to_host' => 'delivery to host',
|
||||
'description_welcome_text' => 'description/welcome text',
|
||||
'enter_your_personal_data_for_homeparty' => 'Enter your personal data for the time-out party',
|
||||
'event_date' => 'event date',
|
||||
'event_place' => 'venue',
|
||||
'from' => 'from',
|
||||
'general_overview' => 'general overview',
|
||||
'guest' => 'Guest',
|
||||
'guest_delete_really' => 'Really delete guest?',
|
||||
'guest_lists' => 'guest list',
|
||||
'guest_order_sent_directly_info' => 'If a guest would like their order sent directly to their personal address, you can specify this separately during the ordering process.',
|
||||
'guests' => 'guest',
|
||||
'homeparty' => 'time out party',
|
||||
'homeparty_add_host_address_info' => 'Please enter the address of the host where the time-out party is being organized.',
|
||||
'homeparty_delete_really' => 'Really delete time out party?',
|
||||
'homeparty_invoice_info' => 'The invoice from mivita will be sent to your address (consultant). You are responsible for billing the host and guests yourself.',
|
||||
'homeparty_manage' => 'manage time out party',
|
||||
'host' => 'host/hostess',
|
||||
'host_address_save' => 'save host address',
|
||||
'host_can_not_delete' => 'host cannot be deleted',
|
||||
'host_homeparty' => 'host/hostess time out party',
|
||||
'host_organiser_event' => 'host/organizer',
|
||||
'invitation' => 'invitation',
|
||||
'invitation_link_for_guests' => 'invitation link for guests',
|
||||
'invoice_address' => 'billing address',
|
||||
'let_your_guests_fill_in_their_own_details' => 'let your guests fill out their data themselves',
|
||||
'manage' => 'administer',
|
||||
'missing' => 'still missing',
|
||||
'next_bonus' => 'next bonus',
|
||||
'order' => 'order',
|
||||
'order_can_be_send_delivery_address_info' => 'The order can only be sent once the host delivery address has been created.',
|
||||
'order_create' => 'create order',
|
||||
'order_host' => 'order host',
|
||||
'order_show' => 'view order',
|
||||
'please_enter_delivery_address_info' => 'Please enter the central delivery address for the orders placed for this time-out party here. This can be your own address or that of the host. Depending on how you want to organize the distribution of the products with your guests.',
|
||||
'revoke_consent_at_any_time' => 'I have been informed that I can revoke this consent at any time.*',
|
||||
'shipping_costs_host' => 'shipping costs for the host',
|
||||
'target_turnover' => 'target sales',
|
||||
'voucher' => 'coupon',
|
||||
'voucher_bonus' => 'voucher bonus',
|
||||
'voucher_bonus_cannot_be_applied' => 'voucher/bonus cannot be applied because no products have been added by the host.',
|
||||
'voucher_total' => 'total voucher',
|
||||
'welcome_copy' => 'Welcome to our time-out party around the topic of organic aloe vera and natural cosmetics. We will inform you about what premium quality in natural cosmetics really means, show you many application examples for skin and intestinal problems and of course you can test our products extensively. We are looking forward to meeting you!',
|
||||
'your_MIVITA_advice' => 'Your MIVITA advice',
|
||||
'your_data_has_been_successfully_created_have_fun' => 'Your data has been successfully created. Have fun at the time out party!',
|
||||
'your_host' => 'your host',
|
||||
'your_hostess' => 'your hostess',
|
||||
);
|
||||
return [
|
||||
'acceptect_data_protection' => 'I hereby consent to the data processing mentioned under :data protection',
|
||||
'add_as_guest' => 'register as a guest',
|
||||
'add_product' => 'add product',
|
||||
'completed' => 'completed',
|
||||
'confirm_my_data_is_correct_and_complete' => 'I confirm that my data is correct and complete. After sending, a change is only possible via my personal MIVITA advisor.*',
|
||||
'copy' => 'Copied!',
|
||||
'copy_link' => 'copy link',
|
||||
'copy_link_info' => 'Share this link with the guests (e.g. WhatsApp or SMS) to take them to a landing page where they can fill out their data themselves. Use the “copy symbol” to copy the link straight to your clipboard.',
|
||||
'country_can_no_longer_be_changed_after_created' => 'The delivery country cannot be changed once it has been created. All shipping addresses must be in this country.',
|
||||
'create_delivery_address_host_info' => 'Delivery address and host have not yet been created.',
|
||||
'create_guest' => 'create guest',
|
||||
'create_guests' => 'create guests',
|
||||
'create_guests_info' => 'Guests can then be created and orders placed.',
|
||||
'create_new_homeparty' => 'create a new time-out party',
|
||||
'credit_bonus' => 'credit bonus',
|
||||
'credit_homeparty_voucher' => 'credit time-out party voucher',
|
||||
'current_bonus_view' => 'current bonus view',
|
||||
'data_protection' => 'data protection',
|
||||
'data_protection_reasons_your_personal_data_will_not_be_shown' => 'Note: For data protection reasons, your personal data will not be shown to other participants here. Once submitted, they can no longer be edited. If you would like to make a change later, please contact your personal MIVITA advisor.',
|
||||
'deduct_points_by_voucher' => 'deduction of points through voucher',
|
||||
'delivery_address_homeparty' => 'delivery address time out party',
|
||||
'delivery_directly_to_the_guest' => 'delivery directly to the guest',
|
||||
'delivery_to_host' => 'delivery to host',
|
||||
'description_welcome_text' => 'description/welcome text',
|
||||
'enter_your_personal_data_for_homeparty' => 'Enter your personal data for the time-out party',
|
||||
'event_date' => 'event date',
|
||||
'event_place' => 'venue',
|
||||
'from' => 'from',
|
||||
'general_overview' => 'general overview',
|
||||
'guest' => 'Guest',
|
||||
'guest_delete_really' => 'Really delete guest?',
|
||||
'guest_lists' => 'guest list',
|
||||
'guest_order_sent_directly_info' => 'If a guest would like their order sent directly to their personal address, you can specify this separately during the ordering process.',
|
||||
'guests' => 'guest',
|
||||
'homeparty' => 'time out party',
|
||||
'homeparty_add_host_address_info' => 'Please enter the address of the host where the time-out party is being organized.',
|
||||
'homeparty_delete_really' => 'Really delete time out party?',
|
||||
'homeparty_invoice_info' => 'The invoice from mivita will be sent to your address (consultant). You are responsible for billing the host and guests yourself.',
|
||||
'homeparty_manage' => 'manage time out party',
|
||||
'host' => 'host/hostess',
|
||||
'host_address_save' => 'save host address',
|
||||
'host_can_not_delete' => 'host cannot be deleted',
|
||||
'host_homeparty' => 'host/hostess time out party',
|
||||
'host_organiser_event' => 'host/organizer',
|
||||
'invitation' => 'invitation',
|
||||
'invitation_link_for_guests' => 'invitation link for guests',
|
||||
'invoice_address' => 'billing address',
|
||||
'let_your_guests_fill_in_their_own_details' => 'let your guests fill out their data themselves',
|
||||
'manage' => 'administer',
|
||||
'missing' => 'still missing',
|
||||
'next_bonus' => 'next bonus',
|
||||
'order' => 'order',
|
||||
'order_can_be_send_delivery_address_info' => 'The order can only be sent once the host delivery address has been created.',
|
||||
'order_create' => 'create order',
|
||||
'order_host' => 'order host',
|
||||
'order_show' => 'view order',
|
||||
'please_enter_delivery_address_info' => 'Please enter the central delivery address for the orders placed for this time-out party here. This can be your own address or that of the host. Depending on how you want to organize the distribution of the products with your guests.',
|
||||
'revoke_consent_at_any_time' => 'I have been informed that I can revoke this consent at any time.*',
|
||||
'shipping_costs_host' => 'shipping costs for the host',
|
||||
'target_turnover' => 'target sales',
|
||||
'voucher' => 'coupon',
|
||||
'voucher_bonus' => 'voucher bonus',
|
||||
'voucher_bonus_cannot_be_applied' => 'voucher/bonus cannot be applied because no products have been added by the host.',
|
||||
'voucher_total' => 'total voucher',
|
||||
'welcome_copy' => 'Welcome to our time-out party around the topic of organic aloe vera and natural cosmetics. We will inform you about what premium quality in natural cosmetics really means, show you many application examples for skin and intestinal problems and of course you can test our products extensively. We are looking forward to meeting you!',
|
||||
'your_MIVITA_advice' => 'Your MIVITA advice',
|
||||
'your_data_has_been_successfully_created_have_fun' => 'Your data has been successfully created. Have fun at the time out party!',
|
||||
'your_host' => 'your host',
|
||||
'your_hostess' => 'your hostess',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
104
resources/lang/en/marketingplan.php
Normal file
104
resources/lang/en/marketingplan.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Marketing plan translations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used in the marketing plan view.
|
||||
| You can adjust them to suit your needs.
|
||||
|
|
||||
*/
|
||||
|
||||
// Header & title
|
||||
'title' => 'Mivita career plan',
|
||||
'subtitle' => 'Discover your advancement opportunities and reach the next level',
|
||||
'current_level' => 'Your current level:',
|
||||
|
||||
// Qualification area
|
||||
'qualification' => 'Qualification',
|
||||
'kp_points' => 'CS points',
|
||||
'tp_points' => 'TP points',
|
||||
'customer_points_full' => 'Customer sales points',
|
||||
'team_points_full' => 'Team points',
|
||||
|
||||
// Commissions
|
||||
'provisions' => 'Commissions',
|
||||
'standard' => 'Standard',
|
||||
'shop' => 'Shop',
|
||||
'provision_rates' => 'Commission rates',
|
||||
|
||||
// Team commissions
|
||||
'team_provisions' => 'Team commissions',
|
||||
'team_provisions_by_lines' => 'Team commissions by lines',
|
||||
|
||||
// Bonuses
|
||||
'growth_bonus' => 'Depth bonus',
|
||||
|
||||
// Navigation & status
|
||||
'next_level' => 'Next level:',
|
||||
'your_current_level' => 'Your current level',
|
||||
'your_next_goal' => 'Your next goal',
|
||||
|
||||
// Legend
|
||||
'legend' => 'Legend',
|
||||
'legend_ku_description' => 'Customer sales points',
|
||||
'legend_tp_description' => 'Team points',
|
||||
'legend_lines_description' => 'Team commissions by lines',
|
||||
'legend_percentage_description' => 'Commission rates',
|
||||
|
||||
// Error messages & status
|
||||
'no_levels_available' => 'No career levels available',
|
||||
'no_levels_configured' => 'No career levels are currently configured.',
|
||||
'loading_error' => 'Error loading the marketing plan:',
|
||||
|
||||
// Performance & debug
|
||||
'loading_time' => 'Loading time:',
|
||||
|
||||
// Buttons & actions
|
||||
'show_details' => 'Show details',
|
||||
'back_to_overview' => 'Back to overview',
|
||||
|
||||
// Level descriptions
|
||||
'level_position' => 'Position',
|
||||
'level_name' => 'Level name',
|
||||
'level_requirements' => 'Requirements',
|
||||
'level_benefits' => 'Benefits',
|
||||
|
||||
// Paylines
|
||||
'paylines' => 'Paylines',
|
||||
'line_1' => 'Line 1',
|
||||
'line_2' => 'Line 2',
|
||||
'line_3' => 'Line 3',
|
||||
'line_4' => 'Line 4',
|
||||
'line_5' => 'Line 5',
|
||||
'line_6' => 'Line 6',
|
||||
'line_7' => 'Line 7',
|
||||
'line_8' => 'Line 8',
|
||||
|
||||
// Additional terms
|
||||
'points' => 'Points',
|
||||
'percent' => 'Percent',
|
||||
'euro' => 'Euro',
|
||||
'active' => 'Active',
|
||||
'inactive' => 'Inactive',
|
||||
'achieved' => 'Achieved',
|
||||
'not_achieved' => 'Not achieved',
|
||||
'in_progress' => 'In progress',
|
||||
|
||||
// Success and motivation texts
|
||||
'congratulations' => 'Congratulations!',
|
||||
'keep_going' => 'Keep it up!',
|
||||
'almost_there' => 'You are almost there!',
|
||||
'next_step' => 'Next step',
|
||||
'goal_reached' => 'Goal reached',
|
||||
|
||||
// Help texts
|
||||
'help_kp_points' => 'CS points (customer sales) are generated through your direct sales.',
|
||||
'help_tp_points' => 'TP points (team points) are generated through your team\'s sales.',
|
||||
'help_provisions' => 'Commissions are the percentages you receive from sales.',
|
||||
'help_growth_bonus' => 'Growth bonuses are additional rewards for your team growth.',
|
||||
|
||||
];
|
||||
|
|
@ -1,59 +1,60 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'MIVITA_BUSINESS_Paket' => 'MIVITA BUSINESS package',
|
||||
'abo_copy_1' => 'Decrease automatic extension and withdraw SEPA mandate.',
|
||||
'abo_copy_2' => 'The next booking is on: <strong>:date </strong>',
|
||||
'abo_copy_3' => 'I hereby confirm that I will delete my SEPA and deactivate the automatic extension.',
|
||||
'active' => 'active',
|
||||
'active_package' => 'active package',
|
||||
'alert_contract_renewal' => 'To extend your consultant membership, please complete the payment for your booked MIVITA package.',
|
||||
'booked_package' => 'booked package',
|
||||
'change' => 'adjust',
|
||||
'change_copy_1' => 'You can change your membership until the next contract extension, on :date.',
|
||||
'change_copy_2' => 'The remaining terms remain the same; the changed package only becomes active when it is extended.',
|
||||
'consultant_membership' => 'Consultant Membership',
|
||||
'consultant_online_shop' => 'consultant online shop',
|
||||
'contract_renewal' => 'contract extension',
|
||||
'deactivate' => 'deactivate',
|
||||
'details' => 'details',
|
||||
'downgrade_membership_is_not_possible' => 'It is no longer possible to downgrade your advisor membership.',
|
||||
'end' => 'finish',
|
||||
'end_button' => 'terminate your membership here',
|
||||
'end_checkbox' => 'Yes, I would like to terminate my MIVITA membership, I waive any claims against MIVITA and would like my account to be deleted!',
|
||||
'end_copy_1' => 'You no longer want to be a MIVITA consultant and end your membership?',
|
||||
'end_copy_2' => 'By doing so, you are giving up all sorts of commissions, perks, access to the sales center, and much more. By submitting this option we will receive a message and will take care of deleting your account. This process may take a few days.',
|
||||
'end_copy_3' => 'The termination and deletion of your MIVITA membership has been requested.',
|
||||
'expired_on' => 'expired on',
|
||||
'home_copy_SEPA_32' => 'Since you have given us a SEPA direct debit mandate, you do not need to take any further action. In accordance with this mandate, we will debit the invoice amount :price from your account on :pay_date.',
|
||||
'home_copy_SEPA_33' => 'We have not yet been able to debit the invoice amount :price on :pay_date from the SEPA direct debit mandate that you gave us.',
|
||||
'home_copy_SEPA_36' => 'Unfortunately, we were unable to collect the amount due for the membership fee from your specified account using a SEPA direct debit mandate.',
|
||||
'home_copy_alert_31' => 'Your membership expires on :datetime',
|
||||
'home_copy_alert_35' => 'Your membership expires today!',
|
||||
'home_copy_alert_36' => 'Your membership expired :days days ago on :datetime!',
|
||||
'home_copy_alert_36_today' => 'Your membership expires today on :datetime!',
|
||||
'home_copy_last_31' => 'You still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_33' => 'You now have :days days left to extend your membership. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_34' => 'Wow... now it\'s time! Your membership expires in :days days, exactly on :datetime. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_35' => 'Wow... now it\'s time! Your membership expires today, exactly on :datetime. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_36' => 'As announced, we have paused your advisor account because you did not renew your membership in time. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time.',
|
||||
'home_hl' => 'membership / annual fee',
|
||||
'inactive' => 'inactive',
|
||||
'info_contract_renewal' => 'Your contract will be automatically extended :days before your consultant membership expires. Once the contract has been extended, it is no longer possible to change the consultant package and you must make the payment for your membership.',
|
||||
'is_no_longer_possible_to_change_package' => 'It is no longer possible to change your advisor package.',
|
||||
'membership' => 'membership',
|
||||
'membership_was_renewed' => 'Your contract was renewed on :date.',
|
||||
'open_payment_options' => 'open payment options',
|
||||
'payment_copy_1' => 'Alternatively, you now have the option of paying for your membership directly using other payment options.',
|
||||
'payment_copy_2' => 'If the membership is paid before the :date, the SEPA mandate will not be executed!',
|
||||
'payment_has_been_made' => 'A payment has been made.',
|
||||
'renewal_is_active_membership_fee_automatic' => 'Your automatic extension is active, we will automatically collect your membership fee via SEPA mandate on <strong>:date</strong>.',
|
||||
'status' => 'status',
|
||||
'until' => 'until',
|
||||
'upgrade' => 'upgrade',
|
||||
'upgrade_copy_1' => 'Expand your membership to the MIVITA BUSINESS package now!',
|
||||
'upgrade_copy_2' => 'The remaining months until the consultant membership extension are calculated. The MIVITA BUSINESS package price will then be calculated annually.',
|
||||
'upgrade_package_and_proceed_payment' => 'You have the option to upgrade your package, simply select the upgraded package and proceed to payment.',
|
||||
'we_do_not_collect_membership_fee' => 'We were unable to automatically collect your membership fee via SEPA mandate on <strong>:date</strong>.',
|
||||
'your_booked_package' => 'your booked package',
|
||||
);
|
||||
return [
|
||||
'MIVITA_BUSINESS_Paket' => 'MIVITA BUSINESS package',
|
||||
'abo_copy_1' => 'Decrease automatic extension and withdraw SEPA mandate.',
|
||||
'abo_copy_2' => 'The next booking is on: <strong>:date </strong>',
|
||||
'abo_copy_3' => 'I hereby confirm that I will delete my SEPA and deactivate the automatic extension.',
|
||||
'active' => 'active',
|
||||
'active_package' => 'active package',
|
||||
'alert_contract_renewal' => 'To extend your consultant membership, please complete the payment for your booked MIVITA package.',
|
||||
'booked_package' => 'booked package',
|
||||
'change' => 'adjust',
|
||||
'change_copy_1' => 'You can change your membership until the next contract extension, on :date.',
|
||||
'change_copy_2' => 'The remaining terms remain the same; the changed package only becomes active when it is extended.',
|
||||
'consultant_membership' => 'Consultant Membership',
|
||||
'consultant_online_shop' => 'consultant online shop',
|
||||
'contract_renewal' => 'contract extension',
|
||||
'deactivate' => 'deactivate',
|
||||
'details' => 'details',
|
||||
'downgrade_membership_is_not_possible' => 'It is no longer possible to downgrade your advisor membership.',
|
||||
'end' => 'finish',
|
||||
'end_button' => 'terminate your membership here',
|
||||
'end_checkbox' => 'Yes, I would like to terminate my MIVITA membership, I waive any claims against MIVITA and would like my account to be deleted!',
|
||||
'end_copy_1' => 'You no longer want to be a MIVITA consultant and end your membership?',
|
||||
'end_copy_2' => 'By doing so, you are giving up all sorts of commissions, perks, access to the sales center, and much more. By submitting this option we will receive a message and will take care of deleting your account. This process may take a few days.',
|
||||
'end_copy_3' => 'The termination and deletion of your MIVITA membership has been requested.',
|
||||
'expired_on' => 'expired on',
|
||||
'home_copy_SEPA_32' => 'Since you have given us a SEPA direct debit mandate, you do not need to take any further action. In accordance with this mandate, we will debit the invoice amount :price from your account on :pay_date.',
|
||||
'home_copy_SEPA_33' => 'We have not yet been able to debit the invoice amount :price on :pay_date from the SEPA direct debit mandate that you gave us.',
|
||||
'home_copy_SEPA_36' => 'Unfortunately, we were unable to collect the amount due for the membership fee from your specified account using a SEPA direct debit mandate.',
|
||||
'home_copy_alert_31' => 'Your membership expires on :datetime',
|
||||
'home_copy_alert_35' => 'Your membership expires today!',
|
||||
'home_copy_alert_36' => 'Your membership expired :days days ago on :datetime!',
|
||||
'home_copy_alert_36_today' => 'Your membership expires today on :datetime!',
|
||||
'home_copy_last_31' => 'You still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_33' => 'You now have :days days left to extend your membership. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_34' => 'Wow... now it\'s time! Your membership expires in :days days, exactly on :datetime. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_35' => 'Wow... now it\'s time! Your membership expires today, exactly on :datetime. However, if you let the deadline pass, your account will automatically be paused until you renew your membership.',
|
||||
'home_copy_last_36' => 'As announced, we have paused your advisor account because you did not renew your membership in time. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time.',
|
||||
'home_hl' => 'membership / annual fee',
|
||||
'inactive' => 'inactive',
|
||||
'info_contract_renewal' => 'Your contract will be automatically extended :days before your consultant membership expires. Once the contract has been extended, it is no longer possible to change the consultant package and you must make the payment for your membership.',
|
||||
'is_no_longer_possible_to_change_package' => 'It is no longer possible to change your advisor package.',
|
||||
'membership' => 'membership',
|
||||
'membership_was_renewed' => 'Your contract was renewed on :date.',
|
||||
'open_payment_options' => 'open payment options',
|
||||
'payment_copy_1' => 'Alternatively, you now have the option of paying for your membership directly using other payment options.',
|
||||
'payment_copy_2' => 'If the membership is paid before the :date, the SEPA mandate will not be executed!',
|
||||
'payment_has_been_made' => 'A payment has been made.',
|
||||
'renewal_is_active_membership_fee_automatic' => 'Your automatic extension is active, we will automatically collect your membership fee via SEPA mandate on <strong>:date</strong>.',
|
||||
'status' => 'status',
|
||||
'until' => 'until',
|
||||
'upgrade' => 'upgrade',
|
||||
'upgrade_copy_1' => 'Expand your membership to the MIVITA BUSINESS package now!',
|
||||
'upgrade_copy_2' => 'The remaining months until the consultant membership extension are calculated. The MIVITA BUSINESS package price will then be calculated annually.',
|
||||
'upgrade_package_and_proceed_payment' => 'You have the option to upgrade your package, simply select the upgraded package and proceed to payment.',
|
||||
'we_do_not_collect_membership_fee' => 'We were unable to automatically collect your membership fee via SEPA mandate on <strong>:date</strong>.',
|
||||
'your_booked_package' => 'your booked package',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -123,4 +123,5 @@ return [
|
|||
'reorder_info' => 'Would you like to order these items again?<br>Click the button to add them to your cart and go to the cart page.',
|
||||
'reorder_info_2' => 'Your delivery country is: :country<br>If you want a different country, update your billing or delivery address under <a class="text-primary" href=":link">My details</a>',
|
||||
'reorder_abo_not_allowed' => 'Subscription orders cannot be repeated via “Reorder”. Please use your subscription area or the shop for one-off orders.',
|
||||
'number' => 'Item no.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -193,4 +193,7 @@ return [
|
|||
'packstation_alert_location' => 'Location of the Packstation',
|
||||
'packstation_alert_not_home' => 'not your home address!',
|
||||
'packstation_alert_footer' => 'The Packstation NUMBER is 3-digits (100-999, on yellow sign). The DHL post number is 6-10 digits and goes in the separate field above.',
|
||||
'' => '',
|
||||
'American Express' => 'American Express',
|
||||
'unknown' => 'unknown',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ return [
|
|||
'shipping_costs' => 'Shipping costs',
|
||||
'total_amount' => 'Total amount',
|
||||
|
||||
// Abo one-time products (invoice/delivery note grouping)
|
||||
'abo_items_heading' => 'Subscription products',
|
||||
'abo_addon_items_heading' => 'One-time added items',
|
||||
|
||||
// Address top
|
||||
'address_top' => 'mivita care gmbh • Leinfeld 2 • 87755 Kirchhaslach',
|
||||
'ek' => 'EK',
|
||||
];
|
||||
|
|
|
|||
39
resources/lang/en/portal.php
Normal file
39
resources/lang/en/portal.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'login' => 'Login',
|
||||
'login_title' => 'Login to your customer account',
|
||||
'login_email' => 'Your email address',
|
||||
'login_password' => 'Password',
|
||||
'login_button' => 'Login',
|
||||
'login_forgot_password' => 'Forgot password?',
|
||||
'login_register' => 'Register',
|
||||
'mail_subject' => 'Your one-time password for your mivita.care customer account',
|
||||
'mail_hello' => 'Hello!',
|
||||
'mail_otp' => 'Your one-time password is: ',
|
||||
'mail_otp_valid' => 'This password is valid for 10 minutes.',
|
||||
'mail_otp_not_requested' => 'If you did not request a password, you can ignore this email.',
|
||||
'mail_greetings' => 'Best regards',
|
||||
'mail_sender' => 'mivita.care',
|
||||
'verify_otp_title' => 'Two-factor login',
|
||||
'verify_otp_description' => 'Please enter the code we sent to your email address.',
|
||||
'verify_otp_resend' => 'If you do not receive an email within the next few minutes, you can request the code again; please also check your spam folder.',
|
||||
'verify_otp_resend_link' => 'Request code again',
|
||||
'login_send_otp_description' => 'Please enter your email address; in the next step we will send a one-time password to this address.',
|
||||
'login_send_otp_description2' => 'To create a customer account, use this login anyway; you can then enter your details in the portal.',
|
||||
'back_to_shop' => 'Back to shop',
|
||||
'guest' => 'Guest',
|
||||
'change_login_title' => 'Switch to customer account?',
|
||||
'change_login_title2' => 'Switch to consultant account?',
|
||||
'logout_button' => 'Log out and switch to login',
|
||||
'change_login_description' => 'You are logged in as a consultant. Would you like to switch to the customer account?',
|
||||
'change_login_description2' => 'You are logged in as a customer. Would you like to switch to the consultant account?',
|
||||
'change_login_description3' => 'You can log out here and then log in again with your customer email.',
|
||||
'change_my_data' => 'Change your billing and delivery address here.',
|
||||
'change_my_data_empty' => 'You have not yet stored a billing and delivery address; enter your details now.',
|
||||
'my_orders_empty' => 'You have not placed any orders yet.',
|
||||
'my_orders_info' => 'Here you can view and manage your orders.',
|
||||
'change_my_data_empty_button' => 'Create billing and delivery address',
|
||||
'my_subscriptions_empty' => 'You have not created a subscription yet.',
|
||||
'my_subscriptions_info' => 'Here you can create and manage your subscription.',
|
||||
];
|
||||
|
|
@ -1,21 +1,26 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'button_31' => 'RENEW MEMBERSHIP',
|
||||
'button_32' => 'MANAGE MEMBERSHIP',
|
||||
'button_33' => 'RENEW MEMBERSHIP',
|
||||
'button_34' => 'RENEW MEMBERSHIP',
|
||||
'button_35' => 'MANAGE MEMBERSHIP',
|
||||
'button_36' => 'MANAGE MEMBERSHIP',
|
||||
'button_37' => 'MANAGE MEMBERSHIP',
|
||||
'copy_first_31' => '<p>We wanted to let you know in good time that your membership will expire at :datetime. Therefore, you should take action now and extend it in good time so that you can continue to</p> <ul> <li>purchase products from MIVITA</li> <li>Customers can purchase via your online shop (optional)</li> <li >You can participate in sales partner sales</li> </ul> <p>But all is well - you still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will be automatically paused until you renew your membership.</p> <p>We\'ll send you another reminder very soon, but you\'ll have it in the back of your mind for now. If you would like to extend your connection by 1 year now, you can do so by clicking on the button below. What\'s gone is gone :) ...</p>',
|
||||
'copy_first_32' => '<p>We wanted to let you know in good time that your membership will be automatically extended at :datetime. Since you have given us a SEPA direct debit mandate, you do not need to take any further action. In accordance with this mandate, we will debit the invoice amount :price from your account on :pay_date.</p> <p>Your membership will then be extended for another year so that you can continue to use</p> <ul> <li>products from You can get MIVITA</li> <li>Customers can shop through your online shop (optional)</li> <li>You can participate in sales partner sales</li> </ul> <p>So far so good. However, if you want to end your membership or take a break for the time being, you can do this yourself in your member area. Simply follow the green button below.</p> <p>If you do not want to renew for the time being, your account will be paused until you renew your membership. Please note, however, that all benefits and functions, from discounted shopping to commission billing, are also paused.</p>',
|
||||
'copy_first_33' => '<p>Here\'s a quick reminder that your membership expires at :datetime. Therefore, you should take action now and extend it in good time so that you can continue to </p> <ul> <li>purchase products from MIVITA</li> <li>Customers can purchase via your online shop (optional)</li> <li >You can participate in sales partner sales</li> </ul> <p>But all is well - you still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will be automatically paused until you renew your membership.</p> <p>We\'ll send you another reminder very soon, but you\'ll have it in the back of your mind for now. If you would like to extend your connection by 1 year now, you can do so by clicking on the button below. What\'s gone is gone :) ...</p>',
|
||||
'copy_first_34' => '<p>huiii... now it\'s time! Your membership expires in :days days, exactly on :datetime. Therefore, you should take action now and extend your membership, otherwise your account will be paused.</p> <p>If you continue to</p> <ul> <li>purchase products from MIVITA</li> <li>an online shop (optional)</li> <li>and want to participate in sales partner sales</li> </ul> <p>you should act quickly now and extend your membership:</p>',
|
||||
'copy_first_35' => '<p>As announced, we have paused your advisor account because you did not renew your membership on time. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time.</p> <p>Click on the button if you would like to make changes to your membership:</p>',
|
||||
'copy_first_36' => '<p>Unfortunately, we were unable to collect the amount due for the membership fee from your specified account.</p> <p>As announced, we have therefore paused your advisor account today because you are not extending your membership in time could. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time using another payment method (e.g. Paypal, credit card, SOFORT transfer or advance payment).</p> <p>To do this, simply click on the following button and make the appropriate settings in your advisor account:</p>',
|
||||
'copy_first_37' => '<p>As announced, we have today arranged for :price to be collected for another year of MIVITA membership in accordance with your SEPA direct debit mandate. This invoice amount will be debited from your account in the next few days. Please note that the extension is only active after payment has been received.</p> <p>If you would like to make changes in the future, you can discontinue all functions and membership in your advisor account.</p> <p>Follow here simply click the button below:</p>',
|
||||
'copy_last_35' => '<p><b>Note:</b><br>Even if your account is paused, past or outstanding commissions will of course be paid out to you in the next payment run. If you want to delete your account completely, please write an email to info @mivita.care. Our advisor service will then take care of this immediately.</p> <p>We hope to welcome you again very soon as an active member of the MIVITA Family.</p>',
|
||||
'copy_last_36' => '<p><b>Note:</b><br>Even if your account is paused, past or still outstanding commissions will of course be paid out to you in the next payment run. If you want to delete your account completely, please write an email to info @mivita.care. Our advisor service will then take care of this immediately.</p> <p>We hope to welcome you again very soon as an active member of the MIVITA Family.</p>',
|
||||
'subject' => 'Your membership at mivita.care',
|
||||
);
|
||||
return [
|
||||
'button_31' => 'RENEW MEMBERSHIP',
|
||||
'button_32' => 'MANAGE MEMBERSHIP',
|
||||
'button_33' => 'RENEW MEMBERSHIP',
|
||||
'button_34' => 'RENEW MEMBERSHIP',
|
||||
'button_35' => 'MANAGE MEMBERSHIP',
|
||||
'button_36' => 'MANAGE MEMBERSHIP',
|
||||
'button_37' => 'MANAGE MEMBERSHIP',
|
||||
'copy_first_31' => '<p>We wanted to let you know in good time that your membership will expire at :datetime. Therefore, you should take action now and extend it in good time so that you can continue to</p> <ul> <li>purchase products from MIVITA</li> <li>Customers can purchase via your online shop (optional)</li> <li >You can participate in sales partner sales</li> </ul> <p>But all is well - you still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will be automatically paused until you renew your membership.</p> <p>We\'ll send you another reminder very soon, but you\'ll have it in the back of your mind for now. If you would like to extend your connection by 1 year now, you can do so by clicking on the button below. What\'s gone is gone :) ...</p>',
|
||||
'copy_first_32' => '<p>We wanted to let you know in good time that your membership will be automatically extended at :datetime. Since you have given us a SEPA direct debit mandate, you do not need to take any further action. In accordance with this mandate, we will debit the invoice amount :price from your account on :pay_date.</p> <p>Your membership will then be extended for another year so that you can continue to use</p> <ul> <li>products from You can get MIVITA</li> <li>Customers can shop through your online shop (optional)</li> <li>You can participate in sales partner sales</li> </ul> <p>So far so good. However, if you want to end your membership or take a break for the time being, you can do this yourself in your member area. Simply follow the green button below.</p> <p>If you do not want to renew for the time being, your account will be paused until you renew your membership. Please note, however, that all benefits and functions, from discounted shopping to commission billing, are also paused.</p>',
|
||||
'copy_first_33' => '<p>Here\'s a quick reminder that your membership expires at :datetime. Therefore, you should take action now and extend it in good time so that you can continue to </p> <ul> <li>purchase products from MIVITA</li> <li>Customers can purchase via your online shop (optional)</li> <li >You can participate in sales partner sales</li> </ul> <p>But all is well - you still have a few relaxing :days days left to extend your membership. However, if you let the deadline pass, your account will be automatically paused until you renew your membership.</p> <p>We\'ll send you another reminder very soon, but you\'ll have it in the back of your mind for now. If you would like to extend your connection by 1 year now, you can do so by clicking on the button below. What\'s gone is gone :) ...</p>',
|
||||
'copy_first_34' => '<p>huiii... now it\'s time! Your membership expires in :days days, exactly on :datetime. Therefore, you should take action now and extend your membership, otherwise your account will be paused.</p> <p>If you continue to</p> <ul> <li>purchase products from MIVITA</li> <li>an online shop (optional)</li> <li>and want to participate in sales partner sales</li> </ul> <p>you should act quickly now and extend your membership:</p>',
|
||||
'copy_first_35' => '<p>As announced, we have paused your advisor account because you did not renew your membership on time. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time.</p> <p>Click on the button if you would like to make changes to your membership:</p>',
|
||||
'copy_first_36' => '<p>Unfortunately, we were unable to collect the amount due for the membership fee from your specified account.</p> <p>As announced, we have therefore paused your advisor account today because you are not extending your membership in time could. If you would like to benefit from the advantages and features of MIVITA again, you can reactivate your account at any time using another payment method (e.g. Paypal, credit card, SOFORT transfer or advance payment).</p> <p>To do this, simply click on the following button and make the appropriate settings in your advisor account:</p>',
|
||||
'copy_first_37' => '<p>As announced, we have today arranged for :price to be collected for another year of MIVITA membership in accordance with your SEPA direct debit mandate. This invoice amount will be debited from your account in the next few days. Please note that the extension is only active after payment has been received.</p> <p>If you would like to make changes in the future, you can discontinue all functions and membership in your advisor account.</p> <p>Follow here simply click the button below:</p>',
|
||||
'copy_last_35' => '<p><b>Note:</b><br>Even if your account is paused, past or outstanding commissions will of course be paid out to you in the next payment run. If you want to delete your account completely, please write an email to info @mivita.care. Our advisor service will then take care of this immediately.</p> <p>We hope to welcome you again very soon as an active member of the MIVITA Family.</p>',
|
||||
'copy_last_36' => '<p><b>Note:</b><br>Even if your account is paused, past or still outstanding commissions will of course be paid out to you in the next payment run. If you want to delete your account completely, please write an email to info @mivita.care. Our advisor service will then take care of this immediately.</p> <p>We hope to welcome you again very soon as an active member of the MIVITA Family.</p>',
|
||||
'subject' => 'Your membership at mivita.care',
|
||||
'copy_last_31' => '',
|
||||
'copy_last_32' => '',
|
||||
'copy_last_33' => '',
|
||||
'copy_last_34' => '',
|
||||
'copy_last_37' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,53 +1,57 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'Choose Your Shop Name' => 'Choose a memorable shop name that suits you.',
|
||||
'Shop details' => 'shop details',
|
||||
'Terms of Use' => 'terms of Use',
|
||||
'Your Shop' => 'your shop',
|
||||
'Your Shop Name' => 'Give your shop a name',
|
||||
'accept_and_next' => 'accept and move on',
|
||||
'active_since' => 'active since',
|
||||
'available' => 'reachable',
|
||||
'check' => 'check',
|
||||
'declaration_of_shop' => 'I hereby confirm and accept the terms of use for my mivita shop.',
|
||||
'domain' => 'domain',
|
||||
'error_subdomain_exists' => 'Error: Subdomain already exists, please choose a new name',
|
||||
'mobil' => 'Mobile',
|
||||
'name' => 'name',
|
||||
'not_available' => 'not reachable',
|
||||
'not_available_copy' => 'For newly created shops, it takes a few minutes until the domain can be reached. Please check again in a few minutes.',
|
||||
'open_copy_1' => 'Choose the prefix of your shop name - e.g. B. firstname(.mivita.care) - You don\'t have to enter "mivita.care". Choose a short and concise name so that you can also place this URL on small advertising materials. Also make sure that you do not violate any third-party trademark rights. MIVITA cannot accept any liability for this. Therefore, try to avoid using fancy terms unless you have registered them as a trademark.',
|
||||
'open_copy_2' => 'Your internet address can later be accessed with “www.” and without.',
|
||||
'open_note_1' => 'Your shop name is used to create the internet address (domain) with which your shop can be accessed. Choose your shop name carefully. This can only be changed by IT and we would have to charge an expense allowance of €59.50.',
|
||||
'open_note_hl' => 'IMPORTANT NOTE:',
|
||||
'open_your_shop' => 'Open your own mivita shop.',
|
||||
'order_customer' => 'order customer',
|
||||
'orders_customers' => 'orders customers',
|
||||
'phone' => 'Phone',
|
||||
'preview_shop_internet_address' => 'preview shop internet address',
|
||||
'save and continue' => 'save and continue',
|
||||
'shop_about' => 'shop personal text',
|
||||
'shop_about_help' => 'Enter your personal text about yourself. (max. 190 characters)',
|
||||
'shop_accessibility' => 'shop accessibility',
|
||||
'shop_accessibility_help' => 'Indicate your availability.',
|
||||
'shop_accessibility_text' => 'Mon-Fri: 9.00 a.m. - 7.00 p.m.\\nSat-Sun: 11.00 a.m. - 6.00 p.m.',
|
||||
'shop_contact' => 'shop contact',
|
||||
'shop_contact_help' => 'Complete your contact details that are displayed in the shop.',
|
||||
'shop_contact_text' => 'Your street/number - Your postal code city\\nFixed line: Your fixed line number\\nMobile: Your mobile number\\nYour e-mail address',
|
||||
'shop_image' => 'your shop picture',
|
||||
'shop_image_copy' => 'Upload a photo/image/logo of yourself here.',
|
||||
'shop_name_description' => 'Your shop name will be displayed in your shop. Your shop name is used to create the internet address (domain) with which your shop can be accessed. Choose your shop name carefully; this can only be changed later for a fee of 59.50 euros.',
|
||||
'shop_name_error_1' => 'Your shop name may only contain unaccented Latin letters and numbers, no spaces.',
|
||||
'shop_name_error_2' => 'Shop names must be 4 to 20 characters long.',
|
||||
'shop_on_site' => 'For you on site:',
|
||||
'shop_on_site_copy' => 'Have you been to the Aloe Vera Farm in Mallorca? Upload up to 6 pictures of yourself here.',
|
||||
'shop_title' => 'shop owner',
|
||||
'shop_title_help' => 'Enter your name for the shop.',
|
||||
'your_city' => 'Your city',
|
||||
'your_mobile_number' => 'Your mobile number',
|
||||
'your_phone_number' => 'Your landline number',
|
||||
'your_shop_name' => 'your shop name',
|
||||
'your_street_number' => 'Your street/number',
|
||||
'your_zip_code' => 'Your postal code',
|
||||
);
|
||||
return [
|
||||
'Choose Your Shop Name' => 'Choose a memorable shop name that suits you.',
|
||||
'Shop details' => 'shop details',
|
||||
'Terms of Use' => 'terms of Use',
|
||||
'Your Shop' => 'your shop',
|
||||
'Your Shop Name' => 'Give your shop a name',
|
||||
'accept_and_next' => 'accept and move on',
|
||||
'active_since' => 'active since',
|
||||
'available' => 'reachable',
|
||||
'check' => 'check',
|
||||
'declaration_of_shop' => 'I hereby confirm and accept the terms of use for my mivita shop.',
|
||||
'domain' => 'domain',
|
||||
'error_subdomain_exists' => 'Error: Subdomain already exists, please choose a new name',
|
||||
'mobil' => 'Mobile',
|
||||
'name' => 'name',
|
||||
'not_available' => 'not reachable',
|
||||
'not_available_copy' => 'For newly created shops, it takes a few minutes until the domain can be reached. Please check again in a few minutes.',
|
||||
'open_copy_1' => 'Choose the prefix of your shop name - e.g. B. firstname(.mivita.care) - You don\'t have to enter "mivita.care". Choose a short and concise name so that you can also place this URL on small advertising materials. Also make sure that you do not violate any third-party trademark rights. MIVITA cannot accept any liability for this. Therefore, try to avoid using fancy terms unless you have registered them as a trademark.',
|
||||
'open_copy_2' => 'Your internet address can later be accessed with “www.” and without.',
|
||||
'open_note_1' => 'Your shop name is used to create the internet address (domain) with which your shop can be accessed. Choose your shop name carefully. This can only be changed by IT and we would have to charge an expense allowance of €59.50.',
|
||||
'open_note_hl' => 'IMPORTANT NOTE:',
|
||||
'open_your_shop' => 'Open your own mivita shop.',
|
||||
'order_customer' => 'order customer',
|
||||
'orders_customers' => 'orders customers',
|
||||
'phone' => 'Phone',
|
||||
'preview_shop_internet_address' => 'preview shop internet address',
|
||||
'save and continue' => 'save and continue',
|
||||
'shop_about' => 'shop personal text',
|
||||
'shop_about_help' => 'Enter your personal text about yourself. (max. 190 characters)',
|
||||
'shop_accessibility' => 'shop accessibility',
|
||||
'shop_accessibility_help' => 'Indicate your availability.',
|
||||
'shop_accessibility_text' => 'Mon-Fri: 9.00 a.m. - 7.00 p.m.\\nSat-Sun: 11.00 a.m. - 6.00 p.m.',
|
||||
'shop_contact' => 'shop contact',
|
||||
'shop_contact_help' => 'Complete your contact details that are displayed in the shop.',
|
||||
'shop_contact_text' => 'Your street/number - Your postal code city\\nFixed line: Your fixed line number\\nMobile: Your mobile number\\nYour e-mail address',
|
||||
'shop_image' => 'your shop picture',
|
||||
'shop_image_copy' => 'Upload a photo/image/logo of yourself here.',
|
||||
'shop_name_description' => 'Your shop name will be displayed in your shop. Your shop name is used to create the internet address (domain) with which your shop can be accessed. Choose your shop name carefully; this can only be changed later for a fee of 59.50 euros.',
|
||||
'shop_name_error_1' => 'Your shop name may only contain unaccented Latin letters and numbers, no spaces.',
|
||||
'shop_name_error_2' => 'Shop names must be 4 to 20 characters long.',
|
||||
'shop_on_site' => 'For you on site:',
|
||||
'shop_on_site_copy' => 'Have you been to the Aloe Vera Farm in Mallorca? Upload up to 6 pictures of yourself here.',
|
||||
'shop_title' => 'shop owner',
|
||||
'shop_title_help' => 'Enter your name for the shop.',
|
||||
'your_city' => 'Your city',
|
||||
'your_mobile_number' => 'Your mobile number',
|
||||
'your_phone_number' => 'Your landline number',
|
||||
'your_shop_name' => 'your shop name',
|
||||
'your_street_number' => 'Your street/number',
|
||||
'your_zip_code' => 'Your postal code',
|
||||
'' => '',
|
||||
'accept_and_change' => 'accept and change',
|
||||
'edit_your_shop' => 'Edit your shop name',
|
||||
'your_current_shop_name' => 'Your current shop name is:',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -94,4 +94,6 @@ return [
|
|||
'type' => 'sort',
|
||||
'vk_price' => 'sales price',
|
||||
'no_data_available' => 'No data available',
|
||||
'' => '',
|
||||
've' => 'VE',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -148,4 +148,6 @@ return [
|
|||
'not_available' => 'N/A',
|
||||
|
||||
'growth_bonus_details_description' => 'L1 = Direct Partner (gets the growth bonus always), L2 = Members (from here the growth bonus is divided if the member is qualified), etc. | Shows commission (€) and volume (points) per level.',
|
||||
'' => '',
|
||||
'open' => 'Open',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,86 +1,87 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'advantages_MIVITA_botl' => '... build a self-determined future for yourself in which you are your own boss.',
|
||||
'advantages_MIVITA_hl' => 'Advantages of MIVITA:',
|
||||
'advantages_MIVITA_list' => '<ul class="small"> <li>20-40% sales margin</li> <li>Attractive bonuses and promotions</li> <li>Earnings up to 3 levels</li> <li>No minimum turnover</ li> <li>Free scheduling</li> <li>Working in a team</li> <li>Advertising materials & online shop on request</li> <li>Shipping and returns processing by MIVITA</li> <li> Training in Mallorca </li></ul>',
|
||||
'advantages_MIVITA_subl' => 'There are many good reasons to become self-employed with mivita. Many consultants answer the question why they chose direct sales at mivita:',
|
||||
'advantages_direct_sales_hl' => 'advantages of direct selling',
|
||||
'advantages_direct_sales_list' => '<ul class="small"> <li>To earn extra money or increase the family\'s quality of life</li> <li>To be your own boss with low risk and low investments</li> < li>To work flexibly with free scheduling</li> <li>To have no purchase obligations</li> <li>To be able to start without age restrictions, without previous knowledge or special qualifications</li> <li>Low risk and low fixed costs </li> <li>Because of the high product quality</li> </ul>',
|
||||
'advantages_direct_sales_subl' => 'Direct selling brings the following advantages',
|
||||
'advantages_of_direct_sales' => 'advantages of direct selling',
|
||||
'aloe_high_quality_copy' => 'Aloe vera leaf gel is a true treasure and a gift from nature. But there are a lot of things to consider, from cultivation to processing, to ensure that these valuable ingredients are preserved and reach the customer. Unfortunately, many manufacturers do not adhere to the 1x1 of aloe vera production and so there are a number of aloe products on the market that have little to no effect. So what makes our products so high quality?',
|
||||
'aloe_high_quality_hl' => 'What makes our aloe vera products so high quality?',
|
||||
'aloe_high_quality_li1' => 'The aloe plants are over 5 years old',
|
||||
'aloe_high_quality_li10' => 'high proportion of pure aloe in every product',
|
||||
'aloe_high_quality_li2' => 'Have well over 2,000 hours of sunshine annually',
|
||||
'aloe_high_quality_li3' => 'purely organically controlled cultivation',
|
||||
'aloe_high_quality_li4' => 'no (!) artificial irrigation',
|
||||
'aloe_high_quality_li5' => 'no pest or weed killers',
|
||||
'aloe_high_quality_li6' => 'harvesting and filleting the leaves by hand',
|
||||
'aloe_high_quality_li7' => 'processing into products directly after harvest',
|
||||
'aloe_high_quality_li8' => 'just the pure gel: no powder or extract',
|
||||
'aloe_high_quality_li9' => 'certified aloverose content over 1,600 mg/l',
|
||||
'aloe_high_quality_subl' => 'One of the world\'s best aloe vera juices as a basis for high-quality aloe products',
|
||||
'aloe_vera_word_copy' => 'The globally unique and outstanding properties of aloe vera are due to the unique interaction and symbiosis of the different ingredients and active ingredients. No other plant known to date has such a wide range of healing and nourishing uses. In total, more than 200 active substances are currently known in the medical literature, and new ones are constantly being discovered. The decoding of the complex interaction of all substances is only just beginning, but the effects are now very well documented.',
|
||||
'bio_quality_copy' => 'We guarantee the best quality through manual production and organic ingredients. The typical climate of Mallorca challenges the plants. Tests have shown that this climate is optimal for perfect plant development.',
|
||||
'bio_quality_hl' => '100% ORGANIC quality',
|
||||
'bio_quality_subl' => 'organic certified handcraft from Mallorca',
|
||||
'business_environment_hl' => 'business environment',
|
||||
'business_environment_list' => '<ul class="small"> <li>Cosmetics / natural cosmetics</li> <li>Hair styling</li> <li>Nutrition</li> <li>Nail & foot care</li> <li>Natural practitioner & Alternative medicine</li> <li>Medicine (skin, physio, general etc.)</li> <li>All about animals</li> <li>Yoga & meditation</li> <li>Gastronomy</li> <li>Sport & Fitness</li> <li>and much more.</li> </ul>',
|
||||
'career_opportunitie_point_1' => 'Sell products that are suitable for a healthy and vital life and that give you and your loved ones a great feel-good experience.',
|
||||
'career_opportunitie_point_2' => 'We keep up to date and support each other in WhatsApp groups and video calls. You\'re not alone!',
|
||||
'career_opportunitie_point_3' => 'We pass on our know-how, proven marketing tools and advertising materials to you, because we are only successful if YOU are successful.',
|
||||
'career_opportunitie_point_4' => 'Benefit from supportive measures such as training, team events or joint sales campaigns. Together we are successful!',
|
||||
'career_opportunitie_point_5' => 'Use social media and talk about products and experiences. Gain new customers and partners via Facebook & Co.',
|
||||
'career_opportunities_at_mivita' => 'career opportunities at mivita',
|
||||
'compatibility_with_family_copy1' => 'Who does not know that? There is a lack of money everywhere and the boss always turns up his nose when the child is sick. Many families rely on a second job or the part-time work of the mother or father. And that often cannot be reconciled with the employer\'s ideas. But what if you simply build up your monthly additional income yourself and at the same time have more time for your child?',
|
||||
'compatibility_with_family_copy2' => 'Particularly in direct sales, with its options for free time management and passive income, you have as much freedom in the medium term as a permanent job cannot offer you. As an independent MIVITA consultant, you decide for yourself when and where you work. And that doesn\'t just affect young parents. Direct sales also represent a perfect solution for people who need to care for their family members or simply want to have more time and financial relief:',
|
||||
'compatibility_with_family_list' => '<ul class="small"> <li>Work from home or on the go</li> <li>No office rent</li> <li>No significant investment in development</li> <li>No costly infrastructure necessary</ li></ul>',
|
||||
'compatibility_with_family_private_life' => 'compatibility with family and private life',
|
||||
'direct_sales_advantages_copy' => '<p>Direct selling has long since established itself worldwide as an independent type of business and is already represented in many industries. Direct sales, which is also known as network marketing, describes the <b>personal</b> sale of goods or services to consumers from the immediate environment: family, friends, colleagues, etc. What is crucial here is personal contact and the advisory function - customer service par excellence! And that is the great strength of direct sales, namely customer service. We create something that is no longer possible in the anonymous vastness of the Internet with a lot of personality and transparency.</p>',
|
||||
'direct_sales_advantages_hl' => 'direct sales and its advantages',
|
||||
'direct_sales_exactly_copy' => '<p>Imagine that you are an enthusiastic fan of a particular company\'s products. You think to yourself: “Great - I have to tell my best friend about that. And my buddy. And the family. And the whole world in general.” - and they buy the product based on your recommendation. Happens every day. We all know it.</p> <p>The difference is, you don\'t just recommend it, no, you yourself are the seller, building up a customer base and thereby a margin of 30-40%. New customers gained - yeah! So far, so good.</p> <p>And now imagine that your friend or girlfriend also becomes a sales partner, builds up a customer base and you also earn money from it. And so it goes - up to 3 levels + bonuses!</p>',
|
||||
'direct_sales_exactly_hl' => 'Direct sales - how does it work exactly?',
|
||||
'funding_opportunities_copy' => '<p>If you want to take the leap into full independence, there are various funding options available. Please take a look at the following where you can apply for your first start-up capital:</p> <p> <a href="https://www.existenzgruender.de" rel="nofollow" target="_blank">www.existenzgruender .de</a><br> <a href="http://www.foerderdatabase.de" rel="nofollow" target="_blank">www.foerderkatalog.de</a><br> <a href ="https://www.kfw.de" rel="nofollow" target="_blank">www.kfw.de</a><br> <a href="http://www.mikrofinanz.net" rel="nofollow" target="_blank">www.mikrofinanz.net</a><br> </p>',
|
||||
'funding_opportunities_hl' => 'funding opportunities',
|
||||
'how_to_sell_exactly_copy' => 'There are many different ways for you to sell products or gain sales partners. Here we introduce you to a few of them. The most important rule is: use the products and talk about them. Then the customers will come to you on their own.',
|
||||
'how_to_sell_exactly_hl' => 'And how do I sell exactly?',
|
||||
'make_people_happy_copy' => 'Our products help people with a wide variety of skin problems and are often used to care for neurodermatitis, psoriasis, acne and many other skin diseases. The pure organic aloe vera juice is an excellent bioregulator, has an anti-inflammatory effect and supports the body in maintaining the intestinal flora. You can also help other people keep their bodies healthy in a natural way.',
|
||||
'make_people_happy_hl' => 'make people happy...',
|
||||
'origin_aloe_copy' => 'The farm on Mallorca is around 40 hectares in size. The aloe vera plants are grown and cared for there. The 200,000 plants must be at least 5 years old before the leaves can be harvested. A plant needs at least 2,000 hours of sunshine per year to build up the valuable nutrients for the juice.',
|
||||
'origin_aloe_hl' => 'origin of our aloe',
|
||||
'origin_aloe_subl' => 'From the Germans\' favorite holiday island',
|
||||
'pillars_best_aloe_vera_quality' => 'The 5 pillars for the best aloe vera quality',
|
||||
'pillars_best_aloe_vera_quality_1_hl' => 'ORGANIC certified',
|
||||
'pillars_best_aloe_vera_quality_1_subl' => 'Aloe vera from organic farming - no harmful substances',
|
||||
'pillars_best_aloe_vera_quality_2_hl' => 'pure aloe gel',
|
||||
'pillars_best_aloe_vera_quality_2_subl' => 'processing of pure aloe gel - no powder-water mixture',
|
||||
'pillars_best_aloe_vera_quality_3_hl' => 'on-site production',
|
||||
'pillars_best_aloe_vera_quality_3_subl' => 'The harvested aloe leaves are immediately processed on site - the active ingredients are retained',
|
||||
'pillars_best_aloe_vera_quality_4_hl' => 'high aloe content',
|
||||
'pillars_best_aloe_vera_quality_4_subl' => 'All products have a high proportion of pure organic aloe vera',
|
||||
'pillars_best_aloe_vera_quality_5_hl' => 'high aloever rose content',
|
||||
'pillars_best_aloe_vera_quality_5_subl' => 'With 1,600-1,700 mg/l, an above-average Aloverose content - THE quality factor for the active ingredient content of Aloe',
|
||||
'private_environment_hl' => 'in a private environment',
|
||||
'private_environment_list' => '<ul class="small"> <li>Family</li> <li>Friends</li> <li>Work colleagues</li> <li>Neighbors</li> <li>Home parties</li> <li> Sports club</li> <li>Family</li> <li>Pet owners</li> <li>and much more.</li> </ul>',
|
||||
'requirement_profile' => 'requirements profile',
|
||||
'requirement_profile_at_mivita' => 'requirements profile',
|
||||
'requirement_profile_at_mivita_copy' => '<p>Everyone who wants to build something of their own with joy and commitment is welcome at MIVITA. Our sales partners primarily include people like...</p> <ul class="small"> <li>Employees with full-time jobs</li> <li>Employees with part-time jobs</li> <li>young families or single parents </li> <li>Independent entrepreneurs</li> <li>Students and trainees</li> <li>+50 generation who want to know again</li> </ul> <p> If you are in If you find this requirement profile, then you have come to the right place. Especially people who feel that there is more they can achieve, who are perhaps stuck in their careers, who would like to work more freely and independently - we would be happy to offer them a non-binding initial consultation. </p>',
|
||||
'shop_at_the_aloe_vera_farm' => 'shop at Aloe Vera Farm',
|
||||
'social_environment_hl' => 'on social media',
|
||||
'social_environment_list' => '<ul class="small"> <li>Facebook</li> <li>Youtube</li> <li>Instagram</li> <li>Snapchat</li> <li>Family</li> <li >among others ...</li></ul>',
|
||||
'social_security_copy' => '<p>Almost everyone gets into direct sales as a part-time job. After all, professional success with a good financial income doesn\'t happen overnight. If you still decide to become self-employed, please note the following points regarding your social security:</p> <p> <ul class="small"> <li>As a self-employed person, you can either take out a private pension plan or join the statutory pension insurance. Deviating from this, there is compulsory insurance in the statutory pension insurance for so-called "employee-like self-employed persons" who work permanently and essentially only for a single client and do not employ their own employees. </li> <li> As a self-employed person, you can take out private health insurance or, under certain conditions, voluntarily insure yourself in a statutory health insurance company. However, they must have some form of health insurance. </li> <li>You must take out nursing care insurance wherever you have health insurance </li> <li> There is no compulsory membership in the statutory unemployment insurance. After setting up your business, you can voluntarily continue to insure yourself there under certain conditions. </li></ul>',
|
||||
'social_security_hl' => 'social security',
|
||||
'start_up' => 'starting a business',
|
||||
'that_sounds_exciting_to_you' => 'Does that sound exciting to you?',
|
||||
'then_get_in_touch_with_us_today' => 'Then contact us today - we look forward to getting to know you.',
|
||||
'to_the_contact_form' => 'to contact form',
|
||||
'to_the_registration' => 'for registration',
|
||||
'trade_licence_copy' => '<p>If you want to start this business, you need a business license. This is nothing wild and can be applied for at the trade office in your city. There are small one-off costs of around EUR 20-25, depending on the city or municipality. Think about a specific activity that you will state on the business license. E.g. “Sales of wellness and care products”. In the information sheet on business registration, setting up a business and formalities you will find helpful and important information on the following points:</p> <ul> <li>Business registration</li> <li>Reporting to the tax office</li> <li>Membership in the industrial association and Chamber of Commerce </li></ul>',
|
||||
'trade_licence_hl' => 'business license',
|
||||
'training_aloe_farm_mallorca' => 'Training at the Aloe Vera Farm in Mallorca.',
|
||||
'training_aloe_farm_mallorca_copy' => 'MIVITA organizes training for consultants twice a year. In addition to your tour of the farm and production facility, farm operator Werner Telwest will introduce you to the secrets of the “desert lily”. And the best thing: There is an advertisement for every training course. Anyone who generates sales will be rewarded with a trip from MIVITA and will fly FOR FREE to the Germans\' favorite holiday island.',
|
||||
'women_direct_sales_copy' => 'Lt. According to the Federal Association for Direct Sales in Germany (BDD), 82% of managers were women. This was the result of a survey within BDD member companies. The proportion of women is therefore significantly higher than in comparison with the economy as a whole. And that doesn\'t come from anywhere. Traditionally, many women work in direct sales who, due to family conditions or a lack of equal opportunities in the market, find their calling here to live out their drive, ideas and energies in order to develop into a successful business woman.',
|
||||
'women_direct_sales_hl' => 'Women in direct sales',
|
||||
);
|
||||
return [
|
||||
'advantages_MIVITA_botl' => '... build a self-determined future for yourself in which you are your own boss.',
|
||||
'advantages_MIVITA_hl' => 'Advantages of MIVITA:',
|
||||
'advantages_MIVITA_list' => '<ul class="small"> <li>20-40% sales margin</li> <li>Attractive bonuses and promotions</li> <li>Earnings up to 3 levels</li> <li>No minimum turnover</ li> <li>Free scheduling</li> <li>Working in a team</li> <li>Advertising materials & online shop on request</li> <li>Shipping and returns processing by MIVITA</li> <li> Training in Mallorca </li></ul>',
|
||||
'advantages_MIVITA_subl' => 'There are many good reasons to become self-employed with mivita. Many consultants answer the question why they chose direct sales at mivita:',
|
||||
'advantages_direct_sales_hl' => 'advantages of direct selling',
|
||||
'advantages_direct_sales_list' => '<ul class="small"> <li>To earn extra money or increase the family\'s quality of life</li> <li>To be your own boss with low risk and low investments</li> < li>To work flexibly with free scheduling</li> <li>To have no purchase obligations</li> <li>To be able to start without age restrictions, without previous knowledge or special qualifications</li> <li>Low risk and low fixed costs </li> <li>Because of the high product quality</li> </ul>',
|
||||
'advantages_direct_sales_subl' => 'Direct selling brings the following advantages',
|
||||
'advantages_of_direct_sales' => 'advantages of direct selling',
|
||||
'aloe_high_quality_copy' => 'Aloe vera leaf gel is a true treasure and a gift from nature. But there are a lot of things to consider, from cultivation to processing, to ensure that these valuable ingredients are preserved and reach the customer. Unfortunately, many manufacturers do not adhere to the 1x1 of aloe vera production and so there are a number of aloe products on the market that have little to no effect. So what makes our products so high quality?',
|
||||
'aloe_high_quality_hl' => 'What makes our aloe vera products so high quality?',
|
||||
'aloe_high_quality_li1' => 'The aloe plants are over 5 years old',
|
||||
'aloe_high_quality_li10' => 'high proportion of pure aloe in every product',
|
||||
'aloe_high_quality_li2' => 'Have well over 2,000 hours of sunshine annually',
|
||||
'aloe_high_quality_li3' => 'purely organically controlled cultivation',
|
||||
'aloe_high_quality_li4' => 'no (!) artificial irrigation',
|
||||
'aloe_high_quality_li5' => 'no pest or weed killers',
|
||||
'aloe_high_quality_li6' => 'harvesting and filleting the leaves by hand',
|
||||
'aloe_high_quality_li7' => 'processing into products directly after harvest',
|
||||
'aloe_high_quality_li8' => 'just the pure gel: no powder or extract',
|
||||
'aloe_high_quality_li9' => 'certified aloverose content over 1,600 mg/l',
|
||||
'aloe_high_quality_subl' => 'One of the world\'s best aloe vera juices as a basis for high-quality aloe products',
|
||||
'aloe_vera_word_copy' => 'The globally unique and outstanding properties of aloe vera are due to the unique interaction and symbiosis of the different ingredients and active ingredients. No other plant known to date has such a wide range of healing and nourishing uses. In total, more than 200 active substances are currently known in the medical literature, and new ones are constantly being discovered. The decoding of the complex interaction of all substances is only just beginning, but the effects are now very well documented.',
|
||||
'bio_quality_copy' => 'We guarantee the best quality through manual production and organic ingredients. The typical climate of Mallorca challenges the plants. Tests have shown that this climate is optimal for perfect plant development.',
|
||||
'bio_quality_hl' => '100% ORGANIC quality',
|
||||
'bio_quality_subl' => 'organic certified handcraft from Mallorca',
|
||||
'business_environment_hl' => 'business environment',
|
||||
'business_environment_list' => '<ul class="small"> <li>Cosmetics / natural cosmetics</li> <li>Hair styling</li> <li>Nutrition</li> <li>Nail & foot care</li> <li>Natural practitioner & Alternative medicine</li> <li>Medicine (skin, physio, general etc.)</li> <li>All about animals</li> <li>Yoga & meditation</li> <li>Gastronomy</li> <li>Sport & Fitness</li> <li>and much more.</li> </ul>',
|
||||
'career_opportunitie_point_1' => 'Sell products that are suitable for a healthy and vital life and that give you and your loved ones a great feel-good experience.',
|
||||
'career_opportunitie_point_2' => 'We keep up to date and support each other in WhatsApp groups and video calls. You\'re not alone!',
|
||||
'career_opportunitie_point_3' => 'We pass on our know-how, proven marketing tools and advertising materials to you, because we are only successful if YOU are successful.',
|
||||
'career_opportunitie_point_4' => 'Benefit from supportive measures such as training, team events or joint sales campaigns. Together we are successful!',
|
||||
'career_opportunitie_point_5' => 'Use social media and talk about products and experiences. Gain new customers and partners via Facebook & Co.',
|
||||
'career_opportunities_at_mivita' => 'career opportunities at mivita',
|
||||
'compatibility_with_family_copy1' => 'Who does not know that? There is a lack of money everywhere and the boss always turns up his nose when the child is sick. Many families rely on a second job or the part-time work of the mother or father. And that often cannot be reconciled with the employer\'s ideas. But what if you simply build up your monthly additional income yourself and at the same time have more time for your child?',
|
||||
'compatibility_with_family_copy2' => 'Particularly in direct sales, with its options for free time management and passive income, you have as much freedom in the medium term as a permanent job cannot offer you. As an independent MIVITA consultant, you decide for yourself when and where you work. And that doesn\'t just affect young parents. Direct sales also represent a perfect solution for people who need to care for their family members or simply want to have more time and financial relief:',
|
||||
'compatibility_with_family_list' => '<ul class="small"> <li>Work from home or on the go</li> <li>No office rent</li> <li>No significant investment in development</li> <li>No costly infrastructure necessary</ li></ul>',
|
||||
'compatibility_with_family_private_life' => 'compatibility with family and private life',
|
||||
'direct_sales_advantages_copy' => '<p>Direct selling has long since established itself worldwide as an independent type of business and is already represented in many industries. Direct sales, which is also known as network marketing, describes the <b>personal</b> sale of goods or services to consumers from the immediate environment: family, friends, colleagues, etc. What is crucial here is personal contact and the advisory function - customer service par excellence! And that is the great strength of direct sales, namely customer service. We create something that is no longer possible in the anonymous vastness of the Internet with a lot of personality and transparency.</p>',
|
||||
'direct_sales_advantages_hl' => 'direct sales and its advantages',
|
||||
'direct_sales_exactly_copy' => '<p>Imagine that you are an enthusiastic fan of a particular company\'s products. You think to yourself: “Great - I have to tell my best friend about that. And my buddy. And the family. And the whole world in general.” - and they buy the product based on your recommendation. Happens every day. We all know it.</p> <p>The difference is, you don\'t just recommend it, no, you yourself are the seller, building up a customer base and thereby a margin of 30-40%. New customers gained - yeah! So far, so good.</p> <p>And now imagine that your friend or girlfriend also becomes a sales partner, builds up a customer base and you also earn money from it. And so it goes - up to 3 levels + bonuses!</p>',
|
||||
'direct_sales_exactly_hl' => 'Direct sales - how does it work exactly?',
|
||||
'funding_opportunities_copy' => '<p>If you want to take the leap into full independence, there are various funding options available. Please take a look at the following where you can apply for your first start-up capital:</p> <p> <a href="https://www.existenzgruender.de" rel="nofollow" target="_blank">www.existenzgruender .de</a><br> <a href="http://www.foerderdatabase.de" rel="nofollow" target="_blank">www.foerderkatalog.de</a><br> <a href ="https://www.kfw.de" rel="nofollow" target="_blank">www.kfw.de</a><br> <a href="http://www.mikrofinanz.net" rel="nofollow" target="_blank">www.mikrofinanz.net</a><br> </p>',
|
||||
'funding_opportunities_hl' => 'funding opportunities',
|
||||
'how_to_sell_exactly_copy' => 'There are many different ways for you to sell products or gain sales partners. Here we introduce you to a few of them. The most important rule is: use the products and talk about them. Then the customers will come to you on their own.',
|
||||
'how_to_sell_exactly_hl' => 'And how do I sell exactly?',
|
||||
'make_people_happy_copy' => 'Our products help people with a wide variety of skin problems and are often used to care for neurodermatitis, psoriasis, acne and many other skin diseases. The pure organic aloe vera juice is an excellent bioregulator, has an anti-inflammatory effect and supports the body in maintaining the intestinal flora. You can also help other people keep their bodies healthy in a natural way.',
|
||||
'make_people_happy_hl' => 'make people happy...',
|
||||
'origin_aloe_copy' => 'The farm on Mallorca is around 40 hectares in size. The aloe vera plants are grown and cared for there. The 200,000 plants must be at least 5 years old before the leaves can be harvested. A plant needs at least 2,000 hours of sunshine per year to build up the valuable nutrients for the juice.',
|
||||
'origin_aloe_hl' => 'origin of our aloe',
|
||||
'origin_aloe_subl' => 'From the Germans\' favorite holiday island',
|
||||
'pillars_best_aloe_vera_quality' => 'The 5 pillars for the best aloe vera quality',
|
||||
'pillars_best_aloe_vera_quality_1_hl' => 'ORGANIC certified',
|
||||
'pillars_best_aloe_vera_quality_1_subl' => 'Aloe vera from organic farming - no harmful substances',
|
||||
'pillars_best_aloe_vera_quality_2_hl' => 'pure aloe gel',
|
||||
'pillars_best_aloe_vera_quality_2_subl' => 'processing of pure aloe gel - no powder-water mixture',
|
||||
'pillars_best_aloe_vera_quality_3_hl' => 'on-site production',
|
||||
'pillars_best_aloe_vera_quality_3_subl' => 'The harvested aloe leaves are immediately processed on site - the active ingredients are retained',
|
||||
'pillars_best_aloe_vera_quality_4_hl' => 'high aloe content',
|
||||
'pillars_best_aloe_vera_quality_4_subl' => 'All products have a high proportion of pure organic aloe vera',
|
||||
'pillars_best_aloe_vera_quality_5_hl' => 'high aloever rose content',
|
||||
'pillars_best_aloe_vera_quality_5_subl' => 'With 1,600-1,700 mg/l, an above-average Aloverose content - THE quality factor for the active ingredient content of Aloe',
|
||||
'private_environment_hl' => 'in a private environment',
|
||||
'private_environment_list' => '<ul class="small"> <li>Family</li> <li>Friends</li> <li>Work colleagues</li> <li>Neighbors</li> <li>Home parties</li> <li> Sports club</li> <li>Family</li> <li>Pet owners</li> <li>and much more.</li> </ul>',
|
||||
'requirement_profile' => 'requirements profile',
|
||||
'requirement_profile_at_mivita' => 'requirements profile',
|
||||
'requirement_profile_at_mivita_copy' => '<p>Everyone who wants to build something of their own with joy and commitment is welcome at MIVITA. Our sales partners primarily include people like...</p> <ul class="small"> <li>Employees with full-time jobs</li> <li>Employees with part-time jobs</li> <li>young families or single parents </li> <li>Independent entrepreneurs</li> <li>Students and trainees</li> <li>+50 generation who want to know again</li> </ul> <p> If you are in If you find this requirement profile, then you have come to the right place. Especially people who feel that there is more they can achieve, who are perhaps stuck in their careers, who would like to work more freely and independently - we would be happy to offer them a non-binding initial consultation. </p>',
|
||||
'shop_at_the_aloe_vera_farm' => 'shop at Aloe Vera Farm',
|
||||
'social_environment_hl' => 'on social media',
|
||||
'social_environment_list' => '<ul class="small"> <li>Facebook</li> <li>Youtube</li> <li>Instagram</li> <li>Snapchat</li> <li>Family</li> <li >among others ...</li></ul>',
|
||||
'social_security_copy' => '<p>Almost everyone gets into direct sales as a part-time job. After all, professional success with a good financial income doesn\'t happen overnight. If you still decide to become self-employed, please note the following points regarding your social security:</p> <p> <ul class="small"> <li>As a self-employed person, you can either take out a private pension plan or join the statutory pension insurance. Deviating from this, there is compulsory insurance in the statutory pension insurance for so-called "employee-like self-employed persons" who work permanently and essentially only for a single client and do not employ their own employees. </li> <li> As a self-employed person, you can take out private health insurance or, under certain conditions, voluntarily insure yourself in a statutory health insurance company. However, they must have some form of health insurance. </li> <li>You must take out nursing care insurance wherever you have health insurance </li> <li> There is no compulsory membership in the statutory unemployment insurance. After setting up your business, you can voluntarily continue to insure yourself there under certain conditions. </li></ul>',
|
||||
'social_security_hl' => 'social security',
|
||||
'start_up' => 'starting a business',
|
||||
'that_sounds_exciting_to_you' => 'Does that sound exciting to you?',
|
||||
'then_get_in_touch_with_us_today' => 'Then contact us today - we look forward to getting to know you.',
|
||||
'to_the_contact_form' => 'to contact form',
|
||||
'to_the_registration' => 'for registration',
|
||||
'trade_licence_copy' => '<p>If you want to start this business, you need a business license. This is nothing wild and can be applied for at the trade office in your city. There are small one-off costs of around EUR 20-25, depending on the city or municipality. Think about a specific activity that you will state on the business license. E.g. “Sales of wellness and care products”. In the information sheet on business registration, setting up a business and formalities you will find helpful and important information on the following points:</p> <ul> <li>Business registration</li> <li>Reporting to the tax office</li> <li>Membership in the industrial association and Chamber of Commerce </li></ul>',
|
||||
'trade_licence_hl' => 'business license',
|
||||
'training_aloe_farm_mallorca' => 'Training at the Aloe Vera Farm in Mallorca.',
|
||||
'training_aloe_farm_mallorca_copy' => 'MIVITA organizes training for consultants twice a year. In addition to your tour of the farm and production facility, farm operator Werner Telwest will introduce you to the secrets of the “desert lily”. And the best thing: There is an advertisement for every training course. Anyone who generates sales will be rewarded with a trip from MIVITA and will fly FOR FREE to the Germans\' favorite holiday island.',
|
||||
'women_direct_sales_copy' => 'Lt. According to the Federal Association for Direct Sales in Germany (BDD), 82% of managers were women. This was the result of a survey within BDD member companies. The proportion of women is therefore significantly higher than in comparison with the economy as a whole. And that doesn\'t come from anywhere. Traditionally, many women work in direct sales who, due to family conditions or a lack of equal opportunities in the market, find their calling here to live out their drive, ideas and energies in order to develop into a successful business woman.',
|
||||
'women_direct_sales_hl' => 'Women in direct sales',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,44 +1,45 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'VAT' => 'VAT',
|
||||
'add_shopping_cart' => 'add to Cart',
|
||||
'all_price_plus_VAT_info' => 'All prices incl. statutory. VAT :link unless otherwise stated',
|
||||
'application' => 'application',
|
||||
'checkout_ssl_server' => 'You will be redirected to our checkout server, the connection is SSL encrypted.',
|
||||
'delivery_time_1_3' => 'delivery time: 1-3 working days',
|
||||
'description' => 'description',
|
||||
'details' => 'details',
|
||||
'excl_VAT_plus_shipping_costs' => 'excl. VAT plus shipping costs',
|
||||
'free_shipping' => 'free shipping',
|
||||
'free_shipping_at' => 'free shipping from :value €',
|
||||
'free_shipping_costs_from' => 'free shipping from',
|
||||
'incl' => 'Incl.',
|
||||
'incl_VAT_plus_shipping_costs' => 'incl. VAT., excl. Shipping costs',
|
||||
'ingredients' => 'ingredients',
|
||||
'not_free_shipping' => 'not free shipping',
|
||||
'only_missing_free_shipping_at' => 'All that\'s left is :value € for your free shipping.',
|
||||
'only_missing_free_shipping_costs_from' => 'All that\'s left is :value € for your free shipping.',
|
||||
'payment_method_creditcard' => 'credit card',
|
||||
'payment_method_creditcard_copy' => 'The amount will be deducted from your credit card as soon as the order is submitted. The credit card process is processed via our payment service provider PAYONE.',
|
||||
'payment_method_direct' => 'instant bank transfer',
|
||||
'payment_method_direct_copy' => 'After successful verification, you will be redirected to PAYONE\'s secured payment page for SOFORT transfers to continue payment. After successful payment, please do not close the browser until you have been redirected back to the shop.',
|
||||
'payment_method_paypal' => 'payment with Paypal',
|
||||
'payment_method_paypal_copy' => 'After successful verification, you will be redirected to Paypal\'s secure payment page to continue payment. After successful payment, please do not close the browser until you have been redirected back to the shop.',
|
||||
'payment_method_prepayment' => 'prepayment',
|
||||
'payment_method_prepayment_copy' => 'After you have submitted the order, you will receive an email with the bank details to make the payment. After receipt of the amount, your goods will be shipped.',
|
||||
'payment_method_sepa' => 'SEPA direct debit',
|
||||
'payment_method_sepa_copy' => 'Your account will be charged for this one order after the order is submitted. The SEPA direct debit is processed via our payment service provider PAYONE.',
|
||||
'payment_methods' => 'payment Methods',
|
||||
'plus_shipping_cost' => 'plus shipping and handling',
|
||||
'price_net' => 'prices net',
|
||||
'product_details' => 'product details',
|
||||
'shipping_cost' => 'shipping',
|
||||
'shipping_methods_costs' => 'shipping methods & shipping costs',
|
||||
'shopping_cart' => 'shopping cart',
|
||||
'shopping_cart_sum' => 'shopping cart total',
|
||||
'sum_net' => 'total net',
|
||||
'to_checkout' => 'to checkout',
|
||||
'to_product' => 'to the product',
|
||||
'to_shopping_cart' => 'to the shopping cart',
|
||||
);
|
||||
return [
|
||||
'VAT' => 'VAT',
|
||||
'add_shopping_cart' => 'add to Cart',
|
||||
'all_price_plus_VAT_info' => 'All prices incl. statutory. VAT :link unless otherwise stated',
|
||||
'application' => 'application',
|
||||
'checkout_ssl_server' => 'You will be redirected to our checkout server, the connection is SSL encrypted.',
|
||||
'delivery_time_1_3' => 'delivery time: 1-3 working days',
|
||||
'description' => 'description',
|
||||
'details' => 'details',
|
||||
'excl_VAT_plus_shipping_costs' => 'excl. VAT plus shipping costs',
|
||||
'free_shipping' => 'free shipping',
|
||||
'free_shipping_at' => 'free shipping from :value €',
|
||||
'free_shipping_costs_from' => 'free shipping from',
|
||||
'incl' => 'Incl.',
|
||||
'incl_VAT_plus_shipping_costs' => 'incl. VAT., excl. Shipping costs',
|
||||
'ingredients' => 'ingredients',
|
||||
'not_free_shipping' => 'not free shipping',
|
||||
'only_missing_free_shipping_at' => 'All that\'s left is :value € for your free shipping.',
|
||||
'only_missing_free_shipping_costs_from' => 'All that\'s left is :value € for your free shipping.',
|
||||
'payment_method_creditcard' => 'credit card',
|
||||
'payment_method_creditcard_copy' => 'The amount will be deducted from your credit card as soon as the order is submitted. The credit card process is processed via our payment service provider PAYONE.',
|
||||
'payment_method_direct' => 'instant bank transfer',
|
||||
'payment_method_direct_copy' => 'After successful verification, you will be redirected to PAYONE\'s secured payment page for SOFORT transfers to continue payment. After successful payment, please do not close the browser until you have been redirected back to the shop.',
|
||||
'payment_method_paypal' => 'payment with Paypal',
|
||||
'payment_method_paypal_copy' => 'After successful verification, you will be redirected to Paypal\'s secure payment page to continue payment. After successful payment, please do not close the browser until you have been redirected back to the shop.',
|
||||
'payment_method_prepayment' => 'prepayment',
|
||||
'payment_method_prepayment_copy' => 'After you have submitted the order, you will receive an email with the bank details to make the payment. After receipt of the amount, your goods will be shipped.',
|
||||
'payment_method_sepa' => 'SEPA direct debit',
|
||||
'payment_method_sepa_copy' => 'Your account will be charged for this one order after the order is submitted. The SEPA direct debit is processed via our payment service provider PAYONE.',
|
||||
'payment_methods' => 'payment Methods',
|
||||
'plus_shipping_cost' => 'plus shipping and handling',
|
||||
'price_net' => 'prices net',
|
||||
'product_details' => 'product details',
|
||||
'shipping_cost' => 'shipping',
|
||||
'shipping_methods_costs' => 'shipping methods & shipping costs',
|
||||
'shopping_cart' => 'shopping cart',
|
||||
'shopping_cart_sum' => 'shopping cart total',
|
||||
'sum_net' => 'total net',
|
||||
'to_checkout' => 'to checkout',
|
||||
'to_product' => 'to the product',
|
||||
'to_shopping_cart' => 'to the shopping cart',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,82 +1,94 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'NOW' => 'NOW',
|
||||
'VATID' => 'VAT ID no.',
|
||||
'accept_youtube_load' => 'accept and load YouTube video',
|
||||
'address' => 'address',
|
||||
'all_rights_reserved' => 'All Rights Reserved, mivita.care',
|
||||
'aloe_vera' => 'Aloe vera',
|
||||
'best_regards' => 'best regards',
|
||||
'business_hours' => 'business hours',
|
||||
'business_hours_details' => 'Mon - Fri: 9 a.m. - 12 p.m. and 1 p.m. - 4 p.m',
|
||||
'business_owner' => 'business owner',
|
||||
'business_owner_value' => 'Alois Ried',
|
||||
'cancellation_policy' => 'right of withdrawal',
|
||||
'career_opportunities' => 'career opportunities',
|
||||
'change_country' => 'change country',
|
||||
'contact' => 'contact',
|
||||
'contact_hl' => 'Write to us!',
|
||||
'contact_now' => 'contact now',
|
||||
'contact_subl' => 'Are you interested in our business or do you have questions about the products? Then we look forward to hearing from you. We will get back to you as soon as possible.',
|
||||
'contents' => 'content',
|
||||
'email' => 'E-Mail',
|
||||
'email_address' => '',
|
||||
'for_you_on_spot' => 'for you on site',
|
||||
'for_you_on_spot_copy' => 'We were there for you at the Aloe Vera Farm on Mallorca, because transparency is important to us. This way you know exactly where your products come from and how they are produced. Real quality.',
|
||||
'gtc' => 'conditions',
|
||||
'impress' => 'imprint',
|
||||
'language' => 'language',
|
||||
'more' => 'more',
|
||||
'my_accessibility' => 'My accessibility',
|
||||
'my_accessibility:' => 'my availability',
|
||||
'no' => 'NO',
|
||||
'note_on_use' => 'usage notice',
|
||||
'note_on_use_copy' => 'Unauthorized use, reproduction, distribution, publication or commercial use without the permission of the author of the content on this website is prohibited and will be prosecuted under both criminal and civil law!',
|
||||
'online_dispute_resolution' => 'online dispute resolution',
|
||||
'online_dispute_resolution_copy' => 'According to Art. 14 Para. 1 ODR-VO: The European Commission provides a platform for online dispute resolution (OS), which you can find here',
|
||||
'partner' => 'partner',
|
||||
'payment_methods' => 'payment methodes',
|
||||
'phone' => 'telephone',
|
||||
'phone_number' => 'telephone: +49 (0) 8333 94 61 767',
|
||||
'privacy_policy' => 'data protection',
|
||||
'productworld' => 'product world',
|
||||
'read' => 'read',
|
||||
'register' => 'registration',
|
||||
'register_now' => 'register now',
|
||||
'register_number' => 'register number',
|
||||
'registry_court' => 'registry court',
|
||||
'sales_partner_or_questions' => 'Would you like to become a sales partner or do you have questions about our products?',
|
||||
'send_message' => 'send massage',
|
||||
'shipping_costs' => 'shipment',
|
||||
'shop' => 'shop',
|
||||
'show_all_products' => 'Show all products',
|
||||
'slider_hl' => 'nutritional supplements',
|
||||
'slider_subl' => 'organic Aloe Vera & Natural cosmetics',
|
||||
'start' => 'start',
|
||||
'start_aloe_copy' => 'With the highest standards, we work together with the Aloe Vera Farm on Mallorca, which guarantees top-class quality worldwide.',
|
||||
'start_aloe_hl' => 'Aloe Vera',
|
||||
'start_copy_mivita' => 'MIVITA is a company based in Germany that sells innovative, environmentally friendly and high-quality products. Since entering the market, the MIVITA company has been committed to an understanding of values that focus on customer satisfaction and responsibility for the environment.',
|
||||
'start_mivitapartner_copy' => '<p>MIVITA is the exclusive partner of the Aloe Vera de Mallorca farm in the area of direct sales in Germany. Two companies have come together here for whom quality and sustainability are top priorities. This is the only way to turn satisfied customers into real fans of our products in the long term.</p> <blockquote> <p><i>“For the sake of people, animals and nature... Sustainability and products that really “do you good” are important to us .”</i></p> <p>Alois Ried - Owner MIVITA</p> </blockquote>',
|
||||
'start_products_copy' => 'Here you will find an overview of MIVITA\'s complete premium product range. From high-quality aloe juice to soothing cosmetics.',
|
||||
'start_products_hl' => 'products',
|
||||
'start_salespartner_copy' => 'Become a MIVITA sales partner and build your own business with quality products. If you like, you can start immediately...',
|
||||
'start_salespartner_hl' => 'Sales partner',
|
||||
'start_why_copy' => '<p>Our customers rightly trust in the excellent properties of MIVITA products. This means that everyone actively makes a smart decision for health and the environment.</p> <p>We not only attach great importance to the quality of our products, but of course also to comprehensive, competent advice from friendly and expert advisors.</p> <p>We only develop and sell products that are high quality. When used and cared for properly, they are long-lasting and very productive. Factors that ensure our customers\' satisfaction.</p>',
|
||||
'start_why_hl' => 'Why MIVITA?',
|
||||
'thank_you_for_your_request' => 'many thanks for your inquiry',
|
||||
'through_whom_label' => 'Who brought you to our attention (sales partner, customer, social media, etc.)? Please be sure to provide a name - this is important for our internal assignment:*',
|
||||
'through_whom_placeholder' => 'first and last name, website, Facebook, Instagram, YouTube profile or similar',
|
||||
'to_contact' => 'to contact',
|
||||
'to_privacy_policy' => 'to the data protection',
|
||||
'we_will_get_back_to_you' => 'We will contact you immediately.',
|
||||
'welcome' => 'welcome',
|
||||
'welcome_copy' => 'I look forward to your visit to my MIVITA online shop. I am your personal advice on the products and their application.',
|
||||
'yes' => 'YES',
|
||||
'you_are_now_in_shop' => 'You are in the shop:',
|
||||
'you_are_now_in_shop_notice' => 'Important note: Orders in the selected country can only be shipped within that country. If you change your country, you will be logged out of your current session and your shopping cart will be emptied.',
|
||||
'your_enquiry_relate_partnership' => 'Does your inquiry concern a desired sales partnership?*',
|
||||
'your_message_to_us' => 'your massage to us',
|
||||
'your_mivita_team' => 'your mivita.care team',
|
||||
'youtube_accepted_copy' => 'By loading the YouTube video you accept our data protection declaration / XII. Integration of third-party services and content',
|
||||
);
|
||||
return [
|
||||
'NOW' => 'NOW',
|
||||
'VATID' => 'VAT ID no.',
|
||||
'accept_youtube_load' => 'accept and load YouTube video',
|
||||
'address' => 'address',
|
||||
'all_rights_reserved' => 'All Rights Reserved, mivita.care',
|
||||
'aloe_vera' => 'Aloe vera',
|
||||
'best_regards' => 'best regards',
|
||||
'business_hours' => 'business hours',
|
||||
'business_hours_details' => 'Mon - Fri: 9 a.m. - 12 p.m. and 1 p.m. - 4 p.m',
|
||||
'business_owner' => 'business owner',
|
||||
'business_owner_value' => 'Alois Ried',
|
||||
'cancellation_policy' => 'right of withdrawal',
|
||||
'career_opportunities' => 'career opportunities',
|
||||
'change_country' => 'change country',
|
||||
'contact' => 'contact',
|
||||
'contact_hl' => 'Write to us!',
|
||||
'contact_now' => 'contact now',
|
||||
'contact_subl' => 'Are you interested in our business or do you have questions about the products? Then we look forward to hearing from you. We will get back to you as soon as possible.',
|
||||
'contents' => 'content',
|
||||
'email' => 'E-Mail',
|
||||
'email_address' => '',
|
||||
'for_you_on_spot' => 'for you on site',
|
||||
'for_you_on_spot_copy' => 'We were there for you at the Aloe Vera Farm on Mallorca, because transparency is important to us. This way you know exactly where your products come from and how they are produced. Real quality.',
|
||||
'gtc' => 'conditions',
|
||||
'impress' => 'imprint',
|
||||
'language' => 'language',
|
||||
'more' => 'more',
|
||||
'my_accessibility' => 'My accessibility',
|
||||
'no' => 'NO',
|
||||
'note_on_use' => 'usage notice',
|
||||
'note_on_use_copy' => 'Unauthorized use, reproduction, distribution, publication or commercial use without the permission of the author of the content on this website is prohibited and will be prosecuted under both criminal and civil law!',
|
||||
'online_dispute_resolution' => 'online dispute resolution',
|
||||
'online_dispute_resolution_copy' => 'According to Art. 14 Para. 1 ODR-VO: The European Commission provides a platform for online dispute resolution (OS), which you can find here',
|
||||
'partner' => 'partner',
|
||||
'payment_methods' => 'payment methodes',
|
||||
'phone' => 'telephone',
|
||||
'phone_number' => 'telephone: +49 (0) 8333 94 61 767',
|
||||
'privacy_policy' => 'data protection',
|
||||
'productworld' => 'product world',
|
||||
'read' => 'read',
|
||||
'register' => 'registration',
|
||||
'register_now' => 'register now',
|
||||
'register_number' => 'register number',
|
||||
'registry_court' => 'registry court',
|
||||
'sales_partner_or_questions' => 'Would you like to become a sales partner or do you have questions about our products?',
|
||||
'send_message' => 'send massage',
|
||||
'shipping_costs' => 'shipment',
|
||||
'shop' => 'shop',
|
||||
'show_all_products' => 'Show all products',
|
||||
'slider_hl' => 'nutritional supplements',
|
||||
'slider_subl' => 'organic Aloe Vera & Natural cosmetics',
|
||||
'start' => 'start',
|
||||
'start_aloe_copy' => 'With the highest standards, we work together with the Aloe Vera Farm on Mallorca, which guarantees top-class quality worldwide.',
|
||||
'start_aloe_hl' => 'Aloe Vera',
|
||||
'start_copy_mivita' => 'MIVITA is a company based in Germany that sells innovative, environmentally friendly and high-quality products. Since entering the market, the MIVITA company has been committed to an understanding of values that focus on customer satisfaction and responsibility for the environment.',
|
||||
'start_mivitapartner_copy' => '<p>MIVITA is the exclusive partner of the Aloe Vera de Mallorca farm in the area of direct sales in Germany. Two companies have come together here for whom quality and sustainability are top priorities. This is the only way to turn satisfied customers into real fans of our products in the long term.</p> <blockquote> <p><i>“For the sake of people, animals and nature... Sustainability and products that really “do you good” are important to us .”</i></p> <p>Alois Ried - Owner MIVITA</p> </blockquote>',
|
||||
'start_products_copy' => 'Here you will find an overview of MIVITA\'s complete premium product range. From high-quality aloe juice to soothing cosmetics.',
|
||||
'start_products_hl' => 'products',
|
||||
'start_salespartner_copy' => 'Become a MIVITA sales partner and build your own business with quality products. If you like, you can start immediately...',
|
||||
'start_salespartner_hl' => 'Sales partner',
|
||||
'start_why_copy' => '<p>Our customers rightly trust in the excellent properties of MIVITA products. This means that everyone actively makes a smart decision for health and the environment.</p> <p>We not only attach great importance to the quality of our products, but of course also to comprehensive, competent advice from friendly and expert advisors.</p> <p>We only develop and sell products that are high quality. When used and cared for properly, they are long-lasting and very productive. Factors that ensure our customers\' satisfaction.</p>',
|
||||
'start_why_hl' => 'Why MIVITA?',
|
||||
'thank_you_for_your_request' => 'many thanks for your inquiry',
|
||||
'through_whom_label' => 'Who brought you to our attention (sales partner, customer, social media, etc.)? Please be sure to provide a name - this is important for our internal assignment:*',
|
||||
'through_whom_placeholder' => 'first and last name, website, Facebook, Instagram, YouTube profile or similar',
|
||||
'to_contact' => 'to contact',
|
||||
'to_privacy_policy' => 'to the data protection',
|
||||
'we_will_get_back_to_you' => 'We will contact you immediately.',
|
||||
'welcome' => 'welcome',
|
||||
'welcome_copy' => 'I look forward to your visit to my MIVITA online shop. I am your personal advice on the products and their application.',
|
||||
'yes' => 'YES',
|
||||
'you_are_now_in_shop' => 'You are in the shop:',
|
||||
'you_are_now_in_shop_notice' => 'Important note: Orders in the selected country can only be shipped within that country. If you change your country, you will be logged out of your current session and your shopping cart will be emptied.',
|
||||
'your_enquiry_relate_partnership' => 'Does your inquiry concern a desired sales partnership?*',
|
||||
'your_message_to_us' => 'your massage to us',
|
||||
'your_mivita_team' => 'your mivita.care team',
|
||||
'youtube_accepted_copy' => 'By loading the YouTube video you accept our data protection declaration / XII. Integration of third-party services and content',
|
||||
'contact_number' => '+49 (0) 8333 94 61 767',
|
||||
'contact_number_link' => '+4983339461767',
|
||||
'contact_address' => 'mivita care gmbh<br>Leinfeld 2<br>87755 Kirchhaslach<br>',
|
||||
'registry_court_value' => 'Memmingen',
|
||||
'register_number_value' => 'HRB 21591',
|
||||
'VATID_value' => 'DE 453867883',
|
||||
'support_mivita' => 'Support mivita',
|
||||
'to_login' => 'to login',
|
||||
'to_customer_portal' => 'to customer area',
|
||||
'to_sales_center' => 'to sales center',
|
||||
'shipping_error_billing' => 'Note: Your shopping cart with the delivery country :shipping_country does not match your billing address - delivery country :billing_country.',
|
||||
'shipping_error_delivery' => 'Note: Your shopping cart with the delivery country :shipping_country does not match your delivery address - delivery country :billing_country.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -144,10 +144,10 @@ return [
|
|||
'warning_next_date_soon_select' => 'Nota: La próxima ejecución de la suscripción es en :placeholder_days días (:placeholder_date).',
|
||||
'warning_next_date_info' => 'La próxima ejecución de la suscripción es en :days días el :date.',
|
||||
'info_next_execution_select' => 'Próxima ejecución: en :placeholder_days días el :placeholder_date.',
|
||||
'error_change_locked' => 'Los cambios ya no son posibles. La próxima ejecución es en :days días. Los cambios deben realizarse al menos 10 días antes.',
|
||||
'error_abo_interval_too_soon' => 'El día de entrega seleccionado está a solo :days días. Elija un día de entrega con al menos 10 días de anticipación.',
|
||||
'error_cancel_locked' => 'La cancelación ya no es posible. La próxima ejecución es en :days días. Las cancelaciones deben realizarse al menos 3 días antes.',
|
||||
'error_pause_locked' => 'La suscripción ya no puede pausarse. La próxima ejecución es en :days días. La pausa debe realizarse al menos 3 días antes.',
|
||||
'error_change_locked' => 'Los cambios ya no son posibles. La próxima ejecución es en :days días. Los cambios deben realizarse al menos :lock días antes.',
|
||||
'error_abo_interval_too_soon' => 'El día de entrega seleccionado está a solo :days días. Elija un día de entrega con al menos :lock días de anticipación.',
|
||||
'error_cancel_locked' => 'La cancelación ya no es posible. La próxima ejecución es en :days días. Las cancelaciones deben realizarse al menos :lock días antes.',
|
||||
'error_pause_locked' => 'La suscripción ya no puede pausarse. La próxima ejecución es en :days días. La pausa debe realizarse al menos :lock días antes.',
|
||||
'cancel_abo' => 'Cancelar suscripción',
|
||||
'confirm_cancel' => '¿Realmente desea cancelar la suscripción?',
|
||||
'retry_payment' => 'Reintentar pago',
|
||||
|
|
@ -165,10 +165,70 @@ return [
|
|||
'back' => 'atrás',
|
||||
'team_subscriptions' => 'Suscripciones de equipo',
|
||||
'team_customer_abos' => 'Suscripciones de clientes del equipo',
|
||||
'team_total' => 'Total',
|
||||
'team_line' => 'Nivel :line',
|
||||
'filter_period' => 'Período:',
|
||||
'team_total_abos' => 'Suscripciones totales del equipo',
|
||||
'team_own_abos' => 'Suscripciones propias',
|
||||
'team_members_with_abo' => 'Con suscripción propia',
|
||||
'team_by_level' => 'Suscripciones por nivel',
|
||||
'new_this_month' => 'nuevas este mes',
|
||||
'with_own_abo' => 'Con suscripción propia',
|
||||
'consultants' => 'Asesores',
|
||||
'level' => 'Nivel',
|
||||
'own_abo' => 'Suscripción propia',
|
||||
'customer_abos_count' => 'Suscripciones de clientes',
|
||||
'career_level' => 'Nivel de carrera',
|
||||
'of' => 'de',
|
||||
'yes' => 'Sí',
|
||||
'no' => 'No',
|
||||
'shop_1000' => 'Tiendas de 1000 puntos',
|
||||
'next_execution' => 'Próxima ejecución',
|
||||
'executions_count' => 'Ejecuciones',
|
||||
'abo_count_points' => 'Puntos',
|
||||
'no_own_abo' => 'Sin suscripción propia.',
|
||||
'no_customer_abos' => 'Sin suscripciones de clientes.',
|
||||
'team_growth' => 'Crecimiento de suscripciones (nuevas por mes)',
|
||||
'month' => 'Mes',
|
||||
'new_own_abos' => 'Nuevas suscripciones propias',
|
||||
'new_customer_abos' => 'Nuevas suscripciones de clientes',
|
||||
'new_total' => 'Nuevas en total',
|
||||
'filter' => 'Filtrar',
|
||||
'reset' => 'Restablecer',
|
||||
'filter_added_period' => 'Añadido en el período:',
|
||||
'chart_monthly_abos' => 'Suscripciones por mes',
|
||||
'chart_active_abos' => 'Suscripciones activas',
|
||||
'chart_abos_label' => 'suscripciones',
|
||||
'abo_count' => 'Número de suscripciones',
|
||||
'customer_privacy_info' => 'Por razones de privacidad, no se muestran datos personales del cliente.',
|
||||
'every_month_on' => 'mensualmente el :day.',
|
||||
|
||||
// Estado / pago pendiente / gestionado externamente (sincronizado con de/abo.php)
|
||||
'abo_extern_done' => 'gestionado externamente',
|
||||
'error_user_has_initiated_abo' => 'Ya se ha creado una suscripción para ti o su pago aún está en curso. Por favor, comprueba el estado en «Mis suscripciones».',
|
||||
'pending_payment_waiting_title' => 'Suscripción creada: pago aún no confirmado',
|
||||
'pending_payment_waiting_copy' => 'El pago se ha completado. Todavía estamos esperando el estado de pago del proveedor de pago. Mientras no se reciba ningún estado, esta entrada no se puede eliminar.',
|
||||
'pending_payment_processing_title' => 'Suscripción creada: pago en proceso',
|
||||
'pending_payment_processing_copy' => 'El proveedor de pago ya ha proporcionado un estado. Por favor, espera la confirmación final del pago.',
|
||||
'pending_payment_failed_title' => 'Pago fallido',
|
||||
'pending_payment_failed_copy' => 'El pago de esta suscripción no se pudo completar. Puedes eliminar esta entrada y luego volver a crear la suscripción.',
|
||||
'pending_delete_button' => 'Eliminar entrada',
|
||||
'pending_delete_success' => 'La entrada de suscripción no confirmada se ha eliminado.',
|
||||
'pending_delete_not_allowed' => 'Esta entrada de suscripción aún no se puede eliminar porque el pago aún no ha fallado definitivamente.',
|
||||
'payment_link_sent_title' => 'Enlace de pago de suscripción enviado',
|
||||
'payment_link_sent_copy' => 'El enlace de pago se ha enviado al cliente. Mientras no se haya iniciado ningún pago, esta entrada se puede eliminar.',
|
||||
'payment_link_processing_copy' => 'El cliente ha iniciado el pago. Estamos esperando el estado de pago final del proveedor de pago. En este estado, la entrada no se puede eliminar.',
|
||||
'payment_link_failed_copy' => 'El pago de este enlace de pago de suscripción ha fallado o se ha cancelado. Puedes eliminar la entrada y luego crear un nuevo enlace de pago.',
|
||||
'payment_link_delete_success' => 'El enlace de pago de suscripción se ha eliminado.',
|
||||
'payment_link_delete_not_allowed' => 'Este enlace de pago no se puede eliminar actualmente porque el pago ya está en curso o se ha completado.',
|
||||
'extern_done' => 'Gestionado externamente',
|
||||
'extern_done_confirm_title' => 'Marcar el pedido como gestionado externamente',
|
||||
'extern_done_confirm_copy' => 'El pedido se marcará como entregado y facturado fuera del sistema. NO se generará ninguna factura ni ningún albarán, el estado permanece como no pagado. Los puntos de la suscripción se abonarán y se levantará el bloqueo de la suscripción, de modo que vuelva a funcionar normalmente en la próxima fecha.',
|
||||
'extern_done_confirm_button' => 'Marcar como gestionado',
|
||||
'extern_done_only_abo' => 'Esta acción solo es posible para pedidos de suscripción.',
|
||||
'extern_done_no_order' => 'No se encontró ningún pedido de suscripción en espera que se pueda gestionar.',
|
||||
'extern_done_already' => 'Este pedido ya se ha marcado como gestionado externamente.',
|
||||
'extern_done_already_paid' => 'Este pedido ya está pagado y no se puede gestionar externamente.',
|
||||
'extern_done_success' => 'El pedido se ha marcado como gestionado externamente. Puntos abonados, bloqueo levantado.',
|
||||
'extern_done_error' => 'El pedido no se pudo marcar como gestionado: :error',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -44,4 +44,5 @@ return [
|
|||
'language_settings' => 'Configuración de idioma',
|
||||
'preferred_language' => 'Idioma preferido',
|
||||
'language_hint' => 'Este idioma se utilizará para sus facturas, extractos de comisiones y albaranes.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'cancel' => 'cancelar',
|
||||
'confirm' => 'confirmar',
|
||||
'file_is_too_big' => 'El archivo es demasiado grande<br>máx. $0MB',
|
||||
'image_too_small' => 'Imagen demasiado pequeña <br>min. $0 píxeles',
|
||||
'invalid_file' => 'Archivo no válido<br>solo por favor: $0',
|
||||
'really_delete_picture' => '¿Realmente eliminar una imagen?',
|
||||
'rotate' => 'doblar',
|
||||
'save_image' => 'guardar imagen',
|
||||
'search_file_or_drag_drop' => 'Buscar archivo o arrastrar y soltar',
|
||||
'upload_photo' => 'subir foto',
|
||||
);
|
||||
return [
|
||||
'cancel' => 'cancelar',
|
||||
'confirm' => 'confirmar',
|
||||
'file_is_too_big' => 'El archivo es demasiado grande<br>máx. $0MB',
|
||||
'image_too_small' => 'Imagen demasiado pequeña <br>min. $0 píxeles',
|
||||
'invalid_file' => 'Archivo no válido<br>solo por favor: $0',
|
||||
'really_delete_picture' => '¿Realmente eliminar una imagen?',
|
||||
'rotate' => 'doblar',
|
||||
'save_image' => 'guardar imagen',
|
||||
'search_file_or_drag_drop' => 'Buscar archivo o arrastrar y soltar',
|
||||
'upload_photo' => 'subir foto',
|
||||
'' => '',
|
||||
'dictDefaultMessage' => 'Suelta los archivos aquí para subirlos',
|
||||
'dictFallbackMessage' => 'Tu navegador no admite la subida de archivos arrastrando y soltando.',
|
||||
'dictFallbackText' => 'Utiliza el formulario alternativo de abajo para subir tus archivos como antaño',
|
||||
'dictFileTooBig' => 'El archivo es demasiado grande ({{filesize}}MiB). Tamaño máximo: {{maxFilesize}}MiB.',
|
||||
'dictInvalidFileType' => 'No puedes subir archivos de este tipo.',
|
||||
'dictResponseError' => 'El servidor respondió con el código {{statusCode}}.',
|
||||
'dictCancelUpload' => 'Cancelar subida',
|
||||
'dictRemoveFile' => 'Eliminar archivo',
|
||||
'dictMaxFilesExceeded' => 'No puedes subir más archivos.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'failed' => 'Esta combinación de credenciales no se encontró en nuestra base de datos.',
|
||||
'throttle' => 'Demasiados intentos de inicio de sesión. Inténtelo de nuevo en :segundos segundos.',
|
||||
);
|
||||
return [
|
||||
'failed' => 'Esta combinación de credenciales no se encontró en nuestra base de datos.',
|
||||
'throttle' => 'Demasiados intentos de inicio de sesión. Inténtelo de nuevo en :segundos segundos.',
|
||||
'not_found' => 'Este correo electrónico no está registrado.',
|
||||
'failed_customer' => 'Este correo electrónico no se encontró en nuestra base de datos.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -32,4 +32,7 @@ return [
|
|||
'select' => 'seleccione',
|
||||
'under_review' => 'en examen',
|
||||
'language_hint' => 'Las facturas y documentos se crearán en este idioma.',
|
||||
'delete_customer' => 'Eliminar cliente',
|
||||
'deleted_successfully' => 'El cliente se eliminó correctamente',
|
||||
'delete_customer_confirm' => '¿Estás seguro de que quieres eliminar este cliente?',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -122,4 +122,14 @@ return [
|
|||
'dhl_tracking_order_ref' => 'Número de pedido: :order',
|
||||
'dhl_tracking_button' => 'Rastrear envío con DHL',
|
||||
'dhl_tracking_info' => 'Puedes consultar el estado actual de tu envío en cualquier momento a través del botón de arriba en DHL.',
|
||||
|
||||
// Productos únicos de suscripción: recordatorio antes de la ejecución
|
||||
'abo_reminder_subject' => 'Tu próxima entrega de suscripción se acerca – añade productos ahora',
|
||||
'abo_reminder_title' => 'Tu próxima entrega de suscripción se acerca',
|
||||
'abo_reminder_intro' => '{1}Tu próxima entrega de suscripción se realizará en :days día (el :date).|[2,*]Tu próxima entrega de suscripción se realizará en :days días (el :date).',
|
||||
'abo_reminder_onetime_hint' => 'Ahora puedes añadir a esta entrega, por una sola vez, más productos de nuestra gama, sin gastos de envío adicionales ni un segundo envío.',
|
||||
'abo_reminder_coverage_hint' => 'Asegúrate de que tu método de pago registrado cubra el importe total (suscripción + productos adicionales).',
|
||||
'abo_reminder_sustainability_hint' => 'Juntos ahorramos embalaje y una segunda ruta de transporte, bueno para el medio ambiente.',
|
||||
'abo_reminder_button_consultant' => 'Añadir productos a la entrega',
|
||||
'abo_reminder_button_customer' => 'Añadir productos a la entrega',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'gtc' => 'Términos y condiciones generales de negocio',
|
||||
'gtc_copy1' => '<strong>Información básica</strong><br> 1) Los siguientes términos y condiciones se aplican a todos los contratos que celebre con nosotros como proveedor (mivita care gmbh) a través del sitio web www.mivita.care. La gama de productos de nuestra tienda online está dirigida exclusivamente a clientes adultos. Ya se objeta la inclusión de términos y condiciones generales de clientes que contradigan estos términos y condiciones. El idioma del contrato es el alemán. Puede acceder e imprimir estos términos y condiciones en nuestro sitio web. <br> <br> 2) No guardamos el texto completo del contrato. Podrás imprimir los datos del contrato o guardarlos electrónicamente mediante el sistema de carrito de compra online antes de enviar tu pedido. Tras recibir tu pedido, te enviaremos de nuevo por correo electrónico los detalles del mismo, la información legalmente requerida para los contratos de venta a distancia y los términos y condiciones generales. <br><br>',
|
||||
'gtc_copy2' => '<strong>Información básica</strong><br> 1) Nuestras ofertas de productos en Internet no son vinculantes y no representan una oferta vinculante para celebrar un contrato. Puede realizar un pedido, es decir, una oferta de compra vinculante, a través de nuestro Sistema de carrito de compras en línea. Para ello, coloque los productos que desea adquirir en el “carrito de compras”. Podrás utilizar el botón correspondiente en la barra de navegación para acceder al “carrito de compras” y realizar allí cambios en cualquier momento. Después de acceder a la página "Pagar" e ingresar sus datos personales, así como las condiciones de pago y envío, todos los datos del pedido se mostrarán nuevamente en una descripción general del pedido. Aquí tienes la oportunidad de comprobar nuevamente toda la información antes de enviar tu pedido, cambiarla (también usando la función “atrás” del navegador de Internet) o cancelar la compra. Al enviar el pedido mediante el botón "Comprar", usted hace una oferta vinculante para celebrar el contrato. A continuación, recibirá una confirmación automática de recepción por correo electrónico, que aún no da lugar a la celebración del contrato. <br><br> (2) Podemos aceptar su oferta dentro de 2 días enviando una confirmación de pedido por correo electrónico. Si no recibe el mensaje correspondiente dentro de este período, ya no estará vinculado a su pedido. En este caso, le reembolsaremos inmediatamente cualquier servicio que ya haya prestado. <br><br> (3) El procesamiento del pedido y la transmisión de toda la información necesaria en relación con la celebración del contrato se realiza parcialmente de forma automatizada por correo electrónico. Por lo tanto, debe asegurarse de que la dirección de correo electrónico que nos proporciona sea correcta, de que la recepción de los correos electrónicos esté técnicamente asegurada y, en particular, de que no la impidan los filtros de SPAM. <br><br>',
|
||||
'gtc_copy3' => '<strong>§ 3 Precios/Métodos de pago</strong><br> (1) Los precios indicados en nuestras ofertas, así como los gastos de envío, representan precios totales e incluyen todos los componentes del precio, incluidos todos los impuestos aplicables. <br><br> (2) Los gastos de envío no están incluidos en el precio de compra. Se puede acceder a ellos a través del botón correspondiente en nuestro sitio web o en la descripción del artículo correspondiente. Los costos de envío seguirán mostrándose por separado durante el proceso de pedido y deberán ser asumidos adicionalmente por usted a menos que se garantice el envío gratuito. <br><br> (3) Te ofrecemos varios métodos de pago. Estos se muestran bajo el botón correspondiente en nuestro sitio web o en la descripción del artículo correspondiente. A menos que se indique lo contrario, los derechos de pago derivados del contrato celebrado deberán pagarse inmediatamente. <br><br>',
|
||||
'gtc_copy4' => '<strong>§ 4 Condiciones de entrega</strong><br> (1) Puede acceder a las condiciones de entrega, las fechas de entrega y las restricciones de entrega existentes mediante el botón correspondiente en nuestro sitio web o en la descripción del artículo respectivo. <br><br> (2) Para los consumidores, el riesgo de pérdida accidental y deterioro accidental del artículo vendido durante el envío sólo pasa al consumidor cuando se le entrega la mercancía. Esto es independientemente de si el envío está asegurado o no. Sin embargo, esto no se aplica si usted ha contratado de forma independiente una empresa de transporte no designada por el empresario u otra persona designada para realizar el envío. <br><br> (3) Para los empresarios, la entrega y el envío se realizan bajo su propia responsabilidad. <br><br>',
|
||||
'gtc_copy5' => '<strong>§ 5 Derecho de retención, reserva de propiedad</strong><br> (1) Sólo podrá ejercer un derecho de retención si se trata de reclamaciones derivadas de la misma relación contractual. <br><br> (2) La mercancía seguirá siendo de nuestra propiedad hasta el pago total del precio de compra. <br><br> (3) Para empresarios también se aplica lo siguiente: <br><br> - Nos reservamos la propiedad de la mercancía hasta que se hayan liquidado íntegramente todas las reclamaciones derivadas de la relación comercial en curso. No se permite la pignoración o transferencia de garantía antes de que se transfiera la propiedad de los bienes reservados. <br> - Usted podrá revender los productos en el curso normal del negocio. En este caso, usted nos cede todos los derechos por el importe de la factura que surjan de la reventa. Aceptamos la cesión, pero usted está autorizado a cobrar las reclamaciones. Si no cumple adecuadamente con sus obligaciones de pago, nos reservamos el derecho de cobrar las reclamaciones nosotros mismos. <br> - Si los bienes reservados se combinan o mezclan, adquirimos la copropiedad del nuevo artículo en la proporción del valor de factura de los bienes reservados con respecto a los demás artículos procesados en el momento del procesamiento. <br> - Nos comprometemos a liberar los títulos a los que tenemos derecho previa solicitud en la medida en que el valor realizable de nuestros títulos supere en más del 10% los derechos a garantizar. Somos responsables de seleccionar los valores a liberar. <br><br>',
|
||||
'gtc_copy6' => '<strong>§ 6 Garantía</strong><br> (1) Se aplican los derechos legales de responsabilidad por defectos. <br><br> (2) Para los empresarios, a diferencia del párrafo 1, se aplica lo siguiente: <br><br> - como empresario, debe inspeccionar la mercancía inmediatamente y con la debida atención para detectar desviaciones en calidad y cantidad e informar cualquier defectos obvios dentro de los 7 días siguientes a la recepción de la mercancía por escrito. El plazo es suficiente para el envío oportuno. Esto también se aplica a los defectos ocultos descubiertos posteriormente. Si no cumple con su obligación de inspeccionar y comunicar reclamaciones, quedará excluido el ejercicio de derechos de garantía. <br> - Si hay defectos, podemos, a nuestra discreción, ofrecer una garantía mediante reparación o entrega de reemplazo. Si la eliminación del defecto fracasa, podrá optar por exigir una reducción del precio o desistir del contrato. La eliminación de los defectos se considerará fallida tras un segundo intento fallido, a menos que la naturaleza del artículo o el defecto u otras circunstancias indiquen lo contrario. En caso de reparación, no tenemos que soportar los mayores costes que se derivan del traslado de la mercancía a un lugar distinto del lugar de cumplimiento si la entrega no corresponde al uso previsto de la mercancía. <br> - el período de garantía es de un año a partir de la entrega de la mercancía. El período de garantía reducido no se aplica a los daños causados culposamente que nos sean imputables como resultado de daños a la vida, el cuerpo o la salud y los daños causados por negligencia grave o dolo o fraude, así como a las reclamaciones de recurso de conformidad con los artículos 478 y 479 de la Ley alemana. Código Civil (BGB). <br><br>',
|
||||
'gtc_copy7' => '<strong>§ 7 Responsabilidad</strong><br> (1) Somos totalmente responsables de los daños resultantes de lesiones a la vida, el cuerpo o la salud. Además, somos responsables sin limitación en todos los casos de dolo y negligencia grave, en caso de ocultación fraudulenta de un defecto, en caso de garantía de la calidad del artículo adquirido y en todos los demás casos regulados por la ley. <br> (2) Si se ven afectadas obligaciones contractuales esenciales, nuestra responsabilidad en caso de negligencia leve se limita a los daños previsibles típicos del contrato. Las obligaciones contractuales esenciales son obligaciones esenciales que surgen de la naturaleza del contrato y cuya violación pondría en peligro la consecución del objeto del contrato, así como obligaciones que el contrato nos impone según su contenido para lograr el objeto del contrato. , cuyo cumplimiento hace posible en primer lugar la correcta ejecución del contrato y en cuyo cumplimiento usted puede confiar regularmente. <br><br>',
|
||||
'gtc_copy8' => '<strong>§ 8 Disposiciones finales</strong><br> (1) Se aplica el derecho alemán. Para los consumidores, esta elección de ley sólo se aplica en la medida en que no se retire la protección otorgada por las disposiciones imperativas de la ley del país de residencia habitual del consumidor (principio de favorabilidad). Las disposiciones de la Convención de las Naciones Unidas sobre Contratos de Compraventa Internacional de Mercaderías no se aplican expresamente. <br><br> (2) El lugar de prestación de todos los servicios derivados de las relaciones comerciales existentes con nosotros y el lugar de jurisdicción es nuestro domicilio social, siempre que usted no sea un consumidor sino un comerciante, una persona jurídica de derecho público o un fondo especial de derecho público. Lo mismo se aplica si usted no tiene un lugar de jurisdicción general en Alemania o la UE o si su lugar de residencia o residencia habitual no se conoce en el momento de presentar la demanda. Esto no afecta al derecho a recurrir ante un tribunal de otra jurisdicción legal. <br><br>',
|
||||
'gtc_copy9' => 'A la fecha: 5 de octubre de 2018 <br><br>',
|
||||
);
|
||||
return [
|
||||
'gtc' => 'Términos y condiciones generales de negocio',
|
||||
'gtc_copy1' => '<strong>Información básica</strong><br> 1) Los siguientes términos y condiciones se aplican a todos los contratos que celebre con nosotros como proveedor (mivita care gmbh) a través del sitio web www.mivita.care. La gama de productos de nuestra tienda online está dirigida exclusivamente a clientes adultos. Ya se objeta la inclusión de términos y condiciones generales de clientes que contradigan estos términos y condiciones. El idioma del contrato es el alemán. Puede acceder e imprimir estos términos y condiciones en nuestro sitio web. <br> <br> 2) No guardamos el texto completo del contrato. Podrás imprimir los datos del contrato o guardarlos electrónicamente mediante el sistema de carrito de compra online antes de enviar tu pedido. Tras recibir tu pedido, te enviaremos de nuevo por correo electrónico los detalles del mismo, la información legalmente requerida para los contratos de venta a distancia y los términos y condiciones generales. <br><br>',
|
||||
'gtc_copy2' => '<strong>Información básica</strong><br> 1) Nuestras ofertas de productos en Internet no son vinculantes y no representan una oferta vinculante para celebrar un contrato. Puede realizar un pedido, es decir, una oferta de compra vinculante, a través de nuestro Sistema de carrito de compras en línea. Para ello, coloque los productos que desea adquirir en el “carrito de compras”. Podrás utilizar el botón correspondiente en la barra de navegación para acceder al “carrito de compras” y realizar allí cambios en cualquier momento. Después de acceder a la página "Pagar" e ingresar sus datos personales, así como las condiciones de pago y envío, todos los datos del pedido se mostrarán nuevamente en una descripción general del pedido. Aquí tienes la oportunidad de comprobar nuevamente toda la información antes de enviar tu pedido, cambiarla (también usando la función “atrás” del navegador de Internet) o cancelar la compra. Al enviar el pedido mediante el botón "Comprar", usted hace una oferta vinculante para celebrar el contrato. A continuación, recibirá una confirmación automática de recepción por correo electrónico, que aún no da lugar a la celebración del contrato. <br><br> (2) Podemos aceptar su oferta dentro de 2 días enviando una confirmación de pedido por correo electrónico. Si no recibe el mensaje correspondiente dentro de este período, ya no estará vinculado a su pedido. En este caso, le reembolsaremos inmediatamente cualquier servicio que ya haya prestado. <br><br> (3) El procesamiento del pedido y la transmisión de toda la información necesaria en relación con la celebración del contrato se realiza parcialmente de forma automatizada por correo electrónico. Por lo tanto, debe asegurarse de que la dirección de correo electrónico que nos proporciona sea correcta, de que la recepción de los correos electrónicos esté técnicamente asegurada y, en particular, de que no la impidan los filtros de SPAM. <br><br>',
|
||||
'gtc_copy3' => '<strong>§ 3 Precios/Métodos de pago</strong><br> (1) Los precios indicados en nuestras ofertas, así como los gastos de envío, representan precios totales e incluyen todos los componentes del precio, incluidos todos los impuestos aplicables. <br><br> (2) Los gastos de envío no están incluidos en el precio de compra. Se puede acceder a ellos a través del botón correspondiente en nuestro sitio web o en la descripción del artículo correspondiente. Los costos de envío seguirán mostrándose por separado durante el proceso de pedido y deberán ser asumidos adicionalmente por usted a menos que se garantice el envío gratuito. <br><br> (3) Te ofrecemos varios métodos de pago. Estos se muestran bajo el botón correspondiente en nuestro sitio web o en la descripción del artículo correspondiente. A menos que se indique lo contrario, los derechos de pago derivados del contrato celebrado deberán pagarse inmediatamente. <br><br>',
|
||||
'gtc_copy4' => '<strong>§ 4 Condiciones de entrega</strong><br> (1) Puede acceder a las condiciones de entrega, las fechas de entrega y las restricciones de entrega existentes mediante el botón correspondiente en nuestro sitio web o en la descripción del artículo respectivo. <br><br> (2) Para los consumidores, el riesgo de pérdida accidental y deterioro accidental del artículo vendido durante el envío sólo pasa al consumidor cuando se le entrega la mercancía. Esto es independientemente de si el envío está asegurado o no. Sin embargo, esto no se aplica si usted ha contratado de forma independiente una empresa de transporte no designada por el empresario u otra persona designada para realizar el envío. <br><br> (3) Para los empresarios, la entrega y el envío se realizan bajo su propia responsabilidad. <br><br>',
|
||||
'gtc_copy5' => '<strong>§ 5 Derecho de retención, reserva de propiedad</strong><br> (1) Sólo podrá ejercer un derecho de retención si se trata de reclamaciones derivadas de la misma relación contractual. <br><br> (2) La mercancía seguirá siendo de nuestra propiedad hasta el pago total del precio de compra. <br><br> (3) Para empresarios también se aplica lo siguiente: <br><br> - Nos reservamos la propiedad de la mercancía hasta que se hayan liquidado íntegramente todas las reclamaciones derivadas de la relación comercial en curso. No se permite la pignoración o transferencia de garantía antes de que se transfiera la propiedad de los bienes reservados. <br> - Usted podrá revender los productos en el curso normal del negocio. En este caso, usted nos cede todos los derechos por el importe de la factura que surjan de la reventa. Aceptamos la cesión, pero usted está autorizado a cobrar las reclamaciones. Si no cumple adecuadamente con sus obligaciones de pago, nos reservamos el derecho de cobrar las reclamaciones nosotros mismos. <br> - Si los bienes reservados se combinan o mezclan, adquirimos la copropiedad del nuevo artículo en la proporción del valor de factura de los bienes reservados con respecto a los demás artículos procesados en el momento del procesamiento. <br> - Nos comprometemos a liberar los títulos a los que tenemos derecho previa solicitud en la medida en que el valor realizable de nuestros títulos supere en más del 10% los derechos a garantizar. Somos responsables de seleccionar los valores a liberar. <br><br>',
|
||||
'gtc_copy6' => '<strong>§ 6 Garantía</strong><br> (1) Se aplican los derechos legales de responsabilidad por defectos. <br><br> (2) Para los empresarios, a diferencia del párrafo 1, se aplica lo siguiente: <br><br> - como empresario, debe inspeccionar la mercancía inmediatamente y con la debida atención para detectar desviaciones en calidad y cantidad e informar cualquier defectos obvios dentro de los 7 días siguientes a la recepción de la mercancía por escrito. El plazo es suficiente para el envío oportuno. Esto también se aplica a los defectos ocultos descubiertos posteriormente. Si no cumple con su obligación de inspeccionar y comunicar reclamaciones, quedará excluido el ejercicio de derechos de garantía. <br> - Si hay defectos, podemos, a nuestra discreción, ofrecer una garantía mediante reparación o entrega de reemplazo. Si la eliminación del defecto fracasa, podrá optar por exigir una reducción del precio o desistir del contrato. La eliminación de los defectos se considerará fallida tras un segundo intento fallido, a menos que la naturaleza del artículo o el defecto u otras circunstancias indiquen lo contrario. En caso de reparación, no tenemos que soportar los mayores costes que se derivan del traslado de la mercancía a un lugar distinto del lugar de cumplimiento si la entrega no corresponde al uso previsto de la mercancía. <br> - el período de garantía es de un año a partir de la entrega de la mercancía. El período de garantía reducido no se aplica a los daños causados culposamente que nos sean imputables como resultado de daños a la vida, el cuerpo o la salud y los daños causados por negligencia grave o dolo o fraude, así como a las reclamaciones de recurso de conformidad con los artículos 478 y 479 de la Ley alemana. Código Civil (BGB). <br><br>',
|
||||
'gtc_copy7' => '<strong>§ 7 Responsabilidad</strong><br> (1) Somos totalmente responsables de los daños resultantes de lesiones a la vida, el cuerpo o la salud. Además, somos responsables sin limitación en todos los casos de dolo y negligencia grave, en caso de ocultación fraudulenta de un defecto, en caso de garantía de la calidad del artículo adquirido y en todos los demás casos regulados por la ley. <br> (2) Si se ven afectadas obligaciones contractuales esenciales, nuestra responsabilidad en caso de negligencia leve se limita a los daños previsibles típicos del contrato. Las obligaciones contractuales esenciales son obligaciones esenciales que surgen de la naturaleza del contrato y cuya violación pondría en peligro la consecución del objeto del contrato, así como obligaciones que el contrato nos impone según su contenido para lograr el objeto del contrato. , cuyo cumplimiento hace posible en primer lugar la correcta ejecución del contrato y en cuyo cumplimiento usted puede confiar regularmente. <br><br>',
|
||||
'gtc_copy8' => '<strong>§ 8 Disposiciones finales</strong><br> (1) Se aplica el derecho alemán. Para los consumidores, esta elección de ley sólo se aplica en la medida en que no se retire la protección otorgada por las disposiciones imperativas de la ley del país de residencia habitual del consumidor (principio de favorabilidad). Las disposiciones de la Convención de las Naciones Unidas sobre Contratos de Compraventa Internacional de Mercaderías no se aplican expresamente. <br><br> (2) El lugar de prestación de todos los servicios derivados de las relaciones comerciales existentes con nosotros y el lugar de jurisdicción es nuestro domicilio social, siempre que usted no sea un consumidor sino un comerciante, una persona jurídica de derecho público o un fondo especial de derecho público. Lo mismo se aplica si usted no tiene un lugar de jurisdicción general en Alemania o la UE o si su lugar de residencia o residencia habitual no se conoce en el momento de presentar la demanda. Esto no afecta al derecho a recurrir ante un tribunal de otra jurisdicción legal. <br><br>',
|
||||
'gtc_copy9' => 'A la fecha: 5 de octubre de 2018 <br><br>',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -57,4 +57,5 @@ return [
|
|||
'own' => 'Propio',
|
||||
'live_calculation_hint' => 'Cálculo en vivo (no finalizado)',
|
||||
'live_calculation_hint_text' => 'Se calculará al final del mes.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,73 +1,74 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'acceptect_data_protection' => 'Por la presente doy mi consentimiento para el procesamiento de datos mencionado en: protección de datos',
|
||||
'add_as_guest' => 'registrarse como invitado',
|
||||
'add_product' => 'agregar producto',
|
||||
'completed' => 'terminado',
|
||||
'confirm_my_data_is_correct_and_complete' => 'Confirmo que mis datos son correctos y completos. Después del envío, el cambio solo es posible a través de mi asesor personal MIVITA.*',
|
||||
'copy' => '¡Copiado!',
|
||||
'copy_link' => 'copiar link',
|
||||
'copy_link_info' => 'Comparte este enlace con los invitados (por ejemplo, WhatsApp o SMS) para llevarlos a una página de destino donde ellos mismos podrán completar sus datos. Utilice el "símbolo de copia" para copiar el enlace directamente a su portapapeles.',
|
||||
'country_can_no_longer_be_changed_after_created' => 'El país de entrega no se puede cambiar una vez creado. Todas las direcciones de envío deben estar en este país.',
|
||||
'create_delivery_address_host_info' => 'La dirección de entrega y el host aún no se han creado.',
|
||||
'create_guest' => 'crear invitado',
|
||||
'create_guests' => 'crear invitados',
|
||||
'create_guests_info' => 'Luego se pueden crear invitados y realizar pedidos.',
|
||||
'create_new_homeparty' => 'Recrea la fiesta de descanso',
|
||||
'credit_bonus' => 'bonificación de crédito',
|
||||
'credit_homeparty_voucher' => 'bono de fiesta de descanso de crédito',
|
||||
'current_bonus_view' => 'vista de bonificación actual',
|
||||
'data_protection' => 'protección de Datos',
|
||||
'data_protection_reasons_your_personal_data_will_not_be_shown' => 'Nota: Por motivos de protección de datos, sus datos personales no se mostrarán aquí a otros participantes. Una vez enviados, ya no se pueden editar. Si desea realizar un cambio más adelante, comuníquese con su asesor personal de MIVITA.',
|
||||
'deduct_points_by_voucher' => 'deducción de puntos mediante bono',
|
||||
'delivery_address_homeparty' => 'Dirección de entrega de la fiesta de descanso',
|
||||
'delivery_directly_to_the_guest' => 'entrega directamente al huésped.',
|
||||
'delivery_to_host' => 'entrega al anfitrión',
|
||||
'description_welcome_text' => 'descripción/texto de bienvenida',
|
||||
'enter_your_personal_data_for_homeparty' => 'Introduce tus datos personales para la fiesta de descanso',
|
||||
'event_date' => 'fecha del evento',
|
||||
'event_place' => 'evento',
|
||||
'from' => 'lejos',
|
||||
'general_overview' => 'visión general',
|
||||
'guest' => 'invitado',
|
||||
'guest_delete_really' => '¿Realmente eliminar invitado?',
|
||||
'guest_lists' => 'lista de invitados',
|
||||
'guest_order_sent_directly_info' => 'Si un huésped desea que su pedido se envíe directamente a su dirección personal, puede especificarlo por separado durante el proceso de pedido.',
|
||||
'guests' => 'invitados',
|
||||
'homeparty' => 'Fiesta de descanso',
|
||||
'homeparty_add_host_address_info' => 'Ingrese la dirección del anfitrión donde se organiza la fiesta de descanso.',
|
||||
'homeparty_delete_really' => '¿Realmente eliminar la fiesta de descanso?',
|
||||
'homeparty_invoice_info' => 'La factura de mivita se enviará a su dirección (consultor). Usted es responsable de facturar al anfitrión y a los invitados.',
|
||||
'homeparty_manage' => 'gestionar fiesta de descanso',
|
||||
'host' => 'anfitriona',
|
||||
'host_address_save' => 'guardar dirección de host',
|
||||
'host_can_not_delete' => 'el host no se puede eliminar',
|
||||
'host_homeparty' => 'anfitrión: fiesta de descanso',
|
||||
'host_organiser_event' => 'anfitrión/organizador',
|
||||
'invitation' => 'invitación',
|
||||
'invitation_link_for_guests' => 'enlace de invitación para invitados.',
|
||||
'invoice_address' => 'dirección de Envio',
|
||||
'let_your_guests_fill_in_their_own_details' => 'deja que tus invitados rellenen ellos mismos sus datos',
|
||||
'manage' => 'administrar',
|
||||
'missing' => 'sigue desaparecido',
|
||||
'next_bonus' => 'próximo bono',
|
||||
'order' => 'orden',
|
||||
'order_can_be_send_delivery_address_info' => 'El pedido sólo podrá enviarse una vez creada la dirección de entrega del anfitrión.',
|
||||
'order_create' => 'crear orden',
|
||||
'order_host' => 'anfitrión del pedido',
|
||||
'order_show' => 'ver pedido',
|
||||
'please_enter_delivery_address_info' => 'Ingrese aquí la dirección de entrega central de los pedidos realizados para esta fiesta de tiempo de espera. Esta puede ser su propia dirección o la del anfitrión. Dependiendo de cómo quieras organizar la distribución de los productos con tus invitados.',
|
||||
'revoke_consent_at_any_time' => 'Me han informado que puedo revocar este consentimiento en cualquier momento.*',
|
||||
'shipping_costs_host' => 'gastos de envío para el anfitrión.',
|
||||
'target_turnover' => 'ventas objetivo',
|
||||
'voucher' => 'cupón',
|
||||
'voucher_bonus' => 'bono de vale',
|
||||
'voucher_bonus_cannot_be_applied' => 'El cupón/bono no se puede aplicar porque el anfitrión no ha agregado ningún producto.',
|
||||
'voucher_total' => 'bono total',
|
||||
'welcome_copy' => 'Bienvenidos a nuestra fiesta de descando sobre aloe vera ecológico y cosmética natural. Le informaremos sobre lo que realmente significa calidad superior en cosmética natural, le mostraremos muchos ejemplos de aplicaciones para problemas de la piel y los intestinos y, por supuesto, podrá probar nuestros productos exhaustivamente. ¡Esperamos verte!',
|
||||
'your_MIVITA_advice' => 'tu consejo MIVITA',
|
||||
'your_data_has_been_successfully_created_have_fun' => 'Tus datos han sido creados exitosamente. ¡Diviértete en la fiesta de descanso!',
|
||||
'your_host' => 'tu anfitrión',
|
||||
'your_hostess' => 'tu anfitriona',
|
||||
);
|
||||
return [
|
||||
'acceptect_data_protection' => 'Por la presente doy mi consentimiento para el procesamiento de datos mencionado en: protección de datos',
|
||||
'add_as_guest' => 'registrarse como invitado',
|
||||
'add_product' => 'agregar producto',
|
||||
'completed' => 'terminado',
|
||||
'confirm_my_data_is_correct_and_complete' => 'Confirmo que mis datos son correctos y completos. Después del envío, el cambio solo es posible a través de mi asesor personal MIVITA.*',
|
||||
'copy' => '¡Copiado!',
|
||||
'copy_link' => 'copiar link',
|
||||
'copy_link_info' => 'Comparte este enlace con los invitados (por ejemplo, WhatsApp o SMS) para llevarlos a una página de destino donde ellos mismos podrán completar sus datos. Utilice el "símbolo de copia" para copiar el enlace directamente a su portapapeles.',
|
||||
'country_can_no_longer_be_changed_after_created' => 'El país de entrega no se puede cambiar una vez creado. Todas las direcciones de envío deben estar en este país.',
|
||||
'create_delivery_address_host_info' => 'La dirección de entrega y el host aún no se han creado.',
|
||||
'create_guest' => 'crear invitado',
|
||||
'create_guests' => 'crear invitados',
|
||||
'create_guests_info' => 'Luego se pueden crear invitados y realizar pedidos.',
|
||||
'create_new_homeparty' => 'Recrea la fiesta de descanso',
|
||||
'credit_bonus' => 'bonificación de crédito',
|
||||
'credit_homeparty_voucher' => 'bono de fiesta de descanso de crédito',
|
||||
'current_bonus_view' => 'vista de bonificación actual',
|
||||
'data_protection' => 'protección de Datos',
|
||||
'data_protection_reasons_your_personal_data_will_not_be_shown' => 'Nota: Por motivos de protección de datos, sus datos personales no se mostrarán aquí a otros participantes. Una vez enviados, ya no se pueden editar. Si desea realizar un cambio más adelante, comuníquese con su asesor personal de MIVITA.',
|
||||
'deduct_points_by_voucher' => 'deducción de puntos mediante bono',
|
||||
'delivery_address_homeparty' => 'Dirección de entrega de la fiesta de descanso',
|
||||
'delivery_directly_to_the_guest' => 'entrega directamente al huésped.',
|
||||
'delivery_to_host' => 'entrega al anfitrión',
|
||||
'description_welcome_text' => 'descripción/texto de bienvenida',
|
||||
'enter_your_personal_data_for_homeparty' => 'Introduce tus datos personales para la fiesta de descanso',
|
||||
'event_date' => 'fecha del evento',
|
||||
'event_place' => 'evento',
|
||||
'from' => 'lejos',
|
||||
'general_overview' => 'visión general',
|
||||
'guest' => 'invitado',
|
||||
'guest_delete_really' => '¿Realmente eliminar invitado?',
|
||||
'guest_lists' => 'lista de invitados',
|
||||
'guest_order_sent_directly_info' => 'Si un huésped desea que su pedido se envíe directamente a su dirección personal, puede especificarlo por separado durante el proceso de pedido.',
|
||||
'guests' => 'invitados',
|
||||
'homeparty' => 'Fiesta de descanso',
|
||||
'homeparty_add_host_address_info' => 'Ingrese la dirección del anfitrión donde se organiza la fiesta de descanso.',
|
||||
'homeparty_delete_really' => '¿Realmente eliminar la fiesta de descanso?',
|
||||
'homeparty_invoice_info' => 'La factura de mivita se enviará a su dirección (consultor). Usted es responsable de facturar al anfitrión y a los invitados.',
|
||||
'homeparty_manage' => 'gestionar fiesta de descanso',
|
||||
'host' => 'anfitriona',
|
||||
'host_address_save' => 'guardar dirección de host',
|
||||
'host_can_not_delete' => 'el host no se puede eliminar',
|
||||
'host_homeparty' => 'anfitrión: fiesta de descanso',
|
||||
'host_organiser_event' => 'anfitrión/organizador',
|
||||
'invitation' => 'invitación',
|
||||
'invitation_link_for_guests' => 'enlace de invitación para invitados.',
|
||||
'invoice_address' => 'dirección de Envio',
|
||||
'let_your_guests_fill_in_their_own_details' => 'deja que tus invitados rellenen ellos mismos sus datos',
|
||||
'manage' => 'administrar',
|
||||
'missing' => 'sigue desaparecido',
|
||||
'next_bonus' => 'próximo bono',
|
||||
'order' => 'orden',
|
||||
'order_can_be_send_delivery_address_info' => 'El pedido sólo podrá enviarse una vez creada la dirección de entrega del anfitrión.',
|
||||
'order_create' => 'crear orden',
|
||||
'order_host' => 'anfitrión del pedido',
|
||||
'order_show' => 'ver pedido',
|
||||
'please_enter_delivery_address_info' => 'Ingrese aquí la dirección de entrega central de los pedidos realizados para esta fiesta de tiempo de espera. Esta puede ser su propia dirección o la del anfitrión. Dependiendo de cómo quieras organizar la distribución de los productos con tus invitados.',
|
||||
'revoke_consent_at_any_time' => 'Me han informado que puedo revocar este consentimiento en cualquier momento.*',
|
||||
'shipping_costs_host' => 'gastos de envío para el anfitrión.',
|
||||
'target_turnover' => 'ventas objetivo',
|
||||
'voucher' => 'cupón',
|
||||
'voucher_bonus' => 'bono de vale',
|
||||
'voucher_bonus_cannot_be_applied' => 'El cupón/bono no se puede aplicar porque el anfitrión no ha agregado ningún producto.',
|
||||
'voucher_total' => 'bono total',
|
||||
'welcome_copy' => 'Bienvenidos a nuestra fiesta de descando sobre aloe vera ecológico y cosmética natural. Le informaremos sobre lo que realmente significa calidad superior en cosmética natural, le mostraremos muchos ejemplos de aplicaciones para problemas de la piel y los intestinos y, por supuesto, podrá probar nuestros productos exhaustivamente. ¡Esperamos verte!',
|
||||
'your_MIVITA_advice' => 'tu consejo MIVITA',
|
||||
'your_data_has_been_successfully_created_have_fun' => 'Tus datos han sido creados exitosamente. ¡Diviértete en la fiesta de descanso!',
|
||||
'your_host' => 'tu anfitrión',
|
||||
'your_hostess' => 'tu anfitriona',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
104
resources/lang/es/marketingplan.php
Normal file
104
resources/lang/es/marketingplan.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Traducciones del plan de marketing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Las siguientes líneas de idioma se utilizan en la vista del plan de marketing.
|
||||
| Puedes adaptarlas según tus necesidades.
|
||||
|
|
||||
*/
|
||||
|
||||
// Encabezado y título
|
||||
'title' => 'Plan de carrera Mivita',
|
||||
'subtitle' => 'Descubre tus oportunidades de ascenso y alcanza el siguiente nivel',
|
||||
'current_level' => 'Tu nivel actual:',
|
||||
|
||||
// Área de cualificación
|
||||
'qualification' => 'Cualificación',
|
||||
'kp_points' => 'Puntos VC',
|
||||
'tp_points' => 'Puntos PE',
|
||||
'customer_points_full' => 'Puntos de ventas a clientes',
|
||||
'team_points_full' => 'Puntos de equipo',
|
||||
|
||||
// Comisiones
|
||||
'provisions' => 'Comisiones',
|
||||
'standard' => 'Estándar',
|
||||
'shop' => 'Tienda',
|
||||
'provision_rates' => 'Tasas de comisión',
|
||||
|
||||
// Comisiones de equipo
|
||||
'team_provisions' => 'Comisiones de equipo',
|
||||
'team_provisions_by_lines' => 'Comisiones de equipo por líneas',
|
||||
|
||||
// Bonos
|
||||
'growth_bonus' => 'Bono de profundidad',
|
||||
|
||||
// Navegación y estado
|
||||
'next_level' => 'Siguiente nivel:',
|
||||
'your_current_level' => 'Tu nivel actual',
|
||||
'your_next_goal' => 'Tu próximo objetivo',
|
||||
|
||||
// Leyenda
|
||||
'legend' => 'Leyenda',
|
||||
'legend_ku_description' => 'Puntos de ventas a clientes',
|
||||
'legend_tp_description' => 'Puntos de equipo',
|
||||
'legend_lines_description' => 'Comisiones de equipo por líneas',
|
||||
'legend_percentage_description' => 'Tasas de comisión',
|
||||
|
||||
// Mensajes de error y estado
|
||||
'no_levels_available' => 'No hay niveles de carrera disponibles',
|
||||
'no_levels_configured' => 'Actualmente no hay niveles de carrera configurados.',
|
||||
'loading_error' => 'Error al cargar el plan de marketing:',
|
||||
|
||||
// Rendimiento y depuración
|
||||
'loading_time' => 'Tiempo de carga:',
|
||||
|
||||
// Botones y acciones
|
||||
'show_details' => 'Mostrar detalles',
|
||||
'back_to_overview' => 'Volver a la vista general',
|
||||
|
||||
// Descripciones de nivel
|
||||
'level_position' => 'Posición',
|
||||
'level_name' => 'Nombre del nivel',
|
||||
'level_requirements' => 'Requisitos',
|
||||
'level_benefits' => 'Ventajas',
|
||||
|
||||
// Paylines
|
||||
'paylines' => 'Paylines',
|
||||
'line_1' => 'Línea 1',
|
||||
'line_2' => 'Línea 2',
|
||||
'line_3' => 'Línea 3',
|
||||
'line_4' => 'Línea 4',
|
||||
'line_5' => 'Línea 5',
|
||||
'line_6' => 'Línea 6',
|
||||
'line_7' => 'Línea 7',
|
||||
'line_8' => 'Línea 8',
|
||||
|
||||
// Términos adicionales
|
||||
'points' => 'Puntos',
|
||||
'percent' => 'Por ciento',
|
||||
'euro' => 'Euro',
|
||||
'active' => 'Activo',
|
||||
'inactive' => 'Inactivo',
|
||||
'achieved' => 'Alcanzado',
|
||||
'not_achieved' => 'No alcanzado',
|
||||
'in_progress' => 'En curso',
|
||||
|
||||
// Textos de éxito y motivación
|
||||
'congratulations' => '¡Enhorabuena!',
|
||||
'keep_going' => '¡Sigue así!',
|
||||
'almost_there' => '¡Ya casi lo tienes!',
|
||||
'next_step' => 'Siguiente paso',
|
||||
'goal_reached' => 'Objetivo alcanzado',
|
||||
|
||||
// Textos de ayuda
|
||||
'help_kp_points' => 'Los puntos VC (ventas a clientes) se generan a través de tus ventas directas.',
|
||||
'help_tp_points' => 'Los puntos PE (puntos de equipo) se generan a través de las ventas de tu equipo.',
|
||||
'help_provisions' => 'Las comisiones son los porcentajes que recibes de las ventas.',
|
||||
'help_growth_bonus' => 'Los bonos de crecimiento son recompensas adicionales por el crecimiento de tu equipo.',
|
||||
|
||||
];
|
||||
|
|
@ -1,59 +1,60 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'MIVITA_BUSINESS_Paket' => 'paquete MIVITA EMPRESARIAL',
|
||||
'abo_copy_1' => 'Disminuir la prórroga automática y retirar el mandato SEPA.',
|
||||
'abo_copy_2' => 'La próxima reserva es el: <strong>:fecha </strong>',
|
||||
'abo_copy_3' => 'Por la presente confirmo que eliminaré mi SEPA y desactivaré la extensión automática.',
|
||||
'active' => 'activo',
|
||||
'active_package' => 'paquete activo',
|
||||
'alert_contract_renewal' => 'Para ampliar su afiliación como consultor, complete el pago de su paquete MIVITA reservado.',
|
||||
'booked_package' => 'paquete reservado',
|
||||
'change' => 'ajustar',
|
||||
'change_copy_1' => 'Puedes cambiar tu membresía hasta la próxima extensión de contrato, el :date.',
|
||||
'change_copy_2' => 'Los términos restantes siguen siendo los mismos; el paquete modificado sólo se activa cuando se amplía.',
|
||||
'consultant_membership' => 'membresía consultora',
|
||||
'consultant_online_shop' => 'tienda online de consultores.',
|
||||
'contract_renewal' => 'extension de contrato',
|
||||
'deactivate' => 'desactivar',
|
||||
'details' => 'detalles',
|
||||
'downgrade_membership_is_not_possible' => 'Ya no es posible bajar de categoría su membresía de asesor.',
|
||||
'end' => 'finalizar',
|
||||
'end_button' => 'cancele su membresía aquí',
|
||||
'end_checkbox' => 'Sí, me gustaría cancelar mi membresía de MIVITA, renuncio a cualquier reclamo contra MIVITA y me gustaría que se elimine mi cuenta.',
|
||||
'end_copy_1' => '¿Ya no quieres ser consultor MIVITA y cancelar tu membresía?',
|
||||
'end_copy_2' => 'Al hacerlo, estás renunciando a todo tipo de comisiones, beneficios, acceso al centro de ventas y mucho más. Al enviar esta opción recibiremos un mensaje y nos encargaremos de eliminar tu cuenta. Este proceso puede tardar unos días.',
|
||||
'end_copy_3' => 'Se ha solicitado la terminación y eliminación de su membresía MIVITA.',
|
||||
'expired_on' => 'expirado el',
|
||||
'home_copy_SEPA_32' => 'Dado que nos ha otorgado un mandato de domiciliación bancaria SEPA, no necesita realizar ninguna acción adicional. De acuerdo con este mandato, debitaremos el importe de la factura :price de su cuenta el :pay_date.',
|
||||
'home_copy_SEPA_33' => 'Von Deinem SEPA-Lastschrift-Mandat, das du uns erteilt hast, konnten wir bisher den Rechnungsbetrag :price am :pay_date nicht abbuchen.',
|
||||
'home_copy_SEPA_36' => 'Lamentablemente, no pudimos cobrar el importe adeudado por la cuota de membresía de su cuenta especificada mediante un mandato de débito directo SEPA.',
|
||||
'home_copy_alert_31' => 'Su membresía vence el :datetime',
|
||||
'home_copy_alert_35' => '¡Tu membresía vence hoy!',
|
||||
'home_copy_alert_36' => '¡Su membresía expiró hace :días días el :datetime!',
|
||||
'home_copy_alert_36_today' => '¡Su membresía vence hoy el :datetime!',
|
||||
'home_copy_last_31' => 'Todavía te quedan algunos días de relax para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_33' => 'Ahora le quedan :días días para ampliar su membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_34' => 'Vaya... ¡ahora es el momento! Su membresía vence en :days días, exactamente el :datetime. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_35' => 'Vaya... ¡ahora es el momento! Su membresía vence hoy, exactamente el :datetime. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_36' => 'Como lo anunciamos, hemos pausado su cuenta de asesor porque no renovó su membresía a tiempo. Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento.',
|
||||
'home_hl' => 'membresía / cuota anual',
|
||||
'inactive' => 'inactivo',
|
||||
'info_contract_renewal' => 'Su contrato se renovará automáticamente :días antes de que expire su afiliación como consultor. Una vez prorrogado el contrato, ya no será posible cambiar el paquete de consultor y deberá abonar su afiliación.',
|
||||
'is_no_longer_possible_to_change_package' => 'Ya no es posible cambiar su paquete de asesor.',
|
||||
'membership' => 'membresía',
|
||||
'membership_was_renewed' => 'Su contrato se prorrogó en :date.',
|
||||
'open_payment_options' => 'abrir opciones de pago',
|
||||
'payment_copy_1' => 'Alternativamente, ahora tiene la opción de pagar su membresía directamente utilizando otras opciones de pago.',
|
||||
'payment_copy_2' => 'Si la membresía se paga antes de la :date, ¡el mandato SEPA no se ejecutará!',
|
||||
'payment_has_been_made' => 'Se ha realizado un pago.',
|
||||
'renewal_is_active_membership_fee_automatic' => 'Su extensión automática está activa, cobraremos automáticamente su cuota de membresía a través del mandato SEPA el <strong>:fecha</strong>.',
|
||||
'status' => 'estado',
|
||||
'until' => 'hasta',
|
||||
'upgrade' => 'mejora',
|
||||
'upgrade_copy_1' => '¡Amplía tu membresía al paquete MIVITA BUSINESS ahora!',
|
||||
'upgrade_copy_2' => 'Se calculan los meses restantes hasta la prórroga de la membresía del consultor. El precio del paquete MIVITA BUSINESS se calculará anualmente.',
|
||||
'upgrade_package_and_proceed_payment' => 'Tiene la opción de actualizar su paquete, simplemente seleccione el paquete actualizado y proceda al pago.',
|
||||
'we_do_not_collect_membership_fee' => 'No pudimos cobrar automáticamente su cuota de membresía a través del mandato SEPA el <strong>: fecha</strong>.',
|
||||
'your_booked_package' => 'tu paquete reservado',
|
||||
);
|
||||
return [
|
||||
'MIVITA_BUSINESS_Paket' => 'paquete MIVITA EMPRESARIAL',
|
||||
'abo_copy_1' => 'Disminuir la prórroga automática y retirar el mandato SEPA.',
|
||||
'abo_copy_2' => 'La próxima reserva es el: <strong>:fecha </strong>',
|
||||
'abo_copy_3' => 'Por la presente confirmo que eliminaré mi SEPA y desactivaré la extensión automática.',
|
||||
'active' => 'activo',
|
||||
'active_package' => 'paquete activo',
|
||||
'alert_contract_renewal' => 'Para ampliar su afiliación como consultor, complete el pago de su paquete MIVITA reservado.',
|
||||
'booked_package' => 'paquete reservado',
|
||||
'change' => 'ajustar',
|
||||
'change_copy_1' => 'Puedes cambiar tu membresía hasta la próxima extensión de contrato, el :date.',
|
||||
'change_copy_2' => 'Los términos restantes siguen siendo los mismos; el paquete modificado sólo se activa cuando se amplía.',
|
||||
'consultant_membership' => 'membresía consultora',
|
||||
'consultant_online_shop' => 'tienda online de consultores.',
|
||||
'contract_renewal' => 'extension de contrato',
|
||||
'deactivate' => 'desactivar',
|
||||
'details' => 'detalles',
|
||||
'downgrade_membership_is_not_possible' => 'Ya no es posible bajar de categoría su membresía de asesor.',
|
||||
'end' => 'finalizar',
|
||||
'end_button' => 'cancele su membresía aquí',
|
||||
'end_checkbox' => 'Sí, me gustaría cancelar mi membresía de MIVITA, renuncio a cualquier reclamo contra MIVITA y me gustaría que se elimine mi cuenta.',
|
||||
'end_copy_1' => '¿Ya no quieres ser consultor MIVITA y cancelar tu membresía?',
|
||||
'end_copy_2' => 'Al hacerlo, estás renunciando a todo tipo de comisiones, beneficios, acceso al centro de ventas y mucho más. Al enviar esta opción recibiremos un mensaje y nos encargaremos de eliminar tu cuenta. Este proceso puede tardar unos días.',
|
||||
'end_copy_3' => 'Se ha solicitado la terminación y eliminación de su membresía MIVITA.',
|
||||
'expired_on' => 'expirado el',
|
||||
'home_copy_SEPA_32' => 'Dado que nos ha otorgado un mandato de domiciliación bancaria SEPA, no necesita realizar ninguna acción adicional. De acuerdo con este mandato, debitaremos el importe de la factura :price de su cuenta el :pay_date.',
|
||||
'home_copy_SEPA_33' => 'Von Deinem SEPA-Lastschrift-Mandat, das du uns erteilt hast, konnten wir bisher den Rechnungsbetrag :price am :pay_date nicht abbuchen.',
|
||||
'home_copy_SEPA_36' => 'Lamentablemente, no pudimos cobrar el importe adeudado por la cuota de membresía de su cuenta especificada mediante un mandato de débito directo SEPA.',
|
||||
'home_copy_alert_31' => 'Su membresía vence el :datetime',
|
||||
'home_copy_alert_35' => '¡Tu membresía vence hoy!',
|
||||
'home_copy_alert_36' => '¡Su membresía expiró hace :días días el :datetime!',
|
||||
'home_copy_alert_36_today' => '¡Su membresía vence hoy el :datetime!',
|
||||
'home_copy_last_31' => 'Todavía te quedan algunos días de relax para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_33' => 'Ahora le quedan :días días para ampliar su membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_34' => 'Vaya... ¡ahora es el momento! Su membresía vence en :days días, exactamente el :datetime. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_35' => 'Vaya... ¡ahora es el momento! Su membresía vence hoy, exactamente el :datetime. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.',
|
||||
'home_copy_last_36' => 'Como lo anunciamos, hemos pausado su cuenta de asesor porque no renovó su membresía a tiempo. Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento.',
|
||||
'home_hl' => 'membresía / cuota anual',
|
||||
'inactive' => 'inactivo',
|
||||
'info_contract_renewal' => 'Su contrato se renovará automáticamente :días antes de que expire su afiliación como consultor. Una vez prorrogado el contrato, ya no será posible cambiar el paquete de consultor y deberá abonar su afiliación.',
|
||||
'is_no_longer_possible_to_change_package' => 'Ya no es posible cambiar su paquete de asesor.',
|
||||
'membership' => 'membresía',
|
||||
'membership_was_renewed' => 'Su contrato se prorrogó en :date.',
|
||||
'open_payment_options' => 'abrir opciones de pago',
|
||||
'payment_copy_1' => 'Alternativamente, ahora tiene la opción de pagar su membresía directamente utilizando otras opciones de pago.',
|
||||
'payment_copy_2' => 'Si la membresía se paga antes de la :date, ¡el mandato SEPA no se ejecutará!',
|
||||
'payment_has_been_made' => 'Se ha realizado un pago.',
|
||||
'renewal_is_active_membership_fee_automatic' => 'Su extensión automática está activa, cobraremos automáticamente su cuota de membresía a través del mandato SEPA el <strong>:fecha</strong>.',
|
||||
'status' => 'estado',
|
||||
'until' => 'hasta',
|
||||
'upgrade' => 'mejora',
|
||||
'upgrade_copy_1' => '¡Amplía tu membresía al paquete MIVITA BUSINESS ahora!',
|
||||
'upgrade_copy_2' => 'Se calculan los meses restantes hasta la prórroga de la membresía del consultor. El precio del paquete MIVITA BUSINESS se calculará anualmente.',
|
||||
'upgrade_package_and_proceed_payment' => 'Tiene la opción de actualizar su paquete, simplemente seleccione el paquete actualizado y proceda al pago.',
|
||||
'we_do_not_collect_membership_fee' => 'No pudimos cobrar automáticamente su cuota de membresía a través del mandato SEPA el <strong>: fecha</strong>.',
|
||||
'your_booked_package' => 'tu paquete reservado',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -39,4 +39,5 @@ return [
|
|||
'your_shopping_cart_is_empty_please_add_products_first' => [
|
||||
'' => 'Su carrito de compras está vacío, agregue productos primero',
|
||||
],
|
||||
'cart_product_not_allowed_for_order_type' => 'El carrito contiene artículos que no están previstos para este tipo de pedido. Vacía el carrito y elige solo productos que correspondan a este pedido.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -120,4 +120,9 @@ return [
|
|||
'free_shipping' => 'Envío gratis',
|
||||
'free_shipping_reached' => 'Envío gratis a partir de :amount €',
|
||||
'free_shipping_info' => 'Solo faltan :missing € para el envío gratis (a partir de :amount €)',
|
||||
'number' => 'N.º art.',
|
||||
'reorder' => 'Volver a pedir',
|
||||
'reorder_info' => '¿Quieres volver a pedir este artículo?<br>Al hacer clic en el botón, los artículos se añadirán de nuevo al carrito y serás redirigido a la página del carrito.',
|
||||
'reorder_info_2' => 'Tu país de entrega es: :country<br>Si quieres que tu pedido se entregue en otro país, cambia tu dirección de facturación o de entrega en <a class="text-primary" href=":link">Mis datos</a>',
|
||||
'reorder_abo_not_allowed' => 'Los pedidos de suscripción no se pueden repetir mediante «Volver a pedir». Utiliza la gestión de tu suscripción o la tienda para pedidos individuales.',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -194,4 +194,6 @@ return [
|
|||
'packstation_alert_location' => 'Ubicación de la Packstation',
|
||||
'packstation_alert_not_home' => '¡no su dirección de casa!',
|
||||
'packstation_alert_footer' => 'El NÚMERO de Packstation tiene 3 dígitos (100-999, en el letrero amarillo). El número de correo DHL tiene 6-10 dígitos y va en el campo separado arriba.',
|
||||
'' => '',
|
||||
'unknown' => 'desconocido',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ return [
|
|||
'shipping_costs' => 'Gastos de envío',
|
||||
'total_amount' => 'Importe total',
|
||||
|
||||
// Productos únicos de suscripción (agrupación factura/albarán)
|
||||
'abo_items_heading' => 'Productos de suscripción',
|
||||
'abo_addon_items_heading' => 'Artículos añadidos una sola vez',
|
||||
|
||||
// Address top
|
||||
'address_top' => 'mivita care gmbh • Leinfeld 2 • 87755 Kirchhaslach',
|
||||
];
|
||||
|
|
|
|||
39
resources/lang/es/portal.php
Normal file
39
resources/lang/es/portal.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'login' => 'Iniciar sesión',
|
||||
'login_title' => 'Inicia sesión en tu cuenta de cliente',
|
||||
'login_email' => 'Tu dirección de correo electrónico',
|
||||
'login_password' => 'Contraseña',
|
||||
'login_button' => 'Iniciar sesión',
|
||||
'login_forgot_password' => '¿Has olvidado la contraseña?',
|
||||
'login_register' => 'Registrarse',
|
||||
'mail_subject' => 'Tu contraseña de un solo uso para tu cuenta de cliente de mivita.care',
|
||||
'mail_hello' => '¡Hola!',
|
||||
'mail_otp' => 'Tu contraseña de un solo uso es: ',
|
||||
'mail_otp_valid' => 'Esta contraseña es válida durante 10 minutos.',
|
||||
'mail_otp_not_requested' => 'Si no has solicitado ninguna contraseña, puedes ignorar este correo electrónico.',
|
||||
'mail_greetings' => 'Atentamente',
|
||||
'mail_sender' => 'mivita.care',
|
||||
'verify_otp_title' => 'Inicio de sesión de dos factores',
|
||||
'verify_otp_description' => 'Por favor, introduce el código que hemos enviado a tu dirección de correo electrónico.',
|
||||
'verify_otp_resend' => 'Si no recibes ningún correo electrónico en los próximos minutos, puedes volver a solicitar el código; comprueba también tu carpeta de spam.',
|
||||
'verify_otp_resend_link' => 'Volver a solicitar el código',
|
||||
'login_send_otp_description' => 'Por favor, introduce tu dirección de correo electrónico; en el siguiente paso te enviaremos una contraseña de un solo uso a esta dirección.',
|
||||
'login_send_otp_description2' => 'Para crear una cuenta de cliente, utiliza igualmente este inicio de sesión; después podrás introducir tus datos en el portal.',
|
||||
'back_to_shop' => 'Volver a la tienda',
|
||||
'guest' => 'Invitado',
|
||||
'change_login_title' => '¿Cambiar a la cuenta de cliente?',
|
||||
'change_login_title2' => '¿Cambiar a la cuenta de asesor?',
|
||||
'logout_button' => 'Cerrar sesión y cambiar al inicio de sesión',
|
||||
'change_login_description' => 'Has iniciado sesión como asesor. ¿Quieres cambiar a la cuenta de cliente?',
|
||||
'change_login_description2' => 'Has iniciado sesión como cliente. ¿Quieres cambiar a la cuenta de asesor?',
|
||||
'change_login_description3' => 'Puedes cerrar sesión aquí y luego volver a iniciar sesión con tu correo electrónico de cliente.',
|
||||
'change_my_data' => 'Cambia aquí tu dirección de facturación y de entrega.',
|
||||
'change_my_data_empty' => 'Todavía no has guardado ninguna dirección de facturación y de entrega; introduce tus datos ahora.',
|
||||
'my_orders_empty' => 'Todavía no has realizado ningún pedido.',
|
||||
'my_orders_info' => 'Aquí puedes ver y gestionar tus pedidos.',
|
||||
'change_my_data_empty_button' => 'Crear dirección de facturación y de entrega',
|
||||
'my_subscriptions_empty' => 'Todavía no has creado ninguna suscripción.',
|
||||
'my_subscriptions_info' => 'Aquí puedes crear y gestionar tu suscripción.',
|
||||
];
|
||||
|
|
@ -1,21 +1,26 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'button_31' => 'RENOVAR MEMBRESIA',
|
||||
'button_32' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_33' => 'RENOVAR MEMBRESIA',
|
||||
'button_34' => 'RENOVAR MEMBRESIA',
|
||||
'button_35' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_36' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_37' => 'GESTIONAR MEMBRESÍA',
|
||||
'copy_first_31' => '<p>Queríamos informarle a tiempo que su membresía caducará en :datetime. Por lo tanto, debes tomar medidas ahora y ampliarlo a su debido tiempo para que puedas seguir</p> <ul> <li>comprando productos de MIVITA</li> productos de MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li >Puedes participar en ventas de socios de ventas</li> </ul> <p>Pero todo está bien: todavía te quedan algunos días relajantes para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.</p> <p>Le enviaremos otro recordatorio muy pronto, pero lo tendrá en mente. por ahora. Si desea extender su conexión por 1 año ahora, puede hacerlo haciendo clic en el botón a continuación. Lo que se fue, se fue :) ...</p>',
|
||||
'copy_first_32' => '<p>Queríamos informarle a tiempo que su membresía se extenderá automáticamente a las :datetime. Dado que nos ha otorgado un mandato de domiciliación bancaria SEPA, no necesita realizar ninguna acción adicional. De acuerdo con este mandato, debitaremos el monto de la factura :price de su cuenta el :pay_date.</p> <p>Su membresía se extenderá por otro año para que pueda continuar usándola</p> <ul > <li>productos de Puedes conseguir MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li>Puedes participar en las ventas de socios comerciales</li> </ul> < p>Hasta ahora todo bien. Sin embargo, si desea cancelar su membresía o tomar un descanso por el momento, puede hacerlo usted mismo en su área de miembros. Simplemente siga el botón verde a continuación.</p> <p>Si no desea renovar por el momento, su cuenta se pausará hasta que renueve su membresía. Sin embargo, tenga en cuenta que todos los beneficios y funciones, desde compras con descuento hasta facturación de comisiones, también están pausados.</p>',
|
||||
'copy_first_33' => '<p>Aquí le recordamos rápidamente que su membresía vence en :datetime. Por lo tanto, debes tomar medidas ahora y ampliarlo a su debido tiempo para que puedas seguir </p> <ul> <li>comprando productos de MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li >Puedes participar en ventas de socios de ventas</li> </ul> <p>Pero todo está bien: todavía te quedan algunos días relajantes para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.</p> <p>Le enviaremos otro recordatorio muy pronto, pero lo tendrá en mente. por ahora. Si desea extender su conexión por 1 año ahora, puede hacerlo haciendo clic en el botón a continuación. Lo que se fue, se fue :) ...</p>',
|
||||
'copy_first_34' => '<p>huiii... ¡ahora es el momento! Su membresía vence en :days días, exactamente el :datetime. Por lo tanto, debe tomar medidas ahora y ampliar su membresía; de lo contrario, su cuenta se pausará.</p> <p>Si continúa</p> <ul> <li>comprando productos de MIVITA</li> <li >una tienda en línea (opcional)</li> <li>y desea participar en las ventas de socios de ventas</li> </ul> <p>debe actuar rápidamente ahora y ampliar su membresía:</p>',
|
||||
'copy_first_35' => '<p>Como lo anunciamos, hemos pausado su cuenta de asesor porque no renovó su membresía a tiempo. Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento.</p> <p>Haz clic en el botón si deseas realizar cambios en tu membresía:</p>',
|
||||
'copy_first_36' => '<p>Desafortunadamente, no pudimos cobrar el monto adeudado por la cuota de membresía de su cuenta especificada.</p> <p>Como anunciamos, hoy hemos pausado su cuenta de asesor porque no va a extender su membresía a tiempo. . Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento utilizando otro método de pago (por ejemplo, Paypal, tarjeta de crédito, transferencia SOFORT o pago anticipado).</p> <p>Para hacer Para ello, simplemente haga clic en el siguiente botón y realice las configuraciones apropiadas en su cuenta de asesor:</p>',
|
||||
'copy_first_37' => '<p>Como anunciamos, hoy hemos acordado que se cobre el precio por otro año de membresía en MIVITA de acuerdo con su mandato de débito directo SEPA. El importe de esta factura se debitará de su cuenta en los próximos días. Tenga en cuenta que la extensión solo está activa después de que se haya recibido el pago.</p> <p>Si desea realizar cambios en el futuro, puede suspender todas las funciones y la membresía en su cuenta de asesor.</p> <p >Sigue aquí simplemente haz clic en el botón de abajo:</p>',
|
||||
'copy_last_35' => '<p><b>Nota:</b><br>Incluso si su cuenta está pausada, las comisiones pasadas o pendientes, por supuesto, se le pagarán en la siguiente ejecución de pago. Si desea eliminar su cuenta por completo, por favor escribe un correo electrónico a info@mivita.care. Nuestro servicio de asesoría se encargará de esto inmediatamente.</p> <p>Esperamos darle la bienvenida nuevamente muy pronto como miembro activo de la Familia MIVITA.</p>',
|
||||
'copy_last_36' => '<p><b>Nota:</b><br>Incluso si su cuenta está pausada, las comisiones pasadas o pendientes, por supuesto, se le pagarán en la siguiente ejecución de pago. Si desea eliminar su cuenta por completo, por favor escribe un correo electrónico a info@mivita.care. Nuestro servicio de asesoría se encargará de esto inmediatamente.</p> <p>Esperamos darle la bienvenida nuevamente muy pronto como miembro activo de la Familia MIVITA.</p>',
|
||||
'subject' => 'Tu membresía en mivita.care',
|
||||
);
|
||||
return [
|
||||
'button_31' => 'RENOVAR MEMBRESIA',
|
||||
'button_32' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_33' => 'RENOVAR MEMBRESIA',
|
||||
'button_34' => 'RENOVAR MEMBRESIA',
|
||||
'button_35' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_36' => 'GESTIONAR MEMBRESÍA',
|
||||
'button_37' => 'GESTIONAR MEMBRESÍA',
|
||||
'copy_first_31' => '<p>Queríamos informarle a tiempo que su membresía caducará en :datetime. Por lo tanto, debes tomar medidas ahora y ampliarlo a su debido tiempo para que puedas seguir</p> <ul> <li>comprando productos de MIVITA</li> productos de MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li >Puedes participar en ventas de socios de ventas</li> </ul> <p>Pero todo está bien: todavía te quedan algunos días relajantes para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.</p> <p>Le enviaremos otro recordatorio muy pronto, pero lo tendrá en mente. por ahora. Si desea extender su conexión por 1 año ahora, puede hacerlo haciendo clic en el botón a continuación. Lo que se fue, se fue :) ...</p>',
|
||||
'copy_first_32' => '<p>Queríamos informarle a tiempo que su membresía se extenderá automáticamente a las :datetime. Dado que nos ha otorgado un mandato de domiciliación bancaria SEPA, no necesita realizar ninguna acción adicional. De acuerdo con este mandato, debitaremos el monto de la factura :price de su cuenta el :pay_date.</p> <p>Su membresía se extenderá por otro año para que pueda continuar usándola</p> <ul > <li>productos de Puedes conseguir MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li>Puedes participar en las ventas de socios comerciales</li> </ul> < p>Hasta ahora todo bien. Sin embargo, si desea cancelar su membresía o tomar un descanso por el momento, puede hacerlo usted mismo en su área de miembros. Simplemente siga el botón verde a continuación.</p> <p>Si no desea renovar por el momento, su cuenta se pausará hasta que renueve su membresía. Sin embargo, tenga en cuenta que todos los beneficios y funciones, desde compras con descuento hasta facturación de comisiones, también están pausados.</p>',
|
||||
'copy_first_33' => '<p>Aquí le recordamos rápidamente que su membresía vence en :datetime. Por lo tanto, debes tomar medidas ahora y ampliarlo a su debido tiempo para que puedas seguir </p> <ul> <li>comprando productos de MIVITA</li> <li>Los clientes pueden comprar a través de tu tienda online (opcional)</li> <li >Puedes participar en ventas de socios de ventas</li> </ul> <p>Pero todo está bien: todavía te quedan algunos días relajantes para ampliar tu membresía. Sin embargo, si deja pasar la fecha límite, su cuenta se pausará automáticamente hasta que renueve su membresía.</p> <p>Le enviaremos otro recordatorio muy pronto, pero lo tendrá en mente. por ahora. Si desea extender su conexión por 1 año ahora, puede hacerlo haciendo clic en el botón a continuación. Lo que se fue, se fue :) ...</p>',
|
||||
'copy_first_34' => '<p>huiii... ¡ahora es el momento! Su membresía vence en :days días, exactamente el :datetime. Por lo tanto, debe tomar medidas ahora y ampliar su membresía; de lo contrario, su cuenta se pausará.</p> <p>Si continúa</p> <ul> <li>comprando productos de MIVITA</li> <li >una tienda en línea (opcional)</li> <li>y desea participar en las ventas de socios de ventas</li> </ul> <p>debe actuar rápidamente ahora y ampliar su membresía:</p>',
|
||||
'copy_first_35' => '<p>Como lo anunciamos, hemos pausado su cuenta de asesor porque no renovó su membresía a tiempo. Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento.</p> <p>Haz clic en el botón si deseas realizar cambios en tu membresía:</p>',
|
||||
'copy_first_36' => '<p>Desafortunadamente, no pudimos cobrar el monto adeudado por la cuota de membresía de su cuenta especificada.</p> <p>Como anunciamos, hoy hemos pausado su cuenta de asesor porque no va a extender su membresía a tiempo. . Si deseas volver a beneficiarte de las ventajas y características de MIVITA, puedes reactivar tu cuenta en cualquier momento utilizando otro método de pago (por ejemplo, Paypal, tarjeta de crédito, transferencia SOFORT o pago anticipado).</p> <p>Para hacer Para ello, simplemente haga clic en el siguiente botón y realice las configuraciones apropiadas en su cuenta de asesor:</p>',
|
||||
'copy_first_37' => '<p>Como anunciamos, hoy hemos acordado que se cobre el precio por otro año de membresía en MIVITA de acuerdo con su mandato de débito directo SEPA. El importe de esta factura se debitará de su cuenta en los próximos días. Tenga en cuenta que la extensión solo está activa después de que se haya recibido el pago.</p> <p>Si desea realizar cambios en el futuro, puede suspender todas las funciones y la membresía en su cuenta de asesor.</p> <p >Sigue aquí simplemente haz clic en el botón de abajo:</p>',
|
||||
'copy_last_35' => '<p><b>Nota:</b><br>Incluso si su cuenta está pausada, las comisiones pasadas o pendientes, por supuesto, se le pagarán en la siguiente ejecución de pago. Si desea eliminar su cuenta por completo, por favor escribe un correo electrónico a info@mivita.care. Nuestro servicio de asesoría se encargará de esto inmediatamente.</p> <p>Esperamos darle la bienvenida nuevamente muy pronto como miembro activo de la Familia MIVITA.</p>',
|
||||
'copy_last_36' => '<p><b>Nota:</b><br>Incluso si su cuenta está pausada, las comisiones pasadas o pendientes, por supuesto, se le pagarán en la siguiente ejecución de pago. Si desea eliminar su cuenta por completo, por favor escribe un correo electrónico a info@mivita.care. Nuestro servicio de asesoría se encargará de esto inmediatamente.</p> <p>Esperamos darle la bienvenida nuevamente muy pronto como miembro activo de la Familia MIVITA.</p>',
|
||||
'subject' => 'Tu membresía en mivita.care',
|
||||
'copy_last_31' => '',
|
||||
'copy_last_32' => '',
|
||||
'copy_last_33' => '',
|
||||
'copy_last_34' => '',
|
||||
'copy_last_37' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,53 +1,57 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'Choose Your Shop Name' => 'Elija un nombre de tienda memorable que se adapte a sus necesidades.',
|
||||
'Shop details' => 'detalles de la tienda',
|
||||
'Terms of Use' => 'condiciones de uso',
|
||||
'Your Shop' => 'su tienda',
|
||||
'Your Shop Name' => 'dale un nombre a tu tienda',
|
||||
'accept_and_next' => 'aceptar y seguir adelante',
|
||||
'active_since' => 'activo desde',
|
||||
'available' => 'accesible',
|
||||
'check' => 'controlar',
|
||||
'declaration_of_shop' => 'Por la presente confirmo y acepto los términos de uso de mi tienda mivita.',
|
||||
'domain' => 'dominio',
|
||||
'error_subdomain_exists' => 'Error: El subdominio ya existe, por favor elija un nuevo nombre',
|
||||
'mobil' => 'Móvil',
|
||||
'name' => 'apellido',
|
||||
'not_available' => 'no alcanzable',
|
||||
'not_available_copy' => 'Para las tiendas recién creadas, se necesitan unos minutos hasta que se pueda acceder al dominio. Vuelva a comprobarlo en unos minutos.',
|
||||
'open_copy_1' => 'Elija el prefijo del nombre de su tienda, p.e. B. nombre(.mivita.care): no es necesario que ingrese "mivita.care". Elija un nombre breve y conciso para poder colocar esta URL también en pequeños materiales publicitarios. También asegúrese de no violar ningún derecho de marca registrada de terceros. MIVITA no puede aceptar ninguna responsabilidad por esto. Por lo tanto, trate de evitar el uso de términos sofisticados a menos que los haya registrado como marca comercial.',
|
||||
'open_copy_2' => 'Posteriormente podrá acceder a su dirección de Internet con "www." y sin él.',
|
||||
'open_note_1' => 'El nombre de su tienda se utiliza para crear la dirección de Internet (dominio) con la que se puede acceder a su tienda. Elija el nombre de su tienda con cuidado. Esto sólo lo puede cambiar TI y tendríamos que cobrar una bonificación de gastos de 59,50€.',
|
||||
'open_note_hl' => 'NOTA IMPORTANTE:',
|
||||
'open_your_shop' => 'Abre tu propia tienda mivita.',
|
||||
'order_customer' => 'cliente de pedido',
|
||||
'orders_customers' => 'pedidos clientes',
|
||||
'phone' => 'Teléfono fijo',
|
||||
'preview_shop_internet_address' => 'vista previa de la dirección de Internet de la tienda',
|
||||
'save and continue' => 'guardar y continuar',
|
||||
'shop_about' => 'comprar texto personal',
|
||||
'shop_about_help' => 'Ingrese su texto personal sobre usted. (máx. 190 caracteres)',
|
||||
'shop_accessibility' => 'accesibilidad de la tienda',
|
||||
'shop_accessibility_help' => 'Indique su disponibilidad.',
|
||||
'shop_accessibility_text' => 'De lunes a viernes: 9.00 - 19.00\\nSáb-Dom: 11.00 - 18.00',
|
||||
'shop_contact' => 'tienda Contacto',
|
||||
'shop_contact_help' => 'Completa tus datos de contacto que se muestran en la tienda.',
|
||||
'shop_contact_text' => 'Su calle/número: su ciudad con código postal\\nLínea fija: su número de línea fija\\nMóvil: su número de móvil\\nSu dirección de correo electrónico',
|
||||
'shop_image' => 'foto de tu tienda',
|
||||
'shop_image_copy' => 'Sube una foto/imagen/logotipo tuyo aquí.',
|
||||
'shop_name_description' => 'El nombre de su tienda se mostrará en su tienda. El nombre de su tienda se utiliza para crear la dirección de Internet (dominio) con la que se puede acceder a su tienda. Elija cuidadosamente el nombre de su tienda; este solo podrá cambiarse más tarde por una tarifa de 59,50 euros.',
|
||||
'shop_name_error_1' => 'El nombre de su tienda sólo puede contener letras y números latinos sin acentos, sin espacios.',
|
||||
'shop_name_error_2' => 'Los nombres de las tiendas deben tener entre 4 y 20 caracteres.',
|
||||
'shop_on_site' => 'para usted en el sitio:',
|
||||
'shop_on_site_copy' => '¿Has estado en la Finca de Aloe Vera en Mallorca? Sube hasta 6 fotos tuyas aquí.',
|
||||
'shop_title' => 'dueño de la tienda',
|
||||
'shop_title_help' => 'Introduce tu nombre para la tienda.',
|
||||
'your_city' => 'Tu casa',
|
||||
'your_mobile_number' => 'Su número de móvil',
|
||||
'your_phone_number' => 'Su número de teléfono fijo',
|
||||
'your_shop_name' => 'el nombre de tu tienda',
|
||||
'your_street_number' => 'Su calle/número',
|
||||
'your_zip_code' => 'Su código postal',
|
||||
);
|
||||
return [
|
||||
'Choose Your Shop Name' => 'Elija un nombre de tienda memorable que se adapte a sus necesidades.',
|
||||
'Shop details' => 'detalles de la tienda',
|
||||
'Terms of Use' => 'condiciones de uso',
|
||||
'Your Shop' => 'su tienda',
|
||||
'Your Shop Name' => 'dale un nombre a tu tienda',
|
||||
'accept_and_next' => 'aceptar y seguir adelante',
|
||||
'active_since' => 'activo desde',
|
||||
'available' => 'accesible',
|
||||
'check' => 'controlar',
|
||||
'declaration_of_shop' => 'Por la presente confirmo y acepto los términos de uso de mi tienda mivita.',
|
||||
'domain' => 'dominio',
|
||||
'error_subdomain_exists' => 'Error: El subdominio ya existe, por favor elija un nuevo nombre',
|
||||
'mobil' => 'Móvil',
|
||||
'name' => 'apellido',
|
||||
'not_available' => 'no alcanzable',
|
||||
'not_available_copy' => 'Para las tiendas recién creadas, se necesitan unos minutos hasta que se pueda acceder al dominio. Vuelva a comprobarlo en unos minutos.',
|
||||
'open_copy_1' => 'Elija el prefijo del nombre de su tienda, p.e. B. nombre(.mivita.care): no es necesario que ingrese "mivita.care". Elija un nombre breve y conciso para poder colocar esta URL también en pequeños materiales publicitarios. También asegúrese de no violar ningún derecho de marca registrada de terceros. MIVITA no puede aceptar ninguna responsabilidad por esto. Por lo tanto, trate de evitar el uso de términos sofisticados a menos que los haya registrado como marca comercial.',
|
||||
'open_copy_2' => 'Posteriormente podrá acceder a su dirección de Internet con "www." y sin él.',
|
||||
'open_note_1' => 'El nombre de su tienda se utiliza para crear la dirección de Internet (dominio) con la que se puede acceder a su tienda. Elija el nombre de su tienda con cuidado. Esto sólo lo puede cambiar TI y tendríamos que cobrar una bonificación de gastos de 59,50€.',
|
||||
'open_note_hl' => 'NOTA IMPORTANTE:',
|
||||
'open_your_shop' => 'Abre tu propia tienda mivita.',
|
||||
'order_customer' => 'cliente de pedido',
|
||||
'orders_customers' => 'pedidos clientes',
|
||||
'phone' => 'Teléfono fijo',
|
||||
'preview_shop_internet_address' => 'vista previa de la dirección de Internet de la tienda',
|
||||
'save and continue' => 'guardar y continuar',
|
||||
'shop_about' => 'comprar texto personal',
|
||||
'shop_about_help' => 'Ingrese su texto personal sobre usted. (máx. 190 caracteres)',
|
||||
'shop_accessibility' => 'accesibilidad de la tienda',
|
||||
'shop_accessibility_help' => 'Indique su disponibilidad.',
|
||||
'shop_accessibility_text' => 'De lunes a viernes: 9.00 - 19.00\\nSáb-Dom: 11.00 - 18.00',
|
||||
'shop_contact' => 'tienda Contacto',
|
||||
'shop_contact_help' => 'Completa tus datos de contacto que se muestran en la tienda.',
|
||||
'shop_contact_text' => 'Su calle/número: su ciudad con código postal\\nLínea fija: su número de línea fija\\nMóvil: su número de móvil\\nSu dirección de correo electrónico',
|
||||
'shop_image' => 'foto de tu tienda',
|
||||
'shop_image_copy' => 'Sube una foto/imagen/logotipo tuyo aquí.',
|
||||
'shop_name_description' => 'El nombre de su tienda se mostrará en su tienda. El nombre de su tienda se utiliza para crear la dirección de Internet (dominio) con la que se puede acceder a su tienda. Elija cuidadosamente el nombre de su tienda; este solo podrá cambiarse más tarde por una tarifa de 59,50 euros.',
|
||||
'shop_name_error_1' => 'El nombre de su tienda sólo puede contener letras y números latinos sin acentos, sin espacios.',
|
||||
'shop_name_error_2' => 'Los nombres de las tiendas deben tener entre 4 y 20 caracteres.',
|
||||
'shop_on_site' => 'para usted en el sitio:',
|
||||
'shop_on_site_copy' => '¿Has estado en la Finca de Aloe Vera en Mallorca? Sube hasta 6 fotos tuyas aquí.',
|
||||
'shop_title' => 'dueño de la tienda',
|
||||
'shop_title_help' => 'Introduce tu nombre para la tienda.',
|
||||
'your_city' => 'Tu casa',
|
||||
'your_mobile_number' => 'Su número de móvil',
|
||||
'your_phone_number' => 'Su número de teléfono fijo',
|
||||
'your_shop_name' => 'el nombre de tu tienda',
|
||||
'your_street_number' => 'Su calle/número',
|
||||
'your_zip_code' => 'Su código postal',
|
||||
'' => '',
|
||||
'accept_and_change' => 'aceptar y cambiar',
|
||||
'edit_your_shop' => 'Adapta el nombre de tu tienda',
|
||||
'your_current_shop_name' => 'El nombre actual de tu tienda es:',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -91,4 +91,9 @@ return [
|
|||
've' => 'VE',
|
||||
'vk_price' => 'precio de venta',
|
||||
'no_data_available' => 'No hay datos disponibles',
|
||||
'' => '',
|
||||
'inactive' => 'Inactivo',
|
||||
'all' => 'Todos',
|
||||
'month' => 'Mes',
|
||||
'year' => 'Año',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -148,4 +148,6 @@ return [
|
|||
'not_available' => 'N/A',
|
||||
|
||||
'growth_bonus_details_description' => 'L1 = Socio Directo (obtiene el bono de crecimiento siempre), L2 = Miembros (a partir de aquí el bono de crecimiento se divide si el miembro está calificado), etc. | Muestra comisión (€) y volumen (puntos) por nivel.',
|
||||
'' => '',
|
||||
'open' => 'Abierto',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,86 +1,87 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'advantages_MIVITA_botl' => '... construye para ti un futuro autodeterminado en el que eres tu propio jefe.',
|
||||
'advantages_MIVITA_hl' => 'Ventajas de MIVITA:',
|
||||
'advantages_MIVITA_list' => '<ul class="small"> <li>20-40% de margen de ventas</li> <li>Bonificaciones y promociones atractivas</li> <li>Ganancias hasta 3 niveles</li> <li>Sin facturación mínima </ li> <li>Programación gratuita</li> <li>Trabajar en equipo</li> <li>Material publicitario y tienda online bajo pedido</li> <li>Procesamiento de envíos y devoluciones por parte de MIVITA</li > <li>Formación en Mallorca </li></ul>',
|
||||
'advantages_MIVITA_subl' => 'Hay muchas buenas razones para trabajar por cuenta propia en mivita. Muchos consultores responden a la pregunta de por qué eligieron la venta directa en mivita:',
|
||||
'advantages_direct_sales_hl' => 'Ventajas de la venta directa',
|
||||
'advantages_direct_sales_list' => '<ul class="small"> <li>Ganar dinero extra o aumentar la calidad de vida de la familia</li> <li>Ser tu propio jefe con bajo riesgo y bajas inversiones</li> < li>Trabajar con flexibilidad con programación gratuita</li> <li>Para no tener obligaciones de compra</li> <li>Poder empezar sin restricciones de edad, sin conocimientos previos ni calificaciones especiales</li> <li>Bajo riesgo y bajos costos fijos </li> <li>Por la alta calidad del producto</li> </ul>',
|
||||
'advantages_direct_sales_subl' => 'La venta directa trae las siguientes ventajas',
|
||||
'advantages_of_direct_sales' => 'ventajas de la venta directa',
|
||||
'aloe_high_quality_copy' => 'El gel de hojas de aloe vera es un verdadero tesoro y un regalo de la naturaleza. Pero hay muchas cosas que considerar, desde el cultivo hasta el procesamiento, para garantizar que estos valiosos ingredientes se conserven y lleguen al cliente. Desafortunadamente, muchos fabricantes no se adhieren al 1x1 de producción de aloe vera, por lo que hay una serie de productos de aloe vera en el mercado que tienen poco o ningún efecto. Entonces, ¿qué hace que nuestros productos sean de tan alta calidad?',
|
||||
'aloe_high_quality_hl' => '¿Qué hace que nuestros productos de aloe vera sean de tan alta calidad?',
|
||||
'aloe_high_quality_li1' => 'Las plantas de aloe tienen más de 5 años.',
|
||||
'aloe_high_quality_li10' => 'Alta proporción de aloe puro en cada producto.',
|
||||
'aloe_high_quality_li2' => 'Tener más de 2000 horas de sol al año.',
|
||||
'aloe_high_quality_li3' => 'cultivo puramente controlado biológicamente',
|
||||
'aloe_high_quality_li4' => 'sin (!) riego artificial',
|
||||
'aloe_high_quality_li5' => 'sin plagas ni herbicidas',
|
||||
'aloe_high_quality_li6' => 'cosechar y filetear las hojas a mano.',
|
||||
'aloe_high_quality_li7' => 'procesamiento en productos directamente después de la cosecha.',
|
||||
'aloe_high_quality_li8' => 'Sólo el gel puro: sin polvo ni extracto.',
|
||||
'aloe_high_quality_li9' => 'Contenido de aloverosa certificado superior a 1.600 mg/l.',
|
||||
'aloe_high_quality_subl' => 'Uno de los mejores jugos de aloe vera del mundo como base para productos de aloe vera de alta calidad.',
|
||||
'aloe_vera_word_copy' => 'Las propiedades excepcionales y únicas del mundo del aloe vera se deben a la interacción y simbiosis únicas de los diferentes ingredientes e ingredientes activos. Ninguna otra planta conocida hasta la fecha tiene una gama tan amplia de usos curativos y nutritivos. En total, actualmente se conocen en la literatura médica más de 200 sustancias activas y constantemente se descubren otras nuevas. La decodificación de la compleja interacción de todas las sustancias apenas comienza, pero sus efectos ya están muy bien documentados.',
|
||||
'bio_quality_copy' => 'Garantizamos la mejor calidad a través de la producción manual e ingredientes orgánicos. El clima típico de Mallorca desafía a las plantas. Las pruebas han demostrado que este clima es óptimo para un perfecto desarrollo de las plantas.',
|
||||
'bio_quality_hl' => 'calidad 100% ORGÁNICA',
|
||||
'bio_quality_subl' => 'artesanía ecológica certificada de Mallorca.',
|
||||
'business_environment_hl' => 'ambiente de negocios',
|
||||
'business_environment_list' => '<ul class="small"> <li>Cosmética / cosmética natural</li> <li>Peinado</li> <li>Nutrición</li> <li>Cuidado de uñas y pies</li> <li> Naturista y medicina alternativa</li> <li>Medicina (piel, fisio, general, etc.)</li> <li>Todo sobre animales</li> <li>Yoga y meditación</li> <li>Gastronomía </li> <li>Deportes y fitness</li> <li>y mucho más.</li> </ul>',
|
||||
'career_opportunitie_point_1' => 'Vende productos adecuados para una vida sana y vital y que te brinden a ti y a tus seres queridos una gran experiencia de bienestar.',
|
||||
'career_opportunitie_point_2' => 'Nos mantenemos actualizados y nos apoyamos en grupos de WhatsApp y videollamadas. ¡No estás solo!',
|
||||
'career_opportunitie_point_3' => 'Le transmitimos nuestros conocimientos, herramientas de marketing probadas y materiales publicitarios, porque sólo tendremos éxito si USTED tiene éxito.',
|
||||
'career_opportunitie_point_4' => 'Benefíciese de medidas de apoyo como formación, eventos de equipo o campañas de ventas conjuntas. ¡Juntos tenemos éxito!',
|
||||
'career_opportunitie_point_5' => 'Utilice las redes sociales y hable sobre productos y experiencias. Obtenga nuevos clientes y socios a través de Facebook & Co.',
|
||||
'career_opportunities_at_mivita' => 'oportunidades laborales en mivita',
|
||||
'compatibility_with_family_copy1' => '¿Quién no lo sabe? Falta dinero por todas partes y el jefe siempre hace mala cara cuando el niño está enfermo. Muchas familias dependen de un segundo empleo o del trabajo a tiempo parcial de la madre o el padre. Y esto muchas veces no puede conciliarse con las ideas del empresario. Pero, ¿qué pasa si usted mismo acumula sus ingresos adicionales mensuales y al mismo tiempo tiene más tiempo para su hijo?',
|
||||
'compatibility_with_family_copy2' => 'Especialmente en la venta directa, con sus opciones de gestión del tiempo libre e ingresos pasivos, a medio plazo tienes tanta libertad que un trabajo fijo no te puede ofrecer. Como consultor independiente de MIVITA, tú decides cuándo y dónde trabajar. Y eso no afecta sólo a los padres jóvenes. Las ventas directas también representan una solución perfecta para personas que necesitan cuidar a sus familiares o simplemente quieren tener más tiempo y alivio económico:',
|
||||
'compatibility_with_family_list' => '<ul class="small"> <li>Trabaja desde casa o mientras viajas</li> <li>Sin alquiler de oficina</li> <li>Sin inversión significativa en desarrollo</li> <li>Sin infraestructura costosa necesario</ li></ul>',
|
||||
'compatibility_with_family_private_life' => 'compatibilidad con la vida familiar y privada',
|
||||
'direct_sales_advantages_copy' => '<p>La venta directa se ha consolidado desde hace tiempo en todo el mundo como un tipo de negocio independiente y ya está representada en muchos sectores. La venta directa, también conocida como mercadeo en red, describe la venta <b>personal</b> de bienes o servicios a consumidores en el entorno inmediato: familiares, amigos, colegas, etc. Lo crucial aquí es el contacto personal y la Función de asesoramiento: ¡atención al cliente por excelencia! Y ese es el gran punto fuerte de la venta directa, el servicio al cliente. Creamos con mucha personalidad y transparencia algo que ya no es posible en la inmensidad anónima de Internet.</p>',
|
||||
'direct_sales_advantages_hl' => 'venta directa y sus ventajas.',
|
||||
'direct_sales_exactly_copy' => '<p>Imagínese que es un fanático entusiasta de los productos de una empresa en particular. Piensas para ti mismo: “Genial, tengo que contárselo a mi mejor amigo. Y mi amigo. Y la familia. Y el mundo entero en general.” - y compran el producto basándose en tu recomendación. Sucede todos los días. Todos lo sabemos.</p> <p>La diferencia es que no sólo lo recomiendas, no, tú mismo eres el vendedor, creando una base de clientes y, por lo tanto, un margen del 30-40%. Se ganaron nuevos clientes, ¡sí! Hasta aquí todo bien.</p> <p>Y ahora imagina que tu amiga o novia también se convierte en socia de ventas, crea una base de clientes y tú también ganas dinero con ello. Y así sigue: ¡hasta 3 niveles + bonificaciones!</p>',
|
||||
'direct_sales_exactly_hl' => 'Venta directa: ¿cómo funciona exactamente?',
|
||||
'funding_opportunities_copy' => '<p>Si desea dar el salto hacia la independencia total, existen varias opciones de financiación disponibles. Eche un vistazo a lo siguiente donde puede solicitar su primer capital inicial:</p> <p> <a href="https://www.existenzgruender.de" rel="nofollow" target="_blank ">www.existenzgruender .de</a><br> <a href="http://www.foerderdatabase.de" rel="nofollow" target="_blank">www.foerderkatalog.de</a><br> <a href ="https://www.kfw.de" rel="nofollow" target="_blank">www.kfw.de</a><br> <a href="http://www .mikrofinanz.net" rel="nofollow" target="_blank">www.mikrofinanz.net</a><br> </p>',
|
||||
'funding_opportunities_hl' => 'oportunidades de financiación',
|
||||
'how_to_sell_exactly_copy' => 'Hay muchas formas diferentes de vender productos o conseguir socios de ventas. Aquí te presentamos algunos de ellos. La regla más importante es: utilizar los productos y hablar de ellos. Entonces los clientes acudirán a usted por su cuenta.',
|
||||
'how_to_sell_exactly_hl' => '¿Y cómo vendo exactamente?',
|
||||
'make_people_happy_copy' => 'Nuestros productos ayudan a las personas con una amplia variedad de problemas de la piel y, a menudo, se utilizan para tratar la neurodermatitis, la psoriasis, el acné y muchas otras enfermedades de la piel. El jugo puro de aloe vera orgánico es un excelente biorregulador, tiene un efecto antiinflamatorio y ayuda al cuerpo a mantener la flora intestinal. También puedes ayudar a otras personas a mantener sus cuerpos sanos de forma natural.',
|
||||
'make_people_happy_hl' => 'Hacer a la gente feliz...',
|
||||
'origin_aloe_copy' => 'La finca en Mallorca tiene una superficie de aproximadamente 40 hectáreas. Allí se cultivan y cuidan las plantas de aloe vera. Las 200.000 plantas deben tener al menos cinco años antes de que se puedan cosechar las hojas. Una planta necesita al menos 2.000 horas de sol al año para acumular los valiosos nutrientes para el jugo.',
|
||||
'origin_aloe_hl' => 'origen de nuestro aloe',
|
||||
'origin_aloe_subl' => 'de la isla de vacaciones favorita de los alemanes',
|
||||
'pillars_best_aloe_vera_quality' => 'Los 5 pilares para la mejor calidad del aloe vera',
|
||||
'pillars_best_aloe_vera_quality_1_hl' => 'certificado ORGÁNICO',
|
||||
'pillars_best_aloe_vera_quality_1_subl' => 'Aloe vera procedente de agricultura biológica: sin sustancias nocivas',
|
||||
'pillars_best_aloe_vera_quality_2_hl' => 'gel puro de aloe',
|
||||
'pillars_best_aloe_vera_quality_2_subl' => 'procesamiento de gel de aloe puro, sin mezcla de agua y polvo',
|
||||
'pillars_best_aloe_vera_quality_3_hl' => 'producción in situ',
|
||||
'pillars_best_aloe_vera_quality_3_subl' => 'Las hojas de aloe recolectadas se procesan inmediatamente in situ y se conservan los principios activos.',
|
||||
'pillars_best_aloe_vera_quality_4_hl' => 'alto contenido de aloe',
|
||||
'pillars_best_aloe_vera_quality_4_subl' => 'Todos los productos tienen una alta proporción de aloe vera orgánico puro.',
|
||||
'pillars_best_aloe_vera_quality_5_hl' => 'alto contenido de rosa de aloever',
|
||||
'pillars_best_aloe_vera_quality_5_subl' => 'con 1.600-1.700 mg/l, un contenido de Aloverosa superior a la media: EL factor de calidad para el contenido de ingrediente activo del Aloe',
|
||||
'private_environment_hl' => 'en un ambiente privado',
|
||||
'private_environment_list' => '<ul class="small"> <li>Familia</li> <li>Amigos</li> <li>colegas de trabajo</li> <li>Vecinos</li> <li>fiestas en casa</li> <li>Club de Deportes</li> <li>Familia</li> <li>Dueño de la mascota</li> <li>u.v.m.</li> </ul>',
|
||||
'requirement_profile' => 'perfil de requisitos',
|
||||
'requirement_profile_at_mivita' => 'perfil de requisitos',
|
||||
'requirement_profile_at_mivita_copy' => '<p>Todo aquel que quiera construir algo propio con alegría y compromiso es bienvenido a MIVITA. Nuestros socios de ventas incluyen principalmente personas como...</p> <ul class="small"> <li>Empleados con trabajos de tiempo completo</li> <li>Empleados con trabajos de tiempo parcial</li> <li >familias jóvenes o familias monoparentales </li> <li>Empresarios independientes</li> <li>Estudiantes y aprendices</li> <li>Generación +50 que quieren volver a saber</li> </ul> <p > Si estás en Si encuentras este perfil de requisitos, entonces has venido al lugar correcto. Especialmente a las personas que sienten que pueden lograr más, que tal vez están estancadas en su carrera, a quienes les gustaría trabajar con mayor libertad e independencia: estaremos encantados de ofrecerles una primera consulta sin compromiso. </p>',
|
||||
'shop_at_the_aloe_vera_farm' => 'compre en la granja de Aloe Vera',
|
||||
'social_environment_hl' => 'en las redes sociales',
|
||||
'social_environment_list' => '<ul class="small"> <li>Facebook</li> <li>Youtube</li> <li>Instagram</li> <li>Snapchat</li> <li>Familia</li> <li >entre otros ...</li></ul>',
|
||||
'social_security_copy' => '<p>Casi todo el mundo se dedica a las ventas directas como trabajo a tiempo parcial. Al fin y al cabo, el éxito profesional con unos buenos ingresos económicos no se consigue de la noche a la mañana. Si aun así decide trabajar por cuenta propia, tenga en cuenta los siguientes puntos con respecto a su seguridad social:</p> <p> <ul class="small"> <li>Como trabajador por cuenta propia, puede contratar un plan de pensiones privado o afiliarse al seguro de pensiones legal. A diferencia de esto, en el seguro de pensiones legal existe un seguro obligatorio para los llamados "autónomos por cuenta ajena", que trabajan de forma permanente y básicamente para un solo cliente y no emplean a sus propios empleados. </li> <li> Como trabajador autónomo, puede contratar un seguro médico privado o, bajo determinadas condiciones, asegurarse voluntariamente en una compañía de seguros de enfermedad obligatoria. Sin embargo, deben tener algún tipo de seguro médico. </li> <li>Debe contratar un seguro de asistencia sanitaria siempre que tenga un seguro médico. </li> <li>No existe una afiliación obligatoria al seguro de desempleo legal. Después de crear su empresa, podrá seguir asegurándose allí voluntariamente bajo determinadas condiciones. </li></ul>',
|
||||
'social_security_hl' => 'seguridad Social',
|
||||
'start_up' => 'iniciar un negocio',
|
||||
'that_sounds_exciting_to_you' => '¿Te parece emocionante?',
|
||||
'then_get_in_touch_with_us_today' => 'Entonces contáctenos hoy; esperamos conocerlo.',
|
||||
'to_the_contact_form' => 'para contactar formulario',
|
||||
'to_the_registration' => 'para registro',
|
||||
'trade_licence_copy' => '<p>Si desea iniciar este negocio, necesita una licencia comercial. Esto no es nada descabellado y se puede solicitar en la oficina comercial de su ciudad. Hay pequeños costes únicos de entre 20 y 25 euros, dependiendo de la ciudad o el municipio. Piensa en una actividad específica que indicarás en la licencia comercial. Por ejemplo, “Venta de productos de cuidado y bienestar”. En el folleto sobre registro de empresas, creación de una empresa y trámites encontrará información útil e importante sobre los siguientes puntos:</p> <ul> <li>Registro de empresas</li> <li>Presentación de informes a la oficina de impuestos< /li> <li>Membresía en la asociación industrial y cámara de comercio </li></ul>',
|
||||
'trade_licence_hl' => 'licencia de negocios',
|
||||
'training_aloe_farm_mallorca' => 'formación en la Finca Aloe Vera de Mallorca.',
|
||||
'training_aloe_farm_mallorca_copy' => 'MIVITA organiza formación para consultores dos veces al año. Además del recorrido por la granja y las instalaciones de producción, el operador agrícola Werner Telwest le presentará los secretos del "lirio del desierto". Y lo mejor: para cada curso de formación hay un anuncio. Quien genere ventas será recompensado con un viaje de MIVITA y volará GRATIS a la isla de vacaciones favorita de los alemanes.',
|
||||
'women_direct_sales_copy' => 'Teniente Según la Asociación Federal de Ventas Directas de Alemania (BDD), el 82% de los directivos eran mujeres. Este fue el resultado de una encuesta realizada entre las empresas miembros de BDD. Por tanto, la proporción de mujeres es significativamente mayor que en comparación con la economía en su conjunto. Y eso no viene de ninguna parte. Tradicionalmente, en la venta directa trabajan muchas mujeres que, por condiciones familiares o por falta de igualdad de oportunidades en el mercado, encuentran aquí su vocación para vivir su empuje, ideas y energías para convertirse en una empresaria de éxito.',
|
||||
'women_direct_sales_hl' => 'mujeres en venta directa',
|
||||
);
|
||||
return [
|
||||
'advantages_MIVITA_botl' => '... construye para ti un futuro autodeterminado en el que eres tu propio jefe.',
|
||||
'advantages_MIVITA_hl' => 'Ventajas de MIVITA:',
|
||||
'advantages_MIVITA_list' => '<ul class="small"> <li>20-40% de margen de ventas</li> <li>Bonificaciones y promociones atractivas</li> <li>Ganancias hasta 3 niveles</li> <li>Sin facturación mínima </ li> <li>Programación gratuita</li> <li>Trabajar en equipo</li> <li>Material publicitario y tienda online bajo pedido</li> <li>Procesamiento de envíos y devoluciones por parte de MIVITA</li > <li>Formación en Mallorca </li></ul>',
|
||||
'advantages_MIVITA_subl' => 'Hay muchas buenas razones para trabajar por cuenta propia en mivita. Muchos consultores responden a la pregunta de por qué eligieron la venta directa en mivita:',
|
||||
'advantages_direct_sales_hl' => 'Ventajas de la venta directa',
|
||||
'advantages_direct_sales_list' => '<ul class="small"> <li>Ganar dinero extra o aumentar la calidad de vida de la familia</li> <li>Ser tu propio jefe con bajo riesgo y bajas inversiones</li> < li>Trabajar con flexibilidad con programación gratuita</li> <li>Para no tener obligaciones de compra</li> <li>Poder empezar sin restricciones de edad, sin conocimientos previos ni calificaciones especiales</li> <li>Bajo riesgo y bajos costos fijos </li> <li>Por la alta calidad del producto</li> </ul>',
|
||||
'advantages_direct_sales_subl' => 'La venta directa trae las siguientes ventajas',
|
||||
'advantages_of_direct_sales' => 'ventajas de la venta directa',
|
||||
'aloe_high_quality_copy' => 'El gel de hojas de aloe vera es un verdadero tesoro y un regalo de la naturaleza. Pero hay muchas cosas que considerar, desde el cultivo hasta el procesamiento, para garantizar que estos valiosos ingredientes se conserven y lleguen al cliente. Desafortunadamente, muchos fabricantes no se adhieren al 1x1 de producción de aloe vera, por lo que hay una serie de productos de aloe vera en el mercado que tienen poco o ningún efecto. Entonces, ¿qué hace que nuestros productos sean de tan alta calidad?',
|
||||
'aloe_high_quality_hl' => '¿Qué hace que nuestros productos de aloe vera sean de tan alta calidad?',
|
||||
'aloe_high_quality_li1' => 'Las plantas de aloe tienen más de 5 años.',
|
||||
'aloe_high_quality_li10' => 'Alta proporción de aloe puro en cada producto.',
|
||||
'aloe_high_quality_li2' => 'Tener más de 2000 horas de sol al año.',
|
||||
'aloe_high_quality_li3' => 'cultivo puramente controlado biológicamente',
|
||||
'aloe_high_quality_li4' => 'sin (!) riego artificial',
|
||||
'aloe_high_quality_li5' => 'sin plagas ni herbicidas',
|
||||
'aloe_high_quality_li6' => 'cosechar y filetear las hojas a mano.',
|
||||
'aloe_high_quality_li7' => 'procesamiento en productos directamente después de la cosecha.',
|
||||
'aloe_high_quality_li8' => 'Sólo el gel puro: sin polvo ni extracto.',
|
||||
'aloe_high_quality_li9' => 'Contenido de aloverosa certificado superior a 1.600 mg/l.',
|
||||
'aloe_high_quality_subl' => 'Uno de los mejores jugos de aloe vera del mundo como base para productos de aloe vera de alta calidad.',
|
||||
'aloe_vera_word_copy' => 'Las propiedades excepcionales y únicas del mundo del aloe vera se deben a la interacción y simbiosis únicas de los diferentes ingredientes e ingredientes activos. Ninguna otra planta conocida hasta la fecha tiene una gama tan amplia de usos curativos y nutritivos. En total, actualmente se conocen en la literatura médica más de 200 sustancias activas y constantemente se descubren otras nuevas. La decodificación de la compleja interacción de todas las sustancias apenas comienza, pero sus efectos ya están muy bien documentados.',
|
||||
'bio_quality_copy' => 'Garantizamos la mejor calidad a través de la producción manual e ingredientes orgánicos. El clima típico de Mallorca desafía a las plantas. Las pruebas han demostrado que este clima es óptimo para un perfecto desarrollo de las plantas.',
|
||||
'bio_quality_hl' => 'calidad 100% ORGÁNICA',
|
||||
'bio_quality_subl' => 'artesanía ecológica certificada de Mallorca.',
|
||||
'business_environment_hl' => 'ambiente de negocios',
|
||||
'business_environment_list' => '<ul class="small"> <li>Cosmética / cosmética natural</li> <li>Peinado</li> <li>Nutrición</li> <li>Cuidado de uñas y pies</li> <li> Naturista y medicina alternativa</li> <li>Medicina (piel, fisio, general, etc.)</li> <li>Todo sobre animales</li> <li>Yoga y meditación</li> <li>Gastronomía </li> <li>Deportes y fitness</li> <li>y mucho más.</li> </ul>',
|
||||
'career_opportunitie_point_1' => 'Vende productos adecuados para una vida sana y vital y que te brinden a ti y a tus seres queridos una gran experiencia de bienestar.',
|
||||
'career_opportunitie_point_2' => 'Nos mantenemos actualizados y nos apoyamos en grupos de WhatsApp y videollamadas. ¡No estás solo!',
|
||||
'career_opportunitie_point_3' => 'Le transmitimos nuestros conocimientos, herramientas de marketing probadas y materiales publicitarios, porque sólo tendremos éxito si USTED tiene éxito.',
|
||||
'career_opportunitie_point_4' => 'Benefíciese de medidas de apoyo como formación, eventos de equipo o campañas de ventas conjuntas. ¡Juntos tenemos éxito!',
|
||||
'career_opportunitie_point_5' => 'Utilice las redes sociales y hable sobre productos y experiencias. Obtenga nuevos clientes y socios a través de Facebook & Co.',
|
||||
'career_opportunities_at_mivita' => 'oportunidades laborales en mivita',
|
||||
'compatibility_with_family_copy1' => '¿Quién no lo sabe? Falta dinero por todas partes y el jefe siempre hace mala cara cuando el niño está enfermo. Muchas familias dependen de un segundo empleo o del trabajo a tiempo parcial de la madre o el padre. Y esto muchas veces no puede conciliarse con las ideas del empresario. Pero, ¿qué pasa si usted mismo acumula sus ingresos adicionales mensuales y al mismo tiempo tiene más tiempo para su hijo?',
|
||||
'compatibility_with_family_copy2' => 'Especialmente en la venta directa, con sus opciones de gestión del tiempo libre e ingresos pasivos, a medio plazo tienes tanta libertad que un trabajo fijo no te puede ofrecer. Como consultor independiente de MIVITA, tú decides cuándo y dónde trabajar. Y eso no afecta sólo a los padres jóvenes. Las ventas directas también representan una solución perfecta para personas que necesitan cuidar a sus familiares o simplemente quieren tener más tiempo y alivio económico:',
|
||||
'compatibility_with_family_list' => '<ul class="small"> <li>Trabaja desde casa o mientras viajas</li> <li>Sin alquiler de oficina</li> <li>Sin inversión significativa en desarrollo</li> <li>Sin infraestructura costosa necesario</ li></ul>',
|
||||
'compatibility_with_family_private_life' => 'compatibilidad con la vida familiar y privada',
|
||||
'direct_sales_advantages_copy' => '<p>La venta directa se ha consolidado desde hace tiempo en todo el mundo como un tipo de negocio independiente y ya está representada en muchos sectores. La venta directa, también conocida como mercadeo en red, describe la venta <b>personal</b> de bienes o servicios a consumidores en el entorno inmediato: familiares, amigos, colegas, etc. Lo crucial aquí es el contacto personal y la Función de asesoramiento: ¡atención al cliente por excelencia! Y ese es el gran punto fuerte de la venta directa, el servicio al cliente. Creamos con mucha personalidad y transparencia algo que ya no es posible en la inmensidad anónima de Internet.</p>',
|
||||
'direct_sales_advantages_hl' => 'venta directa y sus ventajas.',
|
||||
'direct_sales_exactly_copy' => '<p>Imagínese que es un fanático entusiasta de los productos de una empresa en particular. Piensas para ti mismo: “Genial, tengo que contárselo a mi mejor amigo. Y mi amigo. Y la familia. Y el mundo entero en general.” - y compran el producto basándose en tu recomendación. Sucede todos los días. Todos lo sabemos.</p> <p>La diferencia es que no sólo lo recomiendas, no, tú mismo eres el vendedor, creando una base de clientes y, por lo tanto, un margen del 30-40%. Se ganaron nuevos clientes, ¡sí! Hasta aquí todo bien.</p> <p>Y ahora imagina que tu amiga o novia también se convierte en socia de ventas, crea una base de clientes y tú también ganas dinero con ello. Y así sigue: ¡hasta 3 niveles + bonificaciones!</p>',
|
||||
'direct_sales_exactly_hl' => 'Venta directa: ¿cómo funciona exactamente?',
|
||||
'funding_opportunities_copy' => '<p>Si desea dar el salto hacia la independencia total, existen varias opciones de financiación disponibles. Eche un vistazo a lo siguiente donde puede solicitar su primer capital inicial:</p> <p> <a href="https://www.existenzgruender.de" rel="nofollow" target="_blank ">www.existenzgruender .de</a><br> <a href="http://www.foerderdatabase.de" rel="nofollow" target="_blank">www.foerderkatalog.de</a><br> <a href ="https://www.kfw.de" rel="nofollow" target="_blank">www.kfw.de</a><br> <a href="http://www .mikrofinanz.net" rel="nofollow" target="_blank">www.mikrofinanz.net</a><br> </p>',
|
||||
'funding_opportunities_hl' => 'oportunidades de financiación',
|
||||
'how_to_sell_exactly_copy' => 'Hay muchas formas diferentes de vender productos o conseguir socios de ventas. Aquí te presentamos algunos de ellos. La regla más importante es: utilizar los productos y hablar de ellos. Entonces los clientes acudirán a usted por su cuenta.',
|
||||
'how_to_sell_exactly_hl' => '¿Y cómo vendo exactamente?',
|
||||
'make_people_happy_copy' => 'Nuestros productos ayudan a las personas con una amplia variedad de problemas de la piel y, a menudo, se utilizan para tratar la neurodermatitis, la psoriasis, el acné y muchas otras enfermedades de la piel. El jugo puro de aloe vera orgánico es un excelente biorregulador, tiene un efecto antiinflamatorio y ayuda al cuerpo a mantener la flora intestinal. También puedes ayudar a otras personas a mantener sus cuerpos sanos de forma natural.',
|
||||
'make_people_happy_hl' => 'Hacer a la gente feliz...',
|
||||
'origin_aloe_copy' => 'La finca en Mallorca tiene una superficie de aproximadamente 40 hectáreas. Allí se cultivan y cuidan las plantas de aloe vera. Las 200.000 plantas deben tener al menos cinco años antes de que se puedan cosechar las hojas. Una planta necesita al menos 2.000 horas de sol al año para acumular los valiosos nutrientes para el jugo.',
|
||||
'origin_aloe_hl' => 'origen de nuestro aloe',
|
||||
'origin_aloe_subl' => 'de la isla de vacaciones favorita de los alemanes',
|
||||
'pillars_best_aloe_vera_quality' => 'Los 5 pilares para la mejor calidad del aloe vera',
|
||||
'pillars_best_aloe_vera_quality_1_hl' => 'certificado ORGÁNICO',
|
||||
'pillars_best_aloe_vera_quality_1_subl' => 'Aloe vera procedente de agricultura biológica: sin sustancias nocivas',
|
||||
'pillars_best_aloe_vera_quality_2_hl' => 'gel puro de aloe',
|
||||
'pillars_best_aloe_vera_quality_2_subl' => 'procesamiento de gel de aloe puro, sin mezcla de agua y polvo',
|
||||
'pillars_best_aloe_vera_quality_3_hl' => 'producción in situ',
|
||||
'pillars_best_aloe_vera_quality_3_subl' => 'Las hojas de aloe recolectadas se procesan inmediatamente in situ y se conservan los principios activos.',
|
||||
'pillars_best_aloe_vera_quality_4_hl' => 'alto contenido de aloe',
|
||||
'pillars_best_aloe_vera_quality_4_subl' => 'Todos los productos tienen una alta proporción de aloe vera orgánico puro.',
|
||||
'pillars_best_aloe_vera_quality_5_hl' => 'alto contenido de rosa de aloever',
|
||||
'pillars_best_aloe_vera_quality_5_subl' => 'con 1.600-1.700 mg/l, un contenido de Aloverosa superior a la media: EL factor de calidad para el contenido de ingrediente activo del Aloe',
|
||||
'private_environment_hl' => 'en un ambiente privado',
|
||||
'private_environment_list' => '<ul class="small"> <li>Familia</li> <li>Amigos</li> <li>colegas de trabajo</li> <li>Vecinos</li> <li>fiestas en casa</li> <li>Club de Deportes</li> <li>Familia</li> <li>Dueño de la mascota</li> <li>u.v.m.</li> </ul>',
|
||||
'requirement_profile' => 'perfil de requisitos',
|
||||
'requirement_profile_at_mivita' => 'perfil de requisitos',
|
||||
'requirement_profile_at_mivita_copy' => '<p>Todo aquel que quiera construir algo propio con alegría y compromiso es bienvenido a MIVITA. Nuestros socios de ventas incluyen principalmente personas como...</p> <ul class="small"> <li>Empleados con trabajos de tiempo completo</li> <li>Empleados con trabajos de tiempo parcial</li> <li >familias jóvenes o familias monoparentales </li> <li>Empresarios independientes</li> <li>Estudiantes y aprendices</li> <li>Generación +50 que quieren volver a saber</li> </ul> <p > Si estás en Si encuentras este perfil de requisitos, entonces has venido al lugar correcto. Especialmente a las personas que sienten que pueden lograr más, que tal vez están estancadas en su carrera, a quienes les gustaría trabajar con mayor libertad e independencia: estaremos encantados de ofrecerles una primera consulta sin compromiso. </p>',
|
||||
'shop_at_the_aloe_vera_farm' => 'compre en la granja de Aloe Vera',
|
||||
'social_environment_hl' => 'en las redes sociales',
|
||||
'social_environment_list' => '<ul class="small"> <li>Facebook</li> <li>Youtube</li> <li>Instagram</li> <li>Snapchat</li> <li>Familia</li> <li >entre otros ...</li></ul>',
|
||||
'social_security_copy' => '<p>Casi todo el mundo se dedica a las ventas directas como trabajo a tiempo parcial. Al fin y al cabo, el éxito profesional con unos buenos ingresos económicos no se consigue de la noche a la mañana. Si aun así decide trabajar por cuenta propia, tenga en cuenta los siguientes puntos con respecto a su seguridad social:</p> <p> <ul class="small"> <li>Como trabajador por cuenta propia, puede contratar un plan de pensiones privado o afiliarse al seguro de pensiones legal. A diferencia de esto, en el seguro de pensiones legal existe un seguro obligatorio para los llamados "autónomos por cuenta ajena", que trabajan de forma permanente y básicamente para un solo cliente y no emplean a sus propios empleados. </li> <li> Como trabajador autónomo, puede contratar un seguro médico privado o, bajo determinadas condiciones, asegurarse voluntariamente en una compañía de seguros de enfermedad obligatoria. Sin embargo, deben tener algún tipo de seguro médico. </li> <li>Debe contratar un seguro de asistencia sanitaria siempre que tenga un seguro médico. </li> <li>No existe una afiliación obligatoria al seguro de desempleo legal. Después de crear su empresa, podrá seguir asegurándose allí voluntariamente bajo determinadas condiciones. </li></ul>',
|
||||
'social_security_hl' => 'seguridad Social',
|
||||
'start_up' => 'iniciar un negocio',
|
||||
'that_sounds_exciting_to_you' => '¿Te parece emocionante?',
|
||||
'then_get_in_touch_with_us_today' => 'Entonces contáctenos hoy; esperamos conocerlo.',
|
||||
'to_the_contact_form' => 'para contactar formulario',
|
||||
'to_the_registration' => 'para registro',
|
||||
'trade_licence_copy' => '<p>Si desea iniciar este negocio, necesita una licencia comercial. Esto no es nada descabellado y se puede solicitar en la oficina comercial de su ciudad. Hay pequeños costes únicos de entre 20 y 25 euros, dependiendo de la ciudad o el municipio. Piensa en una actividad específica que indicarás en la licencia comercial. Por ejemplo, “Venta de productos de cuidado y bienestar”. En el folleto sobre registro de empresas, creación de una empresa y trámites encontrará información útil e importante sobre los siguientes puntos:</p> <ul> <li>Registro de empresas</li> <li>Presentación de informes a la oficina de impuestos< /li> <li>Membresía en la asociación industrial y cámara de comercio </li></ul>',
|
||||
'trade_licence_hl' => 'licencia de negocios',
|
||||
'training_aloe_farm_mallorca' => 'formación en la Finca Aloe Vera de Mallorca.',
|
||||
'training_aloe_farm_mallorca_copy' => 'MIVITA organiza formación para consultores dos veces al año. Además del recorrido por la granja y las instalaciones de producción, el operador agrícola Werner Telwest le presentará los secretos del "lirio del desierto". Y lo mejor: para cada curso de formación hay un anuncio. Quien genere ventas será recompensado con un viaje de MIVITA y volará GRATIS a la isla de vacaciones favorita de los alemanes.',
|
||||
'women_direct_sales_copy' => 'Teniente Según la Asociación Federal de Ventas Directas de Alemania (BDD), el 82% de los directivos eran mujeres. Este fue el resultado de una encuesta realizada entre las empresas miembros de BDD. Por tanto, la proporción de mujeres es significativamente mayor que en comparación con la economía en su conjunto. Y eso no viene de ninguna parte. Tradicionalmente, en la venta directa trabajan muchas mujeres que, por condiciones familiares o por falta de igualdad de oportunidades en el mercado, encuentran aquí su vocación para vivir su empuje, ideas y energías para convertirse en una empresaria de éxito.',
|
||||
'women_direct_sales_hl' => 'mujeres en venta directa',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,44 +1,45 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'VAT' => 'IVA',
|
||||
'add_shopping_cart' => 'añadir a la cesta',
|
||||
'all_price_plus_VAT_info' => 'Todos los precios incluyen los legales. IVA: enlace a menos que se indique lo contrario',
|
||||
'application' => 'solicitud',
|
||||
'checkout_ssl_server' => 'Será redirigido a nuestro servidor de pago, la conexión está cifrada con SSL.',
|
||||
'delivery_time_1_3' => 'plazo de entrega: 1-3 días laborables',
|
||||
'description' => 'descripción',
|
||||
'details' => 'detalles',
|
||||
'excl_VAT_plus_shipping_costs' => 'sin IVA más gastos de envío',
|
||||
'free_shipping' => 'envío gratis',
|
||||
'free_shipping_at' => 'envío gratuito a partir de :value €',
|
||||
'free_shipping_costs_from' => 'envío gratis desde',
|
||||
'incl' => 'incluido',
|
||||
'incl_VAT_plus_shipping_costs' => 'IVA incluido, sin gastos de envío',
|
||||
'ingredients' => 'ingredientes',
|
||||
'not_free_shipping' => 'no envío gratis',
|
||||
'only_missing_free_shipping_at' => 'Ya sólo te queda :value € para tu envío gratis.',
|
||||
'only_missing_free_shipping_costs_from' => 'Ya sólo te queda :value € para tu envío gratis.',
|
||||
'payment_method_creditcard' => 'tarjeta de crédito',
|
||||
'payment_method_creditcard_copy' => 'El importe se deducirá de su tarjeta de crédito tan pronto como se envíe el pedido. El proceso de la tarjeta de crédito se procesa a través de nuestro proveedor de servicios de pago PAYONE.',
|
||||
'payment_method_direct' => 'transferencia bancaria instantánea',
|
||||
'payment_method_direct_copy' => 'Después de una verificación exitosa, será redirigido a la página de pago seguro de PAYONE para que las transferencias SOFORT continúen con el pago. Después del pago exitoso, no cierre el navegador hasta que haya sido redirigido nuevamente a la tienda.',
|
||||
'payment_method_paypal' => 'pago con Paypal',
|
||||
'payment_method_paypal_copy' => 'Después de una verificación exitosa, será redirigido a la página de pago seguro de Paypal para continuar con el pago. Después del pago exitoso, no cierre el navegador hasta que haya sido redirigido nuevamente a la tienda.',
|
||||
'payment_method_prepayment' => 'pago por adelantado',
|
||||
'payment_method_prepayment_copy' => 'Una vez que hayas enviado el pedido, recibirás un correo electrónico con los datos bancarios para realizar el pago. Una vez recibido el importe, se enviarán sus productos.',
|
||||
'payment_method_sepa' => 'débito directo SEPA',
|
||||
'payment_method_sepa_copy' => 'Se le cobrará a su cuenta por este pedido después de enviarlo. El débito directo SEPA se procesa a través de nuestro proveedor de servicios de pago PAYONE.',
|
||||
'payment_methods' => 'métodos de pago',
|
||||
'plus_shipping_cost' => 'más envío y manipulación',
|
||||
'price_net' => 'precios netos',
|
||||
'product_details' => 'detalles de producto',
|
||||
'shipping_cost' => 'envío',
|
||||
'shipping_methods_costs' => 'métodos de envío y costos de envío',
|
||||
'shopping_cart' => 'carro de la compra',
|
||||
'shopping_cart_sum' => 'total del carrito de compras',
|
||||
'sum_net' => 'neto total',
|
||||
'to_checkout' => 'para revisar',
|
||||
'to_product' => 'al producto',
|
||||
'to_shopping_cart' => 'a la canasta de productos',
|
||||
);
|
||||
return [
|
||||
'VAT' => 'IVA',
|
||||
'add_shopping_cart' => 'añadir a la cesta',
|
||||
'all_price_plus_VAT_info' => 'Todos los precios incluyen los legales. IVA: enlace a menos que se indique lo contrario',
|
||||
'application' => 'solicitud',
|
||||
'checkout_ssl_server' => 'Será redirigido a nuestro servidor de pago, la conexión está cifrada con SSL.',
|
||||
'delivery_time_1_3' => 'plazo de entrega: 1-3 días laborables',
|
||||
'description' => 'descripción',
|
||||
'details' => 'detalles',
|
||||
'excl_VAT_plus_shipping_costs' => 'sin IVA más gastos de envío',
|
||||
'free_shipping' => 'envío gratis',
|
||||
'free_shipping_at' => 'envío gratuito a partir de :value €',
|
||||
'free_shipping_costs_from' => 'envío gratis desde',
|
||||
'incl' => 'incluido',
|
||||
'incl_VAT_plus_shipping_costs' => 'IVA incluido, sin gastos de envío',
|
||||
'ingredients' => 'ingredientes',
|
||||
'not_free_shipping' => 'no envío gratis',
|
||||
'only_missing_free_shipping_at' => 'Ya sólo te queda :value € para tu envío gratis.',
|
||||
'only_missing_free_shipping_costs_from' => 'Ya sólo te queda :value € para tu envío gratis.',
|
||||
'payment_method_creditcard' => 'tarjeta de crédito',
|
||||
'payment_method_creditcard_copy' => 'El importe se deducirá de su tarjeta de crédito tan pronto como se envíe el pedido. El proceso de la tarjeta de crédito se procesa a través de nuestro proveedor de servicios de pago PAYONE.',
|
||||
'payment_method_direct' => 'transferencia bancaria instantánea',
|
||||
'payment_method_direct_copy' => 'Después de una verificación exitosa, será redirigido a la página de pago seguro de PAYONE para que las transferencias SOFORT continúen con el pago. Después del pago exitoso, no cierre el navegador hasta que haya sido redirigido nuevamente a la tienda.',
|
||||
'payment_method_paypal' => 'pago con Paypal',
|
||||
'payment_method_paypal_copy' => 'Después de una verificación exitosa, será redirigido a la página de pago seguro de Paypal para continuar con el pago. Después del pago exitoso, no cierre el navegador hasta que haya sido redirigido nuevamente a la tienda.',
|
||||
'payment_method_prepayment' => 'pago por adelantado',
|
||||
'payment_method_prepayment_copy' => 'Una vez que hayas enviado el pedido, recibirás un correo electrónico con los datos bancarios para realizar el pago. Una vez recibido el importe, se enviarán sus productos.',
|
||||
'payment_method_sepa' => 'débito directo SEPA',
|
||||
'payment_method_sepa_copy' => 'Se le cobrará a su cuenta por este pedido después de enviarlo. El débito directo SEPA se procesa a través de nuestro proveedor de servicios de pago PAYONE.',
|
||||
'payment_methods' => 'métodos de pago',
|
||||
'plus_shipping_cost' => 'más envío y manipulación',
|
||||
'price_net' => 'precios netos',
|
||||
'product_details' => 'detalles de producto',
|
||||
'shipping_cost' => 'envío',
|
||||
'shipping_methods_costs' => 'métodos de envío y costos de envío',
|
||||
'shopping_cart' => 'carro de la compra',
|
||||
'shopping_cart_sum' => 'total del carrito de compras',
|
||||
'sum_net' => 'neto total',
|
||||
'to_checkout' => 'para revisar',
|
||||
'to_product' => 'al producto',
|
||||
'to_shopping_cart' => 'a la canasta de productos',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,89 +1,94 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'NOW' => 'AHORA',
|
||||
'VATID' => 'número de identificación del IVA.',
|
||||
'VATID_value' => 'DE 453867883',
|
||||
'accept_youtube_load' => 'aceptar y cargar video de youtube',
|
||||
'address' => 'dirección',
|
||||
'all_rights_reserved' => 'todos los derechos reservados, mivita.care',
|
||||
'aloe_vera' => 'Aloe vera',
|
||||
'best_regards' => 'atentamente',
|
||||
'business_hours' => 'horas de trabajo',
|
||||
'business_hours_details' => 'lunes a viernes: de 9 a 12 horas y de 13 a 16 horas',
|
||||
'Director General' => 'imprimir',
|
||||
'business_owner_value' => 'Alois Ried',
|
||||
'cancellation_policy' => 'derecho a retirada',
|
||||
'career_opportunities' => 'oportunidades profesionales',
|
||||
'change_country' => 'cambiar pais',
|
||||
'contact' => 'contacto',
|
||||
'contact_address' => 'mivita care gmbh<br>Leinfeld 2<br>87755 Kirchhaslach<br>',
|
||||
'contact_hl' => '¡Escríbenos!',
|
||||
'contact_now' => 'contacta ahora',
|
||||
'contact_number' => '+49 (0) 8333 94 61 767',
|
||||
'contact_number_link' => '+4983339461767',
|
||||
'contact_subl' => '¿Está interesado en nuestro negocio o tiene preguntas sobre los productos? Entonces esperamos tener noticias suyas y nos comunicaremos con usted lo antes posible.',
|
||||
'contents' => 'contenido',
|
||||
'email' => 'correo electrónico',
|
||||
'email_address' => 'info@mivita.care',
|
||||
'for_you_on_spot' => 'para ti en el sitio',
|
||||
'for_you_on_spot_copy' => 'La transparencia es muy imprtante para nosotros. Por eso estuvimos en Mallorca para visitar la granja de Aloe Vera. Para que sepa exactamente de dónde proceden nuestros productos y cómo se producen.',
|
||||
'gtc' => 'condiciones',
|
||||
'impress' => 'imprimir',
|
||||
'language' => 'idioma',
|
||||
'more' => 'más',
|
||||
'my_accessibility' => 'Mi accesibilidad',
|
||||
'my_accessibility:' => 'mi disponibilidad',
|
||||
'no' => 'NO',
|
||||
'note_on_use' => 'aviso de uso',
|
||||
'note_on_use_copy' => '¡El uso, reproducción, distribución, publicación o uso comercial no autorizado sin el permiso del autor del contenido de este sitio web está prohibido y será perseguido tanto bajo la ley penal como civil!',
|
||||
'online_dispute_resolution' => 'resolución de disputas en línea',
|
||||
'online_dispute_resolution_copy' => 'Según el artículo 14, apartado 1, ODR-VO: la Comisión Europea proporciona una plataforma para la resolución de disputas (OS) en línea, que puede encontrar aquí',
|
||||
'partner' => 'socio',
|
||||
'payment_methods' => 'métodos de pago',
|
||||
'phone' => 'teléfono',
|
||||
'phone_number' => 'teléfono: +49 (0) 8333 94 61 767',
|
||||
'privacy_policy' => 'protección de Datos',
|
||||
'productworld' => 'mundo del producto',
|
||||
'read' => 'leer',
|
||||
'register' => 'registro',
|
||||
'register_now' => 'únete ahora',
|
||||
'register_number' => 'número de registro',
|
||||
'register_number_value' => 'HRB 21591',
|
||||
'registry_court' => 'tribunal de registro',
|
||||
'registry_court_value' => 'Memmingen',
|
||||
'sales_partner_or_questions' => '¿Le gustaría convertirse en socio de ventas o tiene preguntas sobre nuestros productos?',
|
||||
'send_message' => 'enviar mensaje',
|
||||
'shipping_costs' => 'envío',
|
||||
'shop' => 'comercio',
|
||||
'show_all_products' => 'Ver todos los productos',
|
||||
'slider_hl' => 'suplementos nutricionales',
|
||||
'slider_subl' => 'Aloe Vera Orgánico & Cosmética natural',
|
||||
'start' => 'comenzar',
|
||||
'start_aloe_copy' => 'Trabajamos con los más altos estándares con Aloe Vera Farm en Mallorca, lo que garantiza la mejor calidad en todo el mundo.',
|
||||
'start_aloe_hl' => 'Aloe vera',
|
||||
'start_copy_mivita' => 'MIVITA es una empresa con sede en Alemania que comercializa productos innovadores, respetuosos con el medio ambiente y de alta calidad. Desde su ingreso al mercado, la empresa MIVITA ha apostado por un entendimiento de valores que se centran en la satisfacción del cliente y la responsabilidad con el medio ambiente.',
|
||||
'start_mivitapartner_copy' => '<p>MIVITA es el socio exclusivo de la finca Aloe Vera de Mallorca en el área de venta directa en Alemania. Aquí se han unido dos empresas para las que la calidad y la sostenibilidad son máximas prioridades. Sólo así podremos convertir a los clientes satisfechos en verdaderos fans de nuestros productos a largo plazo.</p> <blockquote> <p><i>“Por el bien de las personas, los animales y la naturaleza... Sostenibilidad y productos que Realmente "hacerte bien" es importante para nosotros".</i></p> <p>Alois Ried - Propietario de MIVITA</p> </blockquote>',
|
||||
'start_products_copy' => 'Aquí encontrará una descripción general de la gama completa de productos premium de MIVITA. Desde jugo de aloe de alta calidad hasta cosméticos calmantes.',
|
||||
'start_products_hl' => 'productos',
|
||||
'start_salespartner_copy' => 'Conviértete en socio comercial de MIVITA y construye tu propio negocio con productos de calidad. Si lo deseas, puedes empezar inmediatamente...',
|
||||
'start_salespartner_hl' => 'socio de ventas',
|
||||
'start_why_copy' => '<p>Nuestros clientes confían con razón en las excelentes propiedades de los productos MIVITA. Esto significa que todos toman activamente decisiones inteligentes para la salud y el medio ambiente.</p> <p>No sólo damos gran importancia a la calidad de nuestros productos, sino también, por supuesto, al asesoramiento completo y competente de asesores amigables y expertos. </p> <p>Solo desarrollamos y vendemos productos de alta calidad. Cuando se usan y cuidan adecuadamente, son duraderos y muy productivos. Factores que aseguran la satisfacción de nuestros clientes.</p>',
|
||||
'start_why_hl' => '¿Por qué MIVITA?',
|
||||
'support_mivita' => 'soporte mivita',
|
||||
'thank_you_for_your_request' => 'Muchas gracias por tu consulta',
|
||||
'through_whom_label' => '¿Quién nos llamó la atención (socio de ventas, cliente, redes sociales, etc.)? Asegúrese de proporcionar un nombre; esto es importante para nuestra tarea interna:*',
|
||||
'through_whom_placeholder' => 'nombre y apellidos, página web, Facebook, Instagram, perfil de YouTube o similar',
|
||||
'to_contact' => 'contactar',
|
||||
'to_privacy_policy' => 'declaracion de privacidad',
|
||||
'we_will_get_back_to_you' => 'Le contactaremos inmediatamente.',
|
||||
'welcome' => 'bienvenido',
|
||||
'welcome_copy' => 'Espero su visita a mi tienda online MIVITA. Soy tu asesor personal sobre los productos y su aplicación.',
|
||||
'yes' => 'SÍ',
|
||||
'you_are_now_in_shop' => 'Estás en la tienda:',
|
||||
'you_are_now_in_shop_notice' => 'Nota importante: Los pedidos en el país seleccionado solo se pueden enviar dentro de ese país. Si cambia su país, se cerrará su sesión actual y se vaciará su carrito de compras.',
|
||||
'your_enquiry_relate_partnership' => '¿Su consulta se refiere a una asociación de ventas deseada?*',
|
||||
'your_message_to_us' => 'tu mensaje para nosotros',
|
||||
'your_mivita_team' => 'tu equipo mivita.care',
|
||||
'youtube_accepted_copy' => 'Al cargar el vídeo de YouTube aceptas nuestra declaración de protección de datos / XII. Integración de servicios y contenidos de terceros.',
|
||||
);
|
||||
return [
|
||||
'NOW' => 'AHORA',
|
||||
'VATID' => 'número de identificación del IVA.',
|
||||
'VATID_value' => 'DE 453867883',
|
||||
'accept_youtube_load' => 'aceptar y cargar video de youtube',
|
||||
'address' => 'dirección',
|
||||
'all_rights_reserved' => 'todos los derechos reservados, mivita.care',
|
||||
'aloe_vera' => 'Aloe vera',
|
||||
'best_regards' => 'atentamente',
|
||||
'business_hours' => 'horas de trabajo',
|
||||
'business_hours_details' => 'lunes a viernes: de 9 a 12 horas y de 13 a 16 horas',
|
||||
'business_owner_value' => 'Alois Ried',
|
||||
'cancellation_policy' => 'derecho a retirada',
|
||||
'career_opportunities' => 'oportunidades profesionales',
|
||||
'change_country' => 'cambiar pais',
|
||||
'contact' => 'contacto',
|
||||
'contact_address' => 'mivita care gmbh<br>Leinfeld 2<br>87755 Kirchhaslach<br>',
|
||||
'contact_hl' => '¡Escríbenos!',
|
||||
'contact_now' => 'contacta ahora',
|
||||
'contact_number' => '+49 (0) 8333 94 61 767',
|
||||
'contact_number_link' => '+4983339461767',
|
||||
'contact_subl' => '¿Está interesado en nuestro negocio o tiene preguntas sobre los productos? Entonces esperamos tener noticias suyas y nos comunicaremos con usted lo antes posible.',
|
||||
'contents' => 'contenido',
|
||||
'email' => 'correo electrónico',
|
||||
'email_address' => 'info@mivita.care',
|
||||
'for_you_on_spot' => 'para ti en el sitio',
|
||||
'for_you_on_spot_copy' => 'La transparencia es muy imprtante para nosotros. Por eso estuvimos en Mallorca para visitar la granja de Aloe Vera. Para que sepa exactamente de dónde proceden nuestros productos y cómo se producen.',
|
||||
'gtc' => 'condiciones',
|
||||
'impress' => 'imprimir',
|
||||
'language' => 'idioma',
|
||||
'more' => 'más',
|
||||
'my_accessibility' => 'Mi accesibilidad',
|
||||
'no' => 'NO',
|
||||
'note_on_use' => 'aviso de uso',
|
||||
'note_on_use_copy' => '¡El uso, reproducción, distribución, publicación o uso comercial no autorizado sin el permiso del autor del contenido de este sitio web está prohibido y será perseguido tanto bajo la ley penal como civil!',
|
||||
'online_dispute_resolution' => 'resolución de disputas en línea',
|
||||
'online_dispute_resolution_copy' => 'Según el artículo 14, apartado 1, ODR-VO: la Comisión Europea proporciona una plataforma para la resolución de disputas (OS) en línea, que puede encontrar aquí',
|
||||
'partner' => 'socio',
|
||||
'payment_methods' => 'métodos de pago',
|
||||
'phone' => 'teléfono',
|
||||
'phone_number' => 'teléfono: +49 (0) 8333 94 61 767',
|
||||
'privacy_policy' => 'protección de Datos',
|
||||
'productworld' => 'mundo del producto',
|
||||
'read' => 'leer',
|
||||
'register' => 'registro',
|
||||
'register_now' => 'únete ahora',
|
||||
'register_number' => 'número de registro',
|
||||
'register_number_value' => 'HRB 21591',
|
||||
'registry_court' => 'tribunal de registro',
|
||||
'registry_court_value' => 'Memmingen',
|
||||
'sales_partner_or_questions' => '¿Le gustaría convertirse en socio de ventas o tiene preguntas sobre nuestros productos?',
|
||||
'send_message' => 'enviar mensaje',
|
||||
'shipping_costs' => 'envío',
|
||||
'shop' => 'comercio',
|
||||
'show_all_products' => 'Ver todos los productos',
|
||||
'slider_hl' => 'suplementos nutricionales',
|
||||
'slider_subl' => 'Aloe Vera Orgánico & Cosmética natural',
|
||||
'start' => 'comenzar',
|
||||
'start_aloe_copy' => 'Trabajamos con los más altos estándares con Aloe Vera Farm en Mallorca, lo que garantiza la mejor calidad en todo el mundo.',
|
||||
'start_aloe_hl' => 'Aloe vera',
|
||||
'start_copy_mivita' => 'MIVITA es una empresa con sede en Alemania que comercializa productos innovadores, respetuosos con el medio ambiente y de alta calidad. Desde su ingreso al mercado, la empresa MIVITA ha apostado por un entendimiento de valores que se centran en la satisfacción del cliente y la responsabilidad con el medio ambiente.',
|
||||
'start_mivitapartner_copy' => '<p>MIVITA es el socio exclusivo de la finca Aloe Vera de Mallorca en el área de venta directa en Alemania. Aquí se han unido dos empresas para las que la calidad y la sostenibilidad son máximas prioridades. Sólo así podremos convertir a los clientes satisfechos en verdaderos fans de nuestros productos a largo plazo.</p> <blockquote> <p><i>“Por el bien de las personas, los animales y la naturaleza... Sostenibilidad y productos que Realmente "hacerte bien" es importante para nosotros".</i></p> <p>Alois Ried - Propietario de MIVITA</p> </blockquote>',
|
||||
'start_products_copy' => 'Aquí encontrará una descripción general de la gama completa de productos premium de MIVITA. Desde jugo de aloe de alta calidad hasta cosméticos calmantes.',
|
||||
'start_products_hl' => 'productos',
|
||||
'start_salespartner_copy' => 'Conviértete en socio comercial de MIVITA y construye tu propio negocio con productos de calidad. Si lo deseas, puedes empezar inmediatamente...',
|
||||
'start_salespartner_hl' => 'socio de ventas',
|
||||
'start_why_copy' => '<p>Nuestros clientes confían con razón en las excelentes propiedades de los productos MIVITA. Esto significa que todos toman activamente decisiones inteligentes para la salud y el medio ambiente.</p> <p>No sólo damos gran importancia a la calidad de nuestros productos, sino también, por supuesto, al asesoramiento completo y competente de asesores amigables y expertos. </p> <p>Solo desarrollamos y vendemos productos de alta calidad. Cuando se usan y cuidan adecuadamente, son duraderos y muy productivos. Factores que aseguran la satisfacción de nuestros clientes.</p>',
|
||||
'start_why_hl' => '¿Por qué MIVITA?',
|
||||
'support_mivita' => 'soporte mivita',
|
||||
'thank_you_for_your_request' => 'Muchas gracias por tu consulta',
|
||||
'through_whom_label' => '¿Quién nos llamó la atención (socio de ventas, cliente, redes sociales, etc.)? Asegúrese de proporcionar un nombre; esto es importante para nuestra tarea interna:*',
|
||||
'through_whom_placeholder' => 'nombre y apellidos, página web, Facebook, Instagram, perfil de YouTube o similar',
|
||||
'to_contact' => 'contactar',
|
||||
'to_privacy_policy' => 'declaracion de privacidad',
|
||||
'we_will_get_back_to_you' => 'Le contactaremos inmediatamente.',
|
||||
'welcome' => 'bienvenido',
|
||||
'welcome_copy' => 'Espero su visita a mi tienda online MIVITA. Soy tu asesor personal sobre los productos y su aplicación.',
|
||||
'yes' => 'SÍ',
|
||||
'you_are_now_in_shop' => 'Estás en la tienda:',
|
||||
'you_are_now_in_shop_notice' => 'Nota importante: Los pedidos en el país seleccionado solo se pueden enviar dentro de ese país. Si cambia su país, se cerrará su sesión actual y se vaciará su carrito de compras.',
|
||||
'your_enquiry_relate_partnership' => '¿Su consulta se refiere a una asociación de ventas deseada?*',
|
||||
'your_message_to_us' => 'tu mensaje para nosotros',
|
||||
'your_mivita_team' => 'tu equipo mivita.care',
|
||||
'youtube_accepted_copy' => 'Al cargar el vídeo de YouTube aceptas nuestra declaración de protección de datos / XII. Integración de servicios y contenidos de terceros.',
|
||||
'business_owner' => 'Director general',
|
||||
'to_login' => 'iniciar sesión',
|
||||
'to_customer_portal' => 'al área de clientes',
|
||||
'to_sales_center' => 'al sales center',
|
||||
'shipping_error_billing' => 'Nota: Tu carrito con el país de entrega :shipping_country no coincide con tu dirección de facturación - país de entrega :billing_country.',
|
||||
'shipping_error_delivery' => 'Nota: Tu carrito con el país de entrega :shipping_country no coincide con tu dirección de entrega - país de entrega :billing_country.',
|
||||
'' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ return [
|
|||
'warning_next_date_soon_select' => 'Remarque : la prochaine exécution de l’abonnement est déjà dans :placeholder_days jours (:placeholder_date).',
|
||||
'warning_next_date_info' => 'La prochaine exécution de l’abonnement est dans :days jours, le :date.',
|
||||
'info_next_execution_select' => 'Prochaine exécution : dans :placeholder_days jours, le :placeholder_date.',
|
||||
'error_change_locked' => 'Les modifications ne sont plus possibles. La prochaine exécution est dans :days jours. Les modifications doivent être effectuées au moins 10 jours avant.',
|
||||
'error_abo_interval_too_soon' => 'Le jour de livraison choisi n’est qu’à :days jours. Veuillez choisir un jour de livraison situé au moins 10 jours dans le futur.',
|
||||
'error_cancel_locked' => 'Une résiliation n’est plus possible. La prochaine exécution est dans :days jours. Les résiliations doivent être effectuées au moins 3 jours avant.',
|
||||
'error_pause_locked' => 'L’abonnement ne peut plus être mis en pause. La prochaine exécution est dans :days jours. La pause doit être effectuée au moins 3 jours avant.',
|
||||
'error_change_locked' => 'Les modifications ne sont plus possibles. La prochaine exécution est dans :days jours. Les modifications doivent être effectuées au moins :lock jours avant.',
|
||||
'error_abo_interval_too_soon' => 'Le jour de livraison choisi n’est qu’à :days jours. Veuillez choisir un jour de livraison situé au moins :lock jours dans le futur.',
|
||||
'error_cancel_locked' => 'Une résiliation n’est plus possible. La prochaine exécution est dans :days jours. Les résiliations doivent être effectuées au moins :lock jours avant.',
|
||||
'error_pause_locked' => 'L’abonnement ne peut plus être mis en pause. La prochaine exécution est dans :days jours. La pause doit être effectuée au moins :lock jours avant.',
|
||||
'error_next_date' => 'La date de la prochaine exécution est incorrecte',
|
||||
'checkout_mail_abo_hl' => 'Votre abonnement / livraison régulière.',
|
||||
'checkout_mail_abo_start' => 'Votre abonnement a été créé avec succès avec les paramètres suivants :',
|
||||
|
|
@ -164,6 +164,37 @@ return [
|
|||
'retry_exception' => 'La nouvelle tentative de paiement n’a pas pu être finalisée : :error',
|
||||
'team_subscriptions' => 'Abonnements équipe',
|
||||
'team_customer_abos' => 'Abonnements clients de l’équipe',
|
||||
'team_total' => 'Total',
|
||||
'team_line' => 'Niveau :line',
|
||||
'filter_period' => 'Période :',
|
||||
'team_total_abos' => 'Abonnements totaux de l’équipe',
|
||||
'team_own_abos' => 'Abonnements propres',
|
||||
'team_members_with_abo' => 'Avec abonnement propre',
|
||||
'team_by_level' => 'Abonnements par niveau',
|
||||
'new_this_month' => 'nouveaux ce mois-ci',
|
||||
'with_own_abo' => 'Avec abonnement propre',
|
||||
'consultants' => 'Conseillers',
|
||||
'level' => 'Niveau',
|
||||
'own_abo' => 'Abonnement propre',
|
||||
'customer_abos_count' => 'Abonnements clients',
|
||||
'career_level' => 'Niveau de carrière',
|
||||
'of' => 'sur',
|
||||
'yes' => 'Oui',
|
||||
'no' => 'Non',
|
||||
'shop_1000' => 'Boutiques 1000 points',
|
||||
'next_execution' => 'Prochaine exécution',
|
||||
'executions_count' => 'Exécutions',
|
||||
'abo_count_points' => 'Points',
|
||||
'no_own_abo' => 'Aucun abonnement propre.',
|
||||
'no_customer_abos' => 'Aucun abonnement client.',
|
||||
'team_growth' => 'Croissance des abonnements (nouveaux par mois)',
|
||||
'month' => 'Mois',
|
||||
'new_own_abos' => 'Nouveaux abonnements propres',
|
||||
'new_customer_abos' => 'Nouveaux abonnements clients',
|
||||
'new_total' => 'Nouveaux au total',
|
||||
'filter' => 'Filtrer',
|
||||
'reset' => 'Réinitialiser',
|
||||
'filter_added_period' => 'Ajouté durant la période :',
|
||||
'chart_monthly_abos' => 'Abonnements par mois',
|
||||
'chart_active_abos' => 'Abonnements actifs',
|
||||
'chart_abos_label' => 'Abonnements',
|
||||
|
|
@ -171,4 +202,33 @@ return [
|
|||
'customer_privacy_info' => 'Pour des raisons de protection des données, aucune donnée personnelle client n’est affichée.',
|
||||
'every_month_on' => 'mensuellement le :day.',
|
||||
'back' => 'retour',
|
||||
|
||||
// Statut / paiement en attente / traité en externe (synchronisé avec de/abo.php)
|
||||
'abo_extern_done' => 'traité en externe',
|
||||
'error_user_has_initiated_abo' => 'Un abonnement a déjà été créé pour vous ou son paiement est encore en cours. Veuillez vérifier le statut sous « Mes abonnements ».',
|
||||
'pending_payment_waiting_title' => 'Abonnement créé - paiement pas encore confirmé',
|
||||
'pending_payment_waiting_copy' => 'Le paiement a été finalisé. Nous attendons encore le statut de paiement du prestataire de paiement. Tant qu’aucun statut n’est reçu, cette entrée ne peut pas être supprimée.',
|
||||
'pending_payment_processing_title' => 'Abonnement créé - paiement en cours de traitement',
|
||||
'pending_payment_processing_copy' => 'Le prestataire de paiement a déjà fourni un statut. Veuillez attendre la confirmation finale du paiement.',
|
||||
'pending_payment_failed_title' => 'Échec du paiement',
|
||||
'pending_payment_failed_copy' => 'Le paiement de cet abonnement n’a pas pu être finalisé. Vous pouvez supprimer cette entrée puis recréer l’abonnement.',
|
||||
'pending_delete_button' => 'Supprimer l’entrée',
|
||||
'pending_delete_success' => 'L’entrée d’abonnement non confirmée a été supprimée.',
|
||||
'pending_delete_not_allowed' => 'Cette entrée d’abonnement ne peut pas encore être supprimée, car le paiement n’a pas encore définitivement échoué.',
|
||||
'payment_link_sent_title' => 'Lien de paiement d’abonnement envoyé',
|
||||
'payment_link_sent_copy' => 'Le lien de paiement a été envoyé au client. Tant qu’aucun paiement n’a été lancé, cette entrée peut être supprimée.',
|
||||
'payment_link_processing_copy' => 'Le client a lancé le paiement. Nous attendons le statut de paiement final du prestataire de paiement. Dans cet état, l’entrée ne peut pas être supprimée.',
|
||||
'payment_link_failed_copy' => 'Le paiement lié à ce lien de paiement d’abonnement a échoué ou a été annulé. Vous pouvez supprimer l’entrée puis créer un nouveau lien de paiement.',
|
||||
'payment_link_delete_success' => 'Le lien de paiement d’abonnement a été supprimé.',
|
||||
'payment_link_delete_not_allowed' => 'Ce lien de paiement ne peut actuellement pas être supprimé, car le paiement est déjà en cours ou finalisé.',
|
||||
'extern_done' => 'Traité en externe',
|
||||
'extern_done_confirm_title' => 'Marquer la commande comme traitée en externe',
|
||||
'extern_done_confirm_copy' => 'La commande sera marquée comme livrée et facturée en dehors du système. AUCUNE facture ni AUCUN bon de livraison ne sera généré, le statut reste impayé. Les points de l’abonnement seront crédités et le blocage de l’abonnement sera levé, afin qu’il reprenne normalement à la prochaine échéance.',
|
||||
'extern_done_confirm_button' => 'Marquer comme traité',
|
||||
'extern_done_only_abo' => 'Cette action n’est possible que pour les commandes d’abonnement.',
|
||||
'extern_done_no_order' => 'Aucune commande d’abonnement en attente pouvant être traitée n’a été trouvée.',
|
||||
'extern_done_already' => 'Cette commande a déjà été marquée comme traitée en externe.',
|
||||
'extern_done_already_paid' => 'Cette commande est déjà payée et ne peut pas être traitée en externe.',
|
||||
'extern_done_success' => 'La commande a été marquée comme traitée en externe. Points crédités, blocage levé.',
|
||||
'extern_done_error' => 'La commande n’a pas pu être marquée comme traitée : :error',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ return [
|
|||
'cancel' => 'annuler',
|
||||
'confirm' => 'confirmer',
|
||||
'file_is_too_big' => 'Le fichier est trop volumineux<br>max. $0 Mo',
|
||||
'image_too_small ' => 'Image trop petite<br>min. $0 pixels',
|
||||
'image_too_small' => 'Image trop petite<br>min. $0 pixels',
|
||||
'invalid_file' => 'Fichier invalide<br>uniquement : $0',
|
||||
'really_delete_picture' => 'Supprimer vraiment l’image ?',
|
||||
'rotate' => 'pivoter',
|
||||
|
|
|
|||
|
|
@ -127,4 +127,14 @@ Votre équipe MIVITA',
|
|||
'dhl_tracking_order_ref' => 'Numéro de commande : :order',
|
||||
'dhl_tracking_button' => 'Suivre l’envoi chez DHL',
|
||||
'dhl_tracking_info' => 'Vous pouvez consulter à tout moment le statut actuel de votre envoi chez DHL via le bouton ci-dessus.',
|
||||
|
||||
// Produits uniques de l'abonnement : rappel avant l'exécution
|
||||
'abo_reminder_subject' => 'Votre prochaine livraison d\'abonnement approche – ajoutez des produits maintenant',
|
||||
'abo_reminder_title' => 'Votre prochaine livraison d\'abonnement approche',
|
||||
'abo_reminder_intro' => '{1}Votre prochaine livraison d\'abonnement sera traitée dans :days jour (le :date).|[2,*]Votre prochaine livraison d\'abonnement sera traitée dans :days jours (le :date).',
|
||||
'abo_reminder_onetime_hint' => 'Vous pouvez désormais ajouter, une seule fois, d\'autres produits de notre gamme à cette livraison – sans frais de port supplémentaires et sans second envoi.',
|
||||
'abo_reminder_coverage_hint' => 'Veuillez vous assurer que votre moyen de paiement enregistré couvre le montant total (abonnement + produits supplémentaires).',
|
||||
'abo_reminder_sustainability_hint' => 'Ensemble, nous économisons des emballages et un second trajet de transport – bon pour l\'environnement.',
|
||||
'abo_reminder_button_consultant' => 'Ajouter des produits à la livraison',
|
||||
'abo_reminder_button_customer' => 'Ajouter des produits à la livraison',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ return [
|
|||
'weight' => 'Poids',
|
||||
'you_has_article_in_shopping_cart' => 'Vous avez :num article(s) dans votre panier',
|
||||
'excl' => 'plus',
|
||||
'VAT' => 'TVA',
|
||||
'ipay' => 'je paie',
|
||||
'cpay' => 'le client paie',
|
||||
'ipay_text' => 'Je paie moins ma marge et je facture le prix de vente à mon client',
|
||||
|
|
|
|||
|
|
@ -62,4 +62,8 @@ return [
|
|||
'subtotal_net' => 'Sous-total (net)',
|
||||
'shipping_costs' => 'Frais de livraison',
|
||||
'total_amount' => 'Montant total',
|
||||
|
||||
// Produits uniques de l'abonnement (regroupement facture/bon de livraison)
|
||||
'abo_items_heading' => 'Produits d\'abonnement',
|
||||
'abo_addon_items_heading' => 'Articles ajoutés une seule fois',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -92,4 +92,8 @@ return [
|
|||
'previous_orders' => 'commandes clients précédentes',
|
||||
'partner_since' => 'Partenaire depuis',
|
||||
'no_data_available' => 'Aucune donnée disponible',
|
||||
'inactive' => 'Inactif',
|
||||
'all' => 'Tous',
|
||||
'month' => 'Mois',
|
||||
'year' => 'Année',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,143 +1,177 @@
|
|||
|
||||
<style>
|
||||
table.table-product,
|
||||
table.table-product tr td,
|
||||
table.table-product tr th {
|
||||
border: none;
|
||||
}
|
||||
<style>
|
||||
table.table-product,
|
||||
table.table-product tr td,
|
||||
table.table-product tr th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.table-product tr.border-top td {
|
||||
border-top: 1px solid #b8b8b9;
|
||||
}
|
||||
table.table-product tr.border-top td {
|
||||
border-top: 1px solid #b8b8b9;
|
||||
}
|
||||
|
||||
table.table-product tr.border-bottom td,
|
||||
table.table-product tr.border-bottom th {
|
||||
border-bottom: 1px solid #b8b8b9;
|
||||
}
|
||||
|
||||
table.table-product tr.border-bottom td,
|
||||
table.table-product tr.border-bottom th {
|
||||
border-bottom: 1px solid #b8b8b9;
|
||||
}
|
||||
|
||||
.table-small {
|
||||
font-size: 0.9em;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.table-small td {
|
||||
padding: 0.225rem 1rem 0.225rem 0;
|
||||
}
|
||||
.table-small {
|
||||
font-size: 0.9em;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.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-small td {
|
||||
padding: 0.225rem 1rem 0.225rem 0;
|
||||
}
|
||||
|
||||
.table td.border-top {
|
||||
border: none;
|
||||
border-top: 1px solid #ccccdb;
|
||||
}
|
||||
.btn-md-extra {
|
||||
padding: 0.3rem 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.5;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.table td {
|
||||
border: none;
|
||||
}
|
||||
.md-btn-extra {
|
||||
width: calc(1.7rem + 2px) !important;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
.table th {
|
||||
border: none;
|
||||
border-bottom: 1px solid #c3c3d2;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
@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;
|
||||
.input-group-min-w {
|
||||
min-width: 102px;
|
||||
}
|
||||
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.small {
|
||||
font-size: 90%;
|
||||
}
|
||||
.table tfoot td {
|
||||
padding: 0.225rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
.img-extra {
|
||||
min-width: 55px;
|
||||
max-height: 120px;
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
<h5 class=" font-weight-semibold mb-2">
|
||||
{{ __('abo.abo_order_hl') }}
|
||||
</h5>
|
||||
@if(isset($only_show_products) && $only_show_products === true)
|
||||
@if($view === 'team')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_team', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@endif
|
||||
@elseif(isset($add_only_mode) && $add_only_mode)
|
||||
@if($view === 'ot')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_customer', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_add_only', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@endif
|
||||
@else
|
||||
<div class="alert alert-info">{{ __('abo.abo_order_info_2') }}</div>
|
||||
@endif
|
||||
<hr>
|
||||
@include('user.abo.vat_info')
|
||||
@if(!isset($only_show_products) || !$only_show_products)
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="{{ $user_abo->id }}"
|
||||
data-action="abo-add-product"
|
||||
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> {{ __('abo.add_product') }}</button>
|
||||
@endif
|
||||
<div class="" id="insert_show_products_order" data-cart-order-id="{{ $user_abo->id }}">
|
||||
@php
|
||||
$only_show_products = isset($only_show_products) ? $only_show_products : false;
|
||||
$add_only_mode = isset($add_only_mode) ? $add_only_mode : false;
|
||||
$split_mode = isset($split_mode) ? $split_mode : false;
|
||||
$summary = isset($summary) ? $summary : null;
|
||||
@endphp
|
||||
@include('admin.abo._order_abo_show', ['only_show_products' => $only_show_products, 'add_only_mode' => $add_only_mode, 'split_mode' => $split_mode, 'summary' => $summary])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.table tfoot td {
|
||||
padding: 0.225rem;
|
||||
}
|
||||
</style>
|
||||
<div class="card-header bg-light">
|
||||
<h5 class="font-weight-semibold mb-0"> <i class="fa fa-list-alt text-primary"></i>
|
||||
{{ __('abo.abo_order_hl') }}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (isset($only_show_products) && $only_show_products === true)
|
||||
@if ($view === 'team')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_team', [
|
||||
'abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration'),
|
||||
]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block', [
|
||||
'abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration'),
|
||||
]) !!}</div>
|
||||
@endif
|
||||
@elseif(isset($add_only_mode) && $add_only_mode)
|
||||
@if ($view === 'ot')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_customer', [
|
||||
'abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration'),
|
||||
]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_add_only', [
|
||||
'abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration'),
|
||||
]) !!}</div>
|
||||
@endif
|
||||
@else
|
||||
<div class="alert alert-info">{{ __('abo.abo_order_info_2') }}</div>
|
||||
@endif
|
||||
<hr>
|
||||
@include('user.abo.vat_info')
|
||||
@php
|
||||
$only_show_products = isset($only_show_products) ? $only_show_products : false;
|
||||
$add_only_mode = isset($add_only_mode) ? $add_only_mode : false;
|
||||
$split_mode = isset($split_mode) ? $split_mode : false;
|
||||
$summary = isset($summary) ? $summary : null;
|
||||
$change_locked = isset($change_locked) ? $change_locked : false;
|
||||
@endphp
|
||||
@if ($change_locked)
|
||||
<div class="alert alert-warning mt-2">
|
||||
{{ __('abo.error_change_locked', [
|
||||
'days' => (int) now()->diffInDays(\Carbon\Carbon::parse($user_abo->next_date), false),
|
||||
'lock' => App\Repositories\AboRepository::getLockDaysChange(),
|
||||
]) }}
|
||||
</div>
|
||||
@endif
|
||||
@if (!$only_show_products && !$change_locked)
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-block mt-2" data-toggle="modal"
|
||||
data-target="#modals-load-content" data-id="{{ $user_abo->id }}" data-action="abo-add-product"
|
||||
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i>
|
||||
{{ __('abo.add_product') }}</button>
|
||||
@endif
|
||||
<div class="" id="insert_show_products_order" data-cart-order-id="{{ $user_abo->id }}">
|
||||
@include('admin.abo._order_abo_show', [
|
||||
'only_show_products' => $only_show_products,
|
||||
'add_only_mode' => $add_only_mode,
|
||||
'split_mode' => $split_mode,
|
||||
'summary' => $summary,
|
||||
'change_locked' => $change_locked,
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@php($cartInstance = \App\Services\AboOrderCart::INSTANCE)
|
||||
@php($change_locked = isset($change_locked) ? $change_locked : false)
|
||||
@if(isset($error_message) && $error_message)
|
||||
<div class="alert alert-danger mt-2" id="insert_show_error_message">{{ $error_message }}</div>
|
||||
@endif
|
||||
|
|
@ -29,7 +30,7 @@
|
|||
<div>{{ __('order.content') }}: {{ $abo_item->product->contents }}</div>
|
||||
<div>{{ __('order.art_no') }}: {{ $abo_item->product->number }}</div>
|
||||
</div>
|
||||
@if((!isset($only_show_products) || !$only_show_products) && (!isset($add_only_mode) || !$add_only_mode))
|
||||
@if((!isset($only_show_products) || !$only_show_products) && (!isset($add_only_mode) || !$add_only_mode) && !$change_locked)
|
||||
<div class="options">
|
||||
<a href="#" class="auto-delete-product remove_item_form_cart product-tooltip" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}"><i class="fa fa-times"></i> {{ __('order.article_remove') }}</a>
|
||||
</div>
|
||||
|
|
@ -39,15 +40,17 @@
|
|||
@if(!isset($only_show_products) || !$only_show_products)
|
||||
<div class="no-line-break input-group-min-w">
|
||||
<div class="input-group d-inline-flex w-auto">
|
||||
@if(!isset($add_only_mode) || !$add_only_mode)
|
||||
@if((!isset($add_only_mode) || !$add_only_mode) && !$change_locked)
|
||||
<span class="input-group-prepend">
|
||||
<button type="button" class="btn btn-secondary icon-btn md-btn-extra remove-from-basket" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}">-</button>
|
||||
</span>
|
||||
@endif
|
||||
<input type="text" class="form-control text-center input-extra table-input-event-onchange" name="product_qty_{{$abo_item->id}}" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" value="{{$abo_item->qty}}" {{ (isset($add_only_mode) && $add_only_mode) ? 'readonly' : '' }}>
|
||||
<input type="text" class="form-control text-center input-extra table-input-event-onchange" name="product_qty_{{$abo_item->id}}" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" value="{{$abo_item->qty}}" {{ ((isset($add_only_mode) && $add_only_mode) || $change_locked) ? 'readonly' : '' }}>
|
||||
@if(!$change_locked)
|
||||
<span class="input-group-append">
|
||||
<button type="button" class="btn btn-secondary icon-btn md-btn-extra add-from-basket" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" data-product-name="{{ $abo_item->product->getLang('name') }}" data-product-price="{{ $abo_item->getFormattedPrice() }} €">+</button>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
$cartInstance = \App\Services\AboOrderCart::INSTANCE;
|
||||
$taxFree = Yard::instance($cartInstance)->getUserTaxFree();
|
||||
@endphp
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="font-weight-semibold mb-0">{{ __('abo.combined_summary_hl') }}</h5>
|
||||
<div class="card-header bg-primary">
|
||||
<h5 class="font-weight-semibold mb-0 text-white"> <i class="fa fa-shopping-cart text-white"></i>
|
||||
{{ __('abo.combined_summary_hl') }}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body bg-warning-light" style="background-color: rgba(227, 227, 54, 0.5) !important;">
|
||||
<table class="table table-product m-0">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<div class="card-body">
|
||||
<h5 class="font-weight-semibold mb-2">
|
||||
<i class="fa fa-bolt text-warning"></i> {{ __('abo.onetime_card_hl') }}
|
||||
<div class="card-header bg-secondary">
|
||||
<h5 class="font-weight-semibold mb-0"> <i class="fa fa-bolt text-primary"></i> {{ __('abo.onetime_card_hl') }}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info">{!! __('abo.onetime_card_info') !!}</div>
|
||||
<div class="alert alert-warning small mb-3">
|
||||
<strong>{{ __('abo.onetime_important_hl') }}</strong>
|
||||
|
|
@ -11,11 +12,10 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-warning btn-block mt-2"
|
||||
data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="{{ $user_abo->id }}"
|
||||
data-action="abo-add-onetime"
|
||||
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> {{ __('abo.add_onetime_product') }}</button>
|
||||
<button type="button" class="btn btn-sm btn-warning btn-block mt-2" data-toggle="modal"
|
||||
data-target="#modals-load-content" data-id="{{ $user_abo->id }}" data-action="abo-add-onetime"
|
||||
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i>
|
||||
{{ __('abo.add_onetime_product') }}</button>
|
||||
|
||||
<div id="insert_show_onetime_order" data-onetime-abo-id="{{ $user_abo->id }}" class="mt-2">
|
||||
@include('admin.abo._order_onetime_show', ['user_abo' => $user_abo, 'summary' => $summary])
|
||||
|
|
|
|||
|
|
@ -10,18 +10,36 @@
|
|||
<input type="hidden" name="id" value="{{$data['id']}}">
|
||||
<input type="hidden" name="view" value="{{$data['view']}}">
|
||||
|
||||
@php
|
||||
$aboChangeLocked = App\Services\AboHelper::isAboChangeLocked($user_abo, $data['view']);
|
||||
@endphp
|
||||
|
||||
@if(!App\Services\AboHelper::canEditAbo($user_abo, $data['view']))
|
||||
<div class="alert alert-danger">
|
||||
Unauthorized action. Is not my abo
|
||||
</div>
|
||||
@else
|
||||
|
||||
|
||||
@if($aboChangeLocked)
|
||||
<div class="alert alert-warning">
|
||||
{{ __('abo.error_change_locked', [
|
||||
'days' => (int) now()->diffInDays(\Carbon\Carbon::parse($user_abo->next_date), false),
|
||||
'lock' => App\Repositories\AboRepository::getLockDaysChange(),
|
||||
]) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-sm-6">
|
||||
<label for="abo_interval" class="form-label">{{ __('tables.abo_delivery_day') }}*</label>
|
||||
<select class="custom-select" name="abo_interval" id="abo_interval" required>
|
||||
<select class="custom-select" name="abo_interval" id="abo_interval" required {{ $aboChangeLocked ? 'disabled' : '' }}>
|
||||
{!! HTMLHelper::getAboDeliveryOptions($user_abo->abo_interval) !!}
|
||||
</select>
|
||||
@if($aboChangeLocked)
|
||||
{{-- Deaktiviertes Select sendet keinen Wert: aktuellen Liefertag mitsenden,
|
||||
damit andere Aktionen (z. B. Kündigen) nicht an der Liefertag-Validierung scheitern. --}}
|
||||
<input type="hidden" name="abo_interval" value="{{ $user_abo->abo_interval }}">
|
||||
@endif
|
||||
</div>
|
||||
@if($data['view'] === 'admin')
|
||||
@php
|
||||
|
|
|
|||
|
|
@ -76,6 +76,20 @@
|
|||
<small class="form-text text-muted">Anzahl Tage vor der Abo-Ausführung, in denen einmalig Produkte aus dem normalen Sortiment hinzugefügt werden können (Standard: 4).</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">Sperrfrist Abo bearbeiten vor Ausführung (Tage)*</label>
|
||||
{{ Form::text('settings[abo-lock-days-change][val]', \App\Models\Setting::getContentBySlug('abo-lock-days-change'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[abo-lock-days-change][type]', 'int') }}
|
||||
<small class="form-text text-muted">Anzahl Tage vor der Ausführung, ab der das Abo (Intervall/Produkte) nicht mehr bearbeitet werden kann (Standard: 10).</small>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">Sperrfrist Pausieren/Kündigen vor Ausführung (Tage)*</label>
|
||||
{{ Form::text('settings[abo-lock-days-pause-cancel][val]', \App\Models\Setting::getContentBySlug('abo-lock-days-pause-cancel'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[abo-lock-days-pause-cancel][type]', 'int') }}
|
||||
<small class="form-text text-muted">Anzahl Tage vor der Ausführung, ab der das Abo nicht mehr pausiert oder gekündigt werden kann (Standard: 3).</small>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" name="action" value="save_prepayment" class="btn btn-primary btn-sm mb-2"><i class="ion ion-ios-save"></i> speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
25
resources/views/dashboard/_abo_onetime.blade.php
Normal file
25
resources/views/dashboard/_abo_onetime.blade.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
@if (!empty($oneTimeAbo))
|
||||
<div class="d-flex col-xl-6 align-items-stretch">
|
||||
<div class="card w-100 mb-4 border-primary">
|
||||
<h5 class="card-header with-elements border-bottom bg-secondary">
|
||||
<div class="card-header-title">
|
||||
<i class="ion ion-md-add-circle text-primary mr-1"></i> {{ __('abo.onetime_card_hl') }}
|
||||
</div>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<p>{{ __('abo.onetime_card_info') }}</p>
|
||||
<p class="mb-0">
|
||||
<span class="ion ion-md-calendar text-primary"></span>
|
||||
<strong>{{ __('abo.abo_next_execution_date') }}:</strong>
|
||||
{{ \Carbon\Carbon::parse($oneTimeAbo->next_date)->format('d.m.Y') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-footer py-3">
|
||||
<a href="{{ route('user_abos_detail', ['view' => 'me', 'id' => $oneTimeAbo->id]) }}"
|
||||
class="btn btn-primary">
|
||||
<i class="ion ion-ios-cart text-white mr-1"></i> {{ __('abo.add_onetime_product') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
33
resources/views/dashboard/_abo_team_kpis.blade.php
Normal file
33
resources/views/dashboard/_abo_team_kpis.blade.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
@if (!empty($teamAboKpis) && ($teamAboKpis['team_total_abos'] > 0 || $teamAboKpis['shop_1000'] > 0))
|
||||
<div class="col-xl-6">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header with-elements border-bottom">
|
||||
<div class="card-header-title">
|
||||
<i class="ion ion-md-refresh-circle text-primary mr-1"></i> {{ __('abo.team_subscriptions') }}
|
||||
</div>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div class="row text-center">
|
||||
<div class="col-4">
|
||||
<a href="{{ route('user_abos_team_show') }}" class="text-decoration-none">
|
||||
<div class="display-4 font-weight-bold text-primary">{{ $teamAboKpis['team_total_abos'] }}</div>
|
||||
<div class="text-muted small">{{ __('abo.team_total_abos') }}</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="{{ route('user_abos_team_show') }}" class="text-decoration-none">
|
||||
<div class="display-4 font-weight-bold">{{ $teamAboKpis['team_customer_abos'] }}</div>
|
||||
<div class="text-muted small">{{ __('abo.team_customer_abos') }}</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="{{ route('user_abos_team_show') }}" class="text-decoration-none">
|
||||
<div class="display-4 font-weight-bold text-success">{{ $teamAboKpis['shop_1000'] }}</div>
|
||||
<div class="text-muted small">{{ __('abo.shop_1000') }}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
@if (isset($dashboardNews) && $dashboardNews)
|
||||
<div class="d-flex col-xl-12 align-items-stretch">
|
||||
<div class="d-flex {{ $newsColClass ?? 'col-xl-12' }} align-items-stretch">
|
||||
<div class="card w-100 mb-4 border-primary">
|
||||
<h5 class="card-header with-elements bg-primary text-white">
|
||||
<div class="card-header-title">
|
||||
|
|
|
|||
118
resources/views/emails/abo_execution_reminder.blade.php
Normal file
118
resources/views/emails/abo_execution_reminder.blade.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<!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>{{ __('email.abo_reminder_subject') }}</title>
|
||||
<style type="text/css">
|
||||
a { text-decoration: none; border: 0; outline: none; color: #919f7a; }
|
||||
a:hover { color: #b6b600; }
|
||||
td, h1, h2, h3 { font-family: Helvetica, Verdana, Arial, sans-serif; font-weight: 400; }
|
||||
td { text-align: left; }
|
||||
body { -webkit-font-smoothing: antialiased; width: 100%; height: 100%; color: #37302d; background: #ffffff; font-size: 15px; line-height: 26px; }
|
||||
table { border-collapse: separate !important; }
|
||||
.headline { color: #37302d; font-size: 18px; }
|
||||
.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">
|
||||
<table align="left" cellpadding="0" cellspacing="0" width="100%" height="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top" bgcolor="#f8f8f8" width="100%">
|
||||
<br>
|
||||
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="700" class="w320">
|
||||
<tr>
|
||||
<td align="left" valign="top">
|
||||
<table style="margin: 0 auto;" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align:center;">
|
||||
<center>
|
||||
<picture style="text-align: center">
|
||||
<img src="https://my.mivita.care/images/logo_mivita.png" alt="mivita.care" style="border:none" width="230">
|
||||
</picture>
|
||||
</center>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table cellpadding="10" style="padding: 10px;" cellspacing="0" border="0" width="100%" bgcolor="#ffffff">
|
||||
<tr>
|
||||
<td class="headline">
|
||||
<b>{{ __('email.abo_reminder_title') }}</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#37302d;line-height:1.6em;">
|
||||
{{ $salutation }},
|
||||
<br><br>
|
||||
{{ trans_choice('email.abo_reminder_intro', $days, ['days' => $days, 'date' => $nextDate]) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#37302d;line-height:1.6em;">
|
||||
<br>
|
||||
{{ __('email.abo_reminder_onetime_hint') }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="background-color: #f6fdf5; border: 2px solid #b5c49b; border-radius: 8px; margin: 20px 0;" cellpadding="15" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align: center; color: #37302d; font-size: 14px; line-height:1.6em;">
|
||||
{{ __('email.abo_reminder_coverage_hint') }}
|
||||
<br><br>
|
||||
{{ __('email.abo_reminder_sustainability_hint') }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center; padding-top: 10px;">
|
||||
<a href="{{ $link }}" style="display: inline-block; background: #FFCC00; color: #37302d; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; font-size: 14px;">
|
||||
@if($isConsultant)
|
||||
{{ __('email.abo_reminder_button_consultant') }}
|
||||
@else
|
||||
{{ __('email.abo_reminder_button_customer') }}
|
||||
@endif
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#37302d;line-height:1.6em;">
|
||||
<br>
|
||||
{{ $greetings }}<br>
|
||||
{{ $sender }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<center>
|
||||
<table cellpadding="0" cellspacing="0" class="force-full-width" bgcolor="#f8f8f8" style="margin: 0 auto; text-align: center;line-height:1.6em;">
|
||||
<tr>
|
||||
<td style="color:#7B7B7E; font-size:14px; text-align: center;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; text-align: center;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>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -29,8 +29,12 @@
|
|||
|
||||
<div class="row">
|
||||
|
||||
@include('dashboard._abo_onetime')
|
||||
|
||||
@if (Auth::user()->isActiveAccount())
|
||||
@include('dashboard._news')
|
||||
@include('dashboard._abo_team_kpis')
|
||||
|
||||
@include('dashboard._news', ['newsColClass' => empty($oneTimeAbo) ? 'col-xl-12' : 'col-xl-6'])
|
||||
|
||||
@include('dashboard._incentive')
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -10,7 +10,29 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($shopping_order->shopping_order_items as $shopping_order_item)
|
||||
@php
|
||||
$deliveryItems = $shopping_order->shopping_order_items->sortBy(fn ($item) => $item->is_abo_addon ? 1 : 0)->values();
|
||||
$hasAddonItems = $deliveryItems->contains(fn ($item) => $item->is_abo_addon);
|
||||
$addonHeadingShown = false;
|
||||
$aboHeadingShown = false;
|
||||
@endphp
|
||||
@foreach($deliveryItems as $shopping_order_item)
|
||||
@if($hasAddonItems && ! $shopping_order_item->is_abo_addon && ! $aboHeadingShown)
|
||||
@php($aboHeadingShown = true)
|
||||
<tr class="item">
|
||||
<td class="small text-left" colspan="3" style="background-color: #f2f2f2;">
|
||||
<b>{{ __('pdf.abo_items_heading') }}</b>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($hasAddonItems && $shopping_order_item->is_abo_addon && ! $addonHeadingShown)
|
||||
@php($addonHeadingShown = true)
|
||||
<tr class="item">
|
||||
<td class="small text-left" colspan="3" style="background-color: #f2f2f2;">
|
||||
<b>{{ __('pdf.abo_addon_items_heading') }}</b>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr class="item">
|
||||
<td class="small text-left">
|
||||
{{ $shopping_order_item->product->number }}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,30 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($shopping_order->shopping_order_items as $shopping_order_item)
|
||||
@php
|
||||
$invoiceItems = $shopping_order->shopping_order_items->sortBy(fn ($item) => $item->is_abo_addon ? 1 : 0)->values();
|
||||
$hasAddonItems = $invoiceItems->contains(fn ($item) => $item->is_abo_addon);
|
||||
$headingColspan = $shopping_order->payment_for === 6 ? 6 : 7;
|
||||
$addonHeadingShown = false;
|
||||
$aboHeadingShown = false;
|
||||
@endphp
|
||||
@foreach($invoiceItems as $shopping_order_item)
|
||||
@if($hasAddonItems && ! $shopping_order_item->is_abo_addon && ! $aboHeadingShown)
|
||||
@php($aboHeadingShown = true)
|
||||
<tr class="item">
|
||||
<td class="small text-left" colspan="{{ $headingColspan }}" style="background-color: #f2f2f2;">
|
||||
<b>{{ __('pdf.abo_items_heading') }}</b>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($hasAddonItems && $shopping_order_item->is_abo_addon && ! $addonHeadingShown)
|
||||
@php($addonHeadingShown = true)
|
||||
<tr class="item">
|
||||
<td class="small text-left" colspan="{{ $headingColspan }}" style="background-color: #f2f2f2;">
|
||||
<b>{{ __('pdf.abo_addon_items_heading') }}</b>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr class="item">
|
||||
<td class="small text-left">
|
||||
{{ $shopping_order_item->product->number }}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,19 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
@if($user_abo->isPendingInitialPayment())
|
||||
<div class="alert alert-warning">
|
||||
<strong>{{ __('abo.pending_payment_waiting_title') }}</strong><br>
|
||||
@if($user_abo->hasFailedInitialPayment())
|
||||
{{ __('abo.pending_payment_failed_copy') }}
|
||||
@elseif($user_abo->hasInitialPaymentStatus())
|
||||
{{ __('abo.pending_payment_processing_copy') }}
|
||||
@else
|
||||
{{ __('abo.pending_payment_waiting_copy') }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
@include('admin.abo._detail')
|
||||
</div>
|
||||
|
|
@ -36,6 +49,7 @@
|
|||
|
||||
@php
|
||||
$addOnlyMode = App\Services\AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
$aboChangeLocked = App\Services\AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
@endphp
|
||||
{!! Form::open([
|
||||
'action' => route('user_abos_update', [$view, $user_abo->id]),
|
||||
|
|
@ -61,6 +75,7 @@
|
|||
'add_only_mode' => $addOnlyMode,
|
||||
'split_mode' => true,
|
||||
'summary' => $summary,
|
||||
'change_locked' => $aboChangeLocked,
|
||||
])
|
||||
</div>
|
||||
<div id="holder_html_view_comp_product">
|
||||
|
|
@ -80,7 +95,7 @@
|
|||
</div>
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
|
||||
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode, 'change_locked' => $aboChangeLocked])
|
||||
</div>
|
||||
|
||||
<div id="holder_html_view_comp_product">
|
||||
|
|
|
|||
|
|
@ -53,7 +53,11 @@
|
|||
@include('admin.customer._customer_detail', ['shopping_user' => $customer_detail])
|
||||
</div>
|
||||
@php
|
||||
// Selbstbedienung: Add-only (Mindestlaufzeit) und Change-Lock richten sich nach der
|
||||
// Abo-Sicht ($view), NICHT nach Admin-Status. So gelten für VIP/Admin auf der eigenen
|
||||
// Abo-Seite dieselben Regeln wie für jeden Berater (kein Admin-Bypass).
|
||||
$addOnlyMode = App\Services\AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
$aboChangeLocked = App\Services\AboHelper::isAboChangeLocked($user_abo, $view);
|
||||
@endphp
|
||||
{!! Form::open([
|
||||
'action' => route('user_abos_update', [$view, $user_abo->id]),
|
||||
|
|
@ -79,6 +83,7 @@
|
|||
'add_only_mode' => $addOnlyMode,
|
||||
'split_mode' => true,
|
||||
'summary' => $summary,
|
||||
'change_locked' => $aboChangeLocked,
|
||||
])
|
||||
</div>
|
||||
<div id="holder_html_view_comp_product">
|
||||
|
|
@ -98,7 +103,7 @@
|
|||
</div>
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
|
||||
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode, 'change_locked' => $aboChangeLocked])
|
||||
</div>
|
||||
|
||||
<div id="holder_html_view_comp_product">
|
||||
|
|
|
|||
115
tests/Feature/AboExecutionReminderTest.php
Normal file
115
tests/Feature/AboExecutionReminderTest.php
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
use App\Mail\MailAboExecutionReminder;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\Util;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
/**
|
||||
* Phase 6 – Reminder-E-Mail vor der Abo-Ausführung (Einmalprodukte-Fenster).
|
||||
* Default-Fenster = 4 Tage. Berater (is_for=me) → Sales Center, Endkunde (ot) → Portal.
|
||||
*/
|
||||
beforeEach(function () {
|
||||
makeShopEnv();
|
||||
Mail::fake();
|
||||
});
|
||||
|
||||
function makeOtAbo(?\Carbon\Carbon $nextDate = null): UserAbo
|
||||
{
|
||||
$shoppingUser = ShoppingUser::forceCreate([
|
||||
'auth_user_id' => 1,
|
||||
'billing_firstname' => 'Erika',
|
||||
'billing_email' => 'kunde-'.uniqid('', true).'@example.com',
|
||||
'billing_country_id' => 1,
|
||||
'shipping_country_id' => 1,
|
||||
'wp_order_number' => 0,
|
||||
'language' => 'de',
|
||||
]);
|
||||
|
||||
return UserAbo::create([
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'is_for' => 'ot',
|
||||
'email' => $shoppingUser->billing_email,
|
||||
'payone_userid' => 900200,
|
||||
'clearingtype' => 'cc',
|
||||
'active' => true,
|
||||
'status' => 2,
|
||||
'abo_interval' => 5,
|
||||
'next_date' => $nextDate ?? now()->addDays(4),
|
||||
]);
|
||||
}
|
||||
|
||||
describe('AboSendExecutionReminder Selektion', function () {
|
||||
it('versendet an ein Abo, dessen Ausführung im Fenster (heute + 4 Tage) liegt', function () {
|
||||
$abo = makeMeAbo();
|
||||
$abo->update(['next_date' => now()->addDays(4)]);
|
||||
|
||||
$this->artisan('abo:send-execution-reminder')->assertSuccessful();
|
||||
|
||||
Mail::assertSent(MailAboExecutionReminder::class, 1);
|
||||
});
|
||||
|
||||
it('versendet NICHT außerhalb des Fensters', function () {
|
||||
$abo = makeMeAbo();
|
||||
$abo->update(['next_date' => now()->addDays(10)]);
|
||||
|
||||
$this->artisan('abo:send-execution-reminder')->assertSuccessful();
|
||||
|
||||
Mail::assertNothingSent();
|
||||
});
|
||||
|
||||
it('versendet NICHT bei inaktivem oder falschem Status', function () {
|
||||
makeMeAbo()->update(['next_date' => now()->addDays(4), 'active' => false]);
|
||||
makeMeAbo()->update(['next_date' => now()->addDays(4), 'status' => 3]);
|
||||
|
||||
$this->artisan('abo:send-execution-reminder')->assertSuccessful();
|
||||
|
||||
Mail::assertNothingSent();
|
||||
});
|
||||
});
|
||||
|
||||
describe('AboSendExecutionReminder Link-Wahl', function () {
|
||||
it('Berater-Abo verlinkt ins Sales Center', function () {
|
||||
$abo = makeMeAbo();
|
||||
$abo->update(['next_date' => now()->addDays(4)]);
|
||||
|
||||
$html = (new MailAboExecutionReminder($abo->fresh()))->render();
|
||||
|
||||
expect($html)->toContain(rtrim(Util::getMyMivitaUrl(), '/').'/user/abos/detail/me/'.$abo->id);
|
||||
});
|
||||
|
||||
it('Endkunden-Abo verlinkt ins Kundenportal', function () {
|
||||
$abo = makeOtAbo();
|
||||
|
||||
$html = (new MailAboExecutionReminder($abo->fresh()))->render();
|
||||
|
||||
expect($html)->toContain(rtrim(Util::getMyMivitaPortalUrl(), '/').'/portal/my-subscriptions');
|
||||
});
|
||||
|
||||
it('formatiert das Ausführungsdatum korrekt (kein doppeltes ICU-Format)', function () {
|
||||
$abo = makeMeAbo();
|
||||
$abo->update(['next_date' => '2026-07-10']);
|
||||
|
||||
$html = (new MailAboExecutionReminder($abo->fresh()))->render();
|
||||
|
||||
expect($html)->toContain('10.07.2026')
|
||||
->and($html)->not->toContain('1010.0707');
|
||||
});
|
||||
});
|
||||
|
||||
describe('AboSendExecutionReminder Duplikat-Schutz', function () {
|
||||
it('versendet pro Zyklus nur einmal', function () {
|
||||
$abo = makeMeAbo();
|
||||
$abo->update(['next_date' => now()->addDays(4)]);
|
||||
|
||||
$this->artisan('abo:send-execution-reminder')->assertSuccessful();
|
||||
$this->artisan('abo:send-execution-reminder')->assertSuccessful();
|
||||
|
||||
Mail::assertSent(MailAboExecutionReminder::class, 1);
|
||||
expect($abo->fresh()->onetime_reminder_sent_for)->not->toBeNull();
|
||||
});
|
||||
});
|
||||
192
tests/Feature/AboLockDaysSettingTest.php
Normal file
192
tests/Feature/AboLockDaysSettingTest.php
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\Setting;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserAbo;
|
||||
use App\Repositories\AboRepository;
|
||||
use App\Services\AboHelper;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
afterEach(fn () => Carbon::setTestNow());
|
||||
|
||||
describe('Abo-Sperrfristen als Setting', function () {
|
||||
it('nutzt die Defaults, wenn kein Setting gesetzt ist', function () {
|
||||
expect(AboRepository::getLockDaysChange())->toBe(10)
|
||||
->and(AboRepository::getLockDaysPauseCancel())->toBe(3);
|
||||
});
|
||||
|
||||
it('liest die konfigurierten Sperrfristen aus den Settings', function () {
|
||||
Setting::setContentBySlug('abo-lock-days-change', 5, 'int');
|
||||
Setting::setContentBySlug('abo-lock-days-pause-cancel', 7, 'int');
|
||||
|
||||
expect(AboRepository::getLockDaysChange())->toBe(5)
|
||||
->and(AboRepository::getLockDaysPauseCancel())->toBe(7);
|
||||
});
|
||||
|
||||
it('fällt bei 0 / leer auf den Default zurück', function () {
|
||||
Setting::setContentBySlug('abo-lock-days-change', 0, 'int');
|
||||
|
||||
expect(AboRepository::getLockDaysChange())->toBe(10);
|
||||
});
|
||||
|
||||
it('gibt eine Änderung frei, die bei Default gesperrt wäre, wenn die Sperrfrist reduziert wird', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
|
||||
// Liefertag 20, next_date in 6 Tagen → Liefertag-WECHSEL auf 25 testen.
|
||||
$abo = makeLockTestAbo([
|
||||
'abo_interval' => 20,
|
||||
'next_date' => '2026-03-25',
|
||||
]);
|
||||
|
||||
$this->actingAs($abo->user);
|
||||
$repository = new AboRepository;
|
||||
$repository->setModel($abo);
|
||||
|
||||
// Mit Default (10) ist der Wechsel gesperrt (6 < 10):
|
||||
expect($repository->update([
|
||||
'action' => 'abo_update_settings',
|
||||
'id' => $abo->id,
|
||||
'view' => 'me',
|
||||
'abo_interval' => 25,
|
||||
'abo_is_active' => 'true',
|
||||
]))->toBeFalse();
|
||||
|
||||
// Sperrfrist auf 3 Tage reduzieren → Wechsel jetzt erlaubt (6 ≥ 3, neues Datum 2026-03-25):
|
||||
Setting::setContentBySlug('abo-lock-days-change', 3, 'int');
|
||||
|
||||
expect($repository->update([
|
||||
'action' => 'abo_update_settings',
|
||||
'id' => $abo->id,
|
||||
'view' => 'me',
|
||||
'abo_interval' => 25,
|
||||
'abo_is_active' => 'true',
|
||||
]))->toBeTrue()
|
||||
->and($abo->refresh()->abo_interval)->toBe(25);
|
||||
});
|
||||
|
||||
it('zeigt die konfigurierte Sperrfrist in der Fehlermeldung (nicht den Default 10)', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
app()->setLocale('de');
|
||||
Setting::setContentBySlug('abo-lock-days-change', 3, 'int');
|
||||
|
||||
// Liefertag-WECHSEL (20 → 25), next_date morgen (1 Tag) → bei Sperrfrist 3 weiterhin gesperrt.
|
||||
$abo = makeLockTestAbo(['abo_interval' => 20, 'next_date' => '2026-03-20']);
|
||||
$this->actingAs($abo->user);
|
||||
$repository = new AboRepository;
|
||||
$repository->setModel($abo);
|
||||
|
||||
expect($repository->update([
|
||||
'action' => 'abo_update_settings',
|
||||
'id' => $abo->id,
|
||||
'view' => 'me',
|
||||
'abo_interval' => 25,
|
||||
'abo_is_active' => 'true',
|
||||
]))->toBeFalse()
|
||||
->and(session('alert-error'))->toContain('mindestens 3 Tage')
|
||||
->and(session('alert-error'))->not->toContain('mindestens 10 Tage');
|
||||
});
|
||||
|
||||
it('erlaubt Pausieren im Change-Lock-Fenster, wenn außerhalb der Pause-Sperre (Intervall unverändert)', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
// 5 Tage entfernt: innerhalb Change-Lock (10), außerhalb Pause-Lock (3).
|
||||
$abo = makeLockTestAbo(['abo_interval' => 20, 'next_date' => '2026-03-24', 'active' => true, 'status' => 2]);
|
||||
$this->actingAs($abo->user);
|
||||
$repository = new AboRepository;
|
||||
$repository->setModel($abo);
|
||||
|
||||
// Intervall unverändert (20), kein abo_is_active => Pausieren.
|
||||
$result = $repository->update([
|
||||
'action' => 'abo_update_settings',
|
||||
'id' => $abo->id,
|
||||
'view' => 'me',
|
||||
'abo_interval' => 20,
|
||||
]);
|
||||
|
||||
expect($result)->toBeTrue()
|
||||
->and($abo->refresh()->active)->toBeFalse()
|
||||
->and($abo->status)->toBe(6);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAboChangeLocked (UI-Sperre Liefertag)', function () {
|
||||
afterEach(fn () => Carbon::setTestNow());
|
||||
|
||||
it('ist gesperrt im Fenster, frei außerhalb (User-Ansicht)', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
$abo = makeLockTestAbo(['next_date' => '2026-03-20']); // 1 Tag → < Default 10
|
||||
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'me'))->toBeTrue();
|
||||
|
||||
$abo->next_date = '2026-04-19'; // weit entfernt
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'me'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('respektiert die konfigurierte Sperrfrist', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
$abo = makeLockTestAbo(['next_date' => '2026-03-24']); // 5 Tage entfernt
|
||||
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'me'))->toBeTrue(); // 5 < 10 (Default)
|
||||
|
||||
Setting::setContentBySlug('abo-lock-days-change', 3, 'int');
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'me'))->toBeFalse(); // 5 >= 3
|
||||
});
|
||||
|
||||
it('gilt nicht für Admin und nicht ohne next_date', function () {
|
||||
Carbon::setTestNow('2026-03-19 00:00:00');
|
||||
$abo = makeLockTestAbo(['next_date' => '2026-03-20']);
|
||||
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'admin'))->toBeFalse();
|
||||
|
||||
$abo->next_date = null;
|
||||
expect(AboHelper::isAboChangeLocked($abo, 'me'))->toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $overrides
|
||||
*/
|
||||
function makeLockTestAbo(array $overrides = []): UserAbo
|
||||
{
|
||||
$country = Country::create([
|
||||
'code' => 'DE', 'phone' => '49', 'en' => 'Germany', 'de' => 'Deutschland',
|
||||
'es' => 'Alemania', 'fr' => 'Allemagne', 'it' => 'Germania', 'ru' => 'Deutschland',
|
||||
]);
|
||||
|
||||
$user = User::forceCreate([
|
||||
'email' => 'abo-lock-'.uniqid('', true).'@example.com',
|
||||
'password' => bcrypt('secret'),
|
||||
'lang' => 'de',
|
||||
'admin' => 0,
|
||||
]);
|
||||
|
||||
$shoppingUser = ShoppingUser::create([
|
||||
'auth_user_id' => $user->id,
|
||||
'member_id' => $user->id,
|
||||
'billing_country_id' => $country->id,
|
||||
'shipping_country_id' => $country->id,
|
||||
'billing_email' => $user->email,
|
||||
'is_for' => 'me',
|
||||
'is_from' => 'user_order',
|
||||
]);
|
||||
|
||||
return UserAbo::create(array_merge([
|
||||
'user_id' => $user->id,
|
||||
'member_id' => $user->id,
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'is_for' => 'me',
|
||||
'email' => $user->email,
|
||||
'payone_userid' => random_int(100000, 999999),
|
||||
'clearingtype' => 'cc',
|
||||
'active' => true,
|
||||
'status' => 2,
|
||||
'abo_interval' => 5,
|
||||
'start_date' => '2026-01-05',
|
||||
'last_date' => '2026-02-05',
|
||||
'next_date' => '2026-03-05',
|
||||
], $overrides));
|
||||
}
|
||||
110
tests/Feature/AboOneTimeInvoiceGroupingTest.php
Normal file
110
tests/Feature/AboOneTimeInvoiceGroupingTest.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
/**
|
||||
* Phase 5 – Rechnung & Lieferschein: Positionen werden nach `is_abo_addon`
|
||||
* gruppiert (Abo-Produkte oben, abgegrenzter Block „Einmalig hinzugefügte
|
||||
* Artikel" darunter). Bestellungen ohne Einmal-Artikel bleiben unverändert.
|
||||
*/
|
||||
beforeEach(fn () => makeShopEnv());
|
||||
|
||||
function makeMixedOrder(bool $withAddon = true): ShoppingOrder
|
||||
{
|
||||
$order = ShoppingOrder::create([
|
||||
'shopping_user_id' => 1,
|
||||
'auth_user_id' => 1,
|
||||
'country_id' => 1,
|
||||
'user_shop_id' => 0,
|
||||
'payment_for' => 6,
|
||||
'shipping' => 0,
|
||||
'shipping_net' => 0,
|
||||
'subtotal_ws' => 100,
|
||||
'tax' => 0,
|
||||
'total_shipping' => 100,
|
||||
'is_abo' => true,
|
||||
]);
|
||||
|
||||
$aboProduct = makeProduct(['12'], 50, 0);
|
||||
$order->shopping_order_items()->create([
|
||||
'product_id' => $aboProduct->id,
|
||||
'is_abo_addon' => false,
|
||||
'qty' => 1,
|
||||
'price' => 50,
|
||||
'price_net' => 50,
|
||||
'tax_rate' => 0,
|
||||
'tax' => 0,
|
||||
'price_vk_net' => 50,
|
||||
'discount' => 0,
|
||||
'points' => 0,
|
||||
]);
|
||||
|
||||
if ($withAddon) {
|
||||
$addonProduct = makeProduct(['2'], 30, 0);
|
||||
$order->shopping_order_items()->create([
|
||||
'product_id' => $addonProduct->id,
|
||||
'is_abo_addon' => true,
|
||||
'qty' => 1,
|
||||
'price' => 30,
|
||||
'price_net' => 30,
|
||||
'tax_rate' => 0,
|
||||
'tax' => 0,
|
||||
'price_vk_net' => 30,
|
||||
'discount' => 0,
|
||||
'points' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
return $order->fresh('shopping_order_items.product');
|
||||
}
|
||||
|
||||
describe('Rechnung-PDF Gruppierung', function () {
|
||||
it('zeigt bei gemischter Bestellung beide Block-Überschriften, Abo vor Einmal', function () {
|
||||
$order = makeMixedOrder();
|
||||
|
||||
$html = view('pdf.invoice-detail', ['shopping_order' => $order])->render();
|
||||
|
||||
expect($html)->toContain(__('pdf.abo_items_heading'))
|
||||
->and($html)->toContain(__('pdf.abo_addon_items_heading'));
|
||||
|
||||
$aboPos = strpos($html, __('pdf.abo_items_heading'));
|
||||
$addonPos = strpos($html, __('pdf.abo_addon_items_heading'));
|
||||
expect($aboPos)->toBeLessThan($addonPos);
|
||||
});
|
||||
|
||||
it('zeigt KEINE Block-Überschriften bei reiner Bestellung ohne Einmal-Artikel', function () {
|
||||
$order = makeMixedOrder(withAddon: false);
|
||||
|
||||
$html = view('pdf.invoice-detail', ['shopping_order' => $order])->render();
|
||||
|
||||
expect($html)->not->toContain(__('pdf.abo_addon_items_heading'))
|
||||
->and($html)->not->toContain(__('pdf.abo_items_heading'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Lieferschein-PDF Gruppierung', function () {
|
||||
it('zeigt bei gemischter Bestellung beide Block-Überschriften, Abo vor Einmal', function () {
|
||||
$order = makeMixedOrder();
|
||||
|
||||
$html = view('pdf.delivery-detail', ['shopping_order' => $order])->render();
|
||||
|
||||
expect($html)->toContain(__('pdf.abo_items_heading'))
|
||||
->and($html)->toContain(__('pdf.abo_addon_items_heading'));
|
||||
|
||||
$aboPos = strpos($html, __('pdf.abo_items_heading'));
|
||||
$addonPos = strpos($html, __('pdf.abo_addon_items_heading'));
|
||||
expect($aboPos)->toBeLessThan($addonPos);
|
||||
});
|
||||
|
||||
it('zeigt KEINE Block-Überschriften bei reiner Bestellung ohne Einmal-Artikel', function () {
|
||||
$order = makeMixedOrder(withAddon: false);
|
||||
|
||||
$html = view('pdf.delivery-detail', ['shopping_order' => $order])->render();
|
||||
|
||||
expect($html)->not->toContain(__('pdf.abo_addon_items_heading'))
|
||||
->and($html)->not->toContain(__('pdf.abo_items_heading'));
|
||||
});
|
||||
});
|
||||
|
|
@ -238,4 +238,74 @@ describe('Abo Einmal-Produkte Views', function () {
|
|||
]))
|
||||
->and($html)->toContain(__('abo.confirm_add_ok'));
|
||||
});
|
||||
|
||||
it('rendert nach einer Mengenänderung die aktuelle (persistierte) Menge – kein Stale-Cache', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProduct(['12'], 50, 0);
|
||||
$item = \App\Models\UserAboItem::create([
|
||||
'user_abo_id' => $abo->id, 'product_id' => $product->id, 'comp' => 0, 'qty' => 1, 'status' => 1,
|
||||
]);
|
||||
|
||||
// Relation cachen (wie initYard/makeOrderYard im Controller)
|
||||
$abo->load('user_abo_items');
|
||||
expect($abo->user_abo_items->first()->qty)->toBe(1);
|
||||
|
||||
// Menge über separate Instanz erhöhen (wie der Controller in updateCart/addProduct)
|
||||
\App\Models\UserAboItem::find($item->id)->update(['qty' => 3]);
|
||||
|
||||
// Fix: Relation vor dem Render neu laden → gerenderte Menge = gespeicherter Stand
|
||||
$abo->load('user_abo_items');
|
||||
$html = view('admin.abo._order_abo_show', [
|
||||
'user_abo' => $abo,
|
||||
'split_mode' => true,
|
||||
'summary' => ['abo' => ['gross' => 150], 'total_with_shipping' => 150],
|
||||
])->render();
|
||||
|
||||
expect($html)->toContain('value="3"');
|
||||
});
|
||||
|
||||
it('blendet Minus/Entfernen im Add-only-Modus aus (Mindestlaufzeit nicht erfüllt)', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProduct(['12'], 50, 0);
|
||||
\App\Models\UserAboItem::create([
|
||||
'user_abo_id' => $abo->id, 'product_id' => $product->id, 'comp' => 0, 'qty' => 2, 'status' => 1,
|
||||
]);
|
||||
$abo->load('user_abo_items');
|
||||
|
||||
$summary = ['abo' => ['gross' => 100], 'total_with_shipping' => 100];
|
||||
|
||||
$addOnly = view('admin.abo._order_abo_show', [
|
||||
'user_abo' => $abo, 'split_mode' => true, 'summary' => $summary, 'add_only_mode' => true,
|
||||
])->render();
|
||||
expect($addOnly)->not->toContain('remove-from-basket')
|
||||
->and($addOnly)->not->toContain('auto-delete-product')
|
||||
->and($addOnly)->toContain('add-from-basket') // Hinzufügen bleibt möglich
|
||||
->and($addOnly)->toContain('readonly');
|
||||
|
||||
$free = view('admin.abo._order_abo_show', [
|
||||
'user_abo' => $abo, 'split_mode' => true, 'summary' => $summary, 'add_only_mode' => false,
|
||||
])->render();
|
||||
expect($free)->toContain('remove-from-basket')
|
||||
->and($free)->toContain('auto-delete-product');
|
||||
});
|
||||
|
||||
it('friert alle Produkt-Steuerungen ein, wenn der Change-Lock greift', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProduct(['12'], 50, 0);
|
||||
\App\Models\UserAboItem::create([
|
||||
'user_abo_id' => $abo->id, 'product_id' => $product->id, 'comp' => 0, 'qty' => 2, 'status' => 1,
|
||||
]);
|
||||
$abo->load('user_abo_items');
|
||||
|
||||
$html = view('admin.abo._order_abo_show', [
|
||||
'user_abo' => $abo, 'split_mode' => true,
|
||||
'summary' => ['abo' => ['gross' => 100], 'total_with_shipping' => 100],
|
||||
'change_locked' => true,
|
||||
])->render();
|
||||
|
||||
expect($html)->not->toContain('add-from-basket')
|
||||
->and($html)->not->toContain('remove-from-basket')
|
||||
->and($html)->not->toContain('auto-delete-product')
|
||||
->and($html)->toContain('readonly');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -84,10 +84,10 @@ describe('isOneTimeWindowOpen', function () {
|
|||
});
|
||||
|
||||
describe('isOneTimeFeatureVisible', function () {
|
||||
it('ist sichtbar, wenn das Fenster offen ist und ein VIP-User (Admin) eingeloggt ist', function () {
|
||||
$vip = new User;
|
||||
$vip->admin = 1;
|
||||
$this->actingAs($vip, 'user');
|
||||
it('ist sichtbar, wenn das Fenster offen ist (Sales Center, eingeloggter User)', function () {
|
||||
$user = new User;
|
||||
$user->admin = 0;
|
||||
$this->actingAs($user, 'user');
|
||||
|
||||
$abo = new UserAbo;
|
||||
$abo->next_date = now()->addDays(2); // innerhalb des 4-Tage-Fensters
|
||||
|
|
@ -95,29 +95,14 @@ describe('isOneTimeFeatureVisible', function () {
|
|||
expect(AboHelper::isOneTimeFeatureVisible($abo))->toBeTrue();
|
||||
});
|
||||
|
||||
it('ist nicht sichtbar für eingeloggte Nicht-VIP-User', function () {
|
||||
$user = new User;
|
||||
$user->admin = 0;
|
||||
$this->actingAs($user, 'user');
|
||||
|
||||
it('ist sichtbar ohne User auf dem user-Guard (Portal/Endkunde), solange das Fenster offen ist', function () {
|
||||
$abo = new UserAbo;
|
||||
$abo->next_date = now()->addDays(2);
|
||||
|
||||
expect(AboHelper::isOneTimeFeatureVisible($abo))->toBeFalse();
|
||||
expect(AboHelper::isOneTimeFeatureVisible($abo))->toBeTrue();
|
||||
});
|
||||
|
||||
it('ist nicht sichtbar ohne User auf dem user-Guard (Portal/Endkunde)', function () {
|
||||
$abo = new UserAbo;
|
||||
$abo->next_date = now()->addDays(2);
|
||||
|
||||
expect(AboHelper::isOneTimeFeatureVisible($abo))->toBeFalse();
|
||||
});
|
||||
|
||||
it('ist nicht sichtbar bei geschlossenem Fenster, auch für VIP-User', function () {
|
||||
$vip = new User;
|
||||
$vip->admin = 1;
|
||||
$this->actingAs($vip, 'user');
|
||||
|
||||
it('ist nicht sichtbar bei geschlossenem Fenster', function () {
|
||||
$abo = new UserAbo;
|
||||
$abo->next_date = now()->addDays(30); // außerhalb des Fensters
|
||||
|
||||
|
|
|
|||
64
tests/Feature/AboOnetimeDashboardAndMailTest.php
Normal file
64
tests/Feature/AboOnetimeDashboardAndMailTest.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
use App\Mail\MailAboExecutionReminder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
beforeEach(fn () => makeShopEnv());
|
||||
|
||||
describe('Dashboard-Card Einmalprodukte', function () {
|
||||
it('zeigt die Card mit Link zum eigenen Abo', function () {
|
||||
// Domain-aware Route wird im Test-Kontext nicht geladen -> route() mocken
|
||||
URL::shouldReceive('route')->andReturnUsing(
|
||||
fn ($name, $params = [], $absolute = true) => '/user/abos/detail/'.($params['view'] ?? '').'/'.($params['id'] ?? '')
|
||||
);
|
||||
|
||||
$abo = makeMeAbo();
|
||||
|
||||
$html = view('dashboard._abo_onetime', ['oneTimeAbo' => $abo])->render();
|
||||
|
||||
expect($html)->toContain(__('abo.onetime_card_hl'))
|
||||
->and($html)->toContain(__('abo.add_onetime_product'))
|
||||
->and($html)->toContain('/user/abos/detail/me/'.$abo->id);
|
||||
});
|
||||
|
||||
it('rendert nichts, wenn kein Abo übergeben wird', function () {
|
||||
$html = view('dashboard._abo_onetime', ['oneTimeAbo' => null])->render();
|
||||
|
||||
expect(trim($html))->toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Reminder-Mail-Vorschau Command', function () {
|
||||
it('rendert die Reminder-Mail als HTML ohne Versand', function () {
|
||||
Storage::fake('public');
|
||||
Mail::fake();
|
||||
$abo = makeMeAbo();
|
||||
|
||||
$this->artisan('abo:preview-reminder', ['abo' => $abo->id])->assertExitCode(0);
|
||||
|
||||
Storage::disk('public')->assertExists('preview/abo-reminder-'.$abo->id.'.html');
|
||||
$html = Storage::disk('public')->get('preview/abo-reminder-'.$abo->id.'.html');
|
||||
expect($html)->toContain('/user/abos/detail/me/'.$abo->id);
|
||||
Mail::assertNothingSent();
|
||||
});
|
||||
|
||||
it('versendet zusätzlich bei --send (Mailpit-Test)', function () {
|
||||
Storage::fake('public');
|
||||
Mail::fake();
|
||||
$abo = makeMeAbo();
|
||||
|
||||
$this->artisan('abo:preview-reminder', ['abo' => $abo->id, '--send' => 'test@example.com'])
|
||||
->assertExitCode(0);
|
||||
|
||||
Mail::assertSent(MailAboExecutionReminder::class, 1);
|
||||
});
|
||||
|
||||
it('lehnt ein unbekanntes Abo ab', function () {
|
||||
$this->artisan('abo:preview-reminder', ['abo' => 999999])->assertExitCode(1);
|
||||
});
|
||||
});
|
||||
41
tests/Feature/LocalizationSyncTest.php
Normal file
41
tests/Feature/LocalizationSyncTest.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
uses(Tests\TestCase::class);
|
||||
|
||||
/**
|
||||
* Stellt sicher, dass alle Übersetzungsdateien (en/es/fr) exakt dieselben Keys
|
||||
* wie die deutsche Quelle haben – keine fehlenden und keine überzähligen Keys.
|
||||
* Deutsch ist die maßgebliche Quelle.
|
||||
*/
|
||||
it('keeps translation files in sync with the german source keys', function (string $locale) {
|
||||
foreach (glob(resource_path('lang/de/*.php')) as $germanFile) {
|
||||
$fileName = basename($germanFile);
|
||||
$localeFile = resource_path('lang/'.$locale.'/'.$fileName);
|
||||
|
||||
expect($localeFile)->toBeFile("Datei {$fileName} fehlt für Locale {$locale}");
|
||||
expect(localizationSyncFlattenKeys(require $localeFile))
|
||||
->toEqualCanonicalizing(localizationSyncFlattenKeys(require $germanFile));
|
||||
}
|
||||
})->with(['en', 'es', 'fr']);
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
function localizationSyncFlattenKeys(array $translations, string $prefix = ''): array
|
||||
{
|
||||
$keys = [];
|
||||
|
||||
foreach ($translations as $key => $value) {
|
||||
$translationKey = $prefix.(string) $key;
|
||||
|
||||
if (is_array($value)) {
|
||||
$keys = [...$keys, ...localizationSyncFlattenKeys($value, $translationKey.'.')];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$keys[] = $translationKey;
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
75
tests/Feature/PreviewInvoiceCommandTest.php
Normal file
75
tests/Feature/PreviewInvoiceCommandTest.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserInvoice;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
beforeEach(fn () => makeShopEnv());
|
||||
|
||||
function makePreviewOrder(): ShoppingOrder
|
||||
{
|
||||
$shoppingUser = ShoppingUser::forceCreate([
|
||||
'auth_user_id' => 0,
|
||||
'billing_firstname' => 'Max',
|
||||
'billing_lastname' => 'Mustermann',
|
||||
'billing_email' => 'preview@example.com',
|
||||
'billing_country_id' => 1,
|
||||
'shipping_country_id' => 1,
|
||||
'wp_order_number' => 0,
|
||||
'language' => 'de',
|
||||
]);
|
||||
|
||||
$order = ShoppingOrder::create([
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'auth_user_id' => 0,
|
||||
'country_id' => 1,
|
||||
'user_shop_id' => 0,
|
||||
'payment_for' => 6,
|
||||
'shipping' => 0,
|
||||
'shipping_net' => 0,
|
||||
'subtotal_ws' => 80,
|
||||
'subtotal' => 80,
|
||||
'tax' => 0,
|
||||
'total_shipping' => 80,
|
||||
'points' => 0,
|
||||
'is_abo' => true,
|
||||
]);
|
||||
|
||||
$aboProduct = makeProduct(['12'], 50, 0);
|
||||
$order->shopping_order_items()->create([
|
||||
'product_id' => $aboProduct->id, 'is_abo_addon' => false, 'qty' => 1,
|
||||
'price' => 50, 'price_net' => 50, 'tax_rate' => 0, 'tax' => 0, 'price_vk_net' => 50, 'discount' => 0, 'points' => 0,
|
||||
]);
|
||||
$addonProduct = makeProduct(['2'], 30, 0);
|
||||
$order->shopping_order_items()->create([
|
||||
'product_id' => $addonProduct->id, 'is_abo_addon' => true, 'qty' => 1,
|
||||
'price' => 30, 'price_net' => 30, 'tax_rate' => 0, 'tax' => 0, 'price_vk_net' => 30, 'discount' => 0, 'points' => 0,
|
||||
]);
|
||||
|
||||
return $order->fresh('shopping_order_items.product');
|
||||
}
|
||||
|
||||
it('lehnt eine unbekannte Bestellung ab', function () {
|
||||
$this->artisan('sales:preview-invoice', ['order' => 999999])
|
||||
->expectsOutputToContain('nicht gefunden')
|
||||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
it('erzeugt Vorschau-PDFs ohne offizielle Rechnung oder Nummernverbrauch', function () {
|
||||
Storage::fake('public');
|
||||
$order = makePreviewOrder();
|
||||
|
||||
$this->artisan('sales:preview-invoice', ['order' => $order->id])
|
||||
->assertExitCode(0);
|
||||
|
||||
// Keine offizielle Rechnung angelegt, keine Rechnungsnummer verbraucht.
|
||||
expect(UserInvoice::count())->toBe(0);
|
||||
|
||||
// Vorschau-PDFs liegen im Preview-Ordner.
|
||||
Storage::disk('public')->assertExists('invoice/preview/VORSCHAU-'.$order->id.'-MIVITA-Rechnung.pdf');
|
||||
Storage::disk('public')->assertExists('delivery/preview/VORSCHAU-'.$order->id.'-MIVITA-Lieferschein.pdf');
|
||||
});
|
||||
266
tests/Feature/TeamAboOverviewTest.php
Normal file
266
tests/Feature/TeamAboOverviewTest.php
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboItem;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Models\UserSalesVolume;
|
||||
use App\Services\Abo\TeamAboOverviewService;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Tests\TestCase;
|
||||
|
||||
uses(TestCase::class, RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
if (! Schema::connection('sqlite')->hasColumn('products', 'slug')) {
|
||||
Schema::connection('sqlite')->table('products', function ($table) {
|
||||
$table->string('slug')->nullable();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function makeUser(?int $sponsorId = null): User
|
||||
{
|
||||
$user = User::forceCreate([
|
||||
'email' => 'u-'.uniqid('', true).'@example.com',
|
||||
'password' => bcrypt('secret'),
|
||||
'lang' => 'de',
|
||||
'm_level' => 1,
|
||||
'm_sponsor' => $sponsorId,
|
||||
'payment_account' => now()->addYear(),
|
||||
]);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function makeAbo(int $userId, int $memberId, string $isFor, string $startDate, int $points = 0): UserAbo
|
||||
{
|
||||
$abo = UserAbo::create([
|
||||
'user_id' => $userId,
|
||||
'member_id' => $memberId,
|
||||
'shopping_user_id' => 0,
|
||||
'email' => 'a-'.uniqid('', true).'@example.com',
|
||||
'is_for' => $isFor,
|
||||
'payone_userid' => 0,
|
||||
'clearingtype' => 'cc',
|
||||
'amount' => 5000,
|
||||
'active' => true,
|
||||
'status' => 2,
|
||||
'abo_interval' => 5,
|
||||
'start_date' => $startDate,
|
||||
'last_date' => $startDate,
|
||||
'next_date' => '2026-12-10',
|
||||
]);
|
||||
|
||||
if ($points > 0) {
|
||||
$product = Product::forceCreate([
|
||||
'name' => 'P-'.uniqid('', true),
|
||||
'title' => 'Test',
|
||||
'price' => 10.0,
|
||||
'tax' => 19.0,
|
||||
'active' => true,
|
||||
'pos' => 1,
|
||||
'weight' => 100,
|
||||
'points' => $points,
|
||||
'slug' => 'p-'.uniqid('', true),
|
||||
]);
|
||||
|
||||
UserAboItem::create([
|
||||
'user_abo_id' => $abo->id,
|
||||
'product_id' => $product->id,
|
||||
'comp' => 0,
|
||||
'qty' => 1,
|
||||
'status' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
return $abo->fresh();
|
||||
}
|
||||
|
||||
it('gruppiert Team-Abos nach Ebenen mit Eigen- und Kundenabos', function (): void {
|
||||
$root = makeUser();
|
||||
|
||||
// 1. Ebene: zwei direkte Partner
|
||||
$anna = makeUser($root->id);
|
||||
$lena = makeUser($root->id);
|
||||
// 2. Ebene: ein Partner unter Anna
|
||||
$lisa = makeUser($anna->id);
|
||||
|
||||
// Anna hat ein Eigen-Abo (50 Punkte) und 2 Kundenabos
|
||||
makeAbo($anna->id, $anna->id, 'me', '2026-06-05', 50);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10', 20);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-05-10', 30);
|
||||
// Lena hat kein Eigen-Abo, aber 1 Kundenabo
|
||||
makeAbo($lena->id, $lena->id, 'ot', '2026-06-12', 15);
|
||||
// Lisa (Ebene 2) hat ein Eigen-Abo
|
||||
makeAbo($lisa->id, $lisa->id, 'me', '2026-06-01', 40);
|
||||
|
||||
$service = app(TeamAboOverviewService::class);
|
||||
$overview = $service->linesOverview($root, 6, 2026);
|
||||
|
||||
expect($overview['lines'])->toHaveKey(1)
|
||||
->and($overview['lines'])->toHaveKey(2);
|
||||
|
||||
$line1 = $overview['lines'][1];
|
||||
expect($line1['consultants'])->toBe(2)
|
||||
->and($line1['members_with_own_abo'])->toBe(1) // nur Anna
|
||||
->and($line1['own_abos'])->toBe(1)
|
||||
->and($line1['customer_abos'])->toBe(3) // Anna 2 + Lena 1
|
||||
->and($line1['customer_abos_new'])->toBe(2) // im Juni: Anna 1 + Lena 1 (Mai zählt nicht)
|
||||
->and($line1['own_abos_new'])->toBe(1);
|
||||
|
||||
$line2 = $overview['lines'][2];
|
||||
expect($line2['consultants'])->toBe(1)
|
||||
->and($line2['own_abos'])->toBe(1)
|
||||
->and($line2['customer_abos'])->toBe(0);
|
||||
|
||||
$totals = $overview['totals'];
|
||||
expect($totals['own_abos'])->toBe(2)
|
||||
->and($totals['customer_abos'])->toBe(3)
|
||||
->and($totals['total_abos'])->toBe(5);
|
||||
});
|
||||
|
||||
it('liefert pro Mitglied das Eigen-Abo-Flag und Punkte', function (): void {
|
||||
$root = makeUser();
|
||||
$anna = makeUser($root->id);
|
||||
|
||||
makeAbo($anna->id, $anna->id, 'me', '2026-06-05', 50);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10', 20);
|
||||
|
||||
$service = app(TeamAboOverviewService::class);
|
||||
$overview = $service->linesOverview($root, 6, 2026);
|
||||
|
||||
$member = collect($overview['lines'][1]['members'])->firstWhere('user_id', $anna->id);
|
||||
|
||||
expect($member['has_own_abo'])->toBeTrue()
|
||||
->and($member['own_abo_points'])->toBe(50.0)
|
||||
->and($member['customer_abo_count'])->toBe(1)
|
||||
->and($member['customer_abo_points'])->toBe(20.0)
|
||||
->and($member['total_abos'])->toBe(2);
|
||||
});
|
||||
|
||||
it('rendert die Team-Abo-Linienansicht mit Ebenen und Summen', function (): void {
|
||||
URL::resolveMissingNamedRoutesUsing(fn (string $name, array $parameters) => '/'.$name.'/'.implode('/', $parameters));
|
||||
|
||||
$root = makeUser();
|
||||
$anna = makeUser($root->id);
|
||||
makeAbo($anna->id, $anna->id, 'me', '2026-06-05', 50);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10', 20);
|
||||
|
||||
$this->actingAs($root);
|
||||
|
||||
$service = app(TeamAboOverviewService::class);
|
||||
$overview = $service->linesOverview($root, 6, 2026);
|
||||
$growth = $service->monthlyGrowth($root, 2026);
|
||||
|
||||
$html = view('user.team.abos', [
|
||||
'currentMonthName' => HTMLHelper::getTransMonths()[6],
|
||||
'overview' => $overview,
|
||||
'growth' => $growth,
|
||||
'growthYear' => 2026,
|
||||
'filterYears' => HTMLHelper::getYearRange(2022),
|
||||
])->render();
|
||||
|
||||
expect($html)
|
||||
->toContain(__('abo.team_by_level'))
|
||||
->toContain(__('abo.team_total_abos'))
|
||||
->toContain(__('abo.team_growth'))
|
||||
->toContain($anna->email);
|
||||
});
|
||||
|
||||
it('berechnet das monatliche Abo-Wachstum je Jahr', function (): void {
|
||||
$root = makeUser();
|
||||
$anna = makeUser($root->id);
|
||||
$lena = makeUser($root->id);
|
||||
|
||||
// Juni 2026: 1 Eigen-Abo + 2 Kundenabos
|
||||
makeAbo($anna->id, $anna->id, 'me', '2026-06-05');
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10');
|
||||
makeAbo($lena->id, $lena->id, 'ot', '2026-06-20');
|
||||
// März 2026: 1 Kundenabo
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-03-15');
|
||||
// Anderes Jahr: zählt nicht
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2025-06-01');
|
||||
|
||||
$growth = app(TeamAboOverviewService::class)->monthlyGrowth($root, 2026);
|
||||
|
||||
expect($growth['year'])->toBe(2026)
|
||||
->and($growth['months'])->toHaveCount(12);
|
||||
|
||||
$june = collect($growth['months'])->firstWhere('month', 6);
|
||||
$march = collect($growth['months'])->firstWhere('month', 3);
|
||||
|
||||
expect($june['own_new'])->toBe(1)
|
||||
->and($june['customer_new'])->toBe(2)
|
||||
->and($june['total_new'])->toBe(3)
|
||||
->and($march['customer_new'])->toBe(1)
|
||||
->and($march['own_new'])->toBe(0);
|
||||
|
||||
expect($growth['totals']['own_new'])->toBe(1)
|
||||
->and($growth['totals']['customer_new'])->toBe(3)
|
||||
->and($growth['totals']['total_new'])->toBe(4);
|
||||
});
|
||||
|
||||
it('liefert leichtgewichtige Dashboard-KPIs inkl. 1000-Punkte-Shop', function (): void {
|
||||
$root = makeUser();
|
||||
$anna = makeUser($root->id);
|
||||
$lena = makeUser($root->id);
|
||||
|
||||
// Abos
|
||||
makeAbo($anna->id, $anna->id, 'me', '2026-06-05'); // 1 Eigen-Abo
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10'); // 1 Kundenabo
|
||||
makeAbo($lena->id, $lena->id, 'ot', '2026-06-12'); // 1 Kundenabo
|
||||
|
||||
// Anna erreicht 1000 Punkte Kundenumsatz im Juni 2026
|
||||
UserSalesVolume::create([
|
||||
'user_id' => $anna->id,
|
||||
'month' => 6,
|
||||
'year' => 2026,
|
||||
'month_KP_points' => 600,
|
||||
'month_shop_points' => 500,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$kpis = app(TeamAboOverviewService::class)->teamKpis($root, 6, 2026);
|
||||
|
||||
expect($kpis['team_partner_abos'])->toBe(1)
|
||||
->and($kpis['team_customer_abos'])->toBe(2)
|
||||
->and($kpis['team_total_abos'])->toBe(3)
|
||||
->and($kpis['shop_1000'])->toBe(1);
|
||||
});
|
||||
|
||||
it('liefert die Abo-Zusammenfassung eines Team-Mitglieds inkl. Ausführungen', function (): void {
|
||||
$root = makeUser();
|
||||
$anna = makeUser($root->id);
|
||||
|
||||
$ownAbo = makeAbo($anna->id, $anna->id, 'me', '2026-06-05', 50);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-06-10', 20);
|
||||
makeAbo($anna->id, $anna->id, 'ot', '2026-05-01', 30);
|
||||
|
||||
// Zwei ausgeführte (bezahlte) Lieferungen für das Eigen-Abo
|
||||
UserAboOrder::create(['user_abo_id' => $ownAbo->id, 'shopping_order_id' => 0, 'status' => 2, 'paid' => true]);
|
||||
UserAboOrder::create(['user_abo_id' => $ownAbo->id, 'shopping_order_id' => 0, 'status' => 2, 'paid' => true]);
|
||||
|
||||
$summary = app(TeamAboOverviewService::class)->memberAboSummary($root, $anna->id);
|
||||
|
||||
expect($summary)->not->toBeNull()
|
||||
->and($summary['email'])->toBe($anna->email)
|
||||
->and($summary['own_abo'])->not->toBeNull()
|
||||
->and($summary['own_abo']['points'])->toBe(50.0)
|
||||
->and($summary['own_abo']['executions'])->toBe(2)
|
||||
->and($summary['customer_abos']['count'])->toBe(2)
|
||||
->and($summary['customer_abos']['total_points'])->toBe(50.0)
|
||||
->and($summary['customer_abos']['items'])->toHaveCount(2);
|
||||
});
|
||||
|
||||
it('liefert null, wenn das Mitglied nicht im Team liegt', function (): void {
|
||||
$root = makeUser();
|
||||
$stranger = makeUser(); // kein Sponsor → nicht in der Downline
|
||||
|
||||
$summary = app(TeamAboOverviewService::class)->memberAboSummary($root, $stranger->id);
|
||||
|
||||
expect($summary)->toBeNull();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue