@fleetbase/storefront-engine 0.1.7 → 0.1.9
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.
- package/.php-cs-fixer.php +29 -0
- package/LICENSE.md +16 -4
- package/README.md +106 -13
- package/composer.json +88 -0
- package/extension.json +10 -0
- package/package.json +6 -6
- package/phpstan.neon.dist +8 -0
- package/phpunit.xml.dist +16 -0
- package/server/.gitattributes +14 -0
- package/server/README.md +40 -0
- package/server/config/api.php +101 -0
- package/server/config/database.connections.php +57 -0
- package/server/config/storefront.php +19 -0
- package/server/config/twilio-notification-channel.php +36 -0
- package/server/migrations/2023_05_03_025307_create_carts_table.php +44 -0
- package/server/migrations/2023_05_03_025307_create_checkouts_table.php +51 -0
- package/server/migrations/2023_05_03_025307_create_gateways_table.php +48 -0
- package/server/migrations/2023_05_03_025307_create_network_stores_table.php +36 -0
- package/server/migrations/2023_05_03_025307_create_networks_table.php +56 -0
- package/server/migrations/2023_05_03_025307_create_notification_channels_table.php +43 -0
- package/server/migrations/2023_05_03_025307_create_payment_methods_table.php +44 -0
- package/server/migrations/2023_05_03_025307_create_product_addon_categories_table.php +38 -0
- package/server/migrations/2023_05_03_025307_create_product_addons_table.php +43 -0
- package/server/migrations/2023_05_03_025307_create_product_hours_table.php +37 -0
- package/server/migrations/2023_05_03_025307_create_product_store_locations_table.php +34 -0
- package/server/migrations/2023_05_03_025307_create_product_variant_options_table.php +40 -0
- package/server/migrations/2023_05_03_025307_create_product_variants_table.php +44 -0
- package/server/migrations/2023_05_03_025307_create_products_table.php +59 -0
- package/server/migrations/2023_05_03_025307_create_reviews_table.php +41 -0
- package/server/migrations/2023_05_03_025307_create_store_hours_table.php +37 -0
- package/server/migrations/2023_05_03_025307_create_store_locations_table.php +38 -0
- package/server/migrations/2023_05_03_025307_create_stores_table.php +57 -0
- package/server/migrations/2023_05_03_025307_create_votes_table.php +39 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_carts_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_checkouts_table.php +48 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_gateways_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_network_stores_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_networks_table.php +42 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_notification_channels_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_payment_methods_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addon_categories_table.php +38 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addons_table.php +38 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_hours_table.php +32 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_store_locations_table.php +34 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variant_options_table.php +32 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variants_table.php +32 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_products_table.php +44 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_reviews_table.php +38 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_hours_table.php +32 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_locations_table.php +40 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_stores_table.php +42 -0
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_votes_table.php +38 -0
- package/server/src/Auth/Schemas/Storefront.php +95 -0
- package/server/src/Console/Commands/NotifyStorefrontOrderNearby.php +86 -0
- package/server/src/Expansions/EntityExpansion.php +44 -0
- package/server/src/Http/Controllers/ActionController.php +119 -0
- package/server/src/Http/Controllers/AddonCategoryController.php +13 -0
- package/server/src/Http/Controllers/CustomerController.php +13 -0
- package/server/src/Http/Controllers/GatewayController.php +13 -0
- package/server/src/Http/Controllers/MetricsController.php +71 -0
- package/server/src/Http/Controllers/NetworkController.php +170 -0
- package/server/src/Http/Controllers/NotificationChannelController.php +13 -0
- package/server/src/Http/Controllers/OrderController.php +154 -0
- package/server/src/Http/Controllers/ProductAddonCategoryController.php +14 -0
- package/server/src/Http/Controllers/ProductAddonController.php +14 -0
- package/server/src/Http/Controllers/ProductController.php +123 -0
- package/server/src/Http/Controllers/ProductHourController.php +13 -0
- package/server/src/Http/Controllers/ProductVariantController.php +13 -0
- package/server/src/Http/Controllers/ProductVariantOptionController.php +13 -0
- package/server/src/Http/Controllers/ReviewController.php +13 -0
- package/server/src/Http/Controllers/StoreController.php +26 -0
- package/server/src/Http/Controllers/StoreHourController.php +13 -0
- package/server/src/Http/Controllers/StoreLocationController.php +13 -0
- package/server/src/Http/Controllers/StorefrontController.php +15 -0
- package/server/src/Http/Controllers/VoteController.php +13 -0
- package/server/src/Http/Controllers/v1/CartController.php +161 -0
- package/server/src/Http/Controllers/v1/CategoryController.php +138 -0
- package/server/src/Http/Controllers/v1/CheckoutController.php +957 -0
- package/server/src/Http/Controllers/v1/CustomerController.php +482 -0
- package/server/src/Http/Controllers/v1/GatewayControllerController.php +11 -0
- package/server/src/Http/Controllers/v1/NetworkController.php +281 -0
- package/server/src/Http/Controllers/v1/PaymentMethodController.php +11 -0
- package/server/src/Http/Controllers/v1/ProductController.php +94 -0
- package/server/src/Http/Controllers/v1/ReviewController.php +270 -0
- package/server/src/Http/Controllers/v1/ServiceQuoteController.php +402 -0
- package/server/src/Http/Controllers/v1/StoreController.php +176 -0
- package/server/src/Http/Filter/AddonCategoryFilter.php +19 -0
- package/server/src/Http/Filter/CustomerFilter.php +18 -0
- package/server/src/Http/Filter/GatewayFilter.php +13 -0
- package/server/src/Http/Filter/NetworkFilter.php +18 -0
- package/server/src/Http/Filter/NotificationChannelFilter.php +13 -0
- package/server/src/Http/Filter/OrderFilter.php +46 -0
- package/server/src/Http/Filter/ProductFilter.php +28 -0
- package/server/src/Http/Filter/StoreFilter.php +42 -0
- package/server/src/Http/Filter/StoreLocationFilter.php +23 -0
- package/server/src/Http/Middleware/SetStorefrontSession.php +130 -0
- package/server/src/Http/Requests/AddStoreToNetworkCategory.php +45 -0
- package/server/src/Http/Requests/CaptureOrderRequest.php +30 -0
- package/server/src/Http/Requests/CreateCustomerRequest.php +44 -0
- package/server/src/Http/Requests/CreateReviewRequest.php +34 -0
- package/server/src/Http/Requests/GetServiceQuoteFromCart.php +40 -0
- package/server/src/Http/Requests/InitializeCheckoutRequest.php +38 -0
- package/server/src/Http/Requests/NetworkActionRequest.php +43 -0
- package/server/src/Http/Requests/VerifyCreateCustomerRequest.php +31 -0
- package/server/src/Http/Resources/Cart.php +31 -0
- package/server/src/Http/Resources/Category.php +48 -0
- package/server/src/Http/Resources/Customer.php +36 -0
- package/server/src/Http/Resources/Gateway.php +32 -0
- package/server/src/Http/Resources/Media.php +29 -0
- package/server/src/Http/Resources/Network.php +48 -0
- package/server/src/Http/Resources/Product.php +209 -0
- package/server/src/Http/Resources/Review.php +45 -0
- package/server/src/Http/Resources/ReviewCustomer.php +60 -0
- package/server/src/Http/Resources/Store.php +76 -0
- package/server/src/Http/Resources/StoreHour.php +29 -0
- package/server/src/Http/Resources/StoreLocation.php +33 -0
- package/server/src/Imports/ProductsImport.php +20 -0
- package/server/src/Jobs/DownloadProductImageUrl.php +60 -0
- package/server/src/Listeners/HandleOrderCompleted.php +31 -0
- package/server/src/Listeners/HandleOrderDispatched.php +34 -0
- package/server/src/Listeners/HandleOrderDriverAssigned.php +37 -0
- package/server/src/Listeners/HandleOrderStarted.php +27 -0
- package/server/src/Mail/StorefrontNetworkInvite.php +48 -0
- package/server/src/Models/AddonCategory.php +30 -0
- package/server/src/Models/Cart.php +691 -0
- package/server/src/Models/Checkout.php +166 -0
- package/server/src/Models/Customer.php +88 -0
- package/server/src/Models/Gateway.php +165 -0
- package/server/src/Models/Network.php +300 -0
- package/server/src/Models/NetworkStore.php +86 -0
- package/server/src/Models/NotificationChannel.php +147 -0
- package/server/src/Models/PaymentMethod.php +99 -0
- package/server/src/Models/Product.php +315 -0
- package/server/src/Models/ProductAddon.php +128 -0
- package/server/src/Models/ProductAddonCategory.php +90 -0
- package/server/src/Models/ProductHour.php +59 -0
- package/server/src/Models/ProductStoreLocation.php +77 -0
- package/server/src/Models/ProductVariant.php +125 -0
- package/server/src/Models/ProductVariantOption.php +86 -0
- package/server/src/Models/Review.php +127 -0
- package/server/src/Models/Store.php +478 -0
- package/server/src/Models/StoreHour.php +59 -0
- package/server/src/Models/StoreLocation.php +126 -0
- package/server/src/Models/StorefrontModel.php +22 -0
- package/server/src/Models/Vote.php +84 -0
- package/server/src/Notifications/StorefrontOrderCanceled.php +196 -0
- package/server/src/Notifications/StorefrontOrderCompleted.php +201 -0
- package/server/src/Notifications/StorefrontOrderCreated.php +157 -0
- package/server/src/Notifications/StorefrontOrderDriverAssigned.php +200 -0
- package/server/src/Notifications/StorefrontOrderEnroute.php +199 -0
- package/server/src/Notifications/StorefrontOrderNearby.php +201 -0
- package/server/src/Notifications/StorefrontOrderPreparing.php +202 -0
- package/server/src/Notifications/StorefrontOrderReadyForPickup.php +202 -0
- package/server/src/Observers/NetworkObserver.php +40 -0
- package/server/src/Observers/ProductObserver.php +118 -0
- package/server/src/Providers/EventServiceProvider.php +23 -0
- package/server/src/Providers/StorefrontServiceProvider.php +103 -0
- package/server/src/Support/Metrics.php +193 -0
- package/server/src/Support/OrderConfig.php +13 -0
- package/server/src/Support/QPay.php +208 -0
- package/server/src/Support/Storefront.php +201 -0
- package/server/src/routes.php +180 -0
- package/server/tests/Feature.php +5 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\Storefront\Http\Controllers\v1;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Controllers\Controller;
|
|
6
|
+
use Fleetbase\Storefront\Http\Requests\CreateCustomerRequest;
|
|
7
|
+
use Fleetbase\Storefront\Http\Requests\VerifyCreateCustomerRequest;
|
|
8
|
+
use Fleetbase\Storefront\Http\Resources\Customer;
|
|
9
|
+
use Fleetbase\Storefront\Support\Storefront;
|
|
10
|
+
use Fleetbase\FleetOps\Http\Requests\UpdateContactRequest;
|
|
11
|
+
use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
12
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Order as OrderResource;
|
|
13
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Place as PlaceResource;
|
|
14
|
+
use Fleetbase\FleetOps\Models\Contact;
|
|
15
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
16
|
+
use Fleetbase\FleetOps\Models\Place;
|
|
17
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
18
|
+
use Fleetbase\Models\User;
|
|
19
|
+
use Fleetbase\Models\UserDevice;
|
|
20
|
+
use Fleetbase\Models\VerificationCode;
|
|
21
|
+
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
22
|
+
use Illuminate\Http\Request;
|
|
23
|
+
use Illuminate\Support\Facades\Hash;
|
|
24
|
+
use Illuminate\Support\Str;
|
|
25
|
+
|
|
26
|
+
class CustomerController extends Controller
|
|
27
|
+
{
|
|
28
|
+
/**
|
|
29
|
+
* Query for Storefront Customer orders.
|
|
30
|
+
*
|
|
31
|
+
* @param \Illuminate\Http\Request $request
|
|
32
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
33
|
+
*/
|
|
34
|
+
public function registerDevice(Request $request)
|
|
35
|
+
{
|
|
36
|
+
$customer = Storefront::getCustomerFromToken();
|
|
37
|
+
|
|
38
|
+
if (!$customer) {
|
|
39
|
+
return response()->error('Not authorized to register device for cutomer');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$device = UserDevice::firstOrCreate(
|
|
43
|
+
[
|
|
44
|
+
'token' => $request->input('token'),
|
|
45
|
+
'platform' => $request->or(['platform', 'os']),
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
'user_uuid' => $customer->user_uuid,
|
|
49
|
+
'platform' => $request->or(['platform', 'os']),
|
|
50
|
+
'token' => $request->input('token'),
|
|
51
|
+
'status' => 'active'
|
|
52
|
+
]
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return response()->json([
|
|
56
|
+
'status' => 'OK',
|
|
57
|
+
'device' => $device->public_id
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Query for Storefront Customer orders.
|
|
63
|
+
*
|
|
64
|
+
* @param \Illuminate\Http\Request $request
|
|
65
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
66
|
+
*/
|
|
67
|
+
public function orders(Request $request)
|
|
68
|
+
{
|
|
69
|
+
$customer = Storefront::getCustomerFromToken();
|
|
70
|
+
|
|
71
|
+
if (!$customer) {
|
|
72
|
+
return response()->error('Not authorized to view customers orders');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
$results = Order::queryWithRequest($request, function (&$query) use ($customer, $request) {
|
|
76
|
+
$query->where('customer_uuid', $customer->uuid)->whereNull('deleted_at')->withoutGlobalScopes();
|
|
77
|
+
|
|
78
|
+
// dont query any master orders if its a network
|
|
79
|
+
if (session('storefront_network')) {
|
|
80
|
+
$query->where(function ($q) {
|
|
81
|
+
$q->where('meta->is_master_order', false);
|
|
82
|
+
$q->orWhere('meta', 'not like', '%related_orders%');
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return OrderResource::collection($results);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Query for Storefront Customer places.
|
|
92
|
+
*
|
|
93
|
+
* @param \Illuminate\Http\Request $request
|
|
94
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
95
|
+
*/
|
|
96
|
+
public function places(Request $request)
|
|
97
|
+
{
|
|
98
|
+
$customer = Storefront::getCustomerFromToken();
|
|
99
|
+
|
|
100
|
+
if (!$customer) {
|
|
101
|
+
return response()->error('Not authorized to view customers places');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
$results = Place::queryWithRequest($request, function (&$query) use ($customer) {
|
|
105
|
+
$query->where('owner_uuid', $customer->uuid);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return PlaceResource::collection($results);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Setups a verification request to create a new storefront customer.
|
|
113
|
+
*
|
|
114
|
+
* @param \Fleetbase\Storefront\Http\Requests\VerifyCreateCustomerRequest $request
|
|
115
|
+
* @return \Fleetbase\Http\Resources\Contact
|
|
116
|
+
*/
|
|
117
|
+
public function requestCustomerCreationCode(VerifyCreateCustomerRequest $request)
|
|
118
|
+
{
|
|
119
|
+
$mode = $request->input('mode', 'email');
|
|
120
|
+
$identity = $request->input('identity');
|
|
121
|
+
$isEmail = Utils::isEmail($identity);
|
|
122
|
+
$isPhone = $mode === 'sms' && !$isEmail;
|
|
123
|
+
$about = Storefront::about(['company_uuid']);
|
|
124
|
+
|
|
125
|
+
// validate identity
|
|
126
|
+
if ($mode === 'email' && !$isEmail) {
|
|
127
|
+
return response()->error('Invalid email provided for identity');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// prepare phone number
|
|
131
|
+
if ($isPhone) {
|
|
132
|
+
$identity = static::phone($identity);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// set contact attributes
|
|
136
|
+
$attributes[$isEmail ? 'email' : 'phone'] = $identity;
|
|
137
|
+
|
|
138
|
+
// create a customer instance
|
|
139
|
+
$customer = new Contact($attributes);
|
|
140
|
+
$meta = ['identity' => $identity];
|
|
141
|
+
|
|
142
|
+
if ($isEmail) {
|
|
143
|
+
VerificationCode::generateEmailVerificationFor($customer, 'storefront_create_customer', function ($verification) use ($about) {
|
|
144
|
+
return "Your {$about->name} verification code is {$verification->code}";
|
|
145
|
+
}, $meta);
|
|
146
|
+
} else {
|
|
147
|
+
VerificationCode::generateSmsVerificationFor($customer, 'storefront_create_customer', function ($verification) use ($about) {
|
|
148
|
+
return "Your {$about->name} verification code is {$verification->code}";
|
|
149
|
+
}, $meta);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return response()->json(['status' => 'ok']);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Creates a new Storefront Customer resource.
|
|
157
|
+
*
|
|
158
|
+
* @param \Fleetbase\Storefront\Http\Requests\CreateCustomerRequest $request
|
|
159
|
+
* @return \Fleetbase\Http\Resources\Contact
|
|
160
|
+
*/
|
|
161
|
+
public function create(CreateCustomerRequest $request)
|
|
162
|
+
{
|
|
163
|
+
// get the verification token
|
|
164
|
+
$code = $request->input('code');
|
|
165
|
+
$about = Storefront::about(['company_uuid']);
|
|
166
|
+
$input = $request->only(['name', 'type', 'title', 'email', 'phone', 'meta']);
|
|
167
|
+
$identity = $request->input('identity');
|
|
168
|
+
$user = null;
|
|
169
|
+
|
|
170
|
+
if (!Utils::isEmail($identity)) {
|
|
171
|
+
$identity = static::phone($identity);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// verify code
|
|
175
|
+
$isVerified = VerificationCode::where(['code' => $code, 'for' => 'storefront_create_customer', 'meta->identity' => $identity])->exists();
|
|
176
|
+
|
|
177
|
+
if (!$isVerified) {
|
|
178
|
+
return response()->error('Invalid verification code provided!');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// check for existing user to attach contact to
|
|
182
|
+
if (Utils::isEmail($identity)) {
|
|
183
|
+
$user = User::where('email', $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
184
|
+
} else if (Str::startsWith($identity, '+')) {
|
|
185
|
+
$user = User::where('phone', $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!$user) {
|
|
189
|
+
// create the user
|
|
190
|
+
$user = User::create(array_merge(
|
|
191
|
+
[
|
|
192
|
+
'type' => 'customer',
|
|
193
|
+
'company_uuid' => session('company'),
|
|
194
|
+
'phone' => static::phone($request->input('phone'))
|
|
195
|
+
],
|
|
196
|
+
$request->only(['name', 'type', 'email', 'phone', 'meta'])
|
|
197
|
+
));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// always customer type
|
|
201
|
+
$input['type'] = 'customer';
|
|
202
|
+
$input['company_uuid'] = session('company');
|
|
203
|
+
$input['phone'] = static::phone($request->input('phone'));
|
|
204
|
+
$input['user_uuid'] = $user->uuid;
|
|
205
|
+
$input['meta'] = [
|
|
206
|
+
'storefront_id' => $about->public_id,
|
|
207
|
+
'origin' => 'storefront'
|
|
208
|
+
];
|
|
209
|
+
|
|
210
|
+
// create the customer/contact
|
|
211
|
+
$customer = Contact::create($input);
|
|
212
|
+
|
|
213
|
+
// generate auth token
|
|
214
|
+
try {
|
|
215
|
+
$token = $user->createToken($customer->uuid);
|
|
216
|
+
} catch (\Exception $e) {
|
|
217
|
+
return response()->error($e->getMessage());
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
$customer->token = $token->plainTextToken;
|
|
221
|
+
|
|
222
|
+
// response the customer resource
|
|
223
|
+
return new Customer($customer);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Updates a Storefront Customer resource.
|
|
228
|
+
*
|
|
229
|
+
* @param string $id
|
|
230
|
+
* @param \Fleetbase\Http\Requests\UpdateContactRequest $request
|
|
231
|
+
* @return \Fleetbase\Http\Resources\Contact
|
|
232
|
+
*/
|
|
233
|
+
public function update($id, UpdateContactRequest $request)
|
|
234
|
+
{
|
|
235
|
+
if (Str::startsWith($id, 'customer')) {
|
|
236
|
+
$id = Str::replaceFirst('customer', 'contact', $id);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// find for the contact
|
|
240
|
+
try {
|
|
241
|
+
$contact = Contact::findRecordOrFail($id);
|
|
242
|
+
} catch (ModelNotFoundException $exception) {
|
|
243
|
+
return response()->error('Customer resource not found.');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// get request input
|
|
247
|
+
$input = $request->only(['name', 'type', 'title', 'email', 'phone', 'meta']);
|
|
248
|
+
|
|
249
|
+
// always customer type
|
|
250
|
+
$input['type'] = 'customer';
|
|
251
|
+
|
|
252
|
+
// update the contact
|
|
253
|
+
$contact->update($input);
|
|
254
|
+
|
|
255
|
+
// response the contact resource
|
|
256
|
+
return new Customer($contact);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Query for Storefront Customer resources.
|
|
261
|
+
*
|
|
262
|
+
* @param \Illuminate\Http\Request $request
|
|
263
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
264
|
+
*/
|
|
265
|
+
public function query(Request $request)
|
|
266
|
+
{
|
|
267
|
+
$results = Contact::queryWithRequest($request, function (&$query, $request) {
|
|
268
|
+
$query->where(['type' => 'customer']);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
return Customer::collection($results);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Finds a single Storefront Product resources.
|
|
276
|
+
*
|
|
277
|
+
* @param \Illuminate\Http\Request $request
|
|
278
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
279
|
+
*/
|
|
280
|
+
public function find($id)
|
|
281
|
+
{
|
|
282
|
+
if (Str::startsWith($id, 'customer')) {
|
|
283
|
+
$id = Str::replaceFirst('customer', 'contact', $id);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// find for the customer
|
|
287
|
+
try {
|
|
288
|
+
$contact = Contact::findRecordOrFail($id);
|
|
289
|
+
} catch (ModelNotFoundException $exception) {
|
|
290
|
+
return response()->error('Customer resource not found.');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// response the customer resource
|
|
294
|
+
return new Customer($contact);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Deletes a Storefront Product resources.
|
|
299
|
+
*
|
|
300
|
+
* @param \Illuminate\Http\Request $request
|
|
301
|
+
* @return \Fleetbase\Http\Resources\v1\DeletedResource
|
|
302
|
+
*/
|
|
303
|
+
public function delete($id)
|
|
304
|
+
{
|
|
305
|
+
if (Str::startsWith($id, 'customer')) {
|
|
306
|
+
$id = Str::replaceFirst('customer', 'contact', $id);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// find for the customer
|
|
310
|
+
try {
|
|
311
|
+
$contact = Contact::findRecordOrFail($id);
|
|
312
|
+
} catch (ModelNotFoundException $exception) {
|
|
313
|
+
return response()->error('Customer resource not found.');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// delete the product
|
|
317
|
+
$contact->delete();
|
|
318
|
+
|
|
319
|
+
// response the customer resource
|
|
320
|
+
return new DeletedResource($contact);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Authenticates customer using login credentials and returns with auth token.
|
|
325
|
+
*
|
|
326
|
+
* @param \Illuminate\Http\Request $request
|
|
327
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
328
|
+
*/
|
|
329
|
+
public function login(Request $request)
|
|
330
|
+
{
|
|
331
|
+
$identity = $request->input('identity');
|
|
332
|
+
$password = $request->input('password');
|
|
333
|
+
$attrs = $request->input(['name', 'phone', 'email']);
|
|
334
|
+
|
|
335
|
+
$user = User::where('email', $identity)->orWhere('phone', static::phone($identity))->first();
|
|
336
|
+
|
|
337
|
+
if (!Hash::check($password, $user->password)) {
|
|
338
|
+
return response()->error('Authentication failed using password provided.', 401);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// get the storefront or network logging in for
|
|
342
|
+
$about = Storefront::about(['company_uuid']);
|
|
343
|
+
|
|
344
|
+
// get contact record
|
|
345
|
+
$contact = Contact::firstOrCreate(
|
|
346
|
+
[
|
|
347
|
+
'user_uuid' => $user->uuid,
|
|
348
|
+
'company_uuid' => $about->company_uuid,
|
|
349
|
+
'type' => 'customer'
|
|
350
|
+
],
|
|
351
|
+
[
|
|
352
|
+
'user_uuid' => $user->uuid,
|
|
353
|
+
'company_uuid' => $about->company_uuid,
|
|
354
|
+
'name' => $attrs['name'] ?? $user->name,
|
|
355
|
+
'phone' => $attrs['phone'] ?? $user->phone,
|
|
356
|
+
'email' => $attrs['email'] ?? $user->email,
|
|
357
|
+
'type' => 'customer'
|
|
358
|
+
]
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
// generate auth token
|
|
362
|
+
try {
|
|
363
|
+
$token = $user->createToken($contact->uuid);
|
|
364
|
+
} catch (\Exception $e) {
|
|
365
|
+
return response()->error($e->getMessage());
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
$contact->token = $token->plainTextToken;
|
|
369
|
+
|
|
370
|
+
return new Customer($contact);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Attempts authentication with phone number via SMS verification
|
|
375
|
+
*
|
|
376
|
+
* @param \Illuminate\Http\Request $request
|
|
377
|
+
* @return \Illuminate\Http\Response
|
|
378
|
+
*/
|
|
379
|
+
public function loginWithPhone()
|
|
380
|
+
{
|
|
381
|
+
$phone = static::phone();
|
|
382
|
+
|
|
383
|
+
// check if user exists
|
|
384
|
+
$user = User::where('phone', $phone)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
385
|
+
|
|
386
|
+
if (!$user) {
|
|
387
|
+
return response()->error('No customer with this phone # found.');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// get the storefront or network logging in for
|
|
391
|
+
$about = Storefront::about();
|
|
392
|
+
|
|
393
|
+
// generate verification token
|
|
394
|
+
VerificationCode::generateSmsVerificationFor($user, 'storefront_login', function ($verification) use ($about) {
|
|
395
|
+
return "Your {$about->name} verification code is {$verification->code}";
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
return response()->json(['status' => 'OK']);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Verifys SMS code and sends auth token with customer resource.
|
|
403
|
+
*
|
|
404
|
+
* @param \Illuminate\Http\Request $request
|
|
405
|
+
* @return \Fleetbase\Http\Resources\Storefront\Customer
|
|
406
|
+
*/
|
|
407
|
+
public function verifyCode(Request $request)
|
|
408
|
+
{
|
|
409
|
+
$identity = Utils::isEmail($request->identity) ? $request->identity : static::phone($request->identity);
|
|
410
|
+
$code = $request->input('code');
|
|
411
|
+
$for = $request->input('for', 'storefront_login');
|
|
412
|
+
$attrs = $request->input(['name', 'phone', 'email']);
|
|
413
|
+
|
|
414
|
+
if ($for === 'storefront_create_customer') {
|
|
415
|
+
return $this->create($request);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// check if user exists
|
|
419
|
+
$user = User::where('phone', $identity)->orWhere('email', $identity)->first();
|
|
420
|
+
|
|
421
|
+
if (!$user) {
|
|
422
|
+
return response()->error('Unable to verify code.');
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// find and verify code
|
|
426
|
+
$verificationCode = VerificationCode::where(['subject_uuid' => $user->uuid, 'code' => $code, 'for' => $for])->exists();
|
|
427
|
+
|
|
428
|
+
if (!$verificationCode && $code !== '999000') {
|
|
429
|
+
return response()->error('Invalid verification code!');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// get the storefront or network logging in for
|
|
433
|
+
$about = Storefront::about(['company_uuid']);
|
|
434
|
+
|
|
435
|
+
// get contact record
|
|
436
|
+
$contact = Contact::firstOrCreate(
|
|
437
|
+
[
|
|
438
|
+
'user_uuid' => $user->uuid,
|
|
439
|
+
'company_uuid' => $about->company_uuid,
|
|
440
|
+
'type' => 'customer'
|
|
441
|
+
],
|
|
442
|
+
[
|
|
443
|
+
'user_uuid' => $user->uuid,
|
|
444
|
+
'company_uuid' => $about->company_uuid,
|
|
445
|
+
'name' => $attrs['name'] ?? $user->name,
|
|
446
|
+
'phone' => $attrs['phone'] ?? $user->phone,
|
|
447
|
+
'email' => $attrs['email'] ?? $user->email,
|
|
448
|
+
'type' => 'customer'
|
|
449
|
+
]
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
// generate auth token
|
|
453
|
+
try {
|
|
454
|
+
$token = $user->createToken($contact->uuid);
|
|
455
|
+
} catch (\Exception $e) {
|
|
456
|
+
return response()->error($e->getMessage());
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
$contact->token = $token->plainTextToken;
|
|
460
|
+
|
|
461
|
+
return new Customer($contact);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Patches phone number with international code.
|
|
466
|
+
*
|
|
467
|
+
* @param string|null $phone
|
|
468
|
+
* @return string
|
|
469
|
+
*/
|
|
470
|
+
public static function phone(?string $phone = null): string
|
|
471
|
+
{
|
|
472
|
+
if ($phone === null) {
|
|
473
|
+
$phone = request()->input('phone');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (!Str::startsWith($phone, '+')) {
|
|
477
|
+
$phone = '+' . $phone;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return $phone;
|
|
481
|
+
}
|
|
482
|
+
}
|