<%
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
%>
 
<div class="backofficeOrder">
  <h2><%= currentNode.customerName %></h2>
  
  <%
  var OPT_PREFIX_REGEXP = /^opt_/;
  
  for(prop in currentNode) {
    if(!prop.match(OPT_PREFIX_REGEXP)) {
      continue;
    }
    var name = prop.replace(OPT_PREFIX_REGEXP,"");
    var value = currentNode[prop];
    
    %><span class="option"><%= name %><span class="spacer"> </span><b><%= value %></b></span><span class="spacer"> </span><% 
  }
  %>
  <div class="price">
    Price: <b><% sling.include(resource.path, "replaceSelectors=price"); %></b>
  </div>
  <form method="POST" action="<%= currentNode.path %>">
    <input type="hidden" name=":operation" value="delete"/>
    <input type="hidden" name="source" value="<%= currentNode.path %>"/>
    <input type="hidden" name=":redirect" value="<%= currentNode.getParent().path %>.html"/>
    <input type="submit" value="Delivered - delete this order"/>
  </form>
</div>