@fleetbase/storefront-engine 0.3.18 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/addon/components/customer-panel/orders.hbs +107 -104
  2. package/addon/components/customer-panel/orders.js +52 -45
  3. package/addon/components/modals/incoming-order.hbs +208 -199
  4. package/addon/components/modals/order-ready-assign-driver.hbs +1 -1
  5. package/addon/components/order-panel/details.js +0 -2
  6. package/addon/components/order-panel.hbs +314 -1
  7. package/addon/components/order-panel.js +51 -3
  8. package/addon/components/widget/customers.hbs +75 -51
  9. package/addon/components/widget/customers.js +29 -41
  10. package/addon/components/widget/orders.hbs +278 -119
  11. package/addon/components/widget/orders.js +75 -80
  12. package/addon/components/widget/storefront-metrics.hbs +3 -6
  13. package/addon/components/widget/storefront-metrics.js +25 -41
  14. package/addon/controllers/orders/index.js +214 -105
  15. package/addon/controllers/settings/gateways.js +1 -1
  16. package/addon/helpers/get-tip-amount.js +13 -2
  17. package/addon/routes/application.js +2 -4
  18. package/addon/services/order-actions.js +248 -0
  19. package/addon/services/storefront.js +2 -0
  20. package/addon/styles/storefront-engine.css +48 -0
  21. package/addon/templates/home.hbs +2 -1
  22. package/addon/templates/orders/index/view.hbs +1 -1
  23. package/addon/templates/orders/index.hbs +26 -3
  24. package/addon/templates/products/index/index.hbs +28 -28
  25. package/addon/templates/settings.hbs +1 -1
  26. package/app/services/order-actions.js +1 -0
  27. package/composer.json +1 -1
  28. package/extension.json +1 -1
  29. package/package.json +1 -1
  30. package/server/config/storefront.php +20 -0
  31. package/server/migrations/2023_05_03_025307_create_carts_table.php +1 -1
  32. package/server/migrations/2023_05_03_025307_create_checkouts_table.php +1 -1
  33. package/server/migrations/2023_05_03_025307_create_gateways_table.php +1 -1
  34. package/server/migrations/2023_05_03_025307_create_network_stores_table.php +1 -1
  35. package/server/migrations/2023_05_03_025307_create_networks_table.php +1 -1
  36. package/server/migrations/2023_05_03_025307_create_notification_channels_table.php +1 -1
  37. package/server/migrations/2023_05_03_025307_create_payment_methods_table.php +1 -1
  38. package/server/migrations/2023_05_03_025307_create_product_addon_categories_table.php +1 -1
  39. package/server/migrations/2023_05_03_025307_create_product_addons_table.php +1 -1
  40. package/server/migrations/2023_05_03_025307_create_product_hours_table.php +1 -1
  41. package/server/migrations/2023_05_03_025307_create_product_store_locations_table.php +1 -1
  42. package/server/migrations/2023_05_03_025307_create_product_variant_options_table.php +1 -1
  43. package/server/migrations/2023_05_03_025307_create_product_variants_table.php +1 -1
  44. package/server/migrations/2023_05_03_025307_create_products_table.php +1 -1
  45. package/server/migrations/2023_05_03_025307_create_reviews_table.php +1 -1
  46. package/server/migrations/2023_05_03_025307_create_store_hours_table.php +1 -1
  47. package/server/migrations/2023_05_03_025307_create_store_locations_table.php +1 -1
  48. package/server/migrations/2023_05_03_025307_create_stores_table.php +1 -1
  49. package/server/migrations/2023_05_03_025307_create_votes_table.php +1 -1
  50. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_carts_table.php +1 -1
  51. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_checkouts_table.php +1 -1
  52. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_gateways_table.php +1 -1
  53. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_network_stores_table.php +1 -1
  54. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_networks_table.php +1 -1
  55. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_notification_channels_table.php +1 -1
  56. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_payment_methods_table.php +1 -1
  57. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addon_categories_table.php +1 -1
  58. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addons_table.php +1 -1
  59. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_hours_table.php +1 -1
  60. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_store_locations_table.php +1 -1
  61. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variant_options_table.php +1 -1
  62. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variants_table.php +1 -1
  63. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_products_table.php +1 -1
  64. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_reviews_table.php +1 -1
  65. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_hours_table.php +1 -1
  66. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_locations_table.php +1 -1
  67. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_stores_table.php +1 -1
  68. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_votes_table.php +1 -1
  69. package/server/src/Http/Controllers/ActionController.php +2 -1
  70. package/server/src/Http/Controllers/OrderController.php +15 -2
  71. package/server/src/Http/Controllers/v1/CheckoutController.php +12 -12
  72. package/server/src/Http/Controllers/v1/CustomerController.php +15 -7
  73. package/server/src/Http/Controllers/v1/ServiceQuoteController.php +5 -5
  74. package/server/src/Http/Requests/CreateCustomerRequest.php +4 -0
  75. package/server/src/Http/Requests/InitializeCheckoutRequest.php +2 -1
  76. package/server/src/Http/Resources/Cart.php +1 -1
  77. package/server/src/Models/Store.php +2 -2
  78. package/server/src/Observers/OrderObserver.php +7 -1
  79. package/server/src/Rules/IsValidLocation.php +2 -2
  80. package/server/src/Support/Storefront.php +34 -0
  81. package/translations/en-us.yaml +6 -1
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
4
4
  use Illuminate\Database\Schema\Blueprint;
