... | ... |
@@ -95,7 +95,7 @@ |
95 | 95 |
{% endif %} |
96 | 96 |
{% elseif group.type == 'option' %} |
97 | 97 |
<div class="checkbox form-ext-control form-ext-{{ group.multiple ? 'checkbox' : 'radio' }}"> |
98 |
- <input class="form-ext-input" type="{{ group.multiple ? 'checkbox' : 'radio' }}" id="b_attribute_{{ attribute.id }}" name="{{ group.multiple ? 'attribute_'~attribute.id : 'group_'~group.id }}" value="1" {% if attribute.value %}checked{% endif %}> |
|
98 |
+ <input class="form-ext-input" type="{{ group.multiple ? 'checkbox' : 'radio' }}" id="b_attribute_{{ attribute.id }}" name="{{ group.multiple ? 'attribute_'~attribute.id : 'group_'~group.id }}" value="{{ attribute.id }}" {% if attribute.id == attribute.value %}checked{% endif %}> |
|
99 | 99 |
<label class="form-ext-label" for="b_attribute_{{ attribute.id }}">{{ attribute.title }}</label> |
100 | 100 |
</div> |
101 | 101 |
{% endif %} |
... | ... |
@@ -99,6 +99,40 @@ |
99 | 99 |
<div class="col-3 annotation"> |
100 | 100 |
<div class="t-label">Anmerkung des Anlieferers</div> |
101 | 101 |
{{ booking.annotation }} |
102 |
+ |
|
103 |
+ {% if booking.attributes is defined and booking.attributes|length > 0 %} |
|
104 |
+ <div class="t-label">Attribute</div> |
|
105 |
+ <div class="attributes"> |
|
106 |
+ {% set groups = {} %} |
|
107 |
+ {% for attribute in booking.attributes %} |
|
108 |
+ {% set group = attribute.group|default('Sonstige') %} |
|
109 |
+ {% if groups[group] is not defined %} |
|
110 |
+ {% set groups = groups|merge({(group): []}) %} |
|
111 |
+ {% endif %} |
|
112 |
+ {% set groups = groups|merge({ |
|
113 |
+ (group): groups[group]|merge([{ |
|
114 |
+ 'title': attribute.title, |
|
115 |
+ 'value': attribute.value |
|
116 |
+ }]) |
|
117 |
+ }) %} |
|
118 |
+ {% endfor %} |
|
119 |
+ |
|
120 |
+ {% for group, attributes in groups %} |
|
121 |
+ <div class="attribute-group"> |
|
122 |
+ <div class="group-title">{{ group }}</div> |
|
123 |
+ {% for attribute in attributes %} |
|
124 |
+ <div class="attribute-item"> |
|
125 |
+ {% if attribute.value %} |
|
126 |
+ <strong>{{ attribute.title }}:</strong> {{ attribute.value }} |
|
127 |
+ {% else %} |
|
128 |
+ {{ attribute.title }} |
|
129 |
+ {% endif %} |
|
130 |
+ </div> |
|
131 |
+ {% endfor %} |
|
132 |
+ </div> |
|
133 |
+ {% endfor %} |
|
134 |
+ </div> |
|
135 |
+ {% endif %} |
|
102 | 136 |
</div> |
103 | 137 |
<div class="col u-text-right action"> |
104 | 138 |
<a |
... | ... |
@@ -29,6 +29,22 @@ |
29 | 29 |
font-weight: 500; |
30 | 30 |
} |
31 | 31 |
|
32 |
+.attribute-group { |
|
33 |
+ margin-bottom: 0.5rem; |
|
34 |
+} |
|
35 |
+ |
|
36 |
+.attribute-group .group-title { |
|
37 |
+ font-weight: 600; |
|
38 |
+ color: #666; |
|
39 |
+ margin-top: 0.5rem; |
|
40 |
+ border-bottom: 1px solid #eee; |
|
41 |
+} |
|
42 |
+ |
|
43 |
+.attribute-group .attribute-item { |
|
44 |
+ padding-left: 0.5rem; |
|
45 |
+ margin-top: 0.2rem; |
|
46 |
+} |
|
47 |
+ |
|
32 | 48 |
.u-row-striped > *:nth-child(even) { |
33 | 49 |
background-color: #fff6ef; |
34 | 50 |
} |
... | ... |
@@ -32,6 +32,7 @@ use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; |
32 | 32 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; |
33 | 33 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel; |
34 | 34 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungSlotsModel; |
35 |
+use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungAttributeModel; |
|
35 | 36 |
|
36 | 37 |
/** |
37 | 38 |
* @Route("contao/weinanlieferung/buchungsliste", name=WeinanlieferungBookingsController::class, defaults={"_scope" = "backend"}) |
... | ... |
@@ -265,6 +266,52 @@ class WeinanlieferungBookingsController extends AbstractController |
265 | 266 |
$unitLabel = $Unit->title; |
266 | 267 |
} |
267 | 268 |
|
269 |
+ // Process attribute values if available |
|
270 |
+ $formattedAttributes = []; |
|
271 |
+ if (!empty($booking->attribute_values)) { |
|
272 |
+ try { |
|
273 |
+ $attributeValues = json_decode($booking->attribute_values, true); |
|
274 |
+ if (is_array($attributeValues) && !empty($attributeValues)) { |
|
275 |
+ foreach ($attributeValues as $attributeId => $value) { |
|
276 |
+ // Get attribute information |
|
277 |
+ $attribute = WeinanlieferungAttributeModel::findByPk($attributeId); |
|
278 |
+ if ($attribute === null) { |
|
279 |
+ continue; |
|
280 |
+ } |
|
281 |
+ |
|
282 |
+ // Get the group information |
|
283 |
+ $group = $attribute->getRelated('pid'); |
|
284 |
+ $groupTitle = $group !== null ? $group->title : ''; |
|
285 |
+ $groupType = $group !== null ? $group->type : 'text'; |
|
286 |
+ |
|
287 |
+ // Format based on group type |
|
288 |
+ $attributeTitle = $attribute->title; |
|
289 |
+ |
|
290 |
+ if ($groupType === 'option') { |
|
291 |
+ // For option type, the value is either true (selected) or false (not selected) |
|
292 |
+ if ($value === true || $value === 'true' || $value === '1' || $value === 1) { |
|
293 |
+ $formattedAttributes[] = [ |
|
294 |
+ 'title' => $attributeTitle, |
|
295 |
+ 'value' => '', // Don't show value for option attributes |
|
296 |
+ 'group' => $groupTitle |
|
297 |
+ ]; |
|
298 |
+ } |
|
299 |
+ } else { |
|
300 |
+ // Text type or fallback |
|
301 |
+ $formattedValue = is_array($value) ? implode(', ', $value) : $value; |
|
302 |
+ $formattedAttributes[] = [ |
|
303 |
+ 'title' => $attributeTitle, |
|
304 |
+ 'value' => $formattedValue, |
|
305 |
+ 'group' => $groupTitle |
|
306 |
+ ]; |
|
307 |
+ } |
|
308 |
+ } |
|
309 |
+ } |
|
310 |
+ } catch (\Exception $e) { |
|
311 |
+ // Silently fail |
|
312 |
+ } |
|
313 |
+ } |
|
314 |
+ |
|
268 | 315 |
$arrData['days'][$day->dayBegin][$Slot->pid]['times'][$Slot->time]['items'][] = array_merge($booking->row(), [ |
269 | 316 |
'sorte' => $arrSorten, |
270 | 317 |
'ernteart' => $arrErnteart, |
... | ... |
@@ -272,7 +319,8 @@ class WeinanlieferungBookingsController extends AbstractController |
272 | 319 |
'slot' => $Slot->row(), |
273 | 320 |
'unit' => $unitLabel, |
274 | 321 |
'standort' => $strStandort, |
275 |
- 'member' => $booking->getRelated('uid') !== null ? $booking->getRelated('uid')->row() : null |
|
322 |
+ 'member' => $booking->getRelated('uid') !== null ? $booking->getRelated('uid')->row() : null, |
|
323 |
+ 'attributes' => $formattedAttributes |
|
276 | 324 |
]); |
277 | 325 |
} |
278 | 326 |
} |
... | ... |
@@ -621,6 +621,7 @@ class SlotAjaxController extends AbstractController |
621 | 621 |
$attributeKey = 'attribute_' . $attribute->id; |
622 | 622 |
$groupId = $attributeToGroupMap[$attribute->id]; |
623 | 623 |
$groupType = $groupTypeMap[$groupId]; |
624 |
+ $groupKey = 'group_' . $groupId; |
|
624 | 625 |
|
625 | 626 |
if ($groupType === 'text') { |
626 | 627 |
// For text attributes, store the text value |
... | ... |
@@ -629,11 +630,16 @@ class SlotAjaxController extends AbstractController |
629 | 630 |
$groupHasValue[$groupId] = true; |
630 | 631 |
} |
631 | 632 |
} else if ($groupType === 'option') { |
632 |
- // For option attributes, store true if selected |
|
633 |
+ // For option attributes with multiple values (checkboxes) |
|
633 | 634 |
if (Input::post($attributeKey)) { |
634 | 635 |
$attributeValues[$attribute->id] = true; |
635 | 636 |
$groupHasValue[$groupId] = true; |
636 | 637 |
} |
638 |
+ // For option attributes with single value (radio buttons) |
|
639 |
+ else if (Input::post($groupKey) == $attribute->id) { |
|
640 |
+ $attributeValues[$attribute->id] = true; |
|
641 |
+ $groupHasValue[$groupId] = true; |
|
642 |
+ } |
|
637 | 643 |
} |
638 | 644 |
} |
639 | 645 |
|
... | ... |
@@ -803,6 +809,7 @@ class SlotAjaxController extends AbstractController |
803 | 809 |
$attributeKey = 'attribute_' . $attribute->id; |
804 | 810 |
$groupId = $attributeToGroupMap[$attribute->id]; |
805 | 811 |
$groupType = $groupTypeMap[$groupId]; |
812 |
+ $groupKey = 'group_' . $groupId; |
|
806 | 813 |
|
807 | 814 |
if ($groupType === 'text') { |
808 | 815 |
// For text attributes, store the text value |
... | ... |
@@ -811,11 +818,16 @@ class SlotAjaxController extends AbstractController |
811 | 818 |
$groupHasValue[$groupId] = true; |
812 | 819 |
} |
813 | 820 |
} else if ($groupType === 'option') { |
814 |
- // For option attributes, store true if selected |
|
821 |
+ // For option attributes with multiple values (checkboxes) |
|
815 | 822 |
if (Input::post($attributeKey)) { |
816 | 823 |
$attributeValues[$attribute->id] = true; |
817 | 824 |
$groupHasValue[$groupId] = true; |
818 | 825 |
} |
826 |
+ // For option attributes with single value (radio buttons) |
|
827 |
+ else if (Input::post($groupKey) == $attribute->id) { |
|
828 |
+ $attributeValues[$attribute->id] = true; |
|
829 |
+ $groupHasValue[$groupId] = true; |
|
830 |
+ } |
|
819 | 831 |
} |
820 | 832 |
} |
821 | 833 |
|