@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,478 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Storefront\Models;
4
+
5
+ use Fleetbase\Casts\Json;
6
+ use Fleetbase\Models\Category;
7
+ use Fleetbase\Models\User;
8
+ use Fleetbase\Models\Company;
9
+ use Fleetbase\Models\File;
10
+ use Fleetbase\FleetOps\Models\Place;
11
+ use Fleetbase\Support\Utils as FleetbaseUtils;
12
+ use Fleetbase\Traits\HasMetaAttributes;
13
+ use Fleetbase\Traits\HasOptionsAttributes;
14
+ use Fleetbase\Traits\HasUuid;
15
+ use Fleetbase\Traits\HasApiModelBehavior;
16
+ use Fleetbase\Traits\HasPublicid;
17
+ use Fleetbase\Traits\Searchable;
18
+ use Illuminate\Support\Carbon;
19
+ use Illuminate\Support\Str;
20
+ use Spatie\Sluggable\HasSlug;
21
+ use Spatie\Sluggable\SlugOptions;
22
+
23
+ class Store extends StorefrontModel
24
+ {
25
+ use HasUuid, HasPublicid, HasApiModelBehavior, HasOptionsAttributes, HasMetaAttributes, HasSlug, Searchable;
26
+
27
+ /**
28
+ * The type of public Id to generate
29
+ *
30
+ * @var string
31
+ */
32
+ protected $publicIdType = 'store';
33
+
34
+ /**
35
+ * The database table used by the model.
36
+ *
37
+ * @var string
38
+ */
39
+ protected $table = 'stores';
40
+
41
+ /**
42
+ * These attributes that can be queried
43
+ *
44
+ * @var array
45
+ */
46
+ protected $searchableColumns = ['name', 'description', 'tags'];
47
+
48
+ /**
49
+ * The attributes that are mass assignable.
50
+ *
51
+ * @var array
52
+ */
53
+ protected $fillable = ['created_by_uuid', 'company_uuid', 'logo_uuid', 'backdrop_uuid', 'key', 'online', 'name', 'description', 'translations', 'website', 'facebook', 'instagram', 'twitter', 'email', 'phone', 'tags', 'currency', 'meta', 'timezone', 'pod_method', 'options', 'alertable', 'slug'];
54
+
55
+ /**
56
+ * The attributes that should be cast to native types.
57
+ *
58
+ * @var array
59
+ */
60
+ protected $casts = [
61
+ 'options' => Json::class,
62
+ 'meta' => Json::class,
63
+ 'translations' => Json::class,
64
+ 'alertable' => Json::class,
65
+ 'tags' => 'array',
66
+ 'require_account' => 'boolean',
67
+ 'online' => 'boolean'
68
+ ];
69
+
70
+ /**
71
+ * Dynamic attributes that are appended to object
72
+ *
73
+ * @var array
74
+ */
75
+ protected $appends = ['logo_url', 'backdrop_url', 'rating'];
76
+
77
+ /**
78
+ * The attributes excluded from the model's JSON form.
79
+ *
80
+ * @var array
81
+ */
82
+ protected $hidden = ['logo', 'backdrop', 'files'];
83
+
84
+ /**
85
+ * Attributes that is filterable on this model
86
+ *
87
+ * @var array
88
+ */
89
+ protected $filterParams = ['network', 'without_category', 'category', 'category_uuid'];
90
+
91
+ /**
92
+ * @var \Spatie\Sluggable\SlugOptions
93
+ */
94
+ public function getSlugOptions(): SlugOptions
95
+ {
96
+ return SlugOptions::create()
97
+ ->generateSlugsFrom('name')
98
+ ->saveSlugsTo('slug');
99
+ }
100
+
101
+ /** on boot generate key */
102
+ public static function boot()
103
+ {
104
+ parent::boot();
105
+ static::creating(function ($model) {
106
+ $model->key = 'store_' . md5(Str::random(14) . time());
107
+ });
108
+ }
109
+
110
+ /**
111
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
112
+ */
113
+ public function createdBy()
114
+ {
115
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(User::class);
116
+ }
117
+
118
+ /**
119
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
120
+ */
121
+ public function company()
122
+ {
123
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(Company::class);
124
+ }
125
+
126
+ /**
127
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
128
+ */
129
+ public function logo()
130
+ {
131
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(File::class);
132
+ }
133
+
134
+ /**
135
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
136
+ */
137
+ public function files()
138
+ {
139
+ return $this->setConnection(config('fleetbase.connection.db'))->hasMany(File::class, 'subject_uuid');
140
+ }
141
+
142
+ /**
143
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
144
+ */
145
+ public function media()
146
+ {
147
+ return $this->files()
148
+ ->select(
149
+ [
150
+ 'id',
151
+ 'uuid',
152
+ 'public_id',
153
+ 'original_filename',
154
+ 'content_type',
155
+ 'path',
156
+ 'type',
157
+ 'caption',
158
+ 'created_at',
159
+ 'updated_at'
160
+ ]
161
+ )->where('type', 'storefront_store_media');
162
+ }
163
+
164
+ /**
165
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
166
+ */
167
+ public function backdrop()
168
+ {
169
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(File::class);
170
+ }
171
+
172
+ /**
173
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
174
+ */
175
+ public function categories()
176
+ {
177
+ return $this->setConnection(config('fleetbase.connection.db'))->hasMany(Category::class, 'owner_uuid');
178
+ }
179
+
180
+ /**
181
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
182
+ */
183
+ public function products()
184
+ {
185
+ return $this->hasMany(Product::class);
186
+ }
187
+
188
+ /**
189
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
190
+ */
191
+ public function checkouts()
192
+ {
193
+ return $this->hasMany(Checkout::class);
194
+ }
195
+
196
+ /**
197
+ * @return int
198
+ */
199
+ public function getThisMonthCheckoutsCountAttribute()
200
+ {
201
+ return $this->checkouts()->where('created_at', '>=', Carbon::now()->subMonth())->count();
202
+ }
203
+
204
+ /**
205
+ * @return int
206
+ */
207
+ public function get24hCheckoutsCountAttribute()
208
+ {
209
+ return $this->checkouts()->where('created_at', '>=', Carbon::now()->subHours(24))->count();
210
+ }
211
+
212
+ /**
213
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
214
+ */
215
+ public function hours()
216
+ {
217
+ return $this->hasMany(StoreHour::class);
218
+ }
219
+
220
+ /**
221
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
222
+ */
223
+ public function reviews()
224
+ {
225
+ return $this->hasMany(Review::class, 'subject_uuid');
226
+ }
227
+
228
+ /**
229
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
230
+ */
231
+ public function votes()
232
+ {
233
+ return $this->hasMany(Vote::class, 'subject_uuid');
234
+ }
235
+
236
+ /**
237
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
238
+ */
239
+ public function notificationChannels()
240
+ {
241
+ return $this->hasMany(NotificationChannel::class, 'owner_uuid');
242
+ }
243
+
244
+ /**
245
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
246
+ */
247
+ public function gateways()
248
+ {
249
+ return $this->hasMany(Gateway::class, 'owner_uuid');
250
+ }
251
+
252
+ /**
253
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
254
+ */
255
+ public function locations()
256
+ {
257
+ return $this->hasMany(StoreLocation::class);
258
+ }
259
+
260
+ /**
261
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
262
+ */
263
+ public function networkStores()
264
+ {
265
+ return $this->hasMany(NetworkStore::class);
266
+ }
267
+
268
+ /**
269
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
270
+ */
271
+ public function networks()
272
+ {
273
+ return $this->belongsToMany(Network::class, 'network_stores', 'store_uuid', 'network_uuid')
274
+ ->using(NetworkStore::class)
275
+ ->withPivot('category_uuid');
276
+ }
277
+
278
+ /**
279
+ * @var string
280
+ */
281
+ public function getLogoUrlAttribute()
282
+ {
283
+ return data_get($this, 'logo.url', 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/image-file-icon.png');
284
+ }
285
+
286
+ /**
287
+ * @var string
288
+ */
289
+ public function getBackdropUrlAttribute()
290
+ {
291
+ return data_get($this, 'backdrop.url', 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/default-storefront-backdrop.png');
292
+ }
293
+
294
+ /**
295
+ * @var float
296
+ */
297
+ public function getRatingAttribute()
298
+ {
299
+ return $this->reviews()->avg('rating') ?? 0;
300
+ }
301
+
302
+ /**
303
+ * Retrieves the category of the store belonging to the specified network using the network id.
304
+ *
305
+ * @param string $id The ID of the network for which the category is to be retrieved.
306
+ * @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.
307
+ */
308
+ public function getNetworkCategoryUsingId(?string $id)
309
+ {
310
+ if (is_null($id)) {
311
+ return null;
312
+ }
313
+
314
+ try {
315
+ $network = Network::where('uuid', $id)->orWhere('public_id', $id)->first();
316
+ } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
317
+ return null;
318
+ } catch (\Exception $e) {
319
+ return null;
320
+ }
321
+
322
+ return $this->getNetworkCategory($network);
323
+ }
324
+
325
+ /**
326
+ * Retrieves the category of the store belonging to the specified network.
327
+ *
328
+ * @param \Fleetbase\Storefront\Models\Network $network The network for which the category is to be retrieved.
329
+ * @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.
330
+ */
331
+ public function getNetworkCategory(Network $network)
332
+ {
333
+ // Find the relationship between this store and the given network
334
+ $networkRelation = $this->networks()->where('networks.uuid', $network->uuid)->first();
335
+
336
+ // Check if the relationship exists
337
+ if ($networkRelation) {
338
+ // Retrieve the category_uuid from the pivot table
339
+ $categoryUuid = $networkRelation->pivot->category_uuid;
340
+
341
+ // Assuming you have a Category model that's connected to the correct database
342
+ return Category::find($categoryUuid);
343
+ }
344
+
345
+ // Return null if the store does not belong to the given network
346
+ return null;
347
+ }
348
+
349
+ /**
350
+ *'Create a new product category for this store record
351
+ *
352
+ * @param string $name
353
+ * @param string $description
354
+ * @param array|null $meta
355
+ * @param array|null $translations
356
+ * @param Category|null $parent
357
+ * @param File|string|null $icon
358
+ * @param string $iconColor
359
+ * @return Category
360
+ */
361
+ public function createCategory(string $name, string $description = '', ?array $meta = [], ?array $translations = [], ?Category $parent = null, $icon = null, $iconColor = '#000000'): Category
362
+ {
363
+ $iconFile = null;
364
+ $iconName = null;
365
+
366
+ if ($icon instanceof File) {
367
+ $iconFile = $icon;
368
+ }
369
+
370
+ if (is_string($icon)) {
371
+ $iconName = $icon;
372
+ }
373
+
374
+ return Category::create(
375
+ [
376
+ 'company_uuid' => $this->company_uuid,
377
+ 'owner_uuid' => $this->uuid,
378
+ 'owner_type' => FleetbaseUtils::getMutationType('storefront:store'),
379
+ 'parent_uuid' => $parent instanceof Category ? $parent->uuid : null,
380
+ 'icon_file_uuid' => $iconFile instanceof File ? $iconFile->uuid : null,
381
+ 'for' => 'storefront_product',
382
+ 'name' => $name,
383
+ 'description' => $description,
384
+ 'translations' => $translations,
385
+ 'meta' => $meta,
386
+ 'icon' => $iconName,
387
+ 'icon_color' => $iconColor
388
+ ]
389
+ );
390
+ }
391
+
392
+ /**
393
+ * Create a new product category if it doesn't already exists for this store record
394
+ *
395
+ * @param string $name
396
+ * @param string $description
397
+ * @param array|null $meta
398
+ * @param array|null $translations
399
+ * @param Category|null $parent
400
+ * @param File|string|null $icon
401
+ * @param string $iconColor
402
+ * @return Category
403
+ */
404
+ public function createCategoryStrict(string $name, string $description = '', ?array $meta = [], ?array $translations = [], ?Category $parent = null, $icon = null, $iconColor = '#000000'): Category
405
+ {
406
+ $existingCategory = Category::where(['company_uuid' => $this->company_uuid, 'owner_uuid' => $this->uuid, 'name' => $name])->first();
407
+
408
+ if ($existingCategory) {
409
+ return $existingCategory;
410
+ }
411
+
412
+ return $this->createCategory($name, $description, $meta, $translations, $parent, $icon, $iconColor);
413
+ }
414
+
415
+ /**
416
+ * Creates a new product in the store.
417
+ *
418
+ * @param string $name
419
+ * @param string $description
420
+ * @param array $tags
421
+ * @param Category|null $category
422
+ * @param File|null $image
423
+ * @param User|null $createdBy
424
+ * @param string $sku
425
+ * @param integer $price
426
+ * @param string $status
427
+ * @param array $options
428
+ * @return Product
429
+ */
430
+ public function createProduct(string $name, string $description, array $tags = [], ?Category $category = null, ?File $image = null, ?User $createdBy = null, string $sku = '', int $price = 0, string $status = 'available', array $options = []): Product
431
+ {
432
+ return Product::create(
433
+ [
434
+ 'company_uuid' => $this->company_uuid,
435
+ 'primary_image_uuid' => $image instanceof File ? $image->uuid : null,
436
+ 'created_by_uuid' => $createdBy instanceof User ? $createdBy->uuid : null,
437
+ 'store_uuid' => $this->uuid,
438
+ 'category_uuid' => $category instanceof Category ? $category->uuid : null,
439
+ 'name' => $name,
440
+ 'description' => $description,
441
+ 'tags' => $tags,
442
+ 'sku' => $sku,
443
+ 'price' => $price,
444
+ 'sale_price' => isset($options['sale_price']) ? $options['sale_price'] : null,
445
+ 'currency' => $this->currency,
446
+ 'is_service' => isset($options['is_service']) ? $options['is_service'] : false,
447
+ 'is_bookable' => isset($options['is_bookable']) ? $options['is_bookable'] : false,
448
+ 'is_available' => isset($options['is_available']) ? $options['is_available'] : true,
449
+ 'is_on_sale' => isset($options['is_on_sale']) ? $options['is_on_sale'] : false,
450
+ 'is_recommended' => isset($options['is_recommended']) ? $options['is_recommended'] : false,
451
+ 'can_pickup' => isset($options['can_pickup']) ? $options['can_pickup'] : false,
452
+ 'status' => $status
453
+ ]
454
+ );
455
+ }
456
+
457
+ public function createLocation($location, string $name = null, ?User $createdBy): ?StoreLocation
458
+ {
459
+ $place = Place::createFromMixed($location);
460
+
461
+ if (empty($name)) {
462
+ $name = $this->name . ' store location';
463
+ }
464
+
465
+ if ($place instanceof Place) {
466
+ return StoreLocation::create(
467
+ [
468
+ 'store_uuid' => $this->uuid,
469
+ 'created_by_uuid' => $createdBy instanceof User ? $createdBy->uuid : null,
470
+ 'place_uuid' => $place->uuid,
471
+ 'name' => $name
472
+ ]
473
+ );
474
+ }
475
+
476
+ return null;
477
+ }
478
+ }
@@ -0,0 +1,59 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Storefront\Models;
4
+
5
+ use Fleetbase\Traits\HasUuid;
6
+ use Fleetbase\Traits\HasApiModelBehavior;
7
+
8
+ class StoreHour extends StorefrontModel
9
+ {
10
+ use HasUuid, HasApiModelBehavior;
11
+
12
+ /**
13
+ * The database table used by the model.
14
+ *
15
+ * @var string
16
+ */
17
+ protected $table = 'store_hours';
18
+
19
+ /**
20
+ * These attributes that can be queried
21
+ *
22
+ * @var array
23
+ */
24
+ protected $searchableColumns = [];
25
+
26
+ /**
27
+ * The attributes that are mass assignable.
28
+ *
29
+ * @var array
30
+ */
31
+ protected $fillable = [
32
+ 'store_location_uuid',
33
+ 'day_of_week',
34
+ 'start',
35
+ 'end'
36
+ ];
37
+
38
+ /**
39
+ * The attributes that should be cast to native types.
40
+ *
41
+ * @var array
42
+ */
43
+ protected $casts = [];
44
+
45
+ /**
46
+ * Dynamic attributes that are appended to object
47
+ *
48
+ * @var array
49
+ */
50
+ protected $appends = [];
51
+
52
+ /**
53
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
54
+ */
55
+ public function storeLocation()
56
+ {
57
+ return $this->belongsTo(StoreLocation::class);
58
+ }
59
+ }
@@ -0,0 +1,126 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Storefront\Models;
4
+
5
+ use Fleetbase\Models\User;
6
+ use Fleetbase\FleetOps\Models\Place;
7
+ use Fleetbase\Traits\HasUuid;
8
+ use Fleetbase\Traits\HasApiModelBehavior;
9
+ use Fleetbase\Traits\HasPublicid;
10
+ use Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait;
11
+
12
+ class StoreLocation extends StorefrontModel
13
+ {
14
+ use HasUuid, HasPublicid, HasApiModelBehavior, SpatialTrait;
15
+
16
+ /**
17
+ * The type of public Id to generate
18
+ *
19
+ * @var string
20
+ */
21
+ protected $publicIdType = 'store_location';
22
+
23
+ /**
24
+ * The database table used by the model.
25
+ *
26
+ * @var string
27
+ */
28
+ protected $table = 'store_locations';
29
+
30
+ /**
31
+ * These attributes that can be queried
32
+ *
33
+ * @var array
34
+ */
35
+ protected $searchableColumns = [];
36
+
37
+ /**
38
+ * The attributes that are spatial columns.
39
+ *
40
+ * @var array
41
+ */
42
+ protected $spatialFields = ['location'];
43
+
44
+ /**
45
+ * The attributes that are mass assignable.
46
+ *
47
+ * @var array
48
+ */
49
+ protected $fillable = [
50
+ 'public_id',
51
+ 'store_uuid',
52
+ 'created_by_uuid',
53
+ 'place_uuid',
54
+ 'name'
55
+ ];
56
+
57
+ /**
58
+ * The attributes that should be cast to native types.
59
+ *
60
+ * @var array
61
+ */
62
+ protected $casts = [];
63
+
64
+ /**
65
+ * Dynamic attributes that are appended to object
66
+ *
67
+ * @var array
68
+ */
69
+ protected $appends = ['address'];
70
+
71
+ /**
72
+ * The attributes excluded from the model's JSON form.
73
+ *
74
+ * @var array
75
+ */
76
+ protected $hidden = ['place'];
77
+
78
+ /**
79
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
80
+ */
81
+ public function createdBy()
82
+ {
83
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(User::class);
84
+ }
85
+
86
+ /**
87
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
88
+ */
89
+ public function place()
90
+ {
91
+ return $this->setConnection(config('fleetbase.connection.db'))->belongsTo(Place::class, 'place_uuid');
92
+ }
93
+
94
+ /**
95
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
96
+ */
97
+ public function store()
98
+ {
99
+ return $this->belongsTo(Store::class);
100
+ }
101
+
102
+ /**
103
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
104
+ */
105
+ public function hours()
106
+ {
107
+ return $this->hasMany(StoreHour::class);
108
+ }
109
+
110
+ /**
111
+ * Get address for places
112
+ * @return string
113
+ */
114
+ public function getAddressAttribute()
115
+ {
116
+ return $this->fromCache('place.address');
117
+ }
118
+
119
+ /**
120
+ * @return \Grimzy\LaravelMysqlSpatial\Types\Point
121
+ */
122
+ public function getLocationAttribute()
123
+ {
124
+ return $this->place()->first()->location;
125
+ }
126
+ }
@@ -0,0 +1,22 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Storefront\Models;
4
+
5
+ use Fleetbase\Models\Model;
6
+
7
+ class StorefrontModel extends Model
8
+ {
9
+ /**
10
+ * Create a new instance of the model.
11
+ *
12
+ * @param array $attributes The attributes to set on the model.
13
+ *
14
+ * @return void
15
+ */
16
+ public function __construct(array $attributes = [])
17
+ {
18
+ parent::__construct($attributes);
19
+
20
+ $this->connection = config('storefront.connection.db');
21
+ }
22
+ }