5
5
  use Illuminate\Support\Facades\Schema;
6
6
 
7
- return new class() extends Migration {
7
+ return new class extends Migration {
8
8
  /**
9
9
  * Run the migrations.
10
10
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -6,7 +6,7 @@ use Illuminate\Database\Query\Expression;
6
6
  use Illuminate\Database\Schema\Blueprint;
7
7
  use Illuminate\Support\Facades\Schema;
8
8
 
9
- return new class() extends Migration {
9
+ return new class extends Migration {
10
10
  /**
11
11
  * Run the migrations.
12
12
  *
@@ -87,9 +87,10 @@ class ActionController extends Controller
87
87
  ->where('meta->storefront_id', $store->public_id)
88
88
  ->with(['transaction'])
89
89
  ->whereNotIn('status', ['canceled'])
90
+ ->whereNull('deleted_at')
90
91
  ->get()
91
92
  ->sum(function ($order) {
92
- return $order->transaction->amount;
93
+ return data_get($order, 'meta.total');
93
94
  });
94
95
 
95
96
  return response()->json($metrics);
@@ -5,6 +5,7 @@ namespace Fleetbase\Storefront\Http\Controllers;
5
5
  use Fleetbase\FleetOps\Http\Controllers\Internal\v1\OrderController as FleetbaseOrderController;
6
6
  use Fleetbase\FleetOps\Models\Order;
7
7
  use Fleetbase\Storefront\Notifications\StorefrontOrderPreparing;
8
+ use Fleetbase\Storefront\Support\Storefront;
8
9
  use Illuminate\Http\Request;
9
10
 
10
11
  class OrderController extends FleetbaseOrderController
@@ -38,6 +39,9 @@ class OrderController extends FleetbaseOrderController
38
39
  ], 400);
39
40
  }
40
41
 
42
+ // Patch order config
43
+ Storefront::patchOrderConfig($order);
44
+
41
45
  // update activity to prepating
42
46
  $order->updateStatus('preparing');
43
47
  $order->customer->notify(new StorefrontOrderPreparing($order));
@@ -58,7 +62,7 @@ class OrderController extends FleetbaseOrderController
58
62
  {
59
63
  $adhoc = $request->boolean('adhoc');
60
64
  $driver = $request->input('driver');
61
- /** @var \Fleetbase\Models\Order $order */
65
+ /** @var Order $order */
62
66
  $order = Order::where('uuid', $request->order)->whereNull('deleted_at')->with(['customer'])->first();
63
67
 
64
68
  if (!$order) {
@@ -67,8 +71,11 @@ class OrderController extends FleetbaseOrderController
67
71
  ], 400);
68
72
  }
69
73
 
74
+ // Patch order config
75
+ Storefront::patchOrderConfig($order);
76
+
70
77
  if ($order->isMeta('is_pickup')) {
71
- $order->updateStatus('ready');
78
+ $order->updateStatus('pickup_ready');
72
79
 
73
80
  return response()->json([
74
81
  'status' => 'ok',
@@ -113,6 +120,9 @@ class OrderController extends FleetbaseOrderController
113
120
  ], 400);
114
121
  }
