Abo (A1+A2): Liefertag frei waehlbar 1-31, Aenderung nur nach vorn, Sperre erst am Ausfuehrungstag

A1: Jeder Monatstag ist als Liefertag erlaubt (UserAbo::allowedDeliveryDays),
Tage 29-31 liefern in kuerzeren Monaten am letzten Tag. Eine Stelle
AboHelper::dateForDayInMonth klammert; setNextDate, Erstausfuehrung,
Admin-Termin und Pause rechnen darueber, der Folgemonat immer aus dem
Liefertag (31.01 -> 28.02 -> 31.03). Liefertag-Aenderung gilt fuer den
laufenden Zyklus und nur nach vorn: ist der Tag im Referenzmonat vorbei,
wird abgelehnt, der Monat verschiebt sich nie (Rueckfrage R1).
Admin-Filter "naechste Ausfuehrung" als Datumsbereich. Prognose-Kacheln
bekommen die Kachel Monatsende, Team-Abos rechnen bis Monatsende.

A2: Sperrfristen Default 0, Setting 0 ist ausdruecklich 0 (fiel bisher auf
den Default zurueck). Bedingung Kalendertage <= Sperre, zentral in
AboHelper::isWithinLock: am Ausfuehrungstag ab 0:00 Uhr fixiert, Vortag bis
23:59 Uhr frei, fuer Liefertag, Produkte, Pause und Kuendigung (R2). Texte
mit _zero-Varianten ueber AboHelper::lockMessage.

Sprachdateien de/en/es/fr, neuer AboDeliveryDayTest, bestehende Tests
angepasst, Plan-Status mit Deploy-Schritt (Settings auf 0).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-09-16 11:28:55 +00:00
parent ec3ecadc5d
commit 66c6ae05fb
30 changed files with 638 additions and 185 deletions

View file

