From f8042c925383c672db255bd05628dee79806824f Mon Sep 17 00:00:00 2001 From: d-buchmann Date: Thu, 14 Aug 2025 15:00:23 +0200 Subject: [PATCH] Implement N-up label printing --- src/Entity/LabelSystem/LabelOptions.php | 6 ++ src/Form/LabelOptionsType.php | 28 +++++++++ templates/label_system/dialog.html.twig | 12 ++++ .../label_system/labels/base_label.html.twig | 57 +++++++++++++++---- 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/src/Entity/LabelSystem/LabelOptions.php b/src/Entity/LabelSystem/LabelOptions.php index ee1a54146..e90dd0e1c 100644 --- a/src/Entity/LabelSystem/LabelOptions.php +++ b/src/Entity/LabelSystem/LabelOptions.php @@ -65,6 +65,12 @@ class LabelOptions #[Groups(["extended", "full", "import"])] protected float $height = 30.0; + // TODO these have to go into the DB to be persisted. + // The default values preserve the current behaviour of the generator (custom css might break though...) + public int $xcount = 1; + public int $ycount = 1; + public int $skipcount = 0; + /** * @var BarcodeType The type of the barcode that should be used in the label (e.g. 'qr') */ diff --git a/src/Form/LabelOptionsType.php b/src/Form/LabelOptionsType.php index ad4583745..e968f16f6 100644 --- a/src/Form/LabelOptionsType.php +++ b/src/Form/LabelOptionsType.php @@ -81,6 +81,34 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ], ]); + $builder->add('xcount', NumberType::class, [ + 'label' => 'label_options.page_nup.grid', + 'html5' => true, + 'attr' => [ + 'placeholder' => 'label_options.page_nup.xcount', + 'min' => 1, + 'step' => 1, + ], + ]); + $builder->add('ycount', NumberType::class, [ + 'label' => false, + 'html5' => true, + 'attr' => [ + 'placeholder' => 'label_options.page_nup.ycount', + 'min' => 1, + 'step' => 1, + ], + ]); + $builder->add('skipcount', NumberType::class, [ + 'label' => '//', + 'html5' => true, + 'attr' => [ + 'placeholder' => 'label_options.page_nup.skipcount', + 'min' => 0, + 'step' => 1, + ], + ]); + $builder->add('supported_element', EnumType::class, [ 'label' => 'label_options.supported_elements.label', 'class' => LabelSupportedElement::class, diff --git a/templates/label_system/dialog.html.twig b/templates/label_system/dialog.html.twig index 50db99e77..fc296a358 100644 --- a/templates/label_system/dialog.html.twig +++ b/templates/label_system/dialog.html.twig @@ -45,6 +45,18 @@ +
+ {{ form_label(form.options.xcount) }} +
+
+ {{ form_widget(form.options.xcount) }} + x + {{ form_widget(form.options.ycount) }} + {{ form.options.skipcount.vars.label }} + {{ form_widget(form.options.skipcount) }} +
+
+
{{ form_row(form.options.barcode_type) }} {{ form_row(form.options.lines) }} diff --git a/templates/label_system/labels/base_label.html.twig b/templates/label_system/labels/base_label.html.twig index 494b99e49..837afed04 100644 --- a/templates/label_system/labels/base_label.html.twig +++ b/templates/label_system/labels/base_label.html.twig @@ -13,16 +13,51 @@ -{% for element in elements %} -
- {% if options.barcodeType.none %} - {% include "label_system/labels/label_page_none.html.twig" %} - {% elseif options.barcodeType.is2D() %} - {% include "label_system/labels/label_page_qr.html.twig" %} - {% elseif options.barcodeType.is1D() %} - {% include "label_system/labels/label_page_1d.html.twig" %} - {% endif %} -
-{% endfor %} + {% set start_page %} +
+ {% endset %} + + {% set end_page %} +
+ {% endset %} + + {{ start_page }} + {% set labels = (0 .. options.skipcount)|merge(elements) %} + {% for element in labels %} + {% if loop.first %} + {# continue #} + {% else %} + + {% if element <= options.skipcount %} + {% elseif options.barcodeType.none %} + {% include "label_system/labels/label_page_none.html.twig" %} + {% elseif options.barcodeType.is2D() %} + {% include "label_system/labels/label_page_qr.html.twig" %} + {% elseif options.barcodeType.is1D() %} + {% include "label_system/labels/label_page_1d.html.twig" %} + {% endif %} + + {% if not loop.last %} + {# The current row is full. Start a new row #} + {% if (loop.index > 2) and loop.index0 is divisible by(options.xcount) %} + + {% endif %} + + {# The current page is full and there are still labels in the queue. Start a new page #} + {% if loop.index0 is divisible by(options.xcount * options.ycount) %} + {{ end_page }} + {{ start_page }} + {% endif %} + {% else %} + {# last iteration: fill the row if the generated label count is too small #} + {% for i in (labels|length - 1) .. options.xcount %} + {% if labels|length - 1 < options.xcount and i < options.xcount %} + + {% endif %} + {% endfor %} + {% endif %} + {% endif %} + {% endfor %} + {{ end_page }} \ No newline at end of file