115
122
 
123
+ // Patch order config
124
+ Storefront::patchOrderConfig($order);
125
+
116
126
  // update activity to completed
117
127
  $order->updateStatus('completed');
118
128
 
@@ -138,6 +148,9 @@ class OrderController extends FleetbaseOrderController
138
148
  ], 400);
139
149
  }
140
150
 
151
+ // Patch order config
152
+ Storefront::patchOrderConfig($order);
153
+
141
154
  // update activity to dispatched
142
155
  $order->updateStatus('cancel');
143
156
 
@@ -132,7 +132,7 @@ class CheckoutController extends Controller
132
132
  ]);
133
133
  }
134
134
 
135
- public static function initializeStripeCheckout(Contact $customer, Gateway $gateway, ServiceQuote $serviceQuote, Cart $cart, $checkoutOptions)
135
+ public static function initializeStripeCheckout(Contact $customer, Gateway $gateway, ?ServiceQuote $serviceQuote, Cart $cart, $checkoutOptions)
136
136
  {
137
137
  // check if pickup order
138
138
  $isPickup = $checkoutOptions->is_pickup;
@@ -202,7 +202,7 @@ class CheckoutController extends Controller
202
202
  'network_uuid' => session('storefront_network'),
203
203
  'cart_uuid' => $cart->uuid,
204
204
  'gateway_uuid' => $gateway->uuid,
205
- 'service_quote_uuid' => $serviceQuote->uuid,
205
+ 'service_quote_uuid' => $serviceQuote ? $serviceQuote->uuid : null,
206
206
  'owner_uuid' => $customer->uuid,
207
207
  'owner_type' => 'fleet-ops:contact',
208
208
  'amount' => $amount,
@@ -283,6 +283,7 @@ class CheckoutController extends Controller
283
283
  'setupIntent' => $setupIntent->id,
284
284
  'clientSecret' => $setupIntent->client_secret,
285
285
  'defaultPaymentMethod' => $defaultPaymentMethod,
286
+ 'customerId' => $customer->getMeta('stripe_id'),
286
287
  ]);
287
288
  } catch (\Exception $e) {
288
289
  return response()->apiError($e->getMessage());
@@ -327,9 +328,6 @@ class CheckoutController extends Controller
327
328
  $serviceQuote = ServiceQuote::select(['amount', 'meta', 'uuid', 'public_id'])
328
329
  ->where('public_id', $serviceQuoteId)
329
330
  ->first();
330
- if (!$serviceQuote) {
331
- return response()->apiError('Invalid service quote ID provided');
332
- }
333
331
 
334
332
  // Recalculate amount based on cart, serviceQuote, and checkoutOptions
335
333
  $amount = static::calculateCheckoutAmount($cart, $serviceQuote, $checkoutOptions);
@@ -398,7 +396,7 @@ class CheckoutController extends Controller
398
396
  'network_uuid' => session('storefront_network'),
399
397
  'cart_uuid' => $cart->uuid,
400
398
  'gateway_uuid' => $gateway->uuid,
401
- 'service_quote_uuid' => $serviceQuote->uuid,
399
+ 'service_quote_uuid' => $serviceQuote ? $serviceQuote->uuid : null,
402
400
  'owner_uuid' => $customer->uuid,
403
401
  'owner_type' => 'fleet-ops:contact',
404
402
  'amount' => $amount,
@@ -418,7 +416,7 @@ class CheckoutController extends Controller
418
416
  ]);
419
417
  }
420
418
 
