restaurant order placement: new order #3350

This commit is contained in:
Daniel Camargo 2014-06-29 20:00:36 -03:00
parent 7041b91a5c
commit 848ce6dbaf
10 changed files with 386 additions and 93 deletions

View File

@ -1,7 +1,7 @@
<?php
class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
public function init() {
$lastHours = 12; // last 12 hours
@ -11,7 +11,7 @@ class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
switch ( c::getPagePiece( 3 ) ) {
case 'count':
$count = 0;
$orders = Order::deliveryOrders( $lastHours );
$orders = Order::deliveryOrders( $lastHours );
foreach ( $orders as $order ) {
$status = $order->deliveryLastStatus();
if( $status[ 'status' ] == 'new' ){
@ -20,7 +20,7 @@ class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
}
echo json_encode( [ 'total' => $count ] );
break;
default:
$order = Order::o(c::getPagePiece( 3 ) );
@ -32,7 +32,7 @@ class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
c::db()->query( 'DELETE FROM order_action WHERE id_order = "' . $order->id_order . '"' );
}
}
if ( $this->method() == 'post' ) {
@ -56,9 +56,9 @@ class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
$res['status'] = true;
break;
}
if ( $order->deliveryStatus() ){
$ret = $order->deliveryExports();
$ret = $order->deliveryExports();
}
$ret[ 'status' ] = $res[ 'status' ];
@ -79,7 +79,7 @@ class Controller_api_driver_orders extends Crunchbutton_Controller_RestAccount {
$exports = [];
$orders = Order::deliveryOrders( $lastHours );
foreach ( $orders as $order ) {
$exports[] = Model::toModel( [
'id_order' => $order->id_order,

View File

@ -1,49 +1,81 @@
<?php
class Controller_api_order extends Crunchbutton_Controller_RestAccount {
public function init() {
$order = Order::uuid(c::getPagePiece(2));
/* @var $order Crunchbutton_Order */
if (!$order->id_order) {
$order = Order::o(c::getPagePiece(2));
}
// @todo check to see if the restaurant has the permissions for that restaurant id
// $_POST['restaurant']
switch ($this->method()) {
case 'get':
if (get_class($order) != 'Cockpit_Order') {
$order = $order->get(0);
}
switch ( c::getPagePiece( 2 ) ) {
if ($order->id_order) {
echo $order->json();
break;
case 'list':
} else {
echo json_encode(['error' => 'invalid object']);
$restaurant = Admin::restaurantOrderPlacement();
if( $restaurant->id_restaurant ){
$out = [];
$orders = Order::q( 'SELECT * FROM `order` WHERE id_restaurant = "' . $restaurant->id_restaurant . '" ORDER BY id_order DESC LIMIT 20' );
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' ),
);
}
echo json_encode( $out );
} else {
echo json_encode(['error' => 'invalid object']);
}
break;
default:
$order = Order::uuid(c::getPagePiece(2));
/* @var $order Crunchbutton_Order */
if (!$order->id_order) {
$order = Order::o(c::getPagePiece(2));
}
if (get_class($order) != 'Cockpit_Order') {
$order = $order->get(0);
}
if( $order->id_order ){
$restaurant = Admin::restaurantOrderPlacement();
if( $restaurant && $restaurant->id_restaurant && $order->id_restaurant == $order->id_restaurant ){
echo $order->json();
} else {
echo json_encode(['error' => 'invalid object']);
}
}
break;
}
break;
case 'post':
$order = new Order;
// card, subtotal, tip, name, phone, address
$charge = $order->process($_POST, 'restaurant');
if ($charge === true) {
echo json_encode([
'id_order' => $order->id_order,
'id_user' => $order->user()->id_user,
'final_price' => $order->final_price,
'uuid' => (new Order($order->id_order))->uuid
]);
$restaurant = Admin::restaurantOrderPlacement();
if( $restaurant && $restaurant->id_restaurant && $_POST[ 'restaurant' ] == $restaurant->id_restaurant ){
$order = new Order;
// card, subtotal, tip, name, phone, address
$charge = $order->process( $_POST, 'restaurant' );
if ($charge === true) {
echo json_encode([
'id_order' => $order->id_order,
'id_user' => $order->user()->id_user,
'final_price' => $order->final_price,
'uuid' => (new Order($order->id_order))->uuid
]);
} else {
echo json_encode(['status' => 'false', 'errors' => $charge]);
exit;
}
} else {
echo json_encode(['status' => 'false', 'errors' => $charge]);
echo json_encode(['status' => 'false', 'errors' => 'invalid request' ] );
exit;
}
break;
}

View File

@ -39,10 +39,11 @@ class Cockpit_Order extends Crunchbutton_Order {
$date = new DateTime($this->date);
$date->setTimeZone( new DateTimeZone($this->restaurant()->timezone) );
$out['_date_tz'] = $date->format('Y-m-d H:i:s');
$out['_date_formatted'] = $date->format( 'M jS Y g:i:s A' );
$out['_tz'] = $date->format('T');
$out['_tip'] = $this->tip();
$out['_tax'] = $this->tax();
@ -53,15 +54,15 @@ class Cockpit_Order extends Crunchbutton_Order {
$out['summary'] = $this->orderMessage('summary');
if( $this->restaurant()->delivery_estimated_time ){
$out[ '_delivery_estimated_time' ] = $this->date()->modify('+'.$this->restaurant()->delivery_estimated_time.' minutes')->format('h:i A');
$out[ '_delivery_estimated_time' ] = $this->date()->modify('+'.$this->restaurant()->delivery_estimated_time.' minutes')->format('h:i A');
} else {
$out[ '_delivery_estimated_time' ] = false;
}
$out[ '_instructions_payment' ] = $this->driverInstructionsPaymentStatus();
$out[ '_instructions_food' ] = $this->driverInstructionsFoodStatus();
$out[ '_stealth_notification' ] = $this->restaurant()->hasNotification( 'stealth' );
$out[ '_dishes' ] = [];
$delivery_service_markup = ( $this->delivery_service_markup ) ? $this->delivery_service_markup : 0;
@ -74,7 +75,7 @@ class Cockpit_Order extends Crunchbutton_Order {
$price = $dish->dish()->price;
$regular_price = $dish->dish()->price;
// add the delivery markup
// add the delivery markup
if( $delivery_service_markup > 0 && $price > 0 ){
$price = $price + number_format( ( $dish->dish()->price * $delivery_service_markup / 100 ), 2 );
$price = number_format( $price, 2 );
@ -90,10 +91,10 @@ class Cockpit_Order extends Crunchbutton_Order {
$withOptions = '';
$selectOptions = '';
if ($options->count()) {
if ($options->count()) {
foreach ($dish->options() as $option) {
if ($option->option()->type == 'select') {
continue;
}
@ -101,9 +102,9 @@ class Cockpit_Order extends Crunchbutton_Order {
$price += $option->option()->price;
$regular_price += $option->option()->price;
// add the delivery markup
// add the delivery markup
if( $delivery_service_markup > 0 && $price > 0 ){
$option_price = number_format( ( $option->option()->price * $delivery_service_markup / 100 ), 2 );
$option_price = number_format( ( $option->option()->price * $delivery_service_markup / 100 ), 2 );
$price = $price + $option_price;
}
@ -120,15 +121,15 @@ class Cockpit_Order extends Crunchbutton_Order {
$regular_price = number_format( $regular_price, 2 );
}
if( $withOptions != '' ){
$withOptions = substr($withOptions, 0, -2);
$withOptions = substr($withOptions, 0, -2);
}
if( $selectOptions != '' ){
$selectOptions = substr($selectOptions, 0, -2);
$selectOptions = substr($selectOptions, 0, -2);
}
}
$withoutDefaultOptions = '';
if( $dish->id_order_dish && $dish->id_dish ){
if( $dish->id_order_dish && $dish->id_dish ){
$optionsNotChoosen = $dish->optionsDefaultNotChoosen();
$commas = '';
if( $optionsNotChoosen->count() ){

View File

@ -29,7 +29,7 @@
</tr>
</thead>
<?php
<?php
$permissionRefund = c::admin()->permission()->check(['global','orders-all','orders-refund']);
$permissionNotification = c::admin()->permission()->check(['global','orders-all','orders-notification']);
$permissionGiftCard = c::admin()->permission()->check(['global','orders-all','gift-card-all','gift-card-crud']);
@ -61,34 +61,34 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<? endif ; ?>
<?php } ?>
<?php
<?php
$credit = $order->hasCredit();
if( $credit > 0 ){
echo '<div style="color:red;margin-top:8px;">Received <strong style="font-weight:bold;">$' . number_format( $credit, 2 ) . '</strong> credit.</div>';
}
?>
<?php
<?php
$giftcard = $order->hasGiftCard();
if( $giftcard > 0 ){
echo '<br/><br/><i class="icon-gift"></i> Received <b>$' . number_format( $giftcard, 2 ) . '</b> gift card.';
}
?>
<br />
<br />
<br />
<?php if( $permissionRefund ) { ?>
<div style="<?php if( !$order->refunded ) { echo 'display:none;';} ?>" class="pointer refunded-<?php echo $order->uuid; ?> pay_if_refunded" data-value="<?php if( $order->pay_if_refunded ){ echo 1; } else { echo 0; } ?>" data-uuid="<?=$order->uuid?>">
<span><?php if( $order->pay_if_refunded ) { echo '<i class="icon-check"></i>'; } else { echo '<i class="icon-check-empty"></i>'; } ?></span> Pay restaurant despite refund (e.g. this refund was our fault)
</div>
<div style="<?php if( !$order->refunded ) { echo 'display:none;';} ?>" class="pointer refunded-<?php echo $order->uuid; ?> do_not_reimburse_driver" data-value="<?php if( $order->do_not_reimburse_driver ){ echo 1; } else { echo 0; } ?>" data-uuid="<?=$order->uuid?>">
<span><?php if( $order->do_not_reimburse_driver ) { echo '<i class="icon-check"></i>'; } else { echo '<i class="icon-check-empty"></i>'; } ?></span>
<span><?php if( $order->do_not_reimburse_driver ) { echo '<i class="icon-check"></i>'; } else { echo '<i class="icon-check-empty"></i>'; } ?></span>
Do Not Reimburse Driver?
</div>
<?php } ?>
<?php } ?>
<br/>
<?
@ -96,9 +96,9 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
if($suppor ) {
if( $permissionSupportCreate ){
echo '<i class="icon-comments"></i> <a href="/support/' . $support->id . '">View support ticket</a>';
echo '<i class="icon-comments"></i> <a href="/support/' . $support->id . '">View support ticket</a>';
}
}
else {
if( $permissionSupportView ){
@ -125,7 +125,7 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<strong>Notification Sent to Restaurant</strong><br/><br/>
<?php } ?>
<?php if( $order->restaurant()->confirmation || $order->restaurant()->hasPhoneNotification() ){
if( $order->confirmed ) {
if( $order->confirmed ) {
echo '<i class="icon-thumbs-up"></i> Confirmed!';
} else {
echo '<i class="icon-thumbs-down"></i> NOT confirmed.';
@ -154,10 +154,10 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<? foreach ($dish->options() as $option) : ?>
<li><?=$option->option()->name?></li>
<? endforeach ; ?>
<? if( $dish->id_order_dish && $dish->id_dish ){
<? if( $dish->id_order_dish && $dish->id_dish ){
foreach ( $dish->optionsDefaultNotChoosen() as $option ) {
?><li><i style="font-style:italic;">No <?=$option->option()->name?></i></li><?
}
}
}?>
</ul>
<? endif ; ?>
@ -184,15 +184,15 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<tr>
<td nowrap="nowrap">Delivery service percent <br/>(included in subtotal) <br/>
(+<?=$order->delivery_service_markup ? $order->delivery_service_markup : '0'?>% of $
<?php
<?php
if( $order->price_plus_delivery_markup ) {
echo number_format( $order->price, 2 );
} else {
} else {
number_format( $order->price - $order->delivery_service_markup_value, 2 );
} ?>)
</td>
<td>
$<?=number_format( $order->delivery_service_markup_value, 2 )?>
$<?=number_format( $order->delivery_service_markup_value, 2 )?>
<br/>
(+<?=$order->delivery_service_markup ? $order->delivery_service_markup : '0'?>%)
</td>
@ -209,17 +209,17 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<tr>
<td nowrap="">
Tax <br/>
<?php
<?php
if( $order->tax ){
if( $order->price_plus_delivery_markup && $order->delivery_service_markup_value ) {
if( $order->delivery_service ){
echo $order->tax . '% of ' . number_format( ( $order->price ), 2 ) . '<br/>(subtotal without markup)';
echo $order->tax . '% of ' . number_format( ( $order->price ), 2 ) . '<br/>(subtotal without markup)';
} else {
echo $order->tax . '% of ' . number_format( ( $order->price + $order->deliveryFee() ), 2 ) . '<br/>(subtotal without markup)';
}
} else {
} else {
echo $order->tax . '% of ' . number_format( $order->price, 2 ) ;
}
}
}
?>
</td>
@ -292,7 +292,7 @@ $permissionSupportView = c::admin()->permission()->check(['global','support-all'
<tr>
<td><i class="icon-desktop"></i> <?php echo $order->agent()->os . ' ' . $order->agent()->browser ?></td>
</tr>
<?php
<?php
} ?>
</table>
</td>

View File

@ -0,0 +1,69 @@
<div class="top-pad"></div>
<div class="content-padding" ng-show="ready">
<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>
<div ng-show="!error">
<h2 class="title">{{restaurant.name}}</h2>
<div ng-if="orders.length">
<h3 class="title">Showing last {{orders.length}} orders.</h3>
<table class="tb-grid">
<thead>
<tr>
<td>#</td>
<td class="td-medium">Name</td>
<td class="td-medium">Phone</td>
<td>Date</td>
<td>Driver / Status</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders">
<td class="link orange" ng-click="open( order.id_order )">
{{order.id_order}}
</td>
<td>
{{order.name}}
</td>
<td>
{{order.phone}}
</td>
<td>
{{order.date}}
</td>
<td>
<span ng-show="order.lastStatus.name">
{{order.lastStatus.name}} / {{order.lastStatus.status}}
</span>
<span ng-show="!order.lastStatus.name">
new
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="!orders.length" class="box-content">
No orders.
</div>
</div>
</div>
<spinner-loading></spinner-loading>
<hack-expand-content></hack-expand-content>

View File

@ -4,6 +4,11 @@
<h1 class="title left"><i class="fa fa-credit-card"></i><span>New Order</span></h1>
<div class="box-filter right">
<button class="button orange" ng-click="list()">List</button>
<div class="divider"></div>
</div>
<div class="divider"></div>
@ -140,8 +145,8 @@
</li>
<li class="li-input" ng-show="!isProcessing">
<!-- <button class="button orange" ng-click="test();">SEND TEST</button> -->
<button class="button orange" ng-click="processOrder();">Process Order</button>
<button class="button green" ng-click="test();">[TEST]</button>
</li>
<li class="li-input" ng-show="isProcessing">

View File

@ -1,13 +1,153 @@
<div class="top-pad"></div>
<div class="content-padding">
<div class="content-padding" ng-show="ready">
<h1 class="title"><i class="fa fa-credit-card"></i><span>Order Complete</span></h1>
<b>Total</b> {{order.final_price_plus_delivery_markup || order.final_price}}
<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="status"></div>
<div class="header">
<div class="restaurant-name">{{order._restaurant_name}}</div>
<div class="order-id">{{order.id_order}}</div>
<div class="divider"></div>
</div>
<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>
<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>
</div>
</div>
</div>
<spinner-loading></spinner-loading>
<hack-expand-content></hack-expand-content>

View File

@ -84,8 +84,13 @@ NGApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $l
controller: 'RestaurantOrderNew',
templateUrl: 'assets/view/restaurant-order-new.html'
})
.when('/restaurant/order/list', {
action: 'restaurant-order-new',
controller: 'RestaurantOrderList',
templateUrl: 'assets/view/restaurant-order-list.html'
})
.when('/restaurant/order/:id', {
action: 'restaurant-order',
action: 'restaurant-order-new',
controller: 'RestaurantOrderView',
templateUrl: 'assets/view/restaurant-order-view.html'
})

View File

@ -1,7 +1,30 @@
NGApp.controller('RestaurantOrderView', function ($scope, $http, $routeParams) {
$http.get('/api/order/' + $routeParams.id).success(function(data){
$scope.order = data;
});
NGApp.controller('RestaurantOrderView', function ( $scope, RestaurantOrderService ) {
RestaurantOrderService.get( function( json ){
if( json.id_order ){
$scope.order = json;
} else {
$scope.error = true;
}
$scope.ready = true;
} );
$scope.list = function(){
$scope.navigation.link( '/restaurant/order/list' );
}
});
NGApp.controller('RestaurantOrderList', function ( $scope, RestaurantOrderService ) {
RestaurantOrderService.list( function( json ){
if( !json.error ){
$scope.orders = json;
}
$scope.ready = true;
} );
$scope.new = function(){
$scope.navigation.link( '/restaurant/order/new' );
}
$scope.open = function( id_order ){
$scope.navigation.link( '/restaurant/order/' + id_order );
}
});
NGApp.controller( 'RestaurantOrderNew', function ( $scope, RestaurantService, RestaurantOrderService, PositionService ) {
@ -101,8 +124,7 @@ NGApp.controller( 'RestaurantOrderNew', function ( $scope, RestaurantService, Re
return;
} else {
if( data.id_order ) {
// $scope.navigation.link( '/restaurant/order/' + data.id_order );
console.log('data',data);
$scope.navigation.link( '/restaurant/order/' + data.id_order );
$scope.isProcessing = false;
} else {
Alert.alert( data.errors );
@ -111,6 +133,10 @@ NGApp.controller( 'RestaurantOrderNew', function ( $scope, RestaurantService, Re
} );
}
$scope.list = function(){
$scope.navigation.link( '/restaurant/order/list' );
}
$scope.test = function (){
$scope.card.number = '4111111111111111';
$scope.card.year = '2015';

View File

@ -37,9 +37,24 @@ NGApp.factory( 'RestaurantOrderService', function( $rootScope, $resource, $route
var service = {};
var orders = $resource( App.service + 'order/:action', { action: '@action' }, {
'process' : { 'method': 'POST', params : { 'action' : '' } } }
'process' : { 'method': 'POST' },
'get' : { 'method': 'GET' },
'list' : { 'method': 'GET' , params : { 'action' : 'list' }, isArray: true },
}
);
service.get = function( callback ){
orders.get( { 'action': $routeParams.id }, function( data ){
callback( data );
} );
}
service.list = function( callback ){
orders.list( function( data ){
callback( data );
} );
}
service.calcTotal = function( order, restaurant ){
var _fee = function( total ){