@fleetbase/storefront-engine 0.1.6 → 0.1.8

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 (333) hide show
  1. package/.php-cs-fixer.php +29 -0
  2. package/LICENSE.md +16 -4
  3. package/README.md +106 -13
  4. package/addon/components/modals/add-store-to-category.hbs +5 -0
  5. package/addon/components/modals/create-network-category.hbs +28 -28
  6. package/addon/components/modals/share-network.hbs +3 -3
  7. package/addon/components/modals/store-details.hbs +22 -0
  8. package/addon/components/modals/store-form.hbs +22 -0
  9. package/addon/components/modals/store-form.js +21 -0
  10. package/addon/components/network-category-picker.hbs +40 -0
  11. package/addon/components/network-category-picker.js +83 -0
  12. package/addon/components/store-selector.hbs +4 -2
  13. package/addon/components/widget/orders.js +22 -17
  14. package/addon/controllers/networks/index/network/index.js +133 -9
  15. package/addon/controllers/networks/index/network/stores.js +422 -153
  16. package/addon/controllers/networks/index.js +66 -4
  17. package/addon/controllers/products/index/category.js +1 -1
  18. package/addon/controllers/settings/index.js +14 -7
  19. package/addon/controllers/settings/notifications.js +1 -1
  20. package/addon/models/store.js +44 -7
  21. package/addon/routes/networks/index/network/customers.js +4 -1
  22. package/addon/routes/networks/index/network/orders.js +4 -1
  23. package/addon/routes/networks/index/network/stores.js +19 -15
  24. package/addon/serializers/store.js +1 -0
  25. package/addon/templates/customers/index.hbs +0 -11
  26. package/addon/templates/networks/index/network/index.hbs +1 -1
  27. package/addon/templates/networks/index/network/stores.hbs +8 -163
  28. package/addon/templates/networks/index/network.hbs +2 -3
  29. package/addon/utils/create-shareable-link.js +21 -0
  30. package/app/adapters/addon-category.js +1 -1
  31. package/app/adapters/gateway.js +1 -1
  32. package/app/adapters/network.js +1 -1
  33. package/app/adapters/notification-channel.js +1 -1
  34. package/app/adapters/product-addon-category.js +1 -1
  35. package/app/adapters/product-addon.js +1 -1
  36. package/app/adapters/product-hour.js +1 -1
  37. package/app/adapters/product-store-location.js +1 -1
  38. package/app/adapters/product-variant-option.js +1 -1
  39. package/app/adapters/product-variant.js +1 -1
  40. package/app/adapters/product.js +1 -1
  41. package/app/adapters/store-hour.js +1 -1
  42. package/app/adapters/store-location.js +1 -1
  43. package/app/adapters/store.js +1 -1
  44. package/app/adapters/storefront.js +1 -1
  45. package/app/components/file-record.js +1 -1
  46. package/app/components/modals/add-store-hours.js +1 -1
  47. package/app/components/modals/add-store-to-category.js +1 -0
  48. package/app/components/modals/add-stores-to-network.js +1 -1
  49. package/app/components/modals/assign-driver.js +1 -1
  50. package/app/components/modals/create-first-store.js +1 -1
  51. package/app/components/modals/create-gateway.js +1 -1
  52. package/app/components/modals/create-network-category.js +1 -1
  53. package/app/components/modals/create-network.js +1 -1
  54. package/app/components/modals/create-new-variant.js +1 -1
  55. package/app/components/modals/create-notification-channel.js +1 -1
  56. package/app/components/modals/create-product-category.js +1 -1
  57. package/app/components/modals/create-store.js +1 -1
  58. package/app/components/modals/edit-network.js +1 -1
  59. package/app/components/modals/import-products.js +1 -1
  60. package/app/components/modals/incoming-order.js +1 -1
  61. package/app/components/modals/manage-addons.js +1 -1
  62. package/app/components/modals/order-ready-assign-driver.js +1 -1
  63. package/app/components/modals/select-addon-category.js +1 -1
  64. package/app/components/modals/share-network.js +1 -1
  65. package/app/components/modals/store-details.js +1 -0
  66. package/app/components/modals/store-form.js +1 -0
  67. package/app/components/modals/store-location-form.js +1 -1
  68. package/app/components/network-category-picker.js +1 -0
  69. package/app/components/order-card.js +1 -1
  70. package/app/components/schedule-manager.js +1 -1
  71. package/app/components/settings-container.js +1 -1
  72. package/app/components/store-selector.js +1 -1
  73. package/app/components/widget/customers.js +1 -1
  74. package/app/components/widget/orders.js +1 -1
  75. package/app/components/widget/storefront-metrics.js +1 -1
  76. package/app/controllers/application.js +1 -1
  77. package/app/controllers/customers/index.js +1 -1
  78. package/app/controllers/home.js +1 -1
  79. package/app/controllers/networks/index/network/customers.js +1 -1
  80. package/app/controllers/networks/index/network/index.js +1 -1
  81. package/app/controllers/networks/index/network/orders.js +1 -1
  82. package/app/controllers/networks/index/network/stores.js +1 -1
  83. package/app/controllers/networks/index/network.js +1 -1
  84. package/app/controllers/networks/index.js +1 -1
  85. package/app/controllers/orders/index.js +1 -1
  86. package/app/controllers/products/index/category/edit.js +1 -1
  87. package/app/controllers/products/index/category/new.js +1 -1
  88. package/app/controllers/products/index/category.js +1 -1
  89. package/app/controllers/products/index/index/edit.js +1 -1
  90. package/app/controllers/products/index/index.js +1 -1
  91. package/app/controllers/products/index.js +1 -1
  92. package/app/controllers/settings/api.js +1 -1
  93. package/app/controllers/settings/gateways.js +1 -1
  94. package/app/controllers/settings/index.js +1 -1
  95. package/app/controllers/settings/locations.js +1 -1
  96. package/app/controllers/settings/notifications.js +1 -1
  97. package/app/helpers/get-tip-amount.js +1 -1
  98. package/app/models/addon-category.js +1 -1
  99. package/app/models/gateway.js +1 -1
  100. package/app/models/network.js +1 -1
  101. package/app/models/notification-channel.js +1 -1
  102. package/app/models/product-addon-category.js +1 -1
  103. package/app/models/product-addon.js +1 -1
  104. package/app/models/product-hour.js +1 -1
  105. package/app/models/product-store-location.js +1 -1
  106. package/app/models/product-variant-option.js +1 -1
  107. package/app/models/product-variant.js +1 -1
  108. package/app/models/product.js +1 -1
  109. package/app/models/store-hour.js +1 -1
  110. package/app/models/store-location.js +1 -1
  111. package/app/models/store.js +1 -1
  112. package/app/routes/application.js +1 -1
  113. package/app/routes/customers/index/edit.js +1 -1
  114. package/app/routes/customers/index.js +1 -1
  115. package/app/routes/home.js +1 -1
  116. package/app/routes/networks/index/network/customers.js +1 -1
  117. package/app/routes/networks/index/network/index.js +1 -1
  118. package/app/routes/networks/index/network/orders.js +1 -1
  119. package/app/routes/networks/index/network/stores.js +1 -1
  120. package/app/routes/networks/index/network.js +1 -1
  121. package/app/routes/networks/index.js +1 -1
  122. package/app/routes/orders/index/edit.js +1 -1
  123. package/app/routes/orders/index/new.js +1 -1
  124. package/app/routes/orders/index/view.js +1 -1
  125. package/app/routes/orders/index.js +1 -1
  126. package/app/routes/products/index/category/edit.js +1 -1
  127. package/app/routes/products/index/category/new.js +1 -1
  128. package/app/routes/products/index/category.js +1 -1
  129. package/app/routes/products/index/index/edit.js +1 -1
  130. package/app/routes/products/index/index.js +1 -1
  131. package/app/routes/products/index.js +1 -1
  132. package/app/routes/settings/api.js +1 -1
  133. package/app/routes/settings/gateways.js +1 -1
  134. package/app/routes/settings/index.js +1 -1
  135. package/app/routes/settings/locations.js +1 -1
  136. package/app/routes/settings/notifications.js +1 -1
  137. package/app/serializers/addon-category.js +1 -1
  138. package/app/serializers/network.js +1 -1
  139. package/app/serializers/notification-channel.js +1 -1
  140. package/app/serializers/product-addon-category.js +1 -1
  141. package/app/serializers/product-variant.js +1 -1
  142. package/app/serializers/product.js +1 -1
  143. package/app/serializers/store-location.js +1 -1
  144. package/app/serializers/store.js +1 -1
  145. package/app/services/storefront.js +1 -1
  146. package/app/templates/customers/index/edit.js +1 -1
  147. package/app/templates/customers/index.js +1 -1
  148. package/app/templates/home.js +1 -1
  149. package/app/templates/networks/index/network/customers.js +1 -1
  150. package/app/templates/networks/index/network/index.js +1 -1
  151. package/app/templates/networks/index/network/orders.js +1 -1
  152. package/app/templates/networks/index/network/stores.js +1 -1
  153. package/app/templates/networks/index/network.js +1 -1
  154. package/app/templates/networks/index.js +1 -1
  155. package/app/templates/orders/index/edit.js +1 -1
  156. package/app/templates/orders/index/new.js +1 -1
  157. package/app/templates/orders/index/view.js +1 -1
  158. package/app/templates/orders/index.js +1 -1
  159. package/app/templates/products/index/category/edit.js +1 -1
  160. package/app/templates/products/index/category/new.js +1 -1
  161. package/app/templates/products/index/category.js +1 -1
  162. package/app/templates/products/index/index/edit.js +1 -1
  163. package/app/templates/products/index/index.js +1 -1
  164. package/app/templates/products/index.js +1 -1
  165. package/app/templates/settings/api.js +1 -1
  166. package/app/templates/settings/gateways.js +1 -1
  167. package/app/templates/settings/index.js +1 -1
  168. package/app/templates/settings/locations.js +1 -1
  169. package/app/templates/settings/notifications.js +1 -1
  170. package/app/templates/settings.js +1 -1
  171. package/app/utils/create-shareable-link.js +1 -0
  172. package/app/utils/get-gateway-schemas.js +1 -1
  173. package/app/utils/get-notification-schemas.js +1 -1
  174. package/composer.json +88 -0
  175. package/extension.json +10 -0
  176. package/package.json +6 -7
  177. package/phpstan.neon.dist +8 -0
  178. package/phpunit.xml.dist +16 -0
  179. package/server/.gitattributes +14 -0
  180. package/server/README.md +40 -0
  181. package/server/config/api.php +101 -0
  182. package/server/config/database.connections.php +57 -0
  183. package/server/config/storefront.php +19 -0
  184. package/server/config/twilio-notification-channel.php +36 -0
  185. package/server/migrations/2023_05_03_025307_create_carts_table.php +44 -0
  186. package/server/migrations/2023_05_03_025307_create_checkouts_table.php +51 -0
  187. package/server/migrations/2023_05_03_025307_create_gateways_table.php +48 -0
  188. package/server/migrations/2023_05_03_025307_create_network_stores_table.php +36 -0
  189. package/server/migrations/2023_05_03_025307_create_networks_table.php +56 -0
  190. package/server/migrations/2023_05_03_025307_create_notification_channels_table.php +43 -0
  191. package/server/migrations/2023_05_03_025307_create_payment_methods_table.php +44 -0
  192. package/server/migrations/2023_05_03_025307_create_product_addon_categories_table.php +38 -0
  193. package/server/migrations/2023_05_03_025307_create_product_addons_table.php +43 -0
  194. package/server/migrations/2023_05_03_025307_create_product_hours_table.php +37 -0
  195. package/server/migrations/2023_05_03_025307_create_product_store_locations_table.php +34 -0
  196. package/server/migrations/2023_05_03_025307_create_product_variant_options_table.php +40 -0
  197. package/server/migrations/2023_05_03_025307_create_product_variants_table.php +44 -0
  198. package/server/migrations/2023_05_03_025307_create_products_table.php +59 -0
  199. package/server/migrations/2023_05_03_025307_create_reviews_table.php +41 -0
  200. package/server/migrations/2023_05_03_025307_create_store_hours_table.php +37 -0
  201. package/server/migrations/2023_05_03_025307_create_store_locations_table.php +38 -0
  202. package/server/migrations/2023_05_03_025307_create_stores_table.php +57 -0
  203. package/server/migrations/2023_05_03_025307_create_votes_table.php +39 -0
  204. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_carts_table.php +40 -0
  205. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_checkouts_table.php +48 -0
  206. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_gateways_table.php +40 -0
  207. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_network_stores_table.php +40 -0
  208. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_networks_table.php +42 -0
  209. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_notification_channels_table.php +40 -0
  210. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_payment_methods_table.php +40 -0
  211. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addon_categories_table.php +38 -0
  212. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addons_table.php +38 -0
  213. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_hours_table.php +32 -0
  214. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_store_locations_table.php +34 -0
  215. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variant_options_table.php +32 -0
  216. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variants_table.php +32 -0
  217. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_products_table.php +44 -0
  218. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_reviews_table.php +38 -0
  219. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_hours_table.php +32 -0
  220. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_locations_table.php +40 -0
  221. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_stores_table.php +42 -0
  222. package/server/migrations/2023_05_03_025310_add_foreign_keys_to_votes_table.php +38 -0
  223. package/server/src/Auth/Schemas/Storefront.php +95 -0
  224. package/server/src/Console/Commands/NotifyStorefrontOrderNearby.php +86 -0
  225. package/server/src/Expansions/EntityExpansion.php +44 -0
  226. package/server/src/Http/Controllers/ActionController.php +119 -0
  227. package/server/src/Http/Controllers/AddonCategoryController.php +13 -0
  228. package/server/src/Http/Controllers/CustomerController.php +13 -0
  229. package/server/src/Http/Controllers/GatewayController.php +13 -0
  230. package/server/src/Http/Controllers/MetricsController.php +71 -0
  231. package/server/src/Http/Controllers/NetworkController.php +170 -0
  232. package/server/src/Http/Controllers/NotificationChannelController.php +13 -0
  233. package/server/src/Http/Controllers/OrderController.php +154 -0
  234. package/server/src/Http/Controllers/ProductAddonCategoryController.php +14 -0
  235. package/server/src/Http/Controllers/ProductAddonController.php +14 -0
  236. package/server/src/Http/Controllers/ProductController.php +123 -0
  237. package/server/src/Http/Controllers/ProductHourController.php +13 -0
  238. package/server/src/Http/Controllers/ProductVariantController.php +13 -0
  239. package/server/src/Http/Controllers/ProductVariantOptionController.php +13 -0
  240. package/server/src/Http/Controllers/ReviewController.php +13 -0
  241. package/server/src/Http/Controllers/StoreController.php +26 -0
  242. package/server/src/Http/Controllers/StoreHourController.php +13 -0
  243. package/server/src/Http/Controllers/StoreLocationController.php +13 -0
  244. package/server/src/Http/Controllers/StorefrontController.php +15 -0
  245. package/server/src/Http/Controllers/VoteController.php +13 -0
  246. package/server/src/Http/Controllers/v1/CartController.php +161 -0
  247. package/server/src/Http/Controllers/v1/CategoryController.php +138 -0
  248. package/server/src/Http/Controllers/v1/CheckoutController.php +957 -0
  249. package/server/src/Http/Controllers/v1/CustomerController.php +482 -0
  250. package/server/src/Http/Controllers/v1/GatewayControllerController.php +11 -0
  251. package/server/src/Http/Controllers/v1/NetworkController.php +281 -0
  252. package/server/src/Http/Controllers/v1/PaymentMethodController.php +11 -0
  253. package/server/src/Http/Controllers/v1/ProductController.php +94 -0
  254. package/server/src/Http/Controllers/v1/ReviewController.php +270 -0
  255. package/server/src/Http/Controllers/v1/ServiceQuoteController.php +402 -0
  256. package/server/src/Http/Controllers/v1/StoreController.php +176 -0
  257. package/server/src/Http/Filter/AddonCategoryFilter.php +19 -0
  258. package/server/src/Http/Filter/CustomerFilter.php +18 -0
  259. package/server/src/Http/Filter/GatewayFilter.php +13 -0
  260. package/server/src/Http/Filter/NetworkFilter.php +18 -0
  261. package/server/src/Http/Filter/NotificationChannelFilter.php +13 -0
  262. package/server/src/Http/Filter/OrderFilter.php +46 -0
  263. package/server/src/Http/Filter/ProductFilter.php +28 -0
  264. package/server/src/Http/Filter/StoreFilter.php +42 -0
  265. package/server/src/Http/Filter/StoreLocationFilter.php +23 -0
  266. package/server/src/Http/Middleware/SetStorefrontSession.php +130 -0
  267. package/server/src/Http/Requests/AddStoreToNetworkCategory.php +45 -0
  268. package/server/src/Http/Requests/CaptureOrderRequest.php +30 -0
  269. package/server/src/Http/Requests/CreateCustomerRequest.php +44 -0
  270. package/server/src/Http/Requests/CreateReviewRequest.php +34 -0
  271. package/server/src/Http/Requests/GetServiceQuoteFromCart.php +40 -0
  272. package/server/src/Http/Requests/InitializeCheckoutRequest.php +38 -0
  273. package/server/src/Http/Requests/NetworkActionRequest.php +43 -0
  274. package/server/src/Http/Requests/VerifyCreateCustomerRequest.php +31 -0
  275. package/server/src/Http/Resources/Cart.php +31 -0
  276. package/server/src/Http/Resources/Category.php +48 -0
  277. package/server/src/Http/Resources/Customer.php +36 -0
  278. package/server/src/Http/Resources/Gateway.php +32 -0
  279. package/server/src/Http/Resources/Media.php +29 -0
  280. package/server/src/Http/Resources/Network.php +48 -0
  281. package/server/src/Http/Resources/Product.php +209 -0
  282. package/server/src/Http/Resources/Review.php +45 -0
  283. package/server/src/Http/Resources/ReviewCustomer.php +60 -0
  284. package/server/src/Http/Resources/Store.php +76 -0
  285. package/server/src/Http/Resources/StoreHour.php +29 -0
  286. package/server/src/Http/Resources/StoreLocation.php +33 -0
  287. package/server/src/Imports/ProductsImport.php +20 -0
  288. package/server/src/Jobs/DownloadProductImageUrl.php +60 -0
  289. package/server/src/Listeners/HandleOrderCompleted.php +31 -0
  290. package/server/src/Listeners/HandleOrderDispatched.php +34 -0
  291. package/server/src/Listeners/HandleOrderDriverAssigned.php +37 -0
  292. package/server/src/Listeners/HandleOrderStarted.php +27 -0
  293. package/server/src/Mail/StorefrontNetworkInvite.php +48 -0
  294. package/server/src/Models/AddonCategory.php +30 -0
  295. package/server/src/Models/Cart.php +691 -0
  296. package/server/src/Models/Checkout.php +166 -0
  297. package/server/src/Models/Customer.php +88 -0
  298. package/server/src/Models/Gateway.php +165 -0
  299. package/server/src/Models/Network.php +300 -0
  300. package/server/src/Models/NetworkStore.php +86 -0
  301. package/server/src/Models/NotificationChannel.php +147 -0
  302. package/server/src/Models/PaymentMethod.php +99 -0
  303. package/server/src/Models/Product.php +315 -0
  304. package/server/src/Models/ProductAddon.php +128 -0
  305. package/server/src/Models/ProductAddonCategory.php +90 -0
  306. package/server/src/Models/ProductHour.php +59 -0
  307. package/server/src/Models/ProductStoreLocation.php +77 -0
  308. package/server/src/Models/ProductVariant.php +125 -0
  309. package/server/src/Models/ProductVariantOption.php +86 -0
  310. package/server/src/Models/Review.php +127 -0
  311. package/server/src/Models/Store.php +478 -0
  312. package/server/src/Models/StoreHour.php +59 -0
  313. package/server/src/Models/StoreLocation.php +126 -0
  314. package/server/src/Models/StorefrontModel.php +22 -0
  315. package/server/src/Models/Vote.php +84 -0
  316. package/server/src/Notifications/StorefrontOrderCanceled.php +196 -0
  317. package/server/src/Notifications/StorefrontOrderCompleted.php +201 -0
  318. package/server/src/Notifications/StorefrontOrderCreated.php +157 -0
  319. package/server/src/Notifications/StorefrontOrderDriverAssigned.php +200 -0
  320. package/server/src/Notifications/StorefrontOrderEnroute.php +199 -0
  321. package/server/src/Notifications/StorefrontOrderNearby.php +201 -0
  322. package/server/src/Notifications/StorefrontOrderPreparing.php +202 -0
  323. package/server/src/Notifications/StorefrontOrderReadyForPickup.php +202 -0
  324. package/server/src/Observers/NetworkObserver.php +40 -0
  325. package/server/src/Observers/ProductObserver.php +118 -0
  326. package/server/src/Providers/EventServiceProvider.php +23 -0
  327. package/server/src/Providers/StorefrontServiceProvider.php +103 -0
  328. package/server/src/Support/Metrics.php +193 -0
  329. package/server/src/Support/OrderConfig.php +13 -0
  330. package/server/src/Support/QPay.php +208 -0
  331. package/server/src/Support/Storefront.php +201 -0
  332. package/server/src/routes.php +180 -0
  333. 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
+ }
@@ -0,0 +1,11 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Storefront\Http\Controllers\v1;
4
+
5
+ use Fleetbase\Http\Controllers\Controller;
6
+ use Illuminate\Http\Request;
7
+
8
+ class GatewayControllerController extends Controller
9
+ {
10
+ //
11
+ }