source: trunk/grails-app/views/inventoryItemDetailed/show.gsp @ 836

Last change on this file since 836 was 836, checked in by gav, 13 years ago

Fix early closed table row on clickableOdd/clickableEven list tables.

File size: 35.2 KB
Line 
1
2
3<html>
4    <head>
5        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6        <meta name="layout" content="main" />
7        <title>Show InventoryItem</title>
8        <nav:resources override="true"/>
9        <resource:tabView skin="tabviewCustom" />
10        <g:render template="/shared/pictureHead" />
11    </head>
12    <body>
13        <div class="nav">
14            <nav:renderSubItems group="nav"/>
15        </div>
16        <div class="body">
17            <g:render template="/shared/messages" />
18            <g:if test="${inventoryItemInstance.isObsolete || !inventoryItemInstance.isActive}" >
19                <div class="errors">
20                    <ul>
21                        <g:if test="${inventoryItemInstance.isObsolete}" >
22                            <li><g:message code="inventory.item.is.obsolete.message" /><li>
23                        </g:if>
24                        <g:if test="${!inventoryItemInstance.isActive}" >
25                            <li><g:message code="inventory.item.not.active.message" /><li>
26                        </g:if>
27                    </ul>
28                </div>
29            </g:if>
30            <g:if test="${!inventoryItemInstance.enableReorderListing}" >
31                <div class="message">
32                    <g:message code="inventory.item.reorder.listing.disabled" />
33                </div>
34            </g:if>
35            <g:hasErrors bean="${inventoryMovementInstance}">
36                <div class="errors">
37                    <g:renderErrors bean="${inventoryMovementInstance}" as="list" />
38                </div>
39            </g:hasErrors>
40
41            <g:hasErrors bean="${inventoryItemInstance}">
42                <div class="errors">
43                    <g:renderErrors bean="${inventoryItemInstance}" as="list" />
44                </div>
45            </g:hasErrors>
46
47            <div class="tabHeader">
48                <h1>
49                    ${inventoryItemInstance.name}
50                </h1>
51                ${fieldValue(bean:inventoryItemInstance, field:'description')}
52            </div>
53
54            <br/>
55
56            <richui:tabView id="tabView">
57
58                <richui:tabLabels>
59                    <richui:tabLabel selected="${showTab.inventory}" title="Inventory Item" />
60                    <g:if test="${!inventoryMovementList.isEmpty()}">
61                        <richui:tabLabel selected="${showTab.movement}" title="Movement (${inventoryMovementList.size()})" />
62                    </g:if>
63                    <g:else>
64                        <richui:tabLabel selected="${showTab.movement}" title="Movement" />
65                    </g:else>
66                    <g:if test="${!inventoryItemPurchases.isEmpty()}">
67                        <richui:tabLabel selected="${showTab.purchasing}" title="Purchasing (${inventoryItemPurchases.size()})" />
68                    </g:if>
69                    <g:else>
70                        <richui:tabLabel selected="${showTab.purchasing}" title="Purchasing" />
71                    </g:else>
72                </richui:tabLabels>
73
74                <richui:tabContents>
75
76<!-- Start Inventory tab -->
77                    <richui:tabContent>
78
79                        <g:if test="${inventoryMovementInstance}" >
80
81                            <div id="useInventoryItemDiv" style="display:inline"> <!-- inline required for IE -->
82                                <div class="pane_close" >
83                                    <g:remoteLink action="clearUseInventoryItem" update="useInventoryItemDiv">
84                                        <img  src="${resource(dir:'images/skin',file:'cross.png')}" alt="Clear" title="Clear"/>
85                                    </g:remoteLink>
86                                </div>
87                                <g:form controller="inventoryItemDetailed" action="useInventoryItem" method="post" >
88                                    <div class="dialog">
89                                        <table>
90                                            <tbody>
91                                                    <g:hiddenField name="task.id" value="${inventoryMovementInstance.task.id}"/>
92                                                    <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}"/>
93                                                    <tr class="prop">
94                                                        <td valign="top" class="name">Use on task:</td>
95                                                        <td valign="top" class="value">
96                                                            <g:link controller="taskDetailed" action="show" id="${inventoryMovementInstance.task.id}" >
97                                                                ${Task.get(inventoryMovementInstance.task.id).encodeAsHTML()}
98                                                            </g:link>
99                                                        </td>
100                                                    </tr>
101
102                                                    <tr class="prop">
103                                                        <td valign="top" class="name">
104                                                            <label for="quantity">Quantity:</label>
105                                                        </td>
106                                                        <td valign="top">
107                                                            <input class="medium ${hasErrors(bean:inventoryMovementInstance,field:'quantity','errors')}"
108                                                                        type="text" id="quantity" name="quantity"
109                                                                        value="${fieldValue(bean:inventoryMovementInstance,field:'quantity')}"/>
110                                                            ${inventoryItemInstance.unitOfMeasure?.encodeAsHTML()}
111
112                                                            <span class="buttons">
113                                                                <g:actionSubmit action="useInventoryItem" class="save" value="${InventoryMovementType.read(1)}" />
114                                                            </span>
115
116                                                        </td>
117                                                    </tr>
118
119                                            </tbody>
120                                        </table>
121                                    </div>
122                                </g:form>
123
124                                <br />
125                            </div>
126
127                        </g:if>
128
129                        <div class="dialog">
130                            <table>
131                                <tbody>
132
133                                    <tr class="prop">
134                                        <td valign="top" class="groupName">Picture:</td>
135                                        <td valign="top" class="value">
136                                            <g:if test="${inventoryItemInstance.picture}" >
137                                                <span class='gallery'><wa:pictureLightboxAnchor picture="${inventoryItemInstance.picture}" size="${Image.Small}" lightboxSize="${Image.Large}" target="_blank" title="Show Original" /></span>
138                                            </g:if>
139                                            <g:else>
140                                                <g:link controller="pictureDetailed"
141                                                                params="['inventoryItem.id':inventoryItemInstance.id]"
142                                                                action="create">
143                                                    Add Picture
144                                                </g:link>
145                                            </g:else>
146                                        </td>
147                                    </tr>
148
149                                    <tr class="prop">
150                                        <td valign="top" class="groupName">Comment:</td>
151
152                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'comment')}</td>
153                                    </tr>
154
155                                    <tr class="prop">
156                                        <td valign="top" class="groupName">In Stock:</td>
157
158                                        <td valign="top" class="value">
159                                            ${fieldValue(bean:inventoryItemInstance, field:'unitsInStock')} ${inventoryItemInstance.unitOfMeasure.encodeAsHTML()}
160                                        </td>
161                                    </tr>
162
163                                    <tr class="prop">
164                                        <td valign="top" class="groupName">Location:</td>
165
166                                        <td valign="top" class="value">
167                                            <g:link controller="inventoryLocationDetailed" action="show" id="${inventoryItemInstance.inventoryLocation?.id}">
168                                                ${inventoryItemInstance.inventoryLocation?.encodeAsHTML()}
169                                            </g:link>
170                                                in ${inventoryItemInstance.inventoryLocation?.inventoryStore.encodeAsHTML()}
171                                        </td>
172                                    </tr>
173
174                                    <tr class="prop">
175                                        <td valign="top" class="groupName">Inventory Group:</td>
176                                        <td valign="top" class="value">${inventoryItemInstance.inventoryGroup?.encodeAsHTML()}</td>
177                                    </tr>
178
179                                    <tr class="prop">
180                                        <td valign="top" class="groupName">Inventory Type:</td>
181                                        <td valign="top" class="value">${inventoryItemInstance.inventoryType?.encodeAsHTML()}</td>
182                                    </tr>
183
184                                    <tr class="prop">
185                                        <td valign="top" class="groupHeader">
186                                            <label for="name">Reorder Details</label>
187                                        </td>
188                                        <td valign="top" class="value">
189                                        </td>
190                                    </tr>
191
192                                    <tr class="prop">
193                                        <td valign="top" class="groupName">Active:</td>
194
195                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'isActive')}</td>
196                                    </tr>
197
198                                    <tr class="prop">
199                                        <td valign="top" class="groupName">Obsolete:</td>
200                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'isObsolete')}</td>
201                                    </tr>
202
203                                    <tr class="prop">
204                                        <td valign="top" class="groupName">Enable Reorder Listing:</td>
205                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'enableReorderListing')}</td>
206                                    </tr>
207
208                                    <tr class="prop">
209                                        <td valign="top" class="groupName">Reorder Point:</td>
210                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'reorderPoint')}</td>
211                                    </tr>
212
213                                    <tr class="prop">
214                                        <td valign="top" class="groupName">Reorder Quantity:</td>
215                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'reorderQuantity')}</td>
216                                    </tr>
217
218                                    <tr class="prop">
219                                        <td valign="top" class="groupName">Estimated Unit Price:</td>
220
221                                        <td valign="top" class="value">
222                                            <g:if test="${inventoryItemInstance.estimatedUnitPriceAmount}">
223                                                ${inventoryItemInstance.estimatedUnitPriceAmount.encodeAsHTML()}
224                                                ${inventoryItemInstance.estimatedUnitPriceCurrency.encodeAsHTML()}
225                                            </g:if>
226                                        </td>
227                                    </tr>
228
229                                    <tr class="prop">
230                                        <td valign="top" class="groupName">Suppliers Part Number:</td>
231                                        <td valign="top" class="value">${fieldValue(bean:inventoryItemInstance, field:'suppliersPartNumber')}</td>
232                                    </tr>
233
234                                    <tr class="prop">
235                                        <td valign="top" class="groupName">Preferred Supplier:</td>
236
237                                        <td  valign="top" style="text-align:left;" class="value">
238                                            <g:link controller="supplierDetailed" action="show" id="${inventoryItemInstance.preferredSupplier?.id}">
239                                                ${inventoryItemInstance.preferredSupplier?.encodeAsHTML()}
240                                            </g:link>
241                                        </td>
242                                    </tr>
243
244                                    <tr class="prop">
245                                        <td valign="top" class="groupName">Alternate Suppliers:</td>
246
247                                        <td  valign="top" style="text-align:left;" class="value">
248                                            <ul>
249                                            <g:each var="s" in="${ inventoryItemInstance.alternateSuppliers.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
250                                                <li><g:link controller="supplierDetailed" action="show" id="${s.id}">${s?.encodeAsHTML()}</g:link></li>
251                                            </g:each>
252                                            </ul>
253                                        </td>
254                                    </tr>
255
256                                    <tr class="prop">
257                                        <td valign="top" class="groupHeader">
258                                            <label for="name">Spare For</label>
259                                        </td>
260                                        <td valign="top" class="value">
261                                        </td>
262                                    </tr>
263
264                                    <tr class="prop">
265                                        <td valign="top" class="groupName">Assets:</td>
266
267                                        <td  valign="top" style="text-align:left;" class="value">
268                                            <ul>
269                                            <g:each var="s" in="${ inventoryItemInstance.spareFor.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
270                                                <li><g:link controller="assetDetailed" action="show" id="${s.id}">${s?.encodeAsHTML()}</g:link></li>
271                                            </g:each>
272                                            </ul>
273                                        </td>
274                                    </tr>
275
276                                </tbody>
277                            </table>
278                        </div>
279                        <div class="buttons">
280                            <g:form>
281                                <g:hiddenField name="id" value="${inventoryItemInstance.id}" />
282                                <span class="button"><g:actionSubmit class="edit" value="Edit" /></span>
283                                <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
284                            </g:form>
285                        </div>
286
287                        <br />
288
289                    </richui:tabContent>
290<!-- End Inventory tab -->
291
292<!-- Start Movement tab -->
293                    <richui:tabContent>
294
295                        <g:if test="${inventoryMovementList.isEmpty()}">
296                            <br />
297                            No Inventory Movements.
298                            <br />
299                            <br />
300
301                            <div class="buttons">
302                                <g:form controller="inventoryMovementDetailed">
303                                    <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
304                                    <span class="button"><g:actionSubmit action="create" class="add" value="Create" /></span>
305                                </g:form>
306                            </div>
307
308                        </g:if>
309                        <g:else>
310
311                            <div class="list">
312                                <table>
313                                    <thead>
314                                        <tr>
315                                            <th>Quantity</th>
316                                            <th>Movement Type</th>
317                                            <th>Date</th>
318                                            <th>Person</th>
319                                            <th></th>
320                                        </tr>
321                                    </thead>
322                                    <tbody>
323                                        <g:each in="${inventoryMovementList}" status="i" var="movements">
324                                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}">
325
326                                                <td onclick='window.location = "${request.getContextPath()}/inventoryMovementDetailed/show/${movements.id}"'>
327                                                    ${fieldValue(bean:movements, field:'quantity')}
328                                                </td>
329                                                <td onclick='window.location = "${request.getContextPath()}/inventoryMovementDetailed/show/${movements.id}"'>
330                                                    ${fieldValue(bean:movements, field:'inventoryMovementType')}
331                                                </td>
332                                                <td onclick='window.location = "${request.getContextPath()}/inventoryMovementDetailed/show/${movements.id}"'>
333                                                    <g:formatDate date="${movements.date}" format="EEE, dd-MMM-yyyy"/>
334                                                </td>
335                                                <td onclick='window.location = "${request.getContextPath()}/inventoryMovementDetailed/show/${movements.id}"'>
336                                                    ${fieldValue(bean:movements, field:'person')}
337                                                </td>
338
339                                                <td class="notClickable">
340                                                    <g:link controller="inventoryMovementDetailed" action="show" id="${movements.id}">
341                                                        <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" />
342                                                    </g:link>
343                                                </td>
344
345                                            </tr>
346                                        </g:each>
347                                    </tbody>
348                                </table>
349                            </div>
350
351                            <div class="buttons">
352                                <g:form controller="inventoryMovementDetailed">
353                                    <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
354                                    <g:if test="${inventoryMovementListTotal > inventoryMovementListMax}">
355                                        Showing ${inventoryMovementListMax} of ${inventoryMovementListTotal}
356                                        <br />
357                                    </g:if>
358                                    <g:else>
359                                        Total ${inventoryMovementListTotal}
360                                        <br />
361                                    </g:else>
362                                    <span class="button"><g:actionSubmit action="listInventoryMovements" class="table" value="List" /></span>
363                                    <span class="button"><g:actionSubmit action="create" class="add" value="Create" /></span>
364                                </g:form>
365                            </div>
366
367                        </g:else>
368
369                    </richui:tabContent>
370<!-- End Movement tab -->
371
372<!-- Start Purchases tab -->
373                    <richui:tabContent>
374
375                        <g:if test="${inventoryItemPurchases.isEmpty()}">
376                            <br />
377                            No Inventory Purchases.
378                            <br />
379                            <br />
380
381                            <div class="buttons">
382                                <!--Fake button to prevent ordering disabled inventory items-->
383                                <g:if test="${inventoryItemInstance.isObsolete || !inventoryItemInstance.isActive}" >
384                                    <g:form controller="inventoryItemDetailed">
385                                        <g:hiddenField name="id" value="${inventoryItemInstance.id}" />
386                                        <span class="button">
387                                            <g:actionSubmit action="show" class="add" value="${g.message(code:'inventory.item.reorder.not.allowed')}" />
388                                        </span>
389                                        <span class="button">
390                                            <input type="button" class="search" value="Search"
391                                                        onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/search"' />
392                                        </span>
393                                    </g:form>
394                                </g:if>
395                                <g:else><!--Real order button.-->
396                                    <g:form controller="inventoryItemPurchaseDetailed">
397                                        <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
398                                        <span class="button">
399                                            <g:actionSubmit action="create" class="add" value="Order" />
400                                        </span>
401                                        <span class="button">
402                                            <g:actionSubmit action="search" class="search" value="Search" />
403                                        </span>
404                                    </g:form>
405                                </g:else>
406                            </div>
407
408                        </g:if>
409                        <g:else>
410
411                            <div class="list">
412                                <table>
413                                    <thead>
414                                        <tr>
415                                            <g:sortableColumn action="show" property="purchaseOrderNumber"
416                                                                                title="Order #" params="[paginate: 'purchases']"  />
417                                            <g:sortableColumn action="show"  property="date"
418                                                                                title="Date" params="[paginate: 'purchases']" />
419                                            <g:sortableColumn action="show"  property="costCode"
420                                                                                title="Cost Code" params="[paginate: 'purchases']" />
421                                            <g:sortableColumn action="show"  property="quantity"
422                                                                                title="Quantity" params="[paginate: 'purchases']" />
423                                            <g:sortableColumn action="show"  property="orderValueAmount"
424                                                                                title="Order \$" params="[paginate: 'purchases']" />
425                                            <g:sortableColumn action="show"  property="invoiceNumber"
426                                                                                title="Invoice Number" params="[paginate: 'purchases']" />
427                                            <g:sortableColumn action="show"  property="inventoryItemPurchaseType"
428                                                                                title="Type" params="[paginate: 'purchases']" />
429                                            <th>
430                                                <img  src="${resource(dir:'images/skin',file:'database_go_grey.png')}" alt="Show" title="Show" />
431                                            </th>
432                                            <th>
433                                                <img  src="${resource(dir:'images/skin',file:'basket_put_grey.png')}" alt="Receive" title="Receive" />
434                                            </th>
435                                            <th>
436                                                <img  src="${resource(dir:'images/skin',file:'tick_grey.png')}" alt="Approve" title="Approve Payment" />
437                                            </th>
438                                        </tr>
439                                    </thead>
440                                    <tbody>
441                                        <g:each in="${inventoryItemPurchases}" status="i" var="purchase">
442                                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}">
443
444                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
445                                                    ${fieldValue(bean:purchase, field:'purchaseOrderNumber')}
446                                                </td>
447                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
448                                                    <g:formatDate date="${purchase.date}" format="EEE, dd-MMM-yyyy"/>
449                                                </td>
450                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
451                                                    ${fieldValue(bean:purchase, field:'costCode')}
452                                                </td>
453                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
454                                                    ${fieldValue(bean:purchase, field:'quantity')}
455                                                </td>
456                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
457                                                    ${fieldValue(bean:purchase, field:'orderValueAmount')}
458                                                    ${fieldValue(bean:purchase, field:'orderValueCurrency')}
459                                                </td>
460                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
461                                                    ${fieldValue(bean:purchase, field:'invoiceNumber')}
462                                                </td>
463                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
464                                                    ${fieldValue(bean:purchase, field:'inventoryItemPurchaseType')}
465                                                </td>
466                                                <td class="notClickable">
467                                                    <g:link controller="inventoryItemPurchaseDetailed" action="show" id="${purchase.id}">
468                                                        <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" title="Show" />
469                                                    </g:link>
470                                                </td>
471
472                                                <g:if test="${purchase.inventoryItemPurchaseType.id == 1}">
473                                                    <g:if test="${!purchase.receivedComplete}">
474                                                        <td class="notClickable">
475                                                            <g:link controller="inventoryItemPurchaseDetailed" action="receive" params="[id: purchase.id, returnTo: 'inventoryItem']">
476                                                                <img  src="${resource(dir:'images/skin',file:'basket_put.png')}" alt="Receive" title="Receive" />
477                                                            </g:link>
478                                                        </td>
479                                                        <td class="notClickable">
480                                                        </td>
481                                                    </g:if>
482                                                    <g:else>
483                                                        <td class="notClickable">
484                                                        </td>
485                                                        <td class="notClickable">
486                                                        </td>
487                                                    </g:else>
488                                                </g:if>
489                                                <g:elseif test="${(purchase.inventoryItemPurchaseType.id == 2)||(purchase.inventoryItemPurchaseType.id == 3)}">
490                                                    <g:if test="${!purchase.invoicePaymentApproved}">
491                                                        <td class="notClickable">
492                                                        </td>
493                                                        <td class="notClickable">
494                                                            <g:link controller="inventoryItemPurchaseDetailed" action="approveInvoicePayment" params="[id: purchase.id, returnTo: 'inventoryItem']">
495                                                                <img  src="${resource(dir:'images/skin',file:'tick.png')}" alt="Approve" title="Approve Payment" />
496                                                            </g:link>
497                                                        </td>
498                                                    </g:if>
499                                                    <g:else>
500                                                        <td class="notClickable">
501                                                        </td>
502                                                        <td class="notClickable">
503                                                        </td>
504                                                    </g:else>
505                                                </g:elseif>
506                                                <g:else>
507                                                    <td class="notClickable">
508                                                    </td>
509                                                    <td class="notClickable">
510                                                    </td>
511                                                </g:else>
512
513                                            </tr>
514                                        </g:each>
515                                    </tbody>
516                                </table>
517                            </div>
518
519                            <div class="buttons">
520                                <!--Fake button to prevent ordering disabled inventory items-->
521                                <g:if test="${inventoryItemInstance.isObsolete || !inventoryItemInstance.isActive}" >
522                                    <g:form controller="inventoryItemDetailed">
523                                        <g:hiddenField name="id" value="${inventoryItemInstance.id}" />
524                                        Results: ${inventoryItemPurchases.size()} / ${inventoryItemPurchasesTotal}
525                                        <span class="button">
526                                            <g:actionSubmit action="show" class="add" value="${g.message(code:'inventory.item.reorder.not.allowed')}" />
527                                        </span>
528                                        <span class="button">
529                                            <input type="button" class="search" value="Search"
530                                                        onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/search"' />
531                                        </span>
532                                    </g:form>
533                                </g:if>
534                                <g:else><!--Real order button.-->
535                                    <g:form controller="inventoryItemPurchaseDetailed">
536                                        <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
537                                        Results: ${inventoryItemPurchases.size()} / ${inventoryItemPurchasesTotal}
538                                        <span class="button">
539                                            <g:actionSubmit action="create" class="add" value="Order" />
540                                        </span>
541                                        <span class="button">
542                                            <g:actionSubmit action="search" class="search" value="Search" />
543                                        </span>
544                                    </g:form>
545                                </g:else>
546                            </div>
547
548                            <div class="paginateButtons">
549                                <g:paginate action="show"
550                                                        id="${inventoryItemInstance?.id}"
551                                                        total="${inventoryItemPurchasesTotal}"
552                                                        params="[paginate: 'purchases']" />
553                            </div>
554
555                        </g:else>
556
557                    </richui:tabContent>
558<!-- End Movement tab -->
559
560                </richui:tabContents>
561            </richui:tabView>
562
563        </div>
564    </body>
565</html>
Note: See TracBrowser for help on using the repository browser.