... | ... |
@@ -61,6 +61,8 @@ $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['weinanlieferung']['wa_book |
61 | 61 |
'slot_time', |
62 | 62 |
'slot_standort', |
63 | 63 |
'booking_ncsent', |
64 |
+ 'booking_approved', |
|
65 |
+ 'booking_approved_on', |
|
64 | 66 |
), |
65 | 67 |
'email_text' => array |
66 | 68 |
( |
... | ... |
@@ -80,6 +82,8 @@ $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['weinanlieferung']['wa_book |
80 | 82 |
'booking_sorten', |
81 | 83 |
'booking_ernteart', |
82 | 84 |
'booking_lage', |
85 |
+ 'booking_approved', |
|
86 |
+ 'booking_approved_on', |
|
83 | 87 |
), |
84 | 88 |
'email_html' => array |
85 | 89 |
( |
... | ... |
@@ -99,6 +103,8 @@ $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['weinanlieferung']['wa_book |
99 | 103 |
'booking_sorten', |
100 | 104 |
'booking_ernteart', |
101 | 105 |
'booking_lage', |
106 |
+ 'booking_approved', |
|
107 |
+ 'booking_approved_on', |
|
102 | 108 |
) |
103 | 109 |
); |
104 | 110 |
|
... | ... |
@@ -97,7 +97,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array |
97 | 97 |
'palettes' => array |
98 | 98 |
( |
99 | 99 |
'__selector__' => array(), |
100 |
- 'default' => 'pid,uid,behaelter,sorten,lage,ernteart,upload,approved' |
|
100 |
+ 'default' => 'pid,uid,behaelter,sorten,lage,ernteart,upload;{approval_legend},approved' |
|
101 | 101 |
), |
102 | 102 |
|
103 | 103 |
// Subpalettes |
... | ... |
@@ -22,7 +22,10 @@ $GLOBALS['TL_LANG']['tl_vr_wa_reservation']['uid'][0] = 'Winzer'; |
22 | 22 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['uid'][1] = 'Zuordnung des anliefernden Winzers.'; |
23 | 23 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['upload'][0] = 'Datei'; |
24 | 24 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['upload'][1] = 'Die hochgeladene Datei des Winzers.'; |
25 |
+$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['approved'][0] = 'Freigabe'; |
|
26 |
+$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['approved'][1] = 'Der Freigabe-Status der Buchung.'; |
|
25 | 27 |
|
26 | 28 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['title_legend'] = 'Leseart'; |
29 |
+$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['approval_legend'] = 'Freigabe-Einstellungen'; |
|
27 | 30 |
|
28 | 31 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['back'] = 'Zurück'; |
... | ... |
@@ -47,6 +47,21 @@ |
47 | 47 |
<a href="/contao?do=weinanlieferung&table=tl_vr_wa_reservation&act=create&rt={{ request_token }}&ref={{ ref }}" class="header_new" title="" accesskey="n" onclick="Backend.getScrollOffset()">Neu</a> |
48 | 48 |
</div> |
49 | 49 |
<div class="tl_listing_container"> |
50 |
+ <div class="u-flex u-items-center u-gap-2 px-1 text-sm"> |
|
51 |
+ <div><strong>Legende:</strong></div> |
|
52 |
+ <div class="u-flex u-items-center u-gap-1"> |
|
53 |
+ <i class="status-icon status--approved status--small"></i> |
|
54 |
+ angenommen |
|
55 |
+ </div> |
|
56 |
+ <div class="u-flex u-items-center u-gap-1"> |
|
57 |
+ <i class="status-icon status--pending status--small"></i> |
|
58 |
+ Freigabe ausstehend |
|
59 |
+ </div> |
|
60 |
+ <div class="u-flex u-items-center u-gap-1"> |
|
61 |
+ <i class="status-icon status--canceled status--small"></i> |
|
62 |
+ abgelehnt |
|
63 |
+ </div> |
|
64 |
+ </div> |
|
50 | 65 |
<div> |
51 | 66 |
|
52 | 67 |
{% block content %} |
... | ... |
@@ -56,37 +71,47 @@ |
56 | 71 |
<h3 class="tl_folder_list px-1 text-lg text-primary mt-2">{{ day|date('d.m.Y') }}</h3> |
57 | 72 |
{% for standort in standorte %} |
58 | 73 |
{% for time,bookings in standort.times %} |
59 |
- <h3 class="tl_folder_list px-1 row u-items-center"> |
|
60 |
- <div class="col-2 pl-0">{{ time|date('H:i') }}</div> |
|
61 |
- <div class="col-3"> |
|
74 |
+ <h3 class="tl_folder_list row u-items-center"> |
|
75 |
+ <div class="col-2 offset-1">{{ time|date('H:i') }}</div> |
|
76 |
+ <div class="col-2"> |
|
62 | 77 |
<div class="t-label">Standort</div> |
63 | 78 |
{{ standort.standort }} |
64 | 79 |
</div> |
65 |
- <div class="col-3"> |
|
80 |
+ <div class="col-2"> |
|
66 | 81 |
<div class="t-label">Verfügbare Behälterkapazität</div> |
67 | 82 |
{{ bookings.behaelterAvailable }} |
68 | 83 |
</div> |
69 |
- <div class="col"> |
|
84 |
+ <div class="col px-1"> |
|
70 | 85 |
<div class="t-label">Verarbeitete Sorten</div> |
71 | 86 |
{{ bookings.sorten|join(', ') }} |
72 | 87 |
</div> |
73 | 88 |
</h3> |
74 | 89 |
<div class="bookings u-row-striped"> |
75 | 90 |
{% for booking in bookings.items %} |
76 |
- <div class="row u-items-center"> |
|
77 |
- <div class="col-1 time icon-uhr-outline"> |
|
91 |
+ {% if booking.approved == '1' %} |
|
92 |
+ {% set status = 'approved' %} |
|
93 |
+ {% elseif booking.approved == '0' %} |
|
94 |
+ {% set status = 'canceled' %} |
|
95 |
+ {% else %} |
|
96 |
+ {% set status = 'pending' %} |
|
97 |
+ {% endif %} |
|
98 |
+ <div class="row u-items-flex-start my-1 status status--{{ status }}"> |
|
99 |
+ <div class="col-1"> |
|
100 |
+ <i class="status-icon" title="{{ ('MSC.wa_approval_status.'~status)|trans([], 'contao_default') }}">{{ ('MSC.wa_approval_status.'~status)|trans([], 'contao_default') }}</i> |
|
101 |
+ </div> |
|
102 |
+ <div class="col-2 time icon-uhr-outline"> |
|
78 | 103 |
<div class="t-label">Uhrzeit</div> |
79 | 104 |
{{ booking.slot.time|date('H:i') }} |
80 | 105 |
<div class="t-label">Standort</div> |
81 | 106 |
{{ booking.standort }} |
82 | 107 |
</div> |
83 |
- <div class="col-3 behaelter icon-behaelter-outline"> |
|
108 |
+ <div class="col-2 behaelter icon-behaelter-outline"> |
|
84 | 109 |
<div class="t-label">Gebuchte Behälterkapazität</div> |
85 | 110 |
{{ booking.behaelter }} |
86 | 111 |
<div class="t-label">Ernteart</div> |
87 | 112 |
{{ booking.ernteart|join(', ') }} |
88 | 113 |
</div> |
89 |
- <div class="col-3 behaelter icon-behaelter-outline"> |
|
114 |
+ <div class="col-2 behaelter icon-behaelter-outline"> |
|
90 | 115 |
<div class="t-label">Anliefernde Sorten</div> |
91 | 116 |
{{ booking.sorte|join(', ') }} |
92 | 117 |
<div class="t-label">Lage</div> |
... | ... |
@@ -106,7 +131,7 @@ |
106 | 131 |
</div>{% endif %} |
107 | 132 |
{% endif %} |
108 | 133 |
</div> |
109 |
- <div class="col-1 u-text-right action"> |
|
134 |
+ <div class="col px-1 u-text-right action"> |
|
110 | 135 |
<a |
111 | 136 |
href="/contao?do=weinanlieferung&table=tl_vr_wa_reservation&act=edit&id={{ booking.id }}&rt={{ request_token }}&ref={{ ref }}" |
112 | 137 |
{# onclick="Backend.openModalIframe({'title':'Quellelement ID {{ booking.id }} bearbeiten','url':this.href});return false" #} |
... | ... |
@@ -6307,3 +6307,69 @@ |
6307 | 6307 |
.u-border-opacity-100 { |
6308 | 6308 |
--border-opacity: 1; |
6309 | 6309 |
} |
6310 |
+ |
|
6311 |
+ |
|
6312 |
+/** Status icons */ |
|
6313 |
+.status .status-icon { |
|
6314 |
+ visibility: hidden; |
|
6315 |
+ position: relative; |
|
6316 |
+ width: 24px; |
|
6317 |
+ height: 24px; |
|
6318 |
+} |
|
6319 |
+.status .status-icon:after { |
|
6320 |
+ width: 24px; |
|
6321 |
+ height: 24px; |
|
6322 |
+ visibility: visible; |
|
6323 |
+ position: absolute; |
|
6324 |
+ top: 50%; |
|
6325 |
+ left: 50%; |
|
6326 |
+ margin: -12px 0 0 -12px; |
|
6327 |
+ content: ''; |
|
6328 |
+ background-position: 50% 50%; |
|
6329 |
+ background-repeat: no-repeat; |
|
6330 |
+} |
|
6331 |
+.status-icon { |
|
6332 |
+ visibility: hidden; |
|
6333 |
+ position: relative; |
|
6334 |
+ display: inline-block; |
|
6335 |
+ width: 24px; |
|
6336 |
+ height: 24px; |
|
6337 |
+} |
|
6338 |
+.status-icon:after { |
|
6339 |
+ width: 24px; |
|
6340 |
+ height: 24px; |
|
6341 |
+ visibility: visible; |
|
6342 |
+ position: absolute; |
|
6343 |
+ top: 50%; |
|
6344 |
+ left: 50%; |
|
6345 |
+ margin: -12px 0 0 -12px; |
|
6346 |
+ content: ''; |
|
6347 |
+ background-position: 50% 50%; |
|
6348 |
+ background-repeat: no-repeat; |
|
6349 |
+} |
|
6350 |
+.status-icon.status--small, .status.status--small .status-icon, .status-icon.status--small:after, .status.status--small .status-icon:after { |
|
6351 |
+ width: 16px; |
|
6352 |
+ height: 16px; |
|
6353 |
+} |
|
6354 |
+.status-icon.status--small:after, .status.status--small .status-icon:after { |
|
6355 |
+ margin: -8px 0 0 -8px; |
|
6356 |
+} |
|
6357 |
+.status.status--approved:not(.status-icon):not(.status-no-rowcolor), .status-icon.status--approved:not(.status-icon):not(.status-no-rowcolor) { |
|
6358 |
+ background-color: #f3ffe2; |
|
6359 |
+} |
|
6360 |
+.status.status--approved:not(.status):after, .status-icon.status--approved:not(.status):after, .status.status--approved .status-icon:after, .status-icon.status--approved .status-icon:after { |
|
6361 |
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-thumb-up' width='100%25' height='100%25' viewBox='0 0 24 24' stroke-width='1.5' stroke='%2300b341' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3' /%3E%3C/svg%3E"); |
|
6362 |
+} |
|
6363 |
+.status.status--pending:not(.status-icon):not(.status-no-rowcolor), .status-icon.status--pending:not(.status-icon):not(.status-no-rowcolor) { |
|
6364 |
+ background-color: #fff6e4; |
|
6365 |
+} |
|
6366 |
+.status.status--pending:not(.status):after, .status-icon.status--pending:not(.status):after, .status.status--pending .status-icon:after, .status-icon.status--pending .status-icon:after { |
|
6367 |
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-hourglass-high' width='100%25' height='100%25' viewBox='0 0 24 24' stroke-width='1.5' stroke='%23ff9300' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M6.5 7h11' /%3E%3Cpath d='M6 20v-2a6 6 0 1 1 12 0v2a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1z' /%3E%3Cpath d='M6 4v2a6 6 0 1 0 12 0v-2a1 1 0 0 0 -1 -1h-10a1 1 0 0 0 -1 1z' /%3E%3C/svg%3E"); |
|
6368 |
+} |
|
6369 |
+.status.status--canceled:not(.status-icon):not(.status-no-rowcolor), .status-icon.status--canceled:not(.status-icon):not(.status-no-rowcolor) { |
|
6370 |
+ background-color: #ffe7e7; |
|
6371 |
+} |
|
6372 |
+.status.status--canceled:not(.status):after, .status-icon.status--canceled:not(.status):after, .status.status--canceled .status-icon:after, .status-icon.status--canceled .status-icon:after { |
|
6373 |
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-thumb-down' width='100%25' height='100%25' viewBox='0 0 24 24' stroke-width='1.5' stroke='%23ff2825' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3' /%3E%3C/svg%3E"); |
|
6374 |
+} |
|
6375 |
+ |
... | ... |
@@ -62,7 +62,7 @@ class SendBookingChangeNotificationJob |
62 | 62 |
$time = Date::floorToMinute(); |
63 | 63 |
|
64 | 64 |
// Do we have updateable items |
65 |
- $Bookings = $this->db->executeQuery("SELECT r.id, r.pid, r.uid, r.behaelter, r.sorten, r.lage, r.ernteart, r.upload, r.nc_sent, s.date as 'slot_date', s.time as 'slot_time', s.behaelter as 'slot_behaelter', s.sorten as 'slot_sorten', s.ernteart as 'slot_ernteart', s.lage as 'slot_lage', s.anmerkungen as 'slot_anmerkungen' FROM tl_vr_wa_reservation r INNER JOIN tl_vr_wa_slot s ON s.id = r.pid WHERE s.pid = ? AND r.nc_sent < r.tstamp AND s.published='1'",[$Location->id]); |
|
65 |
+ $Bookings = $this->db->executeQuery("SELECT r.id, r.pid, r.uid, r.behaelter, r.sorten, r.lage, r.ernteart, r.upload, r.nc_sent, s.date as 'slot_date', s.time as 'slot_time', s.behaelter as 'slot_behaelter', s.sorten as 'slot_sorten', s.ernteart as 'slot_ernteart', s.lage as 'slot_lage', s.anmerkungen as 'slot_anmerkungen', r.approved, r.approved_on FROM tl_vr_wa_reservation r INNER JOIN tl_vr_wa_slot s ON s.id = r.pid WHERE s.pid = ? AND r.nc_sent < r.tstamp AND s.published='1'",[$Location->id]); |
|
66 | 66 |
|
67 | 67 |
// Load groups and notification models if we have news to share |
68 | 68 |
if ($Bookings->rowCount() && ($Notification = Notification::findByPk($Location->nc_notification)) !== null) |
... | ... |
@@ -139,6 +139,8 @@ class SendBookingChangeNotificationJob |
139 | 139 |
'booking_sorten' => implode(', ',$arrSortenBooked), |
140 | 140 |
'booking_ernteart' => implode(', ',$arrErnteartBooked), |
141 | 141 |
'booking_lage' => implode(', ',$arrLageBooked), |
142 |
+ 'booking_approved' => $Booking['approved'], |
|
143 |
+ 'booking_approved_on'=> $Booking['approved_on'], |
|
142 | 144 |
'admin_email' => $admin_email, |
143 | 145 |
), |
144 | 146 |
$GLOBALS['TL_LANGUAGE']); |
... | ... |
@@ -19,6 +19,7 @@ use Contao\StringUtil; |
19 | 19 |
use Doctrine\DBAL\Connection; |
20 | 20 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; |
21 | 21 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; |
22 |
+use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel; |
|
22 | 23 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungSlotsModel; |
23 | 24 |
|
24 | 25 |
class WeinanlieferungReservationContainerListener |
... | ... |
@@ -145,4 +146,25 @@ class WeinanlieferungReservationContainerListener |
145 | 146 |
|
146 | 147 |
return $arrData; |
147 | 148 |
} |
149 |
+ |
|
150 |
+ /** |
|
151 |
+ * @Callback(table="tl_vr_wa_reservation", target="fields.approved.save") |
|
152 |
+ */ |
|
153 |
+ public function onApprovedSaveCallback($varValue, DataContainer $dc) |
|
154 |
+ { |
|
155 |
+ if (($Current = WeinanlieferungReservationModel::findByPk($dc->activeRecord->id)) !== null) |
|
156 |
+ { |
|
157 |
+ if ($Current->approved === '1' && $varValue !== '1') |
|
158 |
+ { |
|
159 |
+ $Current->approved_on = 0; |
|
160 |
+ $Current->save(); |
|
161 |
+ } elseif ($Current->approved !== '1' && $varValue === '1') |
|
162 |
+ { |
|
163 |
+ $Current->approved_on = time(); |
|
164 |
+ $Current->save(); |
|
165 |
+ } |
|
166 |
+ } |
|
167 |
+ |
|
168 |
+ return $varValue; |
|
169 |
+ } |
|
148 | 170 |
} |
... | ... |
@@ -29,6 +29,12 @@ class WeinanlieferungReservationModel extends Model |
29 | 29 |
$Date = new Date(); |
30 | 30 |
$time = $Date->dayBegin; |
31 | 31 |
|
32 |
- return static::findBy(array("pid IN (SELECT tl_vr_wa_slot.id FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid AND tl_vr_wa_slot.time >= ?)"), $time, $arrOptions); |
|
32 |
+ $arrColumn = ["pid IN (SELECT tl_vr_wa_slot.id FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid AND tl_vr_wa_slot.time >= ?)"]; |
|
33 |
+ |
|
34 |
+ /*if (!isset($arrOptions['showCanceled']) || !$arrOptions['showCanceled']) { |
|
35 |
+ $arrColumn[] = "approved != '0'"; |
|
36 |
+ }*/ |
|
37 |
+ |
|
38 |
+ return static::findBy($arrColumn, $time, $arrOptions); |
|
33 | 39 |
} |
34 | 40 |
} |