421
- public static function initializeQPayCheckout(Contact $customer, Gateway $gateway, ServiceQuote $serviceQuote, Cart $cart, $checkoutOptions)
419
+ public static function initializeQPayCheckout(Contact $customer, Gateway $gateway, ?ServiceQuote $serviceQuote, Cart $cart, $checkoutOptions)
422
420
  {
423
421
  // Get store info
424
422
  $about = Storefront::about();
@@ -455,7 +453,7 @@ class CheckoutController extends Controller
455
453
  'network_uuid' => session('storefront_network'),
456
454
  'cart_uuid' => $cart->uuid,
457
455
  'gateway_uuid' => $gateway->uuid,
458
- 'service_quote_uuid' => $serviceQuote->uuid,
456
+ 'service_quote_uuid' => $serviceQuote ? $serviceQuote->uuid : null,
459
457
  'owner_uuid' => $customer->uuid,
460
458
  'owner_type' => 'fleet-ops:contact',
461
459
  'amount' => $amount,
@@ -612,8 +610,8 @@ class CheckoutController extends Controller
612
610
  $customer = $checkout->owner;
613
611
  $serviceQuote = $checkout->serviceQuote;
614
612
  $gateway = $checkout->is_cod ? Gateway::cash() : $checkout->gateway;
615
- $origin = $serviceQuote->getMeta('origin', []);
616
- $destination = $serviceQuote->getMeta('destination');
613
+ $origin = $serviceQuote ? $serviceQuote->getMeta('origin', []) : null;
614
+ $destination = $serviceQuote ? $serviceQuote->getMeta('destination') : null;
617
615
  $cart = $checkout->cart;
618
616
 
619
617
  // if cart is null then cart has either been deleted or expired
@@ -848,7 +846,9 @@ class CheckoutController extends Controller
848
846
  Storefront::alertNewOrder($order);
849
847
 
850
848
  // purchase service quote
851
- $order->purchaseQuote($serviceQuote->uuid, $transactionDetails);
849
+ if ($serviceQuote) {
850
+ $order->purchaseQuote($serviceQuote->uuid, $transactionDetails);
851
+ }
852
852
 
853
853
  // if order is auto accepted update status
854
854
  if ($about->isOption('auto_accept_orders')) {
@@ -1199,7 +1199,7 @@ class CheckoutController extends Controller
1199
1199
  *
1200
1200
  * @param stdClass $checkoutOptions
1201
1201
  */
1202
- private static function calculateCheckoutAmount(Cart $cart, ServiceQuote $serviceQuote, $checkoutOptions): int
1202
+ private static function calculateCheckoutAmount(Cart $cart, ?ServiceQuote $serviceQuote, $checkoutOptions): int
1203
1203
  {
1204
1204
  // cast checkout options to object always
1205
1205
  $checkoutOptions = (object) $checkoutOptions;
@@ -2,6 +2,7 @@
2
2
 
3
3
  namespace Fleetbase\Storefront\Http\Controllers\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exceptions\UserAlreadyExistsException;
5
6
  use Fleetbase\FleetOps\Http\Requests\UpdateContactRequest;
6
7
  use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
7
8
  use Fleetbase\FleetOps\Http\Resources\v1\Order as OrderResource;
@@ -174,7 +175,6 @@ class CustomerController extends Controller
174
175
 
175
176
  // verify code
176
177
  $isVerified = VerificationCode::where(['code' => $code, 'for' => 'storefront_create_customer', 'meta->identity' => $identity])->exists();
177
-
178
178
  if (!$isVerified) {
179
179
  return response()->error('Invalid verification code provided!');
180
180
  }
@@ -209,13 +209,21 @@ class CustomerController extends Controller
209
209
  ];
210
210
 
211
211
  // create the customer/contact
212
- $customer = Contact::create($input);
212
+ try {
213
+ $customer = Contact::create($input);
214
+ } catch (UserAlreadyExistsException $e) {
215
+ // If the exception is thrown because user already exists and
216
+ // that user is the same user already assigned continue
217
+ $customer = Contact::where(['company_uuid' => session('company'), 'phone' => $input['phone']])->first();
218
+ } catch (\Exception $e) {
219
+ return response()->apiError($e->getMessage());
220
+ }
213
221
 
214
222
  // generate auth token
215
223
  try {
216
224
  $token = $user->createToken($customer->uuid);
217
225
  } catch (\Exception $e) {
218
- return response()->error($e->getMessage());
226
+ return response()->apiError($e->getMessage());
219
227
  }
220
228
 
221
229
  $customer->token = $token->plainTextToken;
@@ -430,8 +438,7 @@ class CustomerController extends Controller
430
438
 
431
439
  // find and verify code
432
440
  $verificationCode = VerificationCode::where(['subject_uuid' => $user->uuid, 'code' => $code, 'for' => $for])->exists();
433
-
434
- if (!$verificationCode && $code !== '999000') {
441
+ if (!$verificationCode && $code !== config('storefront.storefront_app.bypass_verification_code')) {
435
442
  return response()->error('Invalid verification code!');
436
443
  }
437
444
 
@@ -510,8 +517,8 @@ class CustomerController extends Controller
510
517
  );
511
518
 
512
519
  return response()->json([
513
- 'ephemeralKey' => $ephemeralKey->secret,
514
- 'customer' => $customer->getMeta('stripe_id'),
520
+ 'ephemeralKey' => $ephemeralKey->secret,
521
+ 'customerId' => $customer->getMeta('stripe_id'),
515
522
  ]);
516
523
  } catch (\Exception $e) {
517
524
  return response()->apiError($e->getMessage());
@@ -546,6 +553,7 @@ class CustomerController extends Controller
546
553
  return response()->json([
547
554
  'setupIntentId' => $setupIntent->id,
548
555
  'setupIntent' => $setupIntent->client_secret,
556
+ 'customerId' => $customer->getMeta('stripe_id'),
549
557
  ]);
550
558
  } catch (\Exception $e) {
551
559
  return response()->apiError($e->getMessage());
@@ -371,13 +371,13 @@ class ServiceQuoteController extends Controller
371
371
 
372
372
  /**
373
373
  * Returns a place from either a place id or store location id.
374
- *
375
- * @param string $id
376
- *
377
- * @return Place
378
374
  */
379
- public function getPlaceFromId($id)
375
+ public function getPlaceFromId(string|array $id): ?Place
380
376
  {
377
+ if (is_array($id)) {
378
+ $id = implode(',', $id);
379
+ }
380
+
381
381
  if (Str::startsWith($id, 'store_location')) {
382
382
  $storeLocation = StoreLocation::select(['place_uuid'])->where(['public_id' => $id, 'store_uuid' => session('storefront_store')])->with(['place'])->first();
383
383
 
@@ -29,11 +29,15 @@ class CreateCustomerRequest extends FleetbaseRequest
29
29
  'name' => 'required',
30
30
  'email' => [
31
31
  'email', 'nullable', Rule::unique('contacts')->where(function ($query) {
32
+ $query->where('company_uuid', session('company'));
33
+
32
34
  return $query->whereNull('deleted_at');
33
35
  }),
34
36
  ],
35
37
  'phone' => [
36
38
  'nullable', Rule::unique('contacts')->where(function ($query) {
39
+ $query->where('company_uuid', session('company'));
40
+
37
41
  return $query->whereNull('deleted_at');
38
42
  }),
39
43
  ],
@@ -5,6 +5,7 @@ namespace Fleetbase\Storefront\Http\Requests;
5
5
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
6
  use Fleetbase\Storefront\Rules\CustomerExists;
7
7
  use Fleetbase\Storefront\Rules\GatewayExists;
8
+ use Illuminate\Validation\Rule;
8
9
 
9
10
  class InitializeCheckoutRequest extends FleetbaseRequest
10
11
  {
@@ -29,7 +30,7 @@ class InitializeCheckoutRequest extends FleetbaseRequest
29
30
  'gateway' => ['required', new GatewayExists()],
30
31
  'customer' => ['required', new CustomerExists()],
31
32
  'cart' => ['required', 'exists:storefront.carts,public_id'],
32
- 'serviceQuote' => ['required', 'exists:service_quotes,public_id'],
33
+ 'serviceQuote' => [Rule::requiredIf(fn () => !$this->boolean('pickup')), 'exists:service_quotes,public_id'],
33
34
  'cash' => ['sometimes', 'boolean'],
34
35
  'pickup' => ['sometimes', 'boolean'],
35
36
  ];
@@ -44,7 +44,7 @@ class Cart extends FleetbaseResource
44
44
  $items = $this->items ?? [];
45
45
 
46
46
  return array_map(function ($cartItem) {
47
- $product = Product::select(['public_id', 'primary_image_uuid', 'name', 'description'])->where('public_id', data_get($cartItem, 'product_id'))->first();
47
+ $product = Product::select(['uuid', 'public_id', 'primary_image_uuid', 'name', 'description'])->with(['files'])->where('public_id', data_get($cartItem, 'product_id'))->first();
48
48
  if ($product) {
49
49
  data_set($cartItem, 'name', $product->name);
50
50
  data_set($cartItem, 'description', $product->description);
@@ -310,7 +310,7 @@ class Store extends StorefrontModel
310
310
  *
311
311
  * @param string $id the ID of the network for which the category is to be retrieved
312
312
  *
313
- * @return \Fleetbase\Models\Category|null the category of the store in the given network, or null if the store does not belong to the network
313
+ * @return Category|null the category of the store in the given network, or null if the store does not belong to the network
314
314
  */
315
315
  public function getNetworkCategoryUsingId(?string $id)
316
316
  {
@@ -334,7 +334,7 @@ class Store extends StorefrontModel
334
334
  *
335
335
  * @param Network $network the network for which the category is to be retrieved
336
336
  *
337
- * @return \Fleetbase\Models\Category|null the category of the store in the given network, or null if the store does not belong to the network
337
+ * @return Category|null the category of the store in the given network, or null if the store does not belong to the network
338
338
  */
339
339
  public function getNetworkCategory(Network $network)
340
340
  {
@@ -3,6 +3,7 @@
3
3
  namespace Fleetbase\Storefront\Observers;
4
4
 
5
5
  use Fleetbase\FleetOps\Models\Order;
6
+ use Fleetbase\Storefront\Support\Storefront;
6
7
 
7
8
  class OrderObserver
8
9
  {
@@ -11,7 +12,12 @@ class OrderObserver
11
12
  *
12
13
  * @return void
13
14
  */
14
- public function created(Order $order)
15
+ public function creating(Order $order)
15
16
  {
17
+ // Set the storefront order config
18
+ $orderConfig = Storefront::getDefaultOrderConfig();
19
+ if ($orderConfig) {
20
+ $order->order_config_uuid = $orderConfig->uuid;
21
+ }
16
22
  }
17
23
  }
@@ -20,12 +20,12 @@ class IsValidLocation implements Rule
20
20
  public function passes($attribute, $value)
21
21
  {
22
22
  // Validate Place id
23
- if (Str::startsWith($value, 'place_')) {
23
+ if (is_string($value) && Str::startsWith($value, 'place_')) {
24
24
  return Place::where('public_id', $value)->exists();
25
25
  }
26
26
 
27
27
  // Validate StoreLocation id
28
- if (Str::startsWith($value, 'store_location_')) {
28
+ if (is_string($value) && Str::startsWith($value, 'store_location_')) {
29
29
  return StoreLocation::where('public_id', $value)->exists();
30
30
  }
31
31
 
@@ -12,6 +12,7 @@ use Fleetbase\Storefront\Models\Network;
12
12
  use Fleetbase\Storefront\Models\Product;
13
13
  use Fleetbase\Storefront\Models\Store;
14
14
  use Fleetbase\Storefront\Notifications\StorefrontOrderCreated;
15
+ use Fleetbase\Support\Auth;
15
16
  use Fleetbase\Support\Utils;
16
17
  use Illuminate\Support\Facades\Notification;
17
18
  use Illuminate\Support\Facades\Redis;
@@ -203,6 +204,39 @@ class Storefront
203
204
  return $stripeCustomer;
204
205
  }
205
206
 
207
+ public static function patchOrderConfig(Order $order)
208
+ {
209
+ $orderConfig = $order->config();
210
+ if (!$orderConfig) {
211
+ $orderConfig = Storefront::getDefaultOrderConfig();
212
+ if ($orderConfig) {
213
+ $order->update(['order_config_uuid' => $orderConfig->uuid]);
214
+ }
215
+ }
216
+
217
+ return $orderConfig;
218
+ }
219
+
220
+ public static function getDefaultOrderConfig()
221
+ {
222
+ $company = Auth::getCompany();
223
+ if ($company) {
224
+ return static::getOrderConfig($company);
225
+ }
226
+
227
+ return null;
228
+ }
229
+
230
+ public static function getOrderConfig(Company $company)
231
+ {
232
+ $orderConfig = OrderConfig::where(['company_uuid' => $company->uuid, 'key' => 'storefront', 'namespace' => 'system:order-config:storefront'])->first();
233
+ if (!$orderConfig) {
234
+ $orderConfig = static::createStorefrontConfig($company);
235
+ }
236
+
237
+ return $orderConfig;
238
+ }
239
+
206
240
  /**
207
241
  * Creates or retrieves an existing storefront configuration for a given company.
208
242
  *