restaurant order placement: success #3349

This commit is contained in:
Daniel Camargo 2014-07-15 10:33:05 -03:00
parent f93bcf55e0
commit c2369b738b
9 changed files with 148 additions and 170 deletions

View File

@ -19,15 +19,15 @@ class Controller_api_order extends Crunchbutton_Controller_RestAccount {
$restaurant = Admin::restaurantOrderPlacement();
}
if( $restaurant->id_restaurant ){
$out = [];
$out = [ 'id_restaurant' => intval( $restaurant->id_restaurant ), 'orders' => [] ];
$orders = Order::q( 'SELECT * FROM `order` o WHERE id_restaurant = "' . $restaurant->id_restaurant . '" AND o.date BETWEEN NOW() - INTERVAL 7 DAY AND NOW() ORDER BY id_order DESC' );
foreach( $orders as $order ) {
$out[] = array( 'id_order' => $order->id_order,
'lastStatus' => $order->deliveryLastStatus(),
'name' => $order->name,
'phone' => $order->phone,
'date' => $order->date()->format( 'M jS Y g:i:s A' ),
);
$out[ 'orders' ][] = array( 'id_order' => $order->id_order,
'lastStatus' => $order->deliveryLastStatus(),
'name' => $order->name,
'phone' => $order->phone,
'date' => $order->date()->format( 'M jS Y g:i:s A' ),
);
}
echo json_encode( $out );
} else {

View File

@ -23,8 +23,8 @@ class Controller_api_restaurant extends Crunchbutton_Controller_Rest {
if( $restaurant ){
$out = [];
$out[ 'id_restaurant' ] = intval( $restaurant->id_restaurant );
$out[ 'accepted_orders' ] = $restaurant->numberOfOrdersByStatus( Crunchbutton_Order_Action::DELIVERY_ACCEPTED );
$out[ 'pickedup_orders' ] = $restaurant->numberOfOrdersByStatus( Crunchbutton_Order_Action::DELIVERY_PICKEDUP );
$out[ 'peding' ] = ( $restaurant->numberOfOrdersByStatus( Crunchbutton_Order_Action::DELIVERY_ACCEPTED ) + $restaurant->numberOfOrdersByStatus( false ) );
$out[ 'transit' ] = intval( $restaurant->numberOfOrdersByStatus( Crunchbutton_Order_Action::DELIVERY_PICKEDUP ) );
$phone = c::config()->twilio->live->outgoingCustomer;
if( preg_match( '/^\+\d(\d{3})(\d{3})(\d{4})$/', $phone, $matches ) ){
$phone = $matches[1] . '-' .$matches[2] . '-' . $matches[3];

View File

@ -25,23 +25,36 @@ class Cockpit_Restaurant extends Crunchbutton_Restaurant {
return $this->_lastPayment;
}
// get number of orders of a given status
// get number of orders of a given status for last 7 days
public function numberOfOrdersByStatus( $status ){
$query = 'SELECT COUNT(*) AS total
FROM `order` o
INNER JOIN order_action oa ON oa.id_order = o.id_order
AND oa.type = "' . $status . '"
INNER JOIN
(SELECT MAX(oa.id_order_action) AS id_order_action,
type,
id_order
FROM order_action oa
GROUP BY oa.id_order
ORDER BY oa.id_order_action) actions ON actions.id_order = o.id_order
AND actions.id_order_action = oa.id_order_action
WHERE o.id_restaurant = "' . $this->id_restaurant . '"';
$data = c::db()->get( $query )->get( 0 );
return $data->total;
$interval = 'AND o.date BETWEEN NOW() - INTERVAL 7 DAY AND NOW()';
// orders with no status
if( !$status ){
$query = 'SELECT COUNT(*) AS total
FROM `order` o
WHERE o.id_restaurant = "' . $this->id_restaurant . '"
' . $interval . '
AND o.id_order NOT IN( SELECT DISTINCT(o.id_order) id
FROM `order` o
INNER JOIN order_action oa ON oa.id_order = o.id_order
WHERE o.id_restaurant = "' . $this->id_restaurant . '" ' . $interval . ' )';
} else {
$query = 'SELECT COUNT(*) AS total
FROM `order` o
INNER JOIN order_action oa ON oa.id_order = o.id_order
AND oa.type = "' . $status . '"
INNER JOIN
(SELECT MAX(oa.id_order_action) AS id_order_action,
type,
id_order
FROM order_action oa
GROUP BY oa.id_order
ORDER BY oa.id_order_action) actions ON actions.id_order = o.id_order
AND actions.id_order_action = oa.id_order_action
WHERE o.id_restaurant = "' . $this->id_restaurant . '" ' . $interval;
}
$data = c::db()->get( $query )->get( 0 );
return $data->total;
}
// get orders that are payable; not test, within our date range, it just return the order, the calc are made at settlement class

View File

@ -14,31 +14,31 @@
</ul>
</form>
<div class="dashboard-box pending">
<div class="dashboard-box pending pointer" ng-click="list()">
<div class="dashboard-count">
{{status.accepted_orders}}
{{status.peding}}
</div>
<div class="dashboard-content">
<div class="title">
order<span ng-if="status.accepted_orders > 1">s</span> pending
order<span ng-if="status.peding > 1">s</span> pending
</div>
<div class="description">
order<span ng-if="status.accepted_orders > 1">s</span> waiting to be picked up
order<span ng-if="status.peding > 1">s</span> waiting to be picked up
</div>
</div>
<div class="divider"></div>
</div>
<div class="dashboard-box transit">
<div class="dashboard-box transit pointer" ng-click="list()">
<div class="dashboard-count">
{{status.pickedup_orders}}
{{status.transit}}
</div>
<div class="dashboard-content">
<div class="title">
order<span ng-if="status.pickedup_orders > 1">s</span> in transit
order<span ng-if="status.transit > 1">s</span> in transit
</div>
<div class="description">
order<span ng-if="status.pickedup_orders > 1">s</span> waiting to be picked up
order<span ng-if="status.transit > 1">s</span> waiting to be picked up
</div>
</div>
<div class="divider"></div>

View File

@ -4,11 +4,6 @@
<h1 class="title left"><i class="fa fa-credit-card"></i><span>Last Orders</span></h1>
<div class="box-filter right">
<button class="button orange" ng-click="new()">New</button>
<div class="divider"></div>
</div>
<div class="divider"></div>
<form name="form" ng-show="restaurants">

View File

@ -2,145 +2,60 @@
<div class="content-padding" ng-show="ready">
<div class="box-filter right">
<button class="button orange" ng-click="list()">List</button>
<div class="divider"></div>
</div>
<h1 class="title" ng-show="order.id_order"><i class="fa fa-credit-card"></i><span>Order #{{order.id_order}}</span></h1>
<h1 class="title" ng-show="error">
Invalid order!
</h1>
<div class="content box-content" ng-show="order.id_order">
<div class="wrap">
<div class="order">
<div class="order-item-block">
<div class="order-icon">
<i class="icon-{{order.delivery_type}}"></i>
</div>
<div class="order-info">
<span ng-if="order.delivery_type=='takeout'">Takeout</span>
<span ng-if="order.delivery_type=='delivery'">Delivery</span>
</div>
</div>
<div class="order-item-block">
<div class="order-icon"><i class="icon-{{order.pay_type}}"></i></div>
<div class="order-info">
<span ng-if="order.pay_type=='card'">Card</span>
<span ng-if="order.pay_type=='cash'">Cash</span>
</div>
</div>
<div class="order-item-block">
<div class="order-icon"><i class="icon-clock"></i></div>
<div class="order-info">
{{order._date_formatted}}
</div>
</div>
<div class="order-item-block">
<div class="order-icon"><i class="icon-timer"></i></div>
<div class="order-info">
<span ng-if="order._delivery_estimated_time">{{order._delivery_estimated_time}}</span>
</div>
</div>
<p class="order-message">
The customer's card was successfully charged, and the driver has been notified of the order.
</p>
<div class="divider"></div>
<div class="divider dots"></div>
<br><br>
<div class="order-icon"><i class="icon-user"></i></div>
<div class="order-info">
{{order.name}}
<br><a href="tel:+1{{order.phone}}">{{order.phone | formatPhone}}</a>
</div>
<span ng-if="order.notes">
<div class="order-comment-arrow"></div>
<div class="order-comment">
<p>{{ order.notes | nl2br }}</p>
</div>
</span>
<span ng-if="!order.notes">
<br>
</span>
<a href="http://maps.apple.com/?daddr={{order.address}}&saddr={{order._restaurant_address}}">
<div class="order-map" style="background: url('https://maps.googleapis.com/maps/api/staticmap?size=640x300&markers=color:green%7Clabel:A%7C{{order.address | clearAddress}}&markers=color:red%7Clabel:B%7C{{order._restaurant_lat}},{{order._restaurant_lon}}&sensor=false&visual_refresh=true');"></div>
</a>
<br>
<div class="order-item-block order-map-block">
<div class="order-icon"><i class="icon-map-home"></i></div>
<div class="order-info">
<p class="order-info-address"><a href="http://maps.apple.com/?q={{order.address}}">{{order.address | nl2br}}</a></p>
</div>
</div>
<div class="order-item-block order-map-block">
<div class="order-icon"><i class="icon-map-restaurant"></i></div>
<div class="order-info">
<p class="order-info-address"><a href="http://maps.apple.com/?q={{order._restaurant_address}}">{{order._restaurant_address | nl2br }}</a></p>
</div>
</div>
<br><br>
<div class="divider dots"></div>
<br><br>
<table width="100%" celpadding="0" cellspacing="0" class="detail">
<thead style="font-weight:bold">
<td class="topitem"></td>
<td class="topitem" nowrap="nowrap">Customer Price</td>
<td class="topitem">Store Price</td>
</thead>
<tbody>
<tr class="class">
<td>Subtotal</td>
<td>
${{order.price_plus_delivery_markup | formatPrice}}
</td>
<td>
${{order.price | formatPrice}}
</td>
</tr>
<tr ng-if="order._tip">
<td>Tip <span ng-if="order.tip_type != 'number'">%</span></td>
<td>${{order._tip | formatPrice}}</td>
<td>
&mdash;
</td>
</tr>
<tr ng-if="order.delivery_fee">
<td>Delivery Fee</td>
<td>${{order.delivery_fee | formatPrice}}</td>
<td>
&mdash;
</td>
</tr>
<tr ng-if="order.service_fee">
<td>Service Fee</td>
<td>${{order.service_fee | formatPrice}}</td>
<td>
&mdash;
</td>
</tr>
<tr>
<td>Tax</td>
<td>
${{order._tax | formatPrice}}
</td>
<td>
${{order._tax | formatPrice}}
</td>
</tr>
<tr>
<td><strong>Total</strong></td>
<td>
<strong>${{order.final_price_plus_delivery_markup | formatPrice}}</strong>
</td>
<td>
<strong>${{order._final_price | formatPrice}}</strong>
</td>
</tr>
</tbody>
</table>
<div class="content" ng-show="order.id_order">
<div class="box-content">
<div class="order-group">
<div class="order-label">Name</div>
<div class="order-data">{{order.name}}</div>
</div>
<div class="order-group">
<div class="order-label">Phone</div>
<div class="order-data">{{order.phone}}</div>
</div>
<div class="order-group">
<div class="order-label">Address</div>
<div class="order-data">{{order.address}}</div>
</div>
<div class="order-group" ng-show="order.notes">
<div class="order-label">Notes</div>
<div class="order-data">{{order.notes}}</div>
</div>
<div class="order-group" ng-show="order.card_ending">
<div class="order-label">Card</div>
<div class="order-data">XXXX-XXXX-XXXX-{{order.card_ending}}</div>
</div>
</div>
</div>
<div class="prices">
<div class="box-price price">
<div class="title">
<span class="dollar">$</span> {{order.price | formatPrice}}
</div>
<div class="description">
Price
</div>
</div>
<div class="box-price total-price">
<div class="title">
<span class="dollar">$</span> {{order.final_price_plus_delivery_markup | formatPrice}}
</div>
<div class="description">
Total Price
</div>
</div>
<div class="divider"></div>
</div>
<a class="order-print" ng-href="/printorder/{{order.id}}" target="_blank"><i class="fa fa-print"></i> Print Receipt</a>
</div>
<spinner-loading></spinner-loading>

View File

@ -69,7 +69,8 @@ NGApp.controller('RestaurantOrderPlacementList', function ( $scope, RestaurantOr
var start = function(){
RestaurantOrderPlacementService.list( $scope.id_restaurant, function( json ){
if( !json.error ){
$scope.orders = json;
$scope.orders = json.orders;
$scope.id_restaurant = json.id_restaurant;
}
$scope.ready = true;
} );

View File

@ -39,7 +39,7 @@ NGApp.factory( 'RestaurantOrderPlacementService', function( $rootScope, $resourc
var orders = $resource( App.service + 'order/:action/:id_restaurant', { action: '@action', id_restaurant: '@id_restaurant' }, {
'process' : { 'method': 'POST' },
'get' : { 'method': 'GET' },
'list' : { 'method': 'GET', params: { 'action' : 'restaurant-list-last' }, isArray: true },
'list' : { 'method': 'GET', params: { 'action' : 'restaurant-list-last' } },
}
);

View File

@ -1780,4 +1780,58 @@ b, strong{ font-weight: bold; }
font-weight: bold;
font-size: 1.2em;
text-align: center;
}
}
.order-message{
margin-bottom: 1.2em;
line-height: 1.2em;
color: #7b7e88;
}
.order-group{
font-family: Ruda, Open Sans, Helvetica, Arial, sans-serif;
line-height: 1.2em;
margin-bottom: 1em;
font-size: 1.2em;
}
.order-group .order-label{
font-weight: bold;
}
.order-print{
color: #7b7e88;
margin-top: 1.5em;
margin-right: 5px;
display: block;
text-decoration: none;
font-size: 1.2em;
text-align: right;
}
.box-price{
font-family: Ruda, Open Sans, Helvetica, Arial, sans-serif;
text-align: center;
width: 49%;
}
.box-price .title{
font-size: 2em;
font-weight: 600;
padding: 10px;
padding-bottom: 6px;
}
.box-price .description{
padding-bottom: 10px;
}
.box-price .dollar{
font-size: .6em;
font-weight: normal;
}
.box-price.price{
background: #d6d9dc;
color: #8d8d8d;
float: left;
}
.box-price.total-price{
background: #df5850;
color: #FFF;
float: right;
}
.pointer{
cursor: pointer;
}