@ -32,7 +32,7 @@ return [
'abo_is_active' => 'Abo ist aktiv',
'abo_copy_active' => 'Wenn das Abonnement nicht aktiv ist, erfolgt keine automatische Ausführung.',
'abo_copy_next_date' => 'Der nächste Ausführungstermin kann frühesten auf den Folgetag festgelegt werden.',
'abo_copy_abo_interval' => 'Die Anpassung des Abonnement-Liefertags wirkt sich auf den kommenden Ausführungstermin aus, wenn das Abonnement aktiv ist.',
'abo_copy_abo_interval' => 'Der Liefertag gilt ab der kommenden Lieferung und lässt sich im laufenden Zyklus nur nach vorn verschieben. Bis 23:59 Uhr des Vortags änderbar, am Liefertag fixiert.',
'admin_abo_copy_next_date' => 'Admins können den nächsten Ausführungstermin direkt über Monat und Liefertag festlegen.',
'error_abo_interval' => 'Das Abo Interval nicht korrekt',
'error_abo_interval_in_the_past' => 'Das Abo wurde diesen Monat noch nicht ausgeführt. Eine Änderung auf einen vergangenen Tag würde den aktuellen Monat überspringen.',
@ -40,9 +40,9 @@ 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 :lock Tage vorher erfolgen.',
'error_change_locked' => 'Änderungen sind nicht mehr möglich: Die Lieferung am :date ist fixiert. Ä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_cancel_locked' => 'Eine Kündigung ist nicht mehr möglich: Die Lieferung am :date ist fixiert. Kündigungen müssen mindestens :lock Tage vorher erfolgen.',
'abo_copy_pause' => 'Verschiebt die nächste Ausführung um einen Monat nach hinten. Maximal 1x alle :months Monate möglich.',
'payline_abo_turnover' => 'Abo-Umsatz in der Payline',
'payline_abo_turnover_hint' => 'Soll = Abo-Punkte pro Zyklus aller aktiven Abos deiner Payline (Berater- und Kundenabos). Ist = im laufenden Monat bereits abgerechnete Abo-Punkte der Payline.',
@ -52,7 +52,7 @@ return [
'payline_abo_counts' => ':team_abos Teamabos + :customer_abos Kundenabos in der Payline = :total Abos gesamt',
'abo_order_short' => '(Abo)',
'points_order_legend' => 'Bestellungen: blau = eigene Bestellung · grau = Kundenbestellung · türkis mit „(Abo)" = Abo-Lieferung.',
'customer_abo_forecast_title' => 'Punkte aus meinen Kundenabos zum 5. / 10. / 20. / 25.',
'customer_abo_forecast_title' => 'Punkte aus meinen Kundenabos zum 5. / 10. / 20. / 25. / Monatsende',
'customer_abo_forecast_hint' => 'Taggenau: je Termin die bis dahin aus deinen Kundenabos abgerechneten Punkte plus die Lieferungen, die bis dahin noch anstehen. Ohne dein eigenes Abo und ohne Team.',
'customer_abo_forecast_split' => ':billed abgerechnet + :upcoming offen',
'customer_abo_points_recurring' => 'Abo-Punkte',
@ -69,15 +69,15 @@ return [
'payline_none' => 'Noch keine Payline vorhanden (kein Provisionslevel erreicht).',
'abo_points_per_cycle' => 'Punkte pro Lieferung (Bestand)',
'abo_points_billed' => 'abgerechnet (:month)',
'abo_points_expected' => 'bis zum :day. erwartet',
'abo_points_expected_hint' => 'Bereits abgerechnete Abo-Punkte plus die Punkte aller Abos dieser Ebene, deren Lieferung bis zum :day. des Monats noch ansteht.',
'abo_points_expected' => 'bis Monatsende erwartet',
'abo_points_expected_hint' => 'Bereits abgerechnete Abo-Punkte plus die Punkte aller Abos dieser Ebene, deren Lieferung in diesem Monat noch ansteht.',
'pause_abo' => '1 Monat pausieren',
'confirm_pause' => 'Möchtest du das Abo wirklich um einen Monat pausieren? Die nächste Lieferung verschiebt sich auf den Folgemonat.',
'pause_success' => 'Dein Abo wurde um einen Monat pausiert. Die nächste Ausführung ist am :date.',
'error_pause_interval' => 'Das Abo kann maximal 1x alle :months Monate pausiert werden. Die nächste Pause ist ab dem :date möglich.',
'error_pause_not_active' => 'Nur aktive Abos können pausiert werden.',
'info_pause_available_from' => 'Eine Pause ist maximal 1x alle :months Monate möglich — wieder ab dem :date.',
'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_pause_locked' => 'Das Abo kann nicht mehr pausiert werden: Die Lieferung am :date ist fixiert. 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:',
@ -335,7 +335,7 @@ return [
'pause_cancel_title' => 'Abo pausieren oder kündigen',
'pause_cancel_intro' => 'Hier kannst du dein Abo für einen Monat aussetzen oder dauerhaft beenden. Beides ist ab der :min. Lieferung möglich.',
'pause_cancel_progress' => ':count von :min Lieferungen ausgeführt',
'pause_cancel_locked_hint' => 'Die nächste Lieferung am :date wird bereits vorbereitet (Sperre :lock Tage vorher). Pausieren oder Kündigen ist erst nach dieser Lieferung wieder möglich.',
'pause_cancel_locked_hint' => 'Die Lieferung am :date ist fixiert (Sperre :lock Tage vorher). Pausieren oder Kündigen ist erst nach dieser Lieferung wieder möglich.',
'cancel_short_copy' => 'Beendet das Abo dauerhaft. Ein neues Abo beginnt wieder mit :min Pflichtlieferungen.',
'cancel_in_section_hint' => 'Die Kündigung findest du unten auf der Abo-Seite im Abschnitt „Abo pausieren oder kündigen“.',
'cancel_modal_title' => 'Abo wirklich kündigen?',
@ -376,4 +376,14 @@ return [
'actor_by_admin' => 'vom Admin',
'actor_by_system' => 'vom System',
'filter_state' => 'Zustand',
// Freier Liefertag 1-31 und Sperre bis zum Vortag (Tickets A1/A2)
'of_month_short_hint' => '(in kürzeren Monaten der letzte Tag)',
'error_change_locked_zero' => 'Änderungen sind nicht mehr möglich: Die Lieferung am :date wird heute ausgeführt. Nach der Lieferung kannst du den Liefertag für den nächsten Monat ändern.',
'error_abo_interval_passed' => 'Der :day. ist in diesem Monat schon vorbei. Die nächste Lieferung bleibt am :next – danach kannst du den Liefertag für den Folgemonat neu festlegen.',
'error_cancel_locked_zero' => 'Eine Kündigung ist nicht mehr möglich: Die Lieferung am :date wird heute ausgeführt. Nach der Lieferung kannst du kündigen.',
'error_pause_locked_zero' => 'Das Abo kann nicht mehr pausiert werden: Die Lieferung am :date wird heute ausgeführt. Nach der Lieferung kannst du pausieren.',
'pause_cancel_locked_hint_zero' => 'Die Lieferung am :date wird heute ausgeführt. Pausieren oder Kündigen ist danach wieder möglich – bis 23:59 Uhr des Vortags einer Lieferung.',
'filter_next_from' => 'von',
'filter_next_to' => 'bis',
];

View file

@ -50,7 +50,7 @@ return [
'your_shop' => 'Dein Shop',
'commission_today' => 'Provision (Stand heute)',
'commission_unavailable' => 'Die Provisionsberechnung ist gerade nicht verfuegbar. Der Wert wird nachgetragen, sobald sie wieder laeuft.',
'payline_forecast_title' => 'Payline-Prognose zum 5. / 10. / 20. / 25.',
'payline_forecast_title' => 'Payline-Prognose zum 5. / 10. / 20. / 25. / Monatsende',
'payline_forecast_basis' => 'Basis: Paylinepunkte + persönliches Volumen',
'payline_forecast_hint' => 'Basis: aktueller Kundenumsatz + Teamumsatz (Payline). Dazu kommen kumuliert die bis zum jeweiligen Termin noch anstehenden Abo-Punkte deiner Payline (inkl. deiner eigenen Abos und Kundenabos). Prognose: Pausen, Kündigungen oder fehlgeschlagene Zahlungen können den Wert verändern.',
'forecast_day' => 'Prognose zum :date',
@ -106,4 +106,6 @@ return [
'top_results_unit_points' => 'Punkte',
'top_results_unit_partners' => 'Neupartner',
'top_results_unit_abos' => 'Abos',
'forecast_month_end' => 'Prognose zum Monatsende (:date)',
];

View file

@ -32,7 +32,7 @@ return [
'abo_is_active' => 'Subscription is active',
'abo_copy_active' => 'If the subscription is not active, it will not be executed automatically',
'abo_copy_next_date' => 'The next execution date can be set to the following day at the earliest',
'abo_copy_abo_interval' => 'Adjusting the subscription delivery day affects the upcoming execution date when the subscription is active.',
'abo_copy_abo_interval' => 'The delivery day applies from the upcoming delivery and can only be moved forward within the current cycle. Editable until 11:59 pm the day before, fixed on the delivery day.',
'admin_abo_copy_next_date' => 'Admins can set the next execution date directly using month and delivery day.',
'error_abo_interval' => 'The subscription interval is not correct',
'error_next_date' => 'The date for the next execution is not correct',
@ -166,9 +166,9 @@ 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 :lock days in advance.',
'error_change_locked' => 'Changes are no longer possible: the delivery on :date is fixed. 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_cancel_locked' => 'Cancellation is no longer possible: the delivery on :date is fixed. Cancellations must be made at least :lock days in advance.',
'abo_copy_pause' => 'Moves the next execution back by one month. Possible at most once every :months months.',
'payline_abo_turnover' => 'Subscription turnover in the payline',
'payline_abo_turnover_hint' => 'Target = subscription points per cycle of all active subscriptions in your payline (consultant and customer subscriptions). Actual = subscription points of the payline already billed in the current month.',
@ -178,7 +178,7 @@ return [
'payline_abo_counts' => ':team_abos team subscriptions + :customer_abos customer subscriptions in the payline = :total subscriptions in total',
'abo_order_short' => '(subscr.)',
'points_order_legend' => 'Orders: blue = your own order · grey = customer order · turquoise with "(subscr.)" = subscription delivery.',
'customer_abo_forecast_title' => 'Points from my customer subscriptions for the 5th / 10th / 20th / 25th',
'customer_abo_forecast_title' => 'Points from my customer subscriptions for the 5th / 10th / 20th / 25th / end of month',
'customer_abo_forecast_hint' => 'Day by day: for each date, the points billed from your customer subscriptions up to that day, plus the deliveries still due by then. Without your own subscription and without your team.',
'customer_abo_forecast_split' => ':billed billed + :upcoming due',
'customer_abo_points_recurring' => 'Subscription points',
@ -195,15 +195,15 @@ return [
'payline_none' => 'No payline yet (no commission level reached).',
'abo_points_per_cycle' => 'Points per delivery (current stock)',
'abo_points_billed' => 'billed (:month)',
'abo_points_expected' => 'expected by day :day',
'abo_points_expected_hint' => 'Subscription points already billed plus the points of all subscriptions on this level whose delivery is still due by day :day of the month.',
'abo_points_expected' => 'expected by end of month',
'abo_points_expected_hint' => 'Subscription points already billed plus the points of all subscriptions on this level whose delivery is still due this month.',
'pause_abo' => 'Pause for 1 month',
'confirm_pause' => 'Do you really want to pause the subscription for one month? The next delivery will move to the following month.',
'pause_success' => 'Your subscription has been paused for one month. The next execution is on :date.',
'error_pause_interval' => 'The subscription can be paused at most once every :months months. The next pause is possible from :date.',
'error_pause_not_active' => 'Only active subscriptions can be paused.',
'info_pause_available_from' => 'A pause is possible at most once every :months months — available again from :date.',
'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.',
'error_pause_locked' => 'The subscription can no longer be paused: the delivery on :date is fixed. 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',
@ -334,7 +334,7 @@ return [
'pause_cancel_title' => 'Pause or cancel subscription',
'pause_cancel_intro' => 'Here you can pause your subscription for one month or end it permanently. Both are possible from the :min. delivery on.',
'pause_cancel_progress' => ':count of :min deliveries completed',
'pause_cancel_locked_hint' => 'The next delivery on :date is already being prepared (locked :lock days before). Pausing or cancelling is possible again after this delivery.',
'pause_cancel_locked_hint' => 'The delivery on :date is fixed (locked :lock days before). Pausing or cancelling is possible again after this delivery.',
'cancel_short_copy' => 'Ends the subscription permanently. A new subscription starts again with :min mandatory deliveries.',
'cancel_in_section_hint' => 'You will find the cancellation at the bottom of the subscription page in the section "Pause or cancel subscription".',
'cancel_modal_title' => 'Really cancel the subscription?',
@ -374,4 +374,13 @@ return [
'actor_by_admin' => 'by the admin',
'actor_by_system' => 'by the system',
'filter_state' => 'State',
'of_month_short_hint' => '(in shorter months the last day)',
'error_change_locked_zero' => 'Changes are no longer possible: the delivery on :date is being executed today. After the delivery you can change the delivery day for the next month.',
'error_abo_interval_passed' => 'The :day. has already passed this month. The next delivery stays on :next – afterwards you can set the delivery day for the following month.',
'error_cancel_locked_zero' => 'Cancellation is no longer possible: the delivery on :date is being executed today. You can cancel after the delivery.',
'error_pause_locked_zero' => 'The subscription can no longer be paused: the delivery on :date is being executed today. You can pause after the delivery.',
'pause_cancel_locked_hint_zero' => 'The delivery on :date is being executed today. Pausing or cancelling is possible again afterwards – until 11:59 pm the day before a delivery.',
'filter_next_from' => 'from',
'filter_next_to' => 'to',
];

View file

@ -49,7 +49,7 @@ return [
'your_shop' => 'your shop',
'commission_today' => 'Commission (as of today)',
'commission_unavailable' => 'The commission calculation is currently unavailable. The value will appear once it runs again.',
'payline_forecast_title' => 'Payline forecast for the 5th / 10th / 20th / 25th',
'payline_forecast_title' => 'Payline forecast for the 5th / 10th / 20th / 25th / end of month',
'payline_forecast_basis' => 'Basis: payline points + personal volume',
'payline_forecast_hint' => 'Basis: current customer turnover + team turnover (payline). Plus, cumulatively, the subscription points of your payline still due up to the respective date (incl. your own subscriptions and customer subscriptions). Forecast: pauses, cancellations or failed payments can change the value.',
'forecast_day' => 'Forecast for :date',
@ -106,4 +106,6 @@ return [
'top_results_unit_points' => 'points',
'top_results_unit_partners' => 'new partners',
'top_results_unit_abos' => 'subscriptions',
'forecast_month_end' => 'Forecast for end of month (:date)',
];

View file

@ -32,7 +32,7 @@ return [
'abo_is_active' => 'La suscripción está activa',
'abo_copy_active' => 'Si la suscripción no está activa, no se ejecutará automáticamente',
'abo_copy_next_date' => 'La siguiente fecha de ejecución puede establecerse como muy pronto al día siguiente',
'abo_copy_abo_interval' => 'El ajuste del día de entrega de la suscripción afecta a la próxima fecha de ejecución cuando la suscripción está activa.',
'abo_copy_abo_interval' => 'El día de entrega se aplica a partir de la próxima entrega y solo puede adelantarse dentro del ciclo actual. Modificable hasta las 23:59 del día anterior; el día de entrega queda fijado.',
'admin_abo_copy_next_date' => 'Los administradores pueden establecer la próxima fecha de ejecución directamente mediante mes y día de entrega.',
'error_abo_interval' => 'El intervalo de suscripción no es correcto',
'error_next_date' => 'La fecha de la siguiente ejecución no es correcta',
@ -149,9 +149,9 @@ 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 :lock días antes.',
'error_change_locked' => 'Ya no es posible realizar cambios: la entrega del :date está fijada. 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_cancel_locked' => 'La cancelación ya no es posible: la entrega del :date está fijada. Las cancelaciones deben realizarse al menos :lock días antes.',
'abo_copy_pause' => 'Retrasa la próxima ejecución un mes. Posible como máximo 1 vez cada :months meses.',
'payline_abo_turnover' => 'Volumen de suscripciones en la payline',
'payline_abo_turnover_hint' => 'Objetivo = puntos de suscripción por ciclo de todas las suscripciones activas de tu payline (de asesores y clientes). Real = puntos de suscripción de la payline ya facturados en el mes en curso.',
@ -161,7 +161,7 @@ return [
'payline_abo_counts' => ':team_abos suscripciones de equipo + :customer_abos suscripciones de clientes en la payline = :total suscripciones en total',
'abo_order_short' => '(susc.)',
'points_order_legend' => 'Pedidos: azul = pedido propio · gris = pedido de cliente · turquesa con «(susc.)» = entrega de suscripción.',
'customer_abo_forecast_title' => 'Puntos de mis suscripciones de clientes para el 5 / 10 / 20 / 25',
'customer_abo_forecast_title' => 'Puntos de mis suscripciones de clientes para el 5 / 10 / 20 / 25 / fin de mes',
'customer_abo_forecast_hint' => 'Día a día: en cada fecha, los puntos facturados de tus suscripciones de clientes hasta ese día, más las entregas que siguen pendientes. Sin tu propia suscripción y sin el equipo.',
'customer_abo_forecast_split' => ':billed facturados + :upcoming pendientes',
'customer_abo_points_recurring' => 'Puntos de la suscripción',
@ -178,15 +178,15 @@ return [
'payline_none' => 'Aún no hay payline (no se ha alcanzado ningún nivel de comisión).',
'abo_points_per_cycle' => 'Puntos por entrega (cartera actual)',
'abo_points_billed' => 'facturado (:month)',
'abo_points_expected' => 'previsto hasta el día :day',
'abo_points_expected_hint' => 'Puntos de suscripción ya facturados más los puntos de todas las suscripciones de este nivel cuya entrega aún está pendiente hasta el día :day del mes.',
'abo_points_expected' => 'previsto hasta fin de mes',
'abo_points_expected_hint' => 'Puntos de suscripción ya facturados más los puntos de todas las suscripciones de este nivel cuya entrega aún está pendiente este mes.',
'pause_abo' => 'Pausar 1 mes',
'confirm_pause' => '¿Realmente quieres pausar la suscripción un mes? La próxima entrega se trasladará al mes siguiente.',
'pause_success' => 'Tu suscripción se ha pausado un mes. La próxima ejecución es el :date.',
'error_pause_interval' => 'La suscripción puede pausarse como máximo 1 vez cada :months meses. La próxima pausa es posible a partir del :date.',
'error_pause_not_active' => 'Solo se pueden pausar suscripciones activas.',
'info_pause_available_from' => 'Una pausa es posible como máximo 1 vez cada :months meses — de nuevo a partir del :date.',
'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.',
'error_pause_locked' => 'La suscripción ya no puede pausarse: la entrega del :date está fijada. 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',
@ -334,7 +334,7 @@ return [
'pause_cancel_title' => 'Pausar o cancelar la suscripción',
'pause_cancel_intro' => 'Aquí puedes pausar tu suscripción durante un mes o finalizarla definitivamente. Ambas opciones están disponibles a partir de la :min.ª entrega.',
'pause_cancel_progress' => ':count de :min entregas realizadas',
'pause_cancel_locked_hint' => 'La próxima entrega del :date ya se está preparando (bloqueo :lock días antes). Pausar o cancelar volverá a ser posible después de esta entrega.',
'pause_cancel_locked_hint' => 'La entrega del :date está fijada (bloqueo :lock días antes). Pausar o cancelar volverá a ser posible después de esta entrega.',
'cancel_short_copy' => 'Finaliza la suscripción definitivamente. Una nueva suscripción vuelve a empezar con :min entregas obligatorias.',
'cancel_in_section_hint' => 'Encontrarás la cancelación al final de la página de la suscripción, en la sección «Pausar o cancelar la suscripción».',
'cancel_modal_title' => '¿Realmente quieres cancelar la suscripción?',
@ -374,4 +374,13 @@ return [
'actor_by_admin' => 'por el administrador',
'actor_by_system' => 'por el sistema',
'filter_state' => 'Estado actual',
'of_month_short_hint' => '(en meses más cortos, el último día)',
'error_change_locked_zero' => 'Ya no es posible realizar cambios: la entrega del :date se ejecuta hoy. Después de la entrega podrás cambiar el día de entrega para el mes siguiente.',
'error_abo_interval_passed' => 'El día :day ya ha pasado este mes. La próxima entrega se mantiene el :next; después podrás fijar el día de entrega para el mes siguiente.',
'error_cancel_locked_zero' => 'La cancelación ya no es posible: la entrega del :date se ejecuta hoy. Podrás cancelar después de la entrega.',
'error_pause_locked_zero' => 'La suscripción ya no puede pausarse: la entrega del :date se ejecuta hoy. Podrás pausar después de la entrega.',
'pause_cancel_locked_hint_zero' => 'La entrega del :date se ejecuta hoy. Pausar o cancelar volverá a ser posible después, hasta las 23:59 del día anterior a una entrega.',
'filter_next_from' => 'desde',
'filter_next_to' => 'hasta',
];

View file

@ -49,7 +49,7 @@ return [
'your_shop' => 'tu tienda',
'commission_today' => 'Comisión (a día de hoy)',
'commission_unavailable' => 'El calculo de comisiones no esta disponible en este momento. El valor aparecera cuando vuelva a ejecutarse.',
'payline_forecast_title' => 'Pronóstico de payline para el 5 / 10 / 20 / 25',
'payline_forecast_title' => 'Pronóstico de payline para el 5 / 10 / 20 / 25 / fin de mes',
'payline_forecast_basis' => 'Base: puntos de payline + volumen personal',
'payline_forecast_hint' => 'Base: volumen de clientes actual + volumen del equipo (payline). Más, de forma acumulada, los puntos de suscripción de tu payline pendientes hasta la fecha correspondiente (incl. tus propias suscripciones y las de tus clientes). Pronóstico: pausas, cancelaciones o pagos fallidos pueden cambiar el valor.',
'forecast_day' => 'Pronóstico para el :date',
@ -106,4 +106,6 @@ return [
'top_results_unit_points' => 'puntos',
'top_results_unit_partners' => 'nuevos socios',
'top_results_unit_abos' => 'suscripciones',
'forecast_month_end' => 'Pronóstico a fin de mes (:date)',
];

View file

@ -32,7 +32,7 @@ return [
'abo_is_active' => 'L’abonnement est actif',
'abo_copy_active' => 'Si l’abonnement n’est pas actif, aucune exécution automatique n’a lieu.',
'abo_copy_next_date' => 'Le prochain jour d’exécution peut être fixé au plus tôt au lendemain.',
'abo_copy_abo_interval' => 'L’adaptation du jour de livraison de l’abonnement impacte la prochaine date d’exécution si l’abonnement est actif.',
'abo_copy_abo_interval' => 'Le jour de livraison s’applique dès la prochaine livraison et ne peut être que repoussé dans le cycle en cours. Modifiable jusqu’à 23 h 59 la veille, figé le jour de la livraison.',
'admin_abo_copy_next_date' => 'Les admins peuvent définir directement la prochaine date d’exécution via le mois et le jour de livraison.',
'error_abo_interval' => 'L’intervalle d’abonnement est incorrect',
'error_abo_interval_in_the_past' => 'L’abonnement n’a pas encore été exécuté ce mois-ci. Un changement vers un jour passé ferait sauter le mois en cours.',
@ -40,9 +40,9 @@ 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 :lock jours avant.',
'error_change_locked' => 'Les modifications ne sont plus possibles : la livraison du :date est figée. 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_cancel_locked' => 'Une résiliation n’est plus possible : la livraison du :date est figée. Les résiliations doivent être effectuées au moins :lock jours avant.',
'abo_copy_pause' => 'Reporte la prochaine exécution d’un mois. Possible au maximum 1 fois tous les :months mois.',
'payline_abo_turnover' => 'Chiffre d’affaires des abonnements dans la payline',
'payline_abo_turnover_hint' => 'Objectif = points d’abonnement par cycle de tous les abonnements actifs de ta payline (abonnements conseillers et clients). Réel = points d’abonnement de la payline déjà facturés au cours du mois.',
@ -52,7 +52,7 @@ return [
'payline_abo_counts' => ':team_abos abonnements équipe + :customer_abos abonnements clients dans la payline = :total abonnements au total',
'abo_order_short' => '(abo)',
'points_order_legend' => 'Commandes : bleu = commande personnelle · gris = commande client · turquoise avec « (abo) » = livraison d’abonnement.',
'customer_abo_forecast_title' => 'Points de mes abonnements clients pour le 5 / 10 / 20 / 25',
'customer_abo_forecast_title' => 'Points de mes abonnements clients pour le 5 / 10 / 20 / 25 / fin de mois',
'customer_abo_forecast_hint' => 'Jour par jour : à chaque date, les points facturés sur tes abonnements clients jusqu’à ce jour, plus les livraisons encore à venir. Sans ton propre abonnement et sans l’équipe.',
'customer_abo_forecast_split' => ':billed facturés + :upcoming à venir',
'customer_abo_points_recurring' => 'Points de l’abonnement',
@ -69,15 +69,15 @@ return [
'payline_none' => 'Pas encore de payline (aucun niveau de commission atteint).',
'abo_points_per_cycle' => 'Points par livraison (portefeuille actuel)',
'abo_points_billed' => 'facturé (:month)',
'abo_points_expected' => 'prévu jusqu’au :day',
'abo_points_expected_hint' => 'Points d’abonnement déjà facturés plus les points de tous les abonnements de ce niveau dont la livraison est encore à venir d’ici le :day du mois.',
'abo_points_expected' => 'prévu jusqu’à la fin du mois',
'abo_points_expected_hint' => 'Points d’abonnement déjà facturés plus les points de tous les abonnements de ce niveau dont la livraison est encore à venir ce mois-ci.',
'pause_abo' => 'Suspendre 1 mois',
'confirm_pause' => 'Veux-tu vraiment suspendre l’abonnement pendant un mois ? La prochaine livraison sera reportée au mois suivant.',
'pause_success' => 'Ton abonnement a été suspendu pour un mois. La prochaine exécution aura lieu le :date.',
'error_pause_interval' => 'L’abonnement ne peut être suspendu qu’une fois tous les :months mois. La prochaine pause est possible à partir du :date.',
'error_pause_not_active' => 'Seuls les abonnements actifs peuvent être suspendus.',
'info_pause_available_from' => 'Une pause est possible au maximum 1 fois tous les :months mois — de nouveau à partir du :date.',
'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_pause_locked' => 'L’abonnement ne peut plus être mis en pause : la livraison du :date est figée. 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 :',
@ -334,7 +334,7 @@ return [
'pause_cancel_title' => 'Suspendre ou résilier l’abonnement',
'pause_cancel_intro' => 'Ici, tu peux suspendre ton abonnement pendant un mois ou y mettre fin définitivement. Les deux sont possibles à partir de la :min. livraison.',
'pause_cancel_progress' => ':count livraisons sur :min effectuées',
'pause_cancel_locked_hint' => 'La prochaine livraison du :date est déjà en préparation (blocage :lock jours avant). Suspendre ou résilier sera de nouveau possible après cette livraison.',
'pause_cancel_locked_hint' => 'La livraison du :date est figée (blocage :lock jours avant). Suspendre ou résilier sera de nouveau possible après cette livraison.',
'cancel_short_copy' => 'Met fin définitivement à l’abonnement. Un nouvel abonnement recommence avec :min livraisons obligatoires.',
'cancel_in_section_hint' => 'Tu trouveras la résiliation en bas de la page de l’abonnement, dans la section « Suspendre ou résilier l’abonnement ».',
'cancel_modal_title' => 'Vraiment résilier l’abonnement ?',
@ -374,4 +374,13 @@ return [
'actor_by_admin' => 'par l’administrateur',
'actor_by_system' => 'par le système',
'filter_state' => 'État',
'of_month_short_hint' => '(dans les mois plus courts, le dernier jour)',
'error_change_locked_zero' => 'Les modifications ne sont plus possibles : la livraison du :date est exécutée aujourd’hui. Après la livraison, tu pourras changer le jour de livraison pour le mois suivant.',
'error_abo_interval_passed' => 'Le :day est déjà passé ce mois-ci. La prochaine livraison reste le :next ; ensuite tu pourras fixer le jour de livraison pour le mois suivant.',
'error_cancel_locked_zero' => 'Une résiliation n’est plus possible : la livraison du :date est exécutée aujourd’hui. Tu pourras résilier après la livraison.',
'error_pause_locked_zero' => 'L’abonnement ne peut plus être mis en pause : la livraison du :date est exécutée aujourd’hui. Tu pourras suspendre après la livraison.',
'pause_cancel_locked_hint_zero' => 'La livraison du :date est exécutée aujourd’hui. Suspendre ou résilier sera de nouveau possible ensuite – jusqu’à 23 h 59 la veille d’une livraison.',
'filter_next_from' => 'du',
'filter_next_to' => 'au',
];

View file

@ -50,7 +50,7 @@ return [
'your_shop' => 'Votre boutique',
'commission_today' => 'Commission (à ce jour)',
'commission_unavailable' => 'Le calcul des commissions n\'est pas disponible actuellement. La valeur apparaitra des qu\'il fonctionnera de nouveau.',
'payline_forecast_title' => 'Prévision payline pour le 5 / 10 / 20 / 25',
'payline_forecast_title' => 'Prévision payline pour le 5 / 10 / 20 / 25 / fin de mois',
'payline_forecast_basis' => 'Base : points payline + volume personnel',
'payline_forecast_hint' => 'Base : chiffre d’affaires clients actuel + chiffre d’affaires équipe (payline). S’y ajoutent, de manière cumulée, les points d’abonnement de ta payline encore à venir jusqu’à la date concernée (y compris tes propres abonnements et abonnements clients). Prévision : pauses, résiliations ou paiements échoués peuvent modifier la valeur.',
'forecast_day' => 'Prévision pour le :date',
@ -106,4 +106,6 @@ return [
'top_results_unit_points' => 'points',
'top_results_unit_partners' => 'nouveaux partenaires',
'top_results_unit_abos' => 'abonnements',
'forecast_month_end' => 'Prévision à la fin du mois (:date)',
];

View file

@ -43,10 +43,7 @@
</div>
@elseif ($pcLocked && $pcNextDate)
<div class="alert alert-warning mb-0">
{{ __('abo.pause_cancel_locked_hint', [
'date' => $pcNextDate->format(Util::formatDateDB()),
'lock' => App\Repositories\AboRepository::getLockDaysPauseCancel(),
]) }}
{{ App\Services\AboHelper::lockMessage('pause_cancel_locked_hint', $user_abo, App\Repositories\AboRepository::getLockDaysPauseCancel()) }}
</div>
@else
<div class="row">

View file

@ -69,14 +69,12 @@
</select>
</div>
</div>
<div class="col-6 col-md-3 col-lg-2 mb-2">
<label class="form-label" for="filter_next_day">{{ __('tables.next_date') }}</label>
<select class="custom-select" name="filter_next_day" id="filter_next_day">
<option value="">{{ __('tables.all') }}</option>
@foreach ($filter_next_days as $day)
<option value="{{ $day }}" @if((string) get_user_attr('filter_next_day') === (string) $day) selected @endif>{{ \App\Services\HTMLHelper::getAboStrLang($day) }}</option>
@endforeach
</select>
<div class="col-12 col-md-6 col-lg-4 mb-2">
<label class="form-label">{{ __('tables.next_date') }}</label>
<div class="d-flex border rounded p-1" style="gap: 6px;">
<input type="date" class="form-control" name="filter_next_from" id="filter_next_from" value="{{ get_user_attr('filter_next_from') }}" aria-label="{{ __('abo.filter_next_from') }}" placeholder="{{ __('abo.filter_next_from') }}">
<input type="date" class="form-control" name="filter_next_to" id="filter_next_to" value="{{ get_user_attr('filter_next_to') }}" aria-label="{{ __('abo.filter_next_to') }}" placeholder="{{ __('abo.filter_next_to') }}">
</div>
</div>
<div class="col-12 col-sm-6 col-md-3 col-lg-3 mb-2">
<label class="form-label" for="filter_member_id">{{ __('tables.adviser') }}</label>
@ -136,7 +134,8 @@
d.filter_payment = $('select[name=filter_payment]').val();
d.filter_start_month = $('select[name=filter_start_month]').val();
d.filter_start_year = $('select[name=filter_start_year]').val();
d.filter_next_day = $('select[name=filter_next_day]').val();
d.filter_next_from = $('input[name=filter_next_from]').val();
d.filter_next_to = $('input[name=filter_next_to]').val();
}
},
"order": [[0, "desc" ]],
@ -164,7 +163,7 @@
"url": "/js/datatables-{{ \App::getLocale() }}.json"
}
});
$('#filter_start_month, #filter_start_year, #filter_next_day, #filter_status, #filter_state, #filter_active, #filter_is_for, #filter_payment, #filter_member_id').on('change', function(){
$('#filter_start_month, #filter_start_year, #filter_next_from, #filter_next_to, #filter_status, #filter_state, #filter_active, #filter_is_for, #filter_payment, #filter_member_id').on('change', function(){
oTable.draw();
});
});

View file

@ -22,10 +22,7 @@
@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(),
]) }}
{{ App\Services\AboHelper::lockMessage('error_change_locked', $user_abo, App\Repositories\AboRepository::getLockDaysChange()) }}
</div>
@endif

View file

@ -268,11 +268,11 @@
<div class="text-muted small mb-3 mt-n2">{{ __('home.payline_forecast_basis') }}</div>
<div class="row">
@foreach ($s['payline_forecast']['days'] as $forecastDay)
<div class="col-sm-6 col-lg-3 mb-3">
<div class="col-6 col-lg mb-3">
<div class="card h-100 {{ $forecastDay['is_past'] ? 'bg-light' : '' }}">
<div class="card-body py-3 text-center">
<div class="text-muted small">
{{ __('home.forecast_day', ['date' => $forecastDay['date']]) }}
{{ ! empty($forecastDay['is_month_end']) ? __('home.forecast_month_end', ['date' => $forecastDay['date']]) : __('home.forecast_day', ['date' => $forecastDay['date']]) }}
</div>
<div class="font-weight-bold text-large">{{ $fmt($forecastDay['total']) }}</div>
@if ($forecastDay['upcoming'] > 0)

View file

@ -24,11 +24,11 @@
<div class="text-muted small mb-3">{{ __('abo.customer_abo_forecast_hint') }}</div>
<div class="row">
@foreach ($customerAboForecast['days'] as $forecastDay)
<div class="col-sm-6 col-lg-3 mb-2">
<div class="col-6 col-lg mb-2">
<div class="card h-100 {{ $forecastDay['is_past'] ? 'bg-light' : '' }}">
<div class="card-body py-3 text-center">
<div class="text-muted small">
{{ __('home.forecast_day', ['date' => $forecastDay['date']]) }}
{{ ! empty($forecastDay['is_month_end']) ? __('home.forecast_month_end', ['date' => $forecastDay['date']]) : __('home.forecast_day', ['date' => $forecastDay['date']]) }}
</div>
<div class="font-weight-bold text-large">
{{ \App\Services\Util::formatNumber($forecastDay['total']) }}

View file

@ -95,7 +95,7 @@
<th class="text-center">{{ __('abo.team_total') }}</th>
<th class="text-right">{{ __('abo.abo_points_per_cycle') }}</th>
<th class="text-right">{{ __('abo.abo_points_billed', ['month' => $currentMonthName]) }}</th>
<th class="text-right" title="{{ __('abo.abo_points_expected_hint', ['day' => 25]) }}">{{ __('abo.abo_points_expected', ['day' => 25]) }}</th>
<th class="text-right" title="{{ __('abo.abo_points_expected_hint') }}">{{ __('abo.abo_points_expected') }}</th>
</tr>
</thead>
<tbody>