Abo Einmalprodukte und Bestätigung abschließen

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin 2026-06-05 15:28:08 +00:00
parent 2bdc9ada3c
commit 2269ce031f
57 changed files with 3647 additions and 371 deletions

View file

@ -75,10 +75,21 @@ return [
'error_add_only_no_remove' => 'Das Entfernen von Produkten ist während der Mindestlaufzeit nicht möglich.',
'confirm_add_title' => 'Produkt hinzufügen bestätigen',
'confirm_add_title_normal' => 'Produkt zum Abo hinzufügen',
'confirm_increase_title' => 'Abo-Menge erhöhen',
'confirm_add_warning' => 'Während der Mindestlaufzeit können hinzugefügte Produkte nicht wieder entfernt werden. Bitte prüfe Deine Auswahl sorgfältig.',
'confirm_add_warning_normal' => 'Möchtest Du dieses Produkt wirklich zu Deinem Abo hinzufügen?',
'confirm_add_info' => 'Du bist dabei, diesen Artikel zu Deinem laufenden Abo hinzuzufügen. Dadurch ändert sich Dein regelmäßiger Zahlungsbetrag.',
'confirm_increase_info' => 'Du bist dabei, die Menge dieses Artikels in Deinem laufenden Abo zu erhöhen. Dadurch ändert sich Dein regelmäßiger Zahlungsbetrag.',
'confirm_article_details' => 'Artikel-Details',
'confirm_additional_costs' => 'Zusätzliche Kosten',
'confirm_new_total' => 'Neuer Abo-Gesamtbetrag',
'confirm_per_delivery' => 'pro Lieferung',
'confirm_legal_notice' => 'Die Änderung wird zur nächsten Lieferung am :nextBillingDate wirksam. Es gelten unsere :agb und die :withdrawal.',
'confirm_terms_link' => 'AGB',
'confirm_withdrawal_link' => 'Widerrufsbelehrung',
'confirm_next_delivery_unknown' => 'nächsten Liefertermin',
'confirm_add_cancel' => 'Abbrechen',
'confirm_add_ok' => 'Ja, hinzufügen',
'confirm_add_ok' => 'Zahlungspflichtig aktualisieren',
'add_product' => 'Produkt hinzufügen',
'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>.',
@ -91,6 +102,28 @@ return [
'need_basis_product' => 'Sie müssen min. ein Basis-Produkt in Ihrem Abo haben, bitte fügen Sie erst ein neues Basis-Produkt hinzu und entfernen Sie dann das alte Basis-Produkt!',
'abo_item_not_found' => 'Abo-Position nicht gefunden',
'product_not_found' => 'Produkt nicht gefunden',
'onetime_window_closed' => 'Das Zeitfenster zum Hinzufügen einmaliger Produkte ist aktuell nicht geöffnet.',
'onetime_product_not_allowed' => 'Dieses Produkt kann nicht einmalig hinzugefügt werden.',
'onetime_action_required' => 'Es wurde keine Aktion angegeben.',
'onetime_action_invalid' => 'Ungültige Aktion.',
'onetime_qty_required' => 'Bitte eine gültige Menge angeben.',
'onetime_card_hl' => 'Einmalige Produkte zur nächsten Lieferung hinzufügen',
'onetime_card_info' => 'Füge hier Produkte aus dem regulären Sortiment einmalig zu deiner nächsten Abo-Lieferung hinzu. So sparst du dir zusätzliche Versandkosten und erhältst alles in einem Paket.',
'onetime_important_hl' => 'Wichtig:',
'onetime_coverage_hint' => 'Der zusätzliche Betrag wird bei der nächsten Ausführung bequem zusammen mit deinem regulären Abo-Betrag abgebucht.',
'onetime_reset_hint' => 'Einmalige Produkte werden nur deiner nächsten Lieferung beigelegt und danach automatisch wieder aus dem Abo entfernt.',
'add_onetime_product' => 'Einmaliges Produkt hinzufügen',
'onetime_subtotal' => 'Zwischensumme einmalige Produkte',
'onetime_next_delivery_total' => 'Gesamtbetrag der nächsten Lieferung (Abo + Einmalig)',
'onetime_legal_notice' => 'Die hinzugefügten Produkte werden einmalig am :nextBillingDate versendet. Es gelten unsere :agb und die :withdrawal.',
'onetime_discard_changes' => 'Änderungen verwerfen',
'onetime_confirm_paid' => 'Zahlungspflichtig aktualisieren',
'onetime_confirm_success' => 'Die einmaligen Produkte wurden erfolgreich für deine nächste Lieferung vorgemerkt.',
'abo_subtotal' => 'Zwischensumme Abo-Produkte',
'abo_next_delivery_total' => 'Gesamtbetrag der nächsten Lieferung',
'onetime_empty' => 'Noch keine einmaligen Produkte hinzugefügt.',
'onetime_badge' => 'Einmalig',
'combined_summary_hl' => 'Gesamtsumme der nächsten Lieferung',
'create_abo' => 'Abo erstellen',
'info' => 'Info',
'data' => 'Daten',

View file

@ -37,6 +37,7 @@ return [
'shopping_user_not_found' => 'Fehler: Es wurde kein ShoppingUser gefunden',
'account_released' => 'Account freigeschaltet',
'cart_product_not_allowed_for_order_type' => 'Der Warenkorb enthält Artikel, die für diese Bestellart nicht vorgesehen sind. Bitte leere den Warenkorb und wähle nur Produkte, die zu dieser Bestellung passen.',
'cart_max_weight_reached' => 'Das maximale Versandgewicht ist erreicht. Es können keine weiteren Produkte hinzugefügt werden.',
];
/*
{{ __('msg.') }}

View file

@ -83,6 +83,7 @@ return [
'ship_to_this_email_info' => 'Der Bestelllink wird Deinem Kunden an folgenden E-Mail-Adresse gesendet:',
'shipping' => 'Versand',
'shipping_compensation_product' => 'Versand Kompensationsprodukt',
'comp_required_by_additional_products' => 'Dieses Kompensationsprodukt wird durch die zusätzlich hinzugefügten Produkte benötigt.',
'shipping_costs' => 'Versandkosten',
'shopping_cart' => 'Warenkorb',
'shopping_cart_delete' => 'Warenkorb löschen',

View file

@ -66,10 +66,21 @@ return [
'error_add_only_no_remove' => 'Removing products is not possible during the minimum duration period.',
'confirm_add_title' => 'Confirm adding product',
'confirm_add_title_normal' => 'Add product to subscription',
'confirm_increase_title' => 'Increase subscription quantity',
'confirm_add_warning' => 'During the minimum duration, added products cannot be removed again. Please check your selection carefully.',
'confirm_add_warning_normal' => 'Do you really want to add this product to your subscription?',
'confirm_add_info' => 'You are about to add this item to your active subscription. This changes your recurring payment amount.',
'confirm_increase_info' => 'You are about to increase the quantity of this item in your active subscription. This changes your recurring payment amount.',
'confirm_article_details' => 'Item details',
'confirm_additional_costs' => 'Additional costs',
'confirm_new_total' => 'New subscription total',
'confirm_per_delivery' => 'per delivery',
'confirm_legal_notice' => 'The change will take effect with the next delivery on :nextBillingDate. Our :agb and :withdrawal apply.',
'confirm_terms_link' => 'terms and conditions',
'confirm_withdrawal_link' => 'right of withdrawal',
'confirm_next_delivery_unknown' => 'next delivery date',
'confirm_add_cancel' => 'Cancel',
'confirm_add_ok' => 'Yes, add product',
'confirm_add_ok' => 'Update with payment obligation',
'add_product' => 'Add product',
'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>.',
@ -82,6 +93,28 @@ return [
'need_basis_product' => 'You must have at least one base product in your subscription. Please first add a new base product and then remove the old base product!',
'abo_item_not_found' => 'Subscription item not found',
'product_not_found' => 'Product not found',
'onetime_window_closed' => 'The time window for adding one-time products is currently closed.',
'onetime_product_not_allowed' => 'This product cannot be added as a one-time item.',
'onetime_action_required' => 'No action was provided.',
'onetime_action_invalid' => 'Invalid action.',
'onetime_qty_required' => 'Please provide a valid quantity.',
'onetime_card_hl' => 'Add one-time products to your next delivery',
'onetime_card_info' => 'Add products from the regular assortment once to your next subscription delivery. This saves additional shipping costs and you receive everything in one parcel.',
'onetime_important_hl' => 'Important:',
'onetime_coverage_hint' => 'The additional amount will be conveniently charged together with your regular subscription amount on the next execution.',
'onetime_reset_hint' => 'One-time products are added only to your next delivery and are automatically removed from the subscription afterwards.',
'add_onetime_product' => 'Add one-time product',
'onetime_subtotal' => 'Subtotal one-time products',
'onetime_next_delivery_total' => 'Total amount of next delivery (subscription + one-time)',
'onetime_legal_notice' => 'The added products will be shipped once on :nextBillingDate. Our :agb and :withdrawal apply.',
'onetime_discard_changes' => 'Discard changes',
'onetime_confirm_paid' => 'Update with payment obligation',
'onetime_confirm_success' => 'The one-time products were successfully reserved for your next delivery.',
'abo_subtotal' => 'Subtotal subscription products',
'abo_next_delivery_total' => 'Total amount of next delivery',
'onetime_empty' => 'No one-time products added yet.',
'onetime_badge' => 'One-time',
'combined_summary_hl' => 'Total of next delivery',
'create_abo' => 'Create subscription',
'info' => 'Info',
'data' => 'Data',

View file

@ -39,4 +39,5 @@ return [
'' => 'Your shopping cart is empty, please add products first',
],
'cart_product_not_allowed_for_order_type' => 'Your cart contains items that are not allowed for this order type. Please clear the cart and only add products that match this order.',
'cart_max_weight_reached' => 'The maximum shipping weight has been reached. No further products can be added.',
];

View file

@ -95,6 +95,7 @@ return [
'ship_to_this_email_info' => 'The order link will be sent to your customer at the following email address:',
'shipping' => 'shipment',
'shipping_compensation_product' => 'shipping compensation product',
'comp_required_by_additional_products' => 'This compensation product is required because of the additionally added products.',
'shipping_costs' => 'shipping',
'shopping_cart' => 'shopping cart',
'shopping_cart_delete' => 'clear cart',

View file

@ -66,10 +66,21 @@ return [
'error_add_only_no_remove' => 'No es posible eliminar productos durante el periodo de duración mínima.',
'confirm_add_title' => 'Confirmar agregar producto',
'confirm_add_title_normal' => 'Agregar producto a la suscripción',
'confirm_increase_title' => 'Aumentar cantidad de suscripción',
'confirm_add_warning' => 'Durante la duración mínima, los productos agregados no pueden ser eliminados. Por favor, revise su selección cuidadosamente.',
'confirm_add_warning_normal' => '¿Realmente desea agregar este producto a su suscripción?',
'confirm_add_info' => 'Está a punto de agregar este artículo a su suscripción activa. Esto modifica el importe de pago recurrente.',
'confirm_increase_info' => 'Está a punto de aumentar la cantidad de este artículo en su suscripción activa. Esto modifica el importe de pago recurrente.',
'confirm_article_details' => 'Detalles del artículo',
'confirm_additional_costs' => 'Costes adicionales',
'confirm_new_total' => 'Nuevo total de la suscripción',
'confirm_per_delivery' => 'por entrega',
'confirm_legal_notice' => 'El cambio será efectivo con la próxima entrega el :nextBillingDate. Se aplican nuestros :agb y el :withdrawal.',
'confirm_terms_link' => 'términos y condiciones',
'confirm_withdrawal_link' => 'derecho de desistimiento',
'confirm_next_delivery_unknown' => 'próxima fecha de entrega',
'confirm_add_cancel' => 'Cancelar',
'confirm_add_ok' => 'Sí, agregar',
'confirm_add_ok' => 'Actualizar con obligación de pago',
'add_product' => 'Añadir producto',
'product_prices_career_level_info' => 'Los precios de los productos se muestran y calculan según su nivel de carrera <strong>:user_level_name</strong> menos <strong>:user_level_margin %</strong> de margen.',
'product_prices_career_level_cpay_info' => 'Los precios de los productos se muestran como precios minoristas para el cliente. Después de completar el pago del cliente, recibirá su comisión según su nivel de carrera <strong>:user_level_name</strong> comisión <strong>:user_level_margin %</strong>.',
@ -82,6 +93,28 @@ return [
'need_basis_product' => 'Debe tener al menos un producto base en su suscripción. ¡Primero agregue un nuevo producto base y luego elimine el producto base anterior!',
'abo_item_not_found' => 'Artículo de suscripción no encontrado',
'product_not_found' => 'Producto no encontrado',
'onetime_window_closed' => 'La ventana de tiempo para añadir productos puntuales no está abierta actualmente.',
'onetime_product_not_allowed' => 'Este producto no se puede añadir como artículo puntual.',
'onetime_action_required' => 'No se ha indicado ninguna acción.',
'onetime_action_invalid' => 'Acción no válida.',
'onetime_qty_required' => 'Indique una cantidad válida.',
'onetime_card_hl' => 'Añadir productos únicos a su próxima entrega',
'onetime_card_info' => 'Añada productos del surtido habitual una sola vez a su próxima entrega de suscripción. Así ahorra gastos de envío adicionales y recibe todo en un solo paquete.',
'onetime_important_hl' => 'Importante:',
'onetime_coverage_hint' => 'El importe adicional se cargará cómodamente junto con el importe regular de su suscripción en la próxima ejecución.',
'onetime_reset_hint' => 'Los productos únicos solo se añaden a su próxima entrega y después se eliminan automáticamente de la suscripción.',
'add_onetime_product' => 'Añadir producto único',
'onetime_subtotal' => 'Subtotal productos únicos',
'onetime_next_delivery_total' => 'Importe total de la próxima entrega (suscripción + único)',
'onetime_legal_notice' => 'Los productos añadidos se enviarán una sola vez el :nextBillingDate. Se aplican nuestros :agb y el :withdrawal.',
'onetime_discard_changes' => 'Descartar cambios',
'onetime_confirm_paid' => 'Actualizar con obligación de pago',
'onetime_confirm_success' => 'Los productos únicos se han reservado correctamente para su próxima entrega.',
'abo_subtotal' => 'Subtotal productos de suscripción',
'abo_next_delivery_total' => 'Importe total de la próxima entrega',
'onetime_empty' => 'Aún no se han añadido productos únicos.',
'onetime_badge' => 'Único',
'combined_summary_hl' => 'Total de la próxima entrega',
'create_abo' => 'Crear suscripción',
'info' => 'Info',
'data' => 'Datos',

View file

@ -1,42 +1,42 @@
<?php
return array (
'VATID_could_not_be_validated' => 'No se pudo validar el ID de IVA, verifique su entrada',
'VATID_successfully_entered' => 'ID de IVA ingresado exitosamente',
'abo_deaktivert' => 'opción de suscripción deshabilitada',
'account_released' => 'Cuenta activada',
'booked_package_has_been_changed' => 'El paquete reservado ha sido modificado.',
'cancel_membership_is_requested' => 'Se ha solicitado la terminación de la membresía',
'compensation_products_cannot_be_0' => 'Error: Los productos de compensación no pueden ser 0.',
'contact_delete' => 'contacto eliminado',
'country_account_has_been_changed__cost_has_been_reset' => 'Se cambió el país de facturación y se restableció la lista de verificación de mercancías.',
'error_checkbox_not_confirm' => 'Error: Casilla de verificación no confirmada',
'error_occurred_with_order' => 'Se produjo un error al realizar el pedido.',
'file_deleted' => 'archivo eliminado',
'file_empty' => '"archivo vacío"',
'file_not_found' => 'archivo no encontrado',
'file_uploaded' => 'archivo subido',
'homeparty_delete' => 'fiesta de tiempo de espera eliminada',
'homeparty_guest_delete' => 'invitado a la fiesta de tiempo de espera eliminado',
'link_for_homeparty_not_found' => 'El enlace para la fiesta de tiempo de espera no se encontró o ya no está activo.',
'no_change_made' => 'no se realizó ningún cambio',
'no_id_card_deposited_please_upload_first' => 'No se proporcionó ninguna identificación, cárguela primero',
'no_trade_licence_deposited_please_upload_first' => 'No hay ninguna licencia comercial almacenada; cárguela primero',
'please_enter_reason_why_you_not_need_trade_licence' => 'Proporcione una razón por la cual no necesita una licencia comercial',
'please_select_compensation_product' => 'Por favor seleccione un producto de compensación',
'please_select_count_compensation_products' => 'Por favor seleccione: contar productos de compensación',
'reverse_charge_procedure_and_VATID_deleted' => 'Se elimina el procedimiento de inversión del cargo y el número de IVA',
'shipping_cost_cannot_be_0' => 'Error: el costo de envío no puede ser 0',
'shipping_costs_were_not_calculated_correctly' => 'Error: los costos de envío no se calcularon correctamente',
'shipping_country_was_not_correctly' => 'Error: El país de envío no se procesó correctamente en el carrito de compras',
'shipping_country_was_not_found' => 'Error: País de envío no encontrado',
'shopping_cart_was_not_user_shop' => 'Error: El consultor no tiene tienda, el pedido no puede continuar',
'shopping_cart_was_shipping_free' => 'Error: El carrito de compras se especificó como envío gratuito',
'shopping_instance_not_found' => 'Error: No se ha encontrado ninguna ShoppingInstance',
'shopping_user_not_found' => 'Error: No se ha encontrado ningún ShoppingUser',
'user_not_found' => 'El consultor no fue encontrado.<br>La cuenta ha sido desactivada o eliminada.',
'your_shopping_cart_is_empty_please_add_products_first' =>
array (
'' => 'Su carrito de compras está vacío, agregue productos primero',
),
);
return [
'VATID_could_not_be_validated' => 'No se pudo validar el ID de IVA, verifique su entrada',
'VATID_successfully_entered' => 'ID de IVA ingresado exitosamente',
'abo_deaktivert' => 'opción de suscripción deshabilitada',
'account_released' => 'Cuenta activada',
'booked_package_has_been_changed' => 'El paquete reservado ha sido modificado.',
'cancel_membership_is_requested' => 'Se ha solicitado la terminación de la membresía',
'cart_max_weight_reached' => 'Se ha alcanzado el peso máximo de envío. No se pueden añadir más productos.',
'compensation_products_cannot_be_0' => 'Error: Los productos de compensación no pueden ser 0.',
'contact_delete' => 'contacto eliminado',
'country_account_has_been_changed__cost_has_been_reset' => 'Se cambió el país de facturación y se restableció la lista de verificación de mercancías.',
'error_checkbox_not_confirm' => 'Error: Casilla de verificación no confirmada',
'error_occurred_with_order' => 'Se produjo un error al realizar el pedido.',
'file_deleted' => 'archivo eliminado',
'file_empty' => '"archivo vacío"',
'file_not_found' => 'archivo no encontrado',
'file_uploaded' => 'archivo subido',
'homeparty_delete' => 'fiesta de tiempo de espera eliminada',
'homeparty_guest_delete' => 'invitado a la fiesta de tiempo de espera eliminado',
'link_for_homeparty_not_found' => 'El enlace para la fiesta de tiempo de espera no se encontró o ya no está activo.',
'no_change_made' => 'no se realizó ningún cambio',
'no_id_card_deposited_please_upload_first' => 'No se proporcionó ninguna identificación, cárguela primero',
'no_trade_licence_deposited_please_upload_first' => 'No hay ninguna licencia comercial almacenada; cárguela primero',
'please_enter_reason_why_you_not_need_trade_licence' => 'Proporcione una razón por la cual no necesita una licencia comercial',
'please_select_compensation_product' => 'Por favor seleccione un producto de compensación',
'please_select_count_compensation_products' => 'Por favor seleccione: contar productos de compensación',
'reverse_charge_procedure_and_VATID_deleted' => 'Se elimina el procedimiento de inversión del cargo y el número de IVA',
'shipping_cost_cannot_be_0' => 'Error: el costo de envío no puede ser 0',
'shipping_costs_were_not_calculated_correctly' => 'Error: los costos de envío no se calcularon correctamente',
'shipping_country_was_not_correctly' => 'Error: El país de envío no se procesó correctamente en el carrito de compras',
'shipping_country_was_not_found' => 'Error: País de envío no encontrado',
'shopping_cart_was_not_user_shop' => 'Error: El consultor no tiene tienda, el pedido no puede continuar',
'shopping_cart_was_shipping_free' => 'Error: El carrito de compras se especificó como envío gratuito',
'shopping_instance_not_found' => 'Error: No se ha encontrado ninguna ShoppingInstance',
'shopping_user_not_found' => 'Error: No se ha encontrado ningún ShoppingUser',
'user_not_found' => 'El consultor no fue encontrado.<br>La cuenta ha sido desactivada o eliminada.',
'your_shopping_cart_is_empty_please_add_products_first' => [
'' => 'Su carrito de compras está vacío, agregue productos primero',
],
];

View file

@ -96,6 +96,7 @@ return [
'ship_to_this_email_info' => 'El enlace del pedido se enviará a su cliente a la siguiente dirección de correo electrónico',
'shipping' => 'envío',
'shipping_compensation_product' => 'producto de compensación de envío',
'comp_required_by_additional_products' => 'Este producto de compensación es necesario por los productos añadidos adicionalmente.',
'shipping_costs' => 'envío',
'shopping_cart' => 'carro de la compra',
'shopping_cart_delete' => 'vaciar carrito',

View file

@ -75,10 +75,21 @@ return [
'error_add_only_no_remove' => 'La suppression de produits nest pas possible pendant la durée minimale.',
'confirm_add_title' => 'Confirmer lajout du produit',
'confirm_add_title_normal' => 'Ajouter le produit à labonnement',
'confirm_increase_title' => 'Augmenter la quantité de labonnement',
'confirm_add_warning' => 'Pendant la durée minimale, les produits ajoutés ne peuvent pas être retirés. Veuillez vérifier soigneusement votre sélection.',
'confirm_add_warning_normal' => 'Voulez-vous vraiment ajouter ce produit à votre abonnement ?',
'confirm_add_info' => 'Vous êtes sur le point dajouter cet article à votre abonnement en cours. Cela modifie le montant de paiement récurrent.',
'confirm_increase_info' => 'Vous êtes sur le point daugmenter la quantité de cet article dans votre abonnement en cours. Cela modifie le montant de paiement récurrent.',
'confirm_article_details' => 'Détails de larticle',
'confirm_additional_costs' => 'Coûts supplémentaires',
'confirm_new_total' => 'Nouveau total de labonnement',
'confirm_per_delivery' => 'par livraison',
'confirm_legal_notice' => 'La modification prendra effet lors de la prochaine livraison le :nextBillingDate. Nos :agb et le :withdrawal sappliquent.',
'confirm_terms_link' => 'conditions générales',
'confirm_withdrawal_link' => 'droit de rétractation',
'confirm_next_delivery_unknown' => 'prochaine date de livraison',
'confirm_add_cancel' => 'Annuler',
'confirm_add_ok' => 'Oui, ajouter',
'confirm_add_ok' => 'Mettre à jour avec obligation de paiement',
'add_product' => 'Ajouter le produit',
'product_prices_career_level_info' => 'Les prix produits sont affichés et calculés selon votre niveau de carrière <strong>:user_level_name</strong> moins <strong>:user_level_margin %</strong> de marge.',
'product_prices_career_level_cpay_info' => 'Les prix produits sont affichés comme prix de vente client ; après finalisation du paiement client, vous recevez votre commission selon votre niveau de carrière <strong>:user_level_name</strong>, commission <strong>:user_level_margin %</strong>.',
@ -91,6 +102,28 @@ return [
'need_basis_product' => 'Vous devez avoir au moins un produit de base dans votre abonnement. Veuillez dabord ajouter un nouveau produit de base puis supprimer lancien !',
'abo_item_not_found' => 'Position dabonnement introuvable',
'product_not_found' => 'Produit introuvable',
'onetime_window_closed' => "La période pour ajouter des produits ponctuels n'est pas ouverte actuellement.",
'onetime_product_not_allowed' => 'Ce produit ne peut pas être ajouté comme article ponctuel.',
'onetime_action_required' => "Aucune action n'a été indiquée.",
'onetime_action_invalid' => 'Action invalide.',
'onetime_qty_required' => 'Veuillez indiquer une quantité valide.',
'onetime_card_hl' => 'Ajouter des produits ponctuels à votre prochaine livraison',
'onetime_card_info' => 'Ajoutez une seule fois des produits de l\'assortiment habituel à votre prochaine livraison d\'abonnement. Vous économisez ainsi des frais de port supplémentaires et recevez tout dans un seul colis.',
'onetime_important_hl' => 'Important :',
'onetime_coverage_hint' => 'Le montant supplémentaire sera débité facilement avec le montant habituel de votre abonnement lors de la prochaine exécution.',
'onetime_reset_hint' => 'Les produits ponctuels sont ajoutés uniquement à votre prochaine livraison puis supprimés automatiquement de l\'abonnement.',
'add_onetime_product' => 'Ajouter un produit ponctuel',
'onetime_subtotal' => 'Sous-total produits ponctuels',
'onetime_next_delivery_total' => 'Montant total de la prochaine livraison (abonnement + ponctuel)',
'onetime_legal_notice' => 'Les produits ajoutés seront expédiés une seule fois le :nextBillingDate. Nos :agb et le :withdrawal sappliquent.',
'onetime_discard_changes' => 'Annuler les modifications',
'onetime_confirm_paid' => 'Mettre à jour avec obligation de paiement',
'onetime_confirm_success' => 'Les produits ponctuels ont été réservés avec succès pour votre prochaine livraison.',
'abo_subtotal' => 'Sous-total produits d\'abonnement',
'abo_next_delivery_total' => 'Montant total de la prochaine livraison',
'onetime_empty' => 'Aucun produit ponctuel ajouté pour le moment.',
'onetime_badge' => 'Ponctuel',
'combined_summary_hl' => 'Total de la prochaine livraison',
'create_abo' => 'Créer un abonnement',
'info' => 'Info',
'data' => 'Données',

View file

@ -37,4 +37,5 @@ return [
'shopping_user_not_found' => 'Erreur : aucun ShoppingUser trouvé',
'account_released' => 'Compte activé',
'cart_product_not_allowed_for_order_type' => 'Le panier contient des articles qui ne sont pas prévus pour ce type de commande. Veuillez vider le panier et sélectionner uniquement les produits adaptés à cette commande.',
'cart_max_weight_reached' => "Le poids d'expédition maximal est atteint. Aucun autre produit ne peut être ajouté.",
];

View file

@ -83,6 +83,7 @@ return [
'ship_to_this_email_info' => 'Le lien de commande sera envoyé à votre client à ladresse e-mail suivante :',
'shipping' => 'Livraison',
'shipping_compensation_product' => 'Produit de compensation livraison',
'comp_required_by_additional_products' => 'Ce produit de compensation est nécessaire en raison des produits ajoutés en supplément.',
'shipping_costs' => 'Frais de livraison',
'shopping_cart' => 'Panier',
'shopping_cart_delete' => 'Supprimer le panier',

View file

@ -0,0 +1,56 @@
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label"
aria-hidden="true" data-title-add="{{ __('abo.confirm_add_title_normal') }}"
data-title-increase="{{ __('abo.confirm_increase_title') }}"
data-info-add="{{ __('abo.confirm_add_info') }}"
data-info-increase="{{ __('abo.confirm_increase_info') }}"
data-per-delivery="{{ __('abo.confirm_per_delivery') }}"
data-current-total="{{ $user_abo->getFormattedAmount() }}"
data-next-billing-date="{{ $user_abo->next_date ?: __('abo.confirm_next_delivery_unknown') }}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-info mb-3">
<span id="confirm-add-info-text"></span>
</div>
<div class="font-weight-bold mb-2">{{ __('abo.confirm_article_details') }}</div>
<table class="table table-sm mb-0">
<tr>
<td class="font-weight-bold">{{ __('order.article') }}:</td>
<td id="confirm-add-product-name"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
<td id="confirm-add-qty-info"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('abo.confirm_additional_costs') }}:</td>
<td id="confirm-add-product-price"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('abo.confirm_new_total') }}:</td>
<td id="confirm-add-new-total"></td>
</tr>
</table>
<p class="small text-muted mb-0 mt-3">
{!! __('abo.confirm_legal_notice', [
'nextBillingDate' => '<span id="confirm-add-next-billing-date"></span>',
'agb' => '<a href="'.url('/agb').'" target="_blank">'.__('abo.confirm_terms_link').'</a>',
'withdrawal' => '<a href="'.asset('download/mivita_widerruf_formular.pdf').'" target="_blank">'.__('abo.confirm_withdrawal_link').'</a>',
]) !!}
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
<button type="button" class="btn btn-primary"
id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
</div>
</div>
</div>
</div>

View file

@ -134,8 +134,10 @@
@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])
@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>

View file

@ -1,3 +1,4 @@
@php($cartInstance = \App\Services\AboOrderCart::INSTANCE)
@if(isset($error_message) && $error_message)
<div class="alert alert-danger mt-2" id="insert_show_error_message">{{ $error_message }}</div>
@endif
@ -65,37 +66,49 @@
<tr>
<td colspan="4"><hr></td>
</tr>
@if(isset($split_mode) && $split_mode)
<tr>
<td colspan="3" class="text-right small"><strong>{{ __('abo.abo_subtotal') }}:</strong></td>
<td class="text-right small">{{ formatNumber($summary['abo']['gross'] ?? 0) }} </td>
</tr>
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('abo.abo_next_delivery_total') }}:</strong></td>
<td class="text-right small no-border-top">{{ formatNumber($summary['total_with_shipping'] ?? 0) }} </td>
</tr>
@else
@php($taxFree = Yard::instance($cartInstance)->getUserTaxFree())
<tr>
<td colspan="3" class="text-right small"><strong>{{ __('order.subtotal') }}:</strong></td>
<td class="text-right small">{{ Yard::instance('shopping')->subtotal() }} </td>
<td class="text-right small">{{ Yard::instance($cartInstance)->subtotal() }} </td>
</tr>
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('Delivery country') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance('shopping')->getShippingCountryName() }}</td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->getShippingCountryName() }}</td>
</tr>
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('order.shipping_costs') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance('shopping')->shipping() }} </td>
<td class="text-right small no-border-top">{{ $taxFree ? Yard::instance($cartInstance)->shippingNet() : Yard::instance($cartInstance)->shipping() }} </td>
</tr>
@if(Yard::instance('shopping')->getUserTaxFree())
@if($taxFree)
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('order.sum_net') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance('shopping')->subtotalWithShipping() }} </td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->subtotalWithShipping() }} </td>
</tr>
@else
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('order.total_without_VAT') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance('shopping')->subtotalWithShipping() }} </td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->subtotalWithShipping() }} </td>
</tr>
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('order.plus_VAT') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance('shopping')->taxWithShipping() }} </td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->taxWithShipping() }} </td>
</tr>
@endif
<tr>
<td colspan="3" class="text-right"><strong>{{ __('order.total_sum') }}:</strong></td>
<td class="text-right">{{ Yard::instance('shopping')->totalWithShipping() }} </td>
</tr>
<tr>
<td colspan="3" class="text-right"><strong>{{ __('order.total_sum') }}:</strong></td>
<td class="text-right">{{ Yard::instance($cartInstance)->totalWithShipping() }} </td>
</tr>
@endif
</tfoot>
</table>
</div>

View file

@ -0,0 +1,50 @@
@php
$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>
<div class="card-body bg-light">
<table class="table table-product m-0">
<tbody>
@if(($summary['one_time']['gross'] ?? 0) > 0)
<tr>
<td class="small"><strong>{{ __('abo.onetime_subtotal') }}:</strong></td>
<td class="text-right small">{{ formatNumber($summary['one_time']['gross']) }} </td>
</tr>
@endif
<tr>
<td class="small"><strong>{{ __('abo.abo_subtotal') }}:</strong></td>
<td class="text-right small">{{ formatNumber($summary['abo']['gross'] ?? 0) }} </td>
</tr>
<tr>
<td class="small no-border-top"><strong>{{ __('Delivery country') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->getShippingCountryName() }}</td>
</tr>
<tr>
<td class="small no-border-top"><strong>{{ __('order.shipping_costs') }}:</strong></td>
<td class="text-right small no-border-top">{{ $taxFree ? Yard::instance($cartInstance)->shippingNet() : Yard::instance($cartInstance)->shipping() }} </td>
</tr>
@if($taxFree)
<tr>
<td class="small no-border-top"><strong>{{ __('order.sum_net') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->subtotalWithShipping() }} </td>
</tr>
@else
<tr>
<td class="small no-border-top"><strong>{{ __('order.total_without_VAT') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->subtotalWithShipping() }} </td>
</tr>
<tr>
<td class="small no-border-top"><strong>{{ __('order.plus_VAT') }}:</strong></td>
<td class="text-right small no-border-top">{{ Yard::instance($cartInstance)->taxWithShipping() }} </td>
</tr>
@endif
<tr class="bg-white">
<td class="pt-2 pb-2"><strong>{{ __('order.total_sum') }}:</strong></td>
<td class="text-right font-weight-bold pt-2 pb-2">{{ Yard::instance($cartInstance)->totalWithShipping() }} </td>
</tr>
</tbody>
</table>
</div>

View file

@ -0,0 +1,23 @@
<div class="card-body">
<h5 class="font-weight-semibold mb-2">
<i class="fa fa-bolt text-warning"></i> {{ __('abo.onetime_card_hl') }}
</h5>
<div class="alert alert-info">{!! __('abo.onetime_card_info') !!}</div>
<div class="alert alert-warning small mb-3">
<strong>{{ __('abo.onetime_important_hl') }}</strong>
<ul class="mb-0 pl-3">
<li>{{ __('abo.onetime_reset_hint') }}</li>
<li>{{ __('abo.onetime_coverage_hint') }}</li>
</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>
<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])
</div>
</div>

View file

@ -0,0 +1,105 @@
@php
$one_time_items = $user_abo->one_time_items()->with('product')->get();
$hasOneTimeChanges = \App\Services\AboOneTimeService::hasUnconfirmedChanges($user_abo);
$hasConfirmedOneTimeItems = \App\Services\AboOneTimeService::hasConfirmedItems($user_abo);
$oneTimeGross = $summary['one_time']['gross'] ?? 0;
$nextDeliveryTotal = $summary['total_with_shipping'] ?? 0;
$oneTimeConfirmationState = $hasOneTimeChanges ? 'changed' : ($hasConfirmedOneTimeItems ? 'confirmed' : 'empty');
@endphp
@if(isset($error_message) && $error_message)
<div class="alert alert-danger mt-2" id="insert_onetime_error_message">{{ $error_message }}</div>
@endif
<div class="table-responsive">
<table class="table table-product m-0" style="min-width:550px;">
<thead>
<tr>
<th>#</th>
<th>{{ __('order.article') }}</th>
<th>{{ __('tables.quantity') }}</th>
<th class="text-right">{{ __('tables.price') }}</th>
</tr>
</thead>
<tbody>
@forelse($one_time_items as $one_time_item)
<tr>
<td>
@if($one_time_item->product && count($one_time_item->product->images))
<img class="img-fluid img-extra" alt="" src="{{ route('product_image', [$one_time_item->product->images->first()->slug]) }}">
@endif
</td>
<td class="min-width-80">
<strong>{{ $one_time_item->product?->getLang('name') }}</strong>
<span class="badge badge-pill badge-warning"><i class="fa fa-bolt"></i> {{ __('abo.onetime_badge') }}</span>
<div class="text-body">
<div>{{ __('order.content') }}: {{ $one_time_item->product?->contents }}</div>
<div>{{ __('order.art_no') }}: {{ $one_time_item->product?->number }}</div>
</div>
<div class="options">
<a href="#" class="auto-delete-product remove_onetime_from_cart product-tooltip" data-onetime-item-id="{{ $one_time_item->id }}"><i class="fa fa-times"></i> {{ __('order.article_remove') }}</a>
</div>
</td>
<td>
<div class="no-line-break input-group-min-w">
<div class="input-group d-inline-flex w-auto">
<span class="input-group-prepend">
<button type="button" class="btn btn-secondary icon-btn md-btn-extra onetime-remove-from-basket" data-onetime-item-id="{{ $one_time_item->id }}">-</button>
</span>
<input type="text" class="form-control text-center input-extra onetime-input-onchange" name="onetime_qty_{{ $one_time_item->id }}" data-onetime-item-id="{{ $one_time_item->id }}" value="{{ $one_time_item->qty }}">
<span class="input-group-append">
<button type="button" class="btn btn-secondary icon-btn md-btn-extra onetime-add-from-basket" data-onetime-item-id="{{ $one_time_item->id }}">+</button>
</span>
</div>
</div>
</td>
<td class="text-right font-weight-semibold align-top px-3 py-2" style="width: 100px;">
<div class="no-line-break">{{ $one_time_item->getFormattedTotalPrice() }} &euro;</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" class="text-muted small py-3 text-center">{{ __('abo.onetime_empty') }}</td>
</tr>
@endforelse
</tbody>
<tfoot>
<tr>
<td colspan="4"><hr></td>
</tr>
<tr>
<td colspan="3" class="text-right small"><strong>{{ __('abo.onetime_subtotal') }}:</strong></td>
<td class="text-right small">{{ formatNumber($summary['one_time']['gross'] ?? 0) }} </td>
</tr>
@if($oneTimeGross > 0 || $hasOneTimeChanges || $hasConfirmedOneTimeItems)
<tr>
<td colspan="3" class="text-right small no-border-top"><strong>{{ __('abo.onetime_next_delivery_total') }}:</strong></td>
<td class="text-right small no-border-top">{{ formatNumber($nextDeliveryTotal) }} </td>
</tr>
@endif
</tfoot>
</table>
</div>
@if($oneTimeGross > 0 || $hasOneTimeChanges || $hasConfirmedOneTimeItems)
<div class="mt-3" id="onetime_confirmation_block" data-confirmation-state="{{ $oneTimeConfirmationState }}" aria-live="polite">
<p class="small text-muted mb-2">
{!! __('abo.onetime_legal_notice', [
'nextBillingDate' => $user_abo->next_date ?: __('abo.confirm_next_delivery_unknown'),
'agb' => '<a href="'.url('/agb').'" target="_blank">'.__('abo.confirm_terms_link').'</a>',
'withdrawal' => '<a href="'.asset('download/mivita_widerruf_formular.pdf').'" target="_blank">'.__('abo.confirm_withdrawal_link').'</a>',
]) !!}
</p>
@if($hasOneTimeChanges)
<div class="d-flex flex-wrap justify-content-end">
<button type="button" class="btn btn-default mr-2 mb-2 onetime-discard-changes">
{{ __('abo.onetime_discard_changes') }}
</button>
<button type="button" class="btn btn-primary mb-2 onetime-confirm-changes">
{{ __('abo.onetime_confirm_paid') }}
</button>
</div>
@elseif($hasConfirmedOneTimeItems)
<div class="alert alert-success small mb-0">
<span aria-hidden="true">&check;</span> {{ __('abo.onetime_confirm_success') }}
</div>
@endif
</div>
@endif

View file

@ -51,13 +51,14 @@
'data-add-only-mode' => '0',
]) !!}
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
@php($cartInstance = \App\Services\AboOrderCart::INSTANCE)
<div class="card mt-3">
@include('admin.abo._order_abo', ['add_only_mode' => false])
</div>
@if ($comp_products && Yard::instance('shopping')->getNumComp() > 0)
@if ($comp_products && Yard::instance($cartInstance)->getNumComp() > 0)
<div id="holder_html_view_comp_product">
@include('user.order.comp_product')
@include('user.order.comp_product', ['cart_instance' => $cartInstance])
</div>
@endif
@ -78,47 +79,7 @@
<a href="{{ route('admin_abos') }}" class="btn btn-sm btn-default mt-2 float-right">{{ __('back') }}</a>
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label"
aria-hidden="true" data-title-add-only="{{ __('abo.confirm_add_title') }}"
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-warning mb-3">
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
</div>
<table class="table table-sm mb-0">
<tr>
<td class="font-weight-bold">{{ __('order.article') }}:</td>
<td id="confirm-add-product-name"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
<td id="confirm-add-product-price"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
<td id="confirm-add-qty-info"></td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
<button type="button" class="btn btn-primary"
id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
</div>
</div>
</div>
</div>
@include('admin.abo._confirm_add_modal')
@if ($user_abo->status === 3 && $user_abo->active)
<div class="modal fade" id="modal-retry-abo-payment" tabindex="-1" role="dialog" aria-labelledby="modal-retry-abo-payment-label" aria-hidden="true">

View file

@ -69,6 +69,12 @@
{{ Form::text('settings[abo-min-duration][val]', \App\Models\Setting::getContentBySlug('abo-min-duration'), array('class'=>'form-control')) }}
{{ Form::hidden('settings[abo-min-duration][type]', 'int') }}
</div>
<div class="form-group col-sm-6">
<label class="form-label">Zeitfenster für einmalige Produkte vor Ausführung (Tage)*</label>
{{ Form::text('settings[abo-onetime-window-days][val]', \App\Models\Setting::getContentBySlug('abo-onetime-window-days'), array('class'=>'form-control')) }}
{{ Form::hidden('settings[abo-onetime-window-days][type]', 'int') }}
<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>
<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>

View file

@ -2,20 +2,20 @@
@section('content')
<h4 class="font-weight-bold py-2 mb-2">
{{ __('navigation.my_abo') }}
<span class="text-muted">{{ '#'.$user_abo->payone_userid }}</span>
</h4>
<h4 class="font-weight-bold py-2 mb-2">
{{ __('navigation.my_abo') }}
<span class="text-muted">{{ '#' . $user_abo->payone_userid }}</span>
</h4>
@if(Session::has('alert-error'))
<div class="col-sm-12">
<div class="alert alert-danger p-2 mt-2">
<ul>
<li>{{ Session::get('alert-error') }}</li>
</ul>
</div>
</div>
@endif
@if (Session::has('alert-error'))
<div class="col-sm-12">
<div class="alert alert-danger p-2 mt-2">
<ul>
<li>{{ Session::get('alert-error') }}</li>
</ul>
</div>
</div>
@endif
<div class="card">
@include('admin.abo._detail')
@ -28,15 +28,59 @@
@php
$addOnlyMode = App\Services\AboHelper::isAddOnlyMode($user_abo, $view);
@endphp
{!! Form::open(['action' => route('user_abos_update', [$view, $user_abo->id]), 'class' => 'form-horizontal', 'id'=>'cart-order-form', 'data-add-only-mode' => $addOnlyMode ? '1' : '0']) !!}
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
<div class="card mt-3">
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
</div>
{!! Form::open([
'action' => route('user_abos_update', [$view, $user_abo->id]),
'class' => 'form-horizontal',
'id' => 'cart-order-form',
'data-add-only-mode' => $addOnlyMode ? '1' : '0',
]) !!}
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
@php
$oneTimeWindowOpen = isset($one_time_window_open) ? $one_time_window_open : false;
$summary = isset($summary) ? $summary : null;
$cartInstance = \App\Services\AboOrderCart::INSTANCE;
@endphp
@if ($oneTimeWindowOpen)
<div class="row mt-3">
<div class="col-lg-8">
<div class="card" id="onetime_order_card"
data-onetime-route="{{ route('user_abos_onetime', [$view, $user_abo->id]) }}">
@include('admin.abo._order_onetime', ['summary' => $summary])
</div>
<div class="card mt-3 mb-3">
@include('admin.abo._order_abo', [
'add_only_mode' => $addOnlyMode,
'split_mode' => true,
'summary' => $summary,
])
</div>
<div id="holder_html_view_comp_product">
@if ($comp_products && Yard::instance($cartInstance)->getNumComp() > 0)
@include('user.order.comp_product', [
'cart_instance' => $cartInstance,
'base_comp_count' => $base_comp_count ?? Yard::instance($cartInstance)->getNumComp(),
])
@endif
</div>
</div>
<div class="col-lg-4" id="combined_summary_col">
<div class="card js-abo-sticky" id="combined_summary_card">
@include('admin.abo._order_combined_summary', ['summary' => $summary])
</div>
</div>
</div>
@else
<div class="card mt-3">
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
</div>
@if($comp_products && Yard::instance('shopping')->getNumComp() > 0)
<div id="holder_html_view_comp_product">
@include('user.order.comp_product')
@if ($comp_products && Yard::instance($cartInstance)->getNumComp() > 0)
@include('user.order.comp_product', [
'cart_instance' => $cartInstance,
'base_comp_count' => $base_comp_count ?? Yard::instance($cartInstance)->getNumComp(),
])
@endif
</div>
@endif
@ -47,54 +91,18 @@
</div>
<a href="{{route('portal.my_subscriptions')}}" class="btn btn-sm btn-default float-right">{{ __('abo.back') }}</a>
<a href="{{ route('portal.my_subscriptions') }}" class="btn btn-sm btn-default float-right">{{ __('abo.back') }}</a>
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label" aria-hidden="true"
data-title-add-only="{{ __('abo.confirm_add_title') }}"
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-warning mb-3">
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
</div>
<table class="table table-sm mb-0">
<tr>
<td class="font-weight-bold">{{ __('order.article') }}:</td>
<td id="confirm-add-product-name"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
<td id="confirm-add-product-price"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
<td id="confirm-add-qty-info"></td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
<button type="button" class="btn btn-primary" id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
</div>
</div>
</div>
</div>
@include('admin.abo._confirm_add_modal')
@endsection
@section('scripts')
<script src="{{ asset('/js/iq-modal-cart.js') }}?v=1{{ get_file_last_time('/js/iq-modal-cart.js') }}"></script>
<script src="{{ asset('/js/iq-abo-onetime.js') }}?v=1{{ get_file_last_time('/js/iq-abo-onetime.js') }}"></script>
<script type="application/javascript">
var iqModalCart = IqModalCart.init();
var iqAboOneTime = IqAboOneTime.init();
$( document ).ready(function() {
});

View file

@ -53,13 +53,52 @@
'data-add-only-mode' => $addOnlyMode ? '1' : '0',
]) !!}
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
<div class="card mt-3">
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
</div>
@php
$oneTimeWindowOpen = isset($one_time_window_open) ? $one_time_window_open : false;
$summary = isset($summary) ? $summary : null;
$cartInstance = \App\Services\AboOrderCart::INSTANCE;
@endphp
@if ($oneTimeWindowOpen)
<div class="row mt-3">
<div class="col-lg-8">
<div class="card" id="onetime_order_card"
data-onetime-route="{{ route('user_abos_onetime', [$view, $user_abo->id]) }}">
@include('admin.abo._order_onetime', ['summary' => $summary])
</div>
<div class="card mt-3">
@include('admin.abo._order_abo', [
'add_only_mode' => $addOnlyMode,
'split_mode' => true,
'summary' => $summary,
])
</div>
<div id="holder_html_view_comp_product">
@if ($comp_products && Yard::instance($cartInstance)->getNumComp() > 0)
@include('user.order.comp_product', [
'cart_instance' => $cartInstance,
'base_comp_count' => $base_comp_count ?? Yard::instance($cartInstance)->getNumComp(),
])
@endif
</div>
</div>
<div class="col-lg-4" id="combined_summary_col">
<div class="card js-abo-sticky" id="combined_summary_card">
@include('admin.abo._order_combined_summary', ['summary' => $summary])
</div>
</div>
</div>
@else
<div class="card mt-3">
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
</div>
@if ($comp_products && Yard::instance('shopping')->getNumComp() > 0)
<div id="holder_html_view_comp_product">
@include('user.order.comp_product')
@if ($comp_products && Yard::instance($cartInstance)->getNumComp() > 0)
@include('user.order.comp_product', [
'cart_instance' => $cartInstance,
'base_comp_count' => $base_comp_count ?? Yard::instance($cartInstance)->getNumComp(),
])
@endif
</div>
@endif
@ -71,53 +110,15 @@
<a href="{{ route('user_abos', [$view]) }}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label"
aria-hidden="true" data-title-add-only="{{ __('abo.confirm_add_title') }}"
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-warning mb-3">
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
</div>
<table class="table table-sm mb-0">
<tr>
<td class="font-weight-bold">{{ __('order.article') }}:</td>
<td id="confirm-add-product-name"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
<td id="confirm-add-product-price"></td>
</tr>
<tr>
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
<td id="confirm-add-qty-info"></td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
<button type="button" class="btn btn-primary"
id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
</div>
</div>
</div>
</div>
@include('admin.abo._confirm_add_modal')
@endsection
@section('scripts')
<script src="{{ asset('/js/iq-modal-cart.js') }}?v=1{{ get_file_last_time('/js/iq-modal-cart.js') }}"></script>
<script src="{{ asset('/js/iq-abo-onetime.js') }}?v=1{{ get_file_last_time('/js/iq-abo-onetime.js') }}"></script>
<script type="application/javascript">
var iqModalCart = IqModalCart.init();
var iqAboOneTime = IqAboOneTime.init();
$( document ).ready(function() {
});

View file

@ -0,0 +1,57 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fa fa-bolt text-warning"></i> {{ __('abo.add_onetime_product') }}
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body px-0">
<div class="card-datatable pt-0 table-responsive">
<table id="datatable-abo-onetime" class="table table-striped table-bordered" data-user_abo-id="{{ $user_abo->id }}">
<thead>
<tr>
<th></th>
<th>{{ __('tables.image') }}</th>
<th>{{ __('tables.products') }}</th>
<th>{{ __('tables.article_no') }}</th>
<th><span class="no-line-break">{{ __('tables.price') }}</span> {{ __('tables.net') }}</th>
<th><span class="no-line-break">{{ __('tables.price') }}</span> {{ __('tables.gross') }}</th>
<th>{{ __('tables.points') }}</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
</div>
</div>
<script>
$(document).ready(function () {
var oTable = $('#datatable-abo-onetime').DataTable({
"processing": true,
"serverSide": true,
"ajax": '{!! route('user_abo_onetime_datatable', [$user_abo->id]) !!}',
"order": [[2, "asc"]],
"columns": [
{ data: 'add_card', name: 'add_card', searchable: false, orderable: false },
{ data: 'picture', name: 'picture', searchable: false, width: 35 },
{ data: 'name', name: 'name' },
{ data: 'number', name: 'number' },
{ data: 'price_net', name: 'price_net', searchable: false, orderable: false },
{ data: 'price_gross', name: 'price_gross', searchable: false, orderable: false },
{ data: 'points', name: 'points', searchable: false },
],
"bLengthChange": false,
"iDisplayLength": 1000,
"paging": false,
"language": {
"url": "/js/datatables-{{ \App::getLocale() }}.json"
},
drawCallback: function (settings) {
iqAboOneTime.reInitModal();
}
});
iqAboOneTime.setDatabase('#datatable-abo-onetime');
});
</script>

View file

@ -1,39 +1,49 @@
<div class="card mt-4">
@php($cartInstance = $cart_instance ?? 'shopping')
@php($baseCompCount = $base_comp_count ?? Yard::instance($cartInstance)->getNumComp())
<div class="card mt-3 mb-3">
<div class="card-body">
<input type="hidden" name="count_comp_products" value="{{Yard::instance('shopping')->getNumComp()}}">
@for($i = 1; $i <= Yard::instance('shopping')->getNumComp(); $i++)
@if(Yard::instance('shopping')->getNumComp() > 1)
<h5 class="border-bottom pb-2">{{$i}}. {{ __('order.shipping_compensation_product') }} </h5>
@else
<h5 class="border-bottom pb-2">{{ __('order.shipping_compensation_product') }} </h5>
@endif
<input type="hidden" name="count_comp_products" value="{{ Yard::instance($cartInstance)->getNumComp() }}">
@for ($i = 1; $i <= Yard::instance($cartInstance)->getNumComp(); $i++)
@if (Yard::instance($cartInstance)->getNumComp() > 1)
<h5 class="border-bottom pb-2">{{ $i }}. {{ __('order.shipping_compensation_product') }} </h5>
@else
<h5 class="border-bottom pb-2">{{ __('order.shipping_compensation_product') }} </h5>
@endif
@if ($i > $baseCompCount)
<div class="alert alert-warning small">
<i class="fa fa-info-circle"></i> {{ __('order.comp_required_by_additional_products') }}
</div>
@endif
<div class="row no-gutters row-bordered">
@php($counter = 1)
@php($checked_id = Yard::instance('shopping')->getCompProductBy($i))
@foreach($comp_products as $comp_product)
@php($checked_id = Yard::instance($cartInstance)->getCompProductBy($i))
@foreach ($comp_products as $comp_product)
<div class="media col-md-6 col-lg-4 p-4">
<div class="d-block ui-w-80 ui-bordered mr-3">
@if(count($comp_product->images))
<img src="{{ route('product_image', [$comp_product->images->first()->slug]) }}" class="img-fluid" alt="">
@if (count($comp_product->images))
<img src="{{ route('product_image', [$comp_product->images->first()->slug]) }}"
class="img-fluid" alt="">
@endif
</div>
<div class="media-body">
<label class="switcher switcher-secondary">
<input type="radio" class="switcher-input" value="{{$comp_product->id}}" data-comp_num="{{$i}}" name="switchers-comp-product[{{$i}}]" @if($checked_id == $comp_product->id) checked @endif required>
<input type="radio" class="switcher-input" value="{{ $comp_product->id }}"
data-comp_num="{{ $i }}"
name="switchers-comp-product[{{ $i }}]"
@if ($checked_id == $comp_product->id) checked @endif required>
<span class="switcher-indicator">
<span class="switcher-yes"></span>
<span class="switcher-no"></span>
</span>
</span>
<span class="switcher-label"></span>
</label>
<div class="text-body mt-2"><strong>{{ $comp_product->getLang('name') }}</strong></div>
<div class="">{{ __('order.art_no') }}: {{ $comp_product->number }}</div>
</div>
</div>
@php($counter++)
@endforeach
@php($counter++)
@endforeach
</div>
@endfor
@endfor
</div>
</div>
</div>

View file

@ -87,8 +87,44 @@
font-size: 85%;
font-weight: 400;
}
.md-btn-extra {
width: calc(1.7rem + 2px);
line-height: 1.5rem;
}
/* Nicht umbrechen, sonst stapeln sich -/+/Input untereinander (Bootstrap input-group: flex-wrap: wrap). */
.quantity-select .input-group {
flex-wrap: nowrap;
justify-content: flex-end;
}
.quantity-select .input-group .md-btn-extra {
flex: 0 0 auto;
width: calc(1.7rem + 2px);
}
/* Spezifischer als ".quantity-select input.form-control" (min-width: 4em / inline-block) weiter oben. */
.quantity-select .input-group .form-control.input-extra {
flex: 0 0 44px;
width: 44px;
min-width: 44px;
display: block;
padding: 0.28rem 0.6rem;
font-size: 0.8rem;
font-weight: 600;
min-height: calc(1.8rem + 2px);
height: calc(1.8rem + 2px);
}
.input-group-min-w {
min-width: 102px;
}
</style>
<div id="cartContent">
@if (isset($error_message) && $error_message)
<div class="alert alert-danger mt-2" id="insert_show_error_message">{{ $error_message }}</div>
@endif
<div class="yard-items-head d-none d-sm-block">
<div class="row">
@ -176,10 +212,27 @@
<span class="text-right product-tooltip" data-toggle="tooltip"
title="{{ __('order.compensation_product') }}">1 x</span>
@else
<input type="number" class="form-control text-center cart-input-event-onchange"
data-row-id="{{ $row->rowId }}" data-product-id="{{ $product->id }}"
value="{{ $row->qty }}" name="quantity[{{ $row->rowId }}]"
maxlength="3" max="999" min="1">
<div class="no-line-break input-group-min-w d-inline-block">
<div class="input-group d-inline-flex w-auto">
<span class="input-group-prepend">
<button type="button"
class="btn btn-secondary icon-btn md-btn-extra cart-remove-event"
data-row-id="{{ $row->rowId }}"
data-product-id="{{ $product->id }}">-</button>
</span>
<input type="text"
class="form-control text-center input-extra cart-input-event-onchange"
data-row-id="{{ $row->rowId }}"
data-product-id="{{ $product->id }}" value="{{ $row->qty }}"
name="quantity[{{ $row->rowId }}]">
<span class="input-group-append">
<button type="button"
class="btn btn-secondary icon-btn md-btn-extra cart-add-event"
data-row-id="{{ $row->rowId }}"
data-product-id="{{ $product->id }}">+</button>
</span>
</div>
</div>
@endif
</div>
<div class="price-total text-right">