@fleetbase/storefront-engine 0.3.4 → 0.3.6
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/addon/components/context-panel.hbs +5 -0
- package/addon/components/context-panel.js +6 -0
- package/addon/components/customer-panel/details.hbs +34 -0
- package/addon/components/customer-panel/details.js +3 -0
- package/addon/components/customer-panel/orders.hbs +140 -0
- package/addon/components/customer-panel/orders.js +78 -0
- package/addon/components/customer-panel.hbs +70 -0
- package/addon/components/customer-panel.js +171 -0
- package/addon/components/display-place.hbs +52 -0
- package/addon/components/display-place.js +11 -0
- package/addon/components/modals/manage-addons.hbs +15 -52
- package/addon/components/modals/manage-addons.js +93 -43
- package/addon/components/modals/select-addon-category.hbs +1 -1
- package/addon/components/order-panel/details.hbs +245 -0
- package/addon/components/order-panel/details.js +189 -0
- package/addon/components/order-panel.hbs +1 -0
- package/addon/components/order-panel.js +38 -0
- package/addon/components/storefront-order-summary.hbs +9 -2
- package/addon/components/widget/customers.hbs +3 -1
- package/addon/components/widget/customers.js +5 -0
- package/addon/components/widget/orders.js +8 -146
- package/addon/controllers/customers/index/view.js +43 -0
- package/addon/controllers/customers/index.js +10 -6
- package/addon/controllers/networks/index/network/customers.js +68 -2
- package/addon/controllers/networks/index/network/orders.js +324 -1
- package/addon/controllers/networks/index/network/stores.js +0 -2
- package/addon/controllers/orders/index/view.js +13 -0
- package/addon/controllers/orders/index.js +10 -7
- package/addon/controllers/products/index/category/edit.js +12 -16
- package/addon/controllers/products/index/category/new.js +40 -45
- package/addon/controllers/products/index.js +8 -2
- package/addon/helpers/avatar-url.js +9 -0
- package/addon/models/product-variant-option.js +8 -1
- package/addon/models/product-variant.js +12 -2
- package/addon/models/product.js +62 -0
- package/addon/routes/customers/index/view.js +14 -0
- package/addon/routes/networks/index/network/customers.js +29 -0
- package/addon/routes/networks/index/network/orders.js +5 -0
- package/addon/routes/networks/index.js +1 -1
- package/addon/routes/orders/index/view.js +22 -1
- package/addon/routes/products/index/category/edit.js +6 -0
- package/addon/routes/products/index/category/new.js +3 -1
- package/addon/routes.js +1 -0
- package/addon/serializers/product-variant-option.js +14 -0
- package/addon/serializers/product-variant.js +27 -0
- package/addon/serializers/product.js +26 -4
- package/addon/services/context-panel.js +210 -0
- package/addon/styles/storefront-engine.css +6 -0
- package/addon/templates/application.hbs +3 -1
- package/addon/templates/customers/index/view.hbs +1 -0
- package/addon/templates/networks/index/network/customers.hbs +18 -1
- package/addon/templates/networks/index/network/orders.hbs +18 -1
- package/addon/templates/networks/index/network.hbs +1 -1
- package/addon/templates/orders/index/view.hbs +1 -1
- package/addon/templates/products/index/category/new.hbs +12 -67
- package/app/components/context-panel.js +1 -0
- package/app/components/customer-panel/details.js +1 -0
- package/app/components/customer-panel/orders.js +1 -0
- package/app/components/customer-panel.js +1 -0
- package/app/components/display-place.js +1 -0
- package/app/components/order-panel/details.js +1 -0
- package/app/components/order-panel.js +1 -0
- package/app/controllers/customers/index/view.js +1 -0
- package/app/controllers/orders/index/view.js +1 -0
- package/app/helpers/avatar-url.js +1 -0
- package/app/routes/customers/index/view.js +1 -0
- package/app/serializers/product-variant-option.js +1 -0
- package/app/services/context-panel.js +1 -0
- package/app/templates/customers/index/view.js +1 -0
- package/composer.json +4 -4
- package/extension.json +1 -1
- package/package.json +9 -3
- package/server/seeders/OrderConfigSeeder.php +2 -249
- package/server/src/Http/Controllers/AddonCategoryController.php +90 -0
- package/server/src/Http/Controllers/v1/ReviewController.php +43 -52
- package/server/src/Http/Controllers/v1/ServiceQuoteController.php +7 -9
- package/server/src/Http/Resources/Network.php +34 -32
- package/server/src/Http/Resources/NotificationChannel.php +32 -0
- package/server/src/Http/Resources/Product.php +10 -8
- package/server/src/Models/AddonCategory.php +37 -0
- package/server/src/Models/Product.php +6 -7
- package/server/src/Models/ProductAddon.php +3 -0
- package/server/src/Models/ProductAddonCategory.php +12 -2
- package/server/src/Observers/CompanyObserver.php +20 -0
- package/server/src/Providers/StorefrontServiceProvider.php +2 -1
- package/server/src/Support/Storefront.php +249 -0
- package/translations/en-us.yaml +101 -39
- package/server/src/Support/OrderConfig.php +0 -14
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
<Overlay @position="right" @noBackdrop={{true}} @isResizable={{true}} @width="570px" @fullHeight={{true}} @containerClass="border-l border-transparent dark:border-gray-700">
|
|
2
|
-
<Overlay::Header
|
|
3
|
-
@
|
|
4
|
-
@titleClass="truncate"
|
|
5
|
-
@titleWrapperClass="w-3/4"
|
|
6
|
-
@headerLeftClass="w-70pc"
|
|
7
|
-
@headerLeftInnerClass="w-full flex-1"
|
|
8
|
-
@onPressCancel={{this.transitionBack}}
|
|
9
|
-
>
|
|
10
|
-
<Button
|
|
11
|
-
@icon={{this.overlayActionButtonIcon}}
|
|
12
|
-
@type="primary"
|
|
13
|
-
@text={{this.overlayActionButtonTitle}}
|
|
14
|
-
@onClick={{this.saveProduct}}
|
|
15
|
-
@isLoading={{this.isSaving}}
|
|
16
|
-
@isSubscriptionRequired={{true}}
|
|
17
|
-
/>
|
|
2
|
+
<Overlay::Header @title={{this.overlayTitle}} @titleClass="truncate" @titleWrapperClass="w-3/4" @headerLeftClass="w-70pc" @headerLeftInnerClass="w-full flex-1" @onPressCancel={{this.transitionBack}}>
|
|
3
|
+
<Button @icon={{this.overlayActionButtonIcon}} @type="primary" @text={{this.overlayActionButtonTitle}} @onClick={{perform this.saveProduct}} @isLoading={{not this.saveProduct.isIdle}} />
|
|
18
4
|
</Overlay::Header>
|
|
19
5
|
|
|
20
6
|
<Overlay::Body @increaseInnerBodyHeightBy="0" @wrapperClass="new-order-overlay-body px-4 space-y-4 pt-4">
|
|
@@ -23,48 +9,21 @@
|
|
|
23
9
|
<Textarea @value={{this.product.description}} class="form-input w-full" placeholder="Enter a description of your product...." rows={{4}} />
|
|
24
10
|
</InputGroup>
|
|
25
11
|
<InputGroup @name="Product Tags">
|
|
26
|
-
<TagInput
|
|
27
|
-
class="form-input"
|
|
28
|
-
@placeholder="Add tags"
|
|
29
|
-
@allowSpacesInTags={{true}}
|
|
30
|
-
@tags={{this.product.tags}}
|
|
31
|
-
@addTag={{this.addTag}}
|
|
32
|
-
@removeTagAtIndex={{this.removeTag}}
|
|
33
|
-
as |tag|
|
|
34
|
-
>
|
|
12
|
+
<TagInput class="form-input" @placeholder="Add tags" @allowSpacesInTags={{true}} @tags={{this.product.tags}} @addTag={{this.addTag}} @removeTagAtIndex={{this.removeTag}} as |tag|>
|
|
35
13
|
{{tag}}
|
|
36
14
|
</TagInput>
|
|
37
15
|
</InputGroup>
|
|
38
16
|
<InputGroup @name="Product SKU" @value={{this.product.sku}} @helpText="Enter product SKU if applicable" />
|
|
39
17
|
<div class="grid grid-cols-2 gap-2">
|
|
40
18
|
<InputGroup @name="Price" @helpText="Enter a price users will pay to purchase this product">
|
|
41
|
-
<MoneyInput
|
|
42
|
-
class="w-full"
|
|
43
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
44
|
-
@value={{this.product.price}}
|
|
45
|
-
@canSelectCurrency={{false}}
|
|
46
|
-
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
47
|
-
/>
|
|
19
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @value={{this.product.price}} @canSelectCurrency={{false}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
48
20
|
</InputGroup>
|
|
49
21
|
<InputGroup @name="Sale Price" @helpText="Optionally add a sale price for the product if the product is put on sale">
|
|
50
|
-
<MoneyInput
|
|
51
|
-
class="w-full"
|
|
52
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
53
|
-
@value={{this.product.sale_price}}
|
|
54
|
-
@canSelectCurrency={{false}}
|
|
55
|
-
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
56
|
-
/>
|
|
22
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @value={{this.product.sale_price}} @canSelectCurrency={{false}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
57
23
|
</InputGroup>
|
|
58
24
|
</div>
|
|
59
25
|
|
|
60
|
-
<ContentPanel
|
|
61
|
-
@title="Metadata"
|
|
62
|
-
@open={{this.product.meta_array.length}}
|
|
63
|
-
@actionButtons={{this.metadataButtons}}
|
|
64
|
-
@pad={{true}}
|
|
65
|
-
@panelBodyWrapperClass="px-0 py-4"
|
|
66
|
-
@panelBodyClass="bg-white dark:bg-gray-800"
|
|
67
|
-
>
|
|
26
|
+
<ContentPanel @title="Metadata" @open={{this.product.meta_array.length}} @actionButtons={{this.metadataButtons}} @pad={{true}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
68
27
|
{{#each this.product.meta_array as |metaField index|}}
|
|
69
28
|
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700">
|
|
70
29
|
<div class="input-group">
|
|
@@ -119,7 +78,7 @@
|
|
|
119
78
|
</div>
|
|
120
79
|
</div>
|
|
121
80
|
|
|
122
|
-
<ContentPanel @title="Variants" @open={{
|
|
81
|
+
<ContentPanel @title="Variants" @open={{true}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
123
82
|
<div class="content-panel-body p-4">
|
|
124
83
|
<div class="flex items-center justify-end">
|
|
125
84
|
<Button @text="New Variant" @icon="plus" @iconPrefix="fas" @onClick={{this.createProductVariant}} />
|
|
@@ -144,12 +103,7 @@
|
|
|
144
103
|
<Input @type="text" @value={{variantOption.description}} class="form-input w-full" placeholder="Option Description" />
|
|
145
104
|
</div>
|
|
146
105
|
<div class="col-span-2">
|
|
147
|
-
<MoneyInput
|
|
148
|
-
class="w-full"
|
|
149
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
150
|
-
@canSelectCurrency={{false}}
|
|
151
|
-
@value={{variantOption.additional_cost}}
|
|
152
|
-
/>
|
|
106
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @canSelectCurrency={{false}} @value={{variantOption.additional_cost}} />
|
|
153
107
|
</div>
|
|
154
108
|
<div class="flex items-center justify-center text-center text-sm">
|
|
155
109
|
<a href="javascript:;" {{on "click" (fn this.removeVariantOption variant index)}}>Remove</a>
|
|
@@ -163,10 +117,10 @@
|
|
|
163
117
|
</Tabs>
|
|
164
118
|
</ContentPanel>
|
|
165
119
|
|
|
166
|
-
<ContentPanel @title="Add-Ons" @open={{
|
|
120
|
+
<ContentPanel @title="Add-Ons" @open={{true}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
167
121
|
<div class="px-4">
|
|
168
122
|
<div class="flex items-center justify-end mb-3">
|
|
169
|
-
<Button @text="Select Addon Categories" @icon="plus" @iconPrefix="fas" @onClick={{this.
|
|
123
|
+
<Button @text="Select Addon Categories" @icon="plus" @iconPrefix="fas" @onClick={{perform this.promptSelectAddonCategories}} />
|
|
170
124
|
</div>
|
|
171
125
|
<div class="space-y-2">
|
|
172
126
|
{{#each this.product.addon_categories as |addonCategory index|}}
|
|
@@ -215,9 +169,7 @@
|
|
|
215
169
|
<ContentPanel @title="Images & Videos" @open={{this.product.files.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
216
170
|
<div class="px-6 space-y-4">
|
|
217
171
|
{{#if this.isUploading}}
|
|
218
|
-
<div
|
|
219
|
-
class="min-h-56 dropzone w-full rounded-lg px-4 py-8 min-h bg-gray-50 dark:bg-gray-900 bg-opacity-25 text-gray-900 dark:text-white text-center flex flex-col items-center justify-center border-2 border-dashed border-gray-200 dark:border-indigo-500"
|
|
220
|
-
>
|
|
172
|
+
<div class="min-h-56 dropzone w-full rounded-lg px-4 py-8 min-h bg-gray-50 dark:bg-gray-900 bg-opacity-25 text-gray-900 dark:text-white text-center flex flex-col items-center justify-center border-2 border-dashed border-gray-200 dark:border-indigo-500">
|
|
221
173
|
<div class="flex items-center justify-center py-5">
|
|
222
174
|
<Spinner class="text-sm dar:text-gray-100" @loadingMessage={{t "component.dropzone.uploading"}} />
|
|
223
175
|
</div>
|
|
@@ -276,14 +228,7 @@
|
|
|
276
228
|
{{#each this.product.files as |file|}}
|
|
277
229
|
<FileRecord @file={{file}} @fileIconClass={{if (eq this.product.primary_image_uuid file.id) "border-blue-400"}} @onDelete={{this.removeFile}}>
|
|
278
230
|
<div class="flex items-center justify-evenly">
|
|
279
|
-
<Button
|
|
280
|
-
@icon="magic"
|
|
281
|
-
@text="Make Primary"
|
|
282
|
-
@size="xs"
|
|
283
|
-
@textClass="text-xs truncate"
|
|
284
|
-
@onClick={{fn this.makePrimaryFile file}}
|
|
285
|
-
@disabled={{eq this.product.primary_image_uuid file.id}}
|
|
286
|
-
/>
|
|
231
|
+
<Button @icon="magic" @text="Make Primary" @size="xs" @textClass="text-xs truncate" @onClick={{fn this.makePrimaryFile file}} @disabled={{eq this.product.primary_image_uuid file.id}} />
|
|
287
232
|
</div>
|
|
288
233
|
</FileRecord>
|
|
289
234
|
{{/each}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/context-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel/orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/display-place';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/order-panel/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/order-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/controllers/customers/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/controllers/orders/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/helpers/avatar-url';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/routes/customers/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/serializers/product-variant-option';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/services/context-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/templates/customers/index/view';
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/storefront-api",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
],
|
|
23
23
|
"require": {
|
|
24
24
|
"php": "^8.0",
|
|
25
|
-
"fleetbase/core-api": "^1.4.
|
|
26
|
-
"fleetbase/fleetops-api": "^0.4.
|
|
25
|
+
"fleetbase/core-api": "^1.4.15",
|
|
26
|
+
"fleetbase/fleetops-api": "^0.4.23",
|
|
27
27
|
"geocoder-php/google-maps-places-provider": "^1.4",
|
|
28
28
|
"laravel-notification-channels/apn": "^5.0",
|
|
29
29
|
"laravel-notification-channels/fcm": "^4.1",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"autoload": {
|
|
45
45
|
"psr-4": {
|
|
46
46
|
"Fleetbase\\Storefront\\": "server/src/",
|
|
47
|
-
"Fleetbase\\Storefront\\Seeders\\": "seeders/"
|
|
47
|
+
"Fleetbase\\Storefront\\Seeders\\": "server/seeders/"
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"autoload-dev": {
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/storefront-engine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "storefront",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@fleetbase/ember-core": "^0.2.
|
|
46
|
+
"@fleetbase/ember-core": "^0.2.8",
|
|
47
47
|
"@fleetbase/ember-ui": "^0.2.11",
|
|
48
|
-
"@fleetbase/fleetops-data": "^0.1.
|
|
48
|
+
"@fleetbase/fleetops-data": "^0.1.14",
|
|
49
49
|
"@babel/core": "^7.23.2",
|
|
50
50
|
"@fortawesome/ember-fontawesome": "^0.4.1",
|
|
51
51
|
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
|
@@ -130,6 +130,12 @@
|
|
|
130
130
|
"options": {
|
|
131
131
|
"singleQuote": false
|
|
132
132
|
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"files": "*.{yml,yaml}",
|
|
136
|
+
"options": {
|
|
137
|
+
"tabWidth": 2
|
|
138
|
+
}
|
|
133
139
|
}
|
|
134
140
|
]
|
|
135
141
|
}
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\Storefront\Seeders;
|
|
4
4
|
|
|
5
|
-
use Fleetbase\FleetOps\Models\OrderConfig;
|
|
6
5
|
use Fleetbase\Models\Company;
|
|
6
|
+
use Fleetbase\Storefront\Support\Storefront;
|
|
7
7
|
use Illuminate\Database\Seeder;
|
|
8
|
-
use Illuminate\Support\Str;
|
|
9
8
|
|
|
10
9
|
class OrderConfigSeeder extends Seeder
|
|
11
10
|
{
|
|
@@ -18,253 +17,7 @@ class OrderConfigSeeder extends Seeder
|
|
|
18
17
|
{
|
|
19
18
|
$companies = Company::all();
|
|
20
19
|
foreach ($companies as $company) {
|
|
21
|
-
|
|
20
|
+
Storefront::createStorefrontConfig($company);
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Creates or retrieves an existing storefront configuration for a given company.
|
|
27
|
-
*
|
|
28
|
-
* This method checks if a storefront configuration (OrderConfig) already exists for the given company.
|
|
29
|
-
* If it exists, the method returns the existing configuration. Otherwise, it creates a new configuration with
|
|
30
|
-
* predefined settings for a storefront order process. The configuration includes various stages like 'created',
|
|
31
|
-
* 'started', 'canceled', 'completed', etc., each defined with specific attributes like key, code, color, logic,
|
|
32
|
-
* events, status, actions, details, and more. These stages help manage the order lifecycle in a storefront context.
|
|
33
|
-
*
|
|
34
|
-
* @param Company $company The company for which the storefront configuration is being created or retrieved.
|
|
35
|
-
* @return OrderConfig The storefront order configuration associated with the specified company.
|
|
36
|
-
*/
|
|
37
|
-
public static function createStorefrontConfig(Company $company): OrderConfig
|
|
38
|
-
{
|
|
39
|
-
return OrderConfig::firstOrCreate(
|
|
40
|
-
[
|
|
41
|
-
'company_uuid' => $company->uuid,
|
|
42
|
-
'key' => 'storefront',
|
|
43
|
-
'namespace' => 'system:order-config:storefront',
|
|
44
|
-
],
|
|
45
|
-
[
|
|
46
|
-
'name' => 'Storefront',
|
|
47
|
-
'key' => 'storefront',
|
|
48
|
-
'namespace' => 'system:order-config:storefront',
|
|
49
|
-
'description' => 'Storefront order configuration for hyperlocal delivery and pickup',
|
|
50
|
-
'core_service' => 1,
|
|
51
|
-
'status' => 'private',
|
|
52
|
-
'version' => '0.0.1',
|
|
53
|
-
'tags' => ['storefront', 'ecommerce', 'hyperlocal'],
|
|
54
|
-
'entities' => [],
|
|
55
|
-
'meta' => [],
|
|
56
|
-
'flow' => [
|
|
57
|
-
'created' => [
|
|
58
|
-
'key' => 'created',
|
|
59
|
-
'code' => 'created',
|
|
60
|
-
'color' => '#1f2937',
|
|
61
|
-
'logic' => [],
|
|
62
|
-
'events' => [],
|
|
63
|
-
'status' => 'Order Created',
|
|
64
|
-
'actions' => [],
|
|
65
|
-
'details' => 'New order was created.',
|
|
66
|
-
'options' => [],
|
|
67
|
-
'complete' => false,
|
|
68
|
-
'entities' => [],
|
|
69
|
-
'sequence' => 0,
|
|
70
|
-
'activities' => ['dispatched'],
|
|
71
|
-
'internalId' => Str::uuid(),
|
|
72
|
-
'pod_method' => 'scan',
|
|
73
|
-
'require_pod' => false,
|
|
74
|
-
],
|
|
75
|
-
'started' => [
|
|
76
|
-
'key' => 'started',
|
|
77
|
-
'code' => 'started',
|
|
78
|
-
'color' => '#1f2937',
|
|
79
|
-
'logic' => [],
|
|
80
|
-
'events' => [],
|
|
81
|
-
'status' => 'Order Started',
|
|
82
|
-
'actions' => [],
|
|
83
|
-
'details' => 'Order has been started',
|
|
84
|
-
'options' => [],
|
|
85
|
-
'complete' => false,
|
|
86
|
-
'entities' => [],
|
|
87
|
-
'sequence' => 0,
|
|
88
|
-
'activities' => ['canceled', 'preparing'],
|
|
89
|
-
'internalId' => Str::uuid(),
|
|
90
|
-
'pod_method' => 'scan',
|
|
91
|
-
'require_pod' => false,
|
|
92
|
-
],
|
|
93
|
-
'canceled' => [
|
|
94
|
-
'key' => 'canceled',
|
|
95
|
-
'code' => 'canceled',
|
|
96
|
-
'color' => '#1f2937',
|
|
97
|
-
'logic' => [],
|
|
98
|
-
'events' => ['order.canceled'],
|
|
99
|
-
'status' => 'Order canceled',
|
|
100
|
-
'actions' => [],
|
|
101
|
-
'details' => 'Order could not be accepted',
|
|
102
|
-
'options' => [],
|
|
103
|
-
'complete' => false,
|
|
104
|
-
'entities' => [],
|
|
105
|
-
'sequence' => 0,
|
|
106
|
-
'activities' => [],
|
|
107
|
-
'internalId' => Str::uuid(),
|
|
108
|
-
'pod_method' => 'scan',
|
|
109
|
-
'require_pod' => false,
|
|
110
|
-
],
|
|
111
|
-
'completed' => [
|
|
112
|
-
'key' => 'completed',
|
|
113
|
-
'code' => 'completed',
|
|
114
|
-
'color' => '#1f2937',
|
|
115
|
-
'logic' => [],
|
|
116
|
-
'events' => [],
|
|
117
|
-
'status' => 'Order completed',
|
|
118
|
-
'actions' => [],
|
|
119
|
-
'details' => 'Driver has completed the order',
|
|
120
|
-
'options' => [],
|
|
121
|
-
'complete' => true,
|
|
122
|
-
'entities' => [],
|
|
123
|
-
'sequence' => 0,
|
|
124
|
-
'activities' => [],
|
|
125
|
-
'internalId' => Str::uuid(),
|
|
126
|
-
'pod_method' => 'scan',
|
|
127
|
-
'require_pod' => false,
|
|
128
|
-
],
|
|
129
|
-
'picked_up' => [
|
|
130
|
-
'key' => 'completed',
|
|
131
|
-
'code' => 'picked_up',
|
|
132
|
-
'color' => '#1f2937',
|
|
133
|
-
'logic' => [],
|
|
134
|
-
'events' => [],
|
|
135
|
-
'status' => 'Order picked up',
|
|
136
|
-
'actions' => [],
|
|
137
|
-
'details' => 'Order has been picked up by customer',
|
|
138
|
-
'options' => [],
|
|
139
|
-
'complete' => true,
|
|
140
|
-
'entities' => [],
|
|
141
|
-
'sequence' => 0,
|
|
142
|
-
'activities' => [],
|
|
143
|
-
'internalId' => Str::uuid(),
|
|
144
|
-
'pod_method' => 'scan',
|
|
145
|
-
'require_pod' => false,
|
|
146
|
-
],
|
|
147
|
-
'preparing' => [
|
|
148
|
-
'key' => 'preparing',
|
|
149
|
-
'code' => 'preparing',
|
|
150
|
-
'color' => '#1f2937',
|
|
151
|
-
'logic' => [],
|
|
152
|
-
'events' => [],
|
|
153
|
-
'status' => 'Order is being prepared',
|
|
154
|
-
'actions' => [],
|
|
155
|
-
'details' => 'Order has been received by {storefront.name} and is being prepared',
|
|
156
|
-
'options' => [],
|
|
157
|
-
'complete' => false,
|
|
158
|
-
'entities' => [],
|
|
159
|
-
'sequence' => 0,
|
|
160
|
-
'activities' => ['driver_enroute_to_store', 'pickup_ready'],
|
|
161
|
-
'internalId' => Str::uuid(),
|
|
162
|
-
'pod_method' => 'scan',
|
|
163
|
-
'require_pod' => false,
|
|
164
|
-
],
|
|
165
|
-
'dispatched' => [
|
|
166
|
-
'key' => 'dispatched',
|
|
167
|
-
'code' => 'dispatched',
|
|
168
|
-
'color' => '#1f2937',
|
|
169
|
-
'logic' => [],
|
|
170
|
-
'events' => [],
|
|
171
|
-
'status' => 'Order Dispatched',
|
|
172
|
-
'actions' => [],
|
|
173
|
-
'details' => 'Order has been dispatched.',
|
|
174
|
-
'options' => [],
|
|
175
|
-
'complete' => false,
|
|
176
|
-
'entities' => [],
|
|
177
|
-
'sequence' => 0,
|
|
178
|
-
'activities' => ['started'],
|
|
179
|
-
'internalId' => Str::uuid(),
|
|
180
|
-
'pod_method' => 'scan',
|
|
181
|
-
'require_pod' => false,
|
|
182
|
-
],
|
|
183
|
-
'pickup_ready' => [
|
|
184
|
-
'key' => 'ready',
|
|
185
|
-
'code' => 'pickup_ready',
|
|
186
|
-
'color' => '#1f2937',
|
|
187
|
-
'logic' => [
|
|
188
|
-
[
|
|
189
|
-
'type' => 'if',
|
|
190
|
-
'conditions' => [
|
|
191
|
-
[
|
|
192
|
-
'field' => 'meta.is_pickup',
|
|
193
|
-
'value' => 'true',
|
|
194
|
-
'operator' => 'equal',
|
|
195
|
-
],
|
|
196
|
-
],
|
|
197
|
-
],
|
|
198
|
-
],
|
|
199
|
-
'events' => [],
|
|
200
|
-
'status' => 'Order is ready for pickup',
|
|
201
|
-
'actions' => [],
|
|
202
|
-
'details' => 'Order is ready to be picked up by customer',
|
|
203
|
-
'options' => [],
|
|
204
|
-
'complete' => false,
|
|
205
|
-
'entities' => [],
|
|
206
|
-
'sequence' => 0,
|
|
207
|
-
'activities' => ['picked_up'],
|
|
208
|
-
'internalId' => Str::uuid(),
|
|
209
|
-
'pod_method' => 'scan',
|
|
210
|
-
'require_pod' => false,
|
|
211
|
-
],
|
|
212
|
-
'driver_enroute' => [
|
|
213
|
-
'key' => 'driver_enroute',
|
|
214
|
-
'code' => 'driver_enroute',
|
|
215
|
-
'color' => '#1f2937',
|
|
216
|
-
'logic' => [],
|
|
217
|
-
'events' => [],
|
|
218
|
-
'status' => 'Driver en-route',
|
|
219
|
-
'actions' => [],
|
|
220
|
-
'details' => 'Driver is on the way to the customer',
|
|
221
|
-
'options' => [],
|
|
222
|
-
'complete' => false,
|
|
223
|
-
'entities' => [],
|
|
224
|
-
'sequence' => 0,
|
|
225
|
-
'activities' => ['completed'],
|
|
226
|
-
'internalId' => Str::uuid(),
|
|
227
|
-
'pod_method' => 'scan',
|
|
228
|
-
'require_pod' => false,
|
|
229
|
-
],
|
|
230
|
-
'driver_picked_up' => [
|
|
231
|
-
'key' => 'driver_picked_up',
|
|
232
|
-
'code' => 'driver_picked_up',
|
|
233
|
-
'color' => '#1f2937',
|
|
234
|
-
'logic' => [],
|
|
235
|
-
'events' => [],
|
|
236
|
-
'status' => 'Driver picked up',
|
|
237
|
-
'actions' => [],
|
|
238
|
-
'details' => 'Driver has picked up order',
|
|
239
|
-
'options' => [],
|
|
240
|
-
'complete' => false,
|
|
241
|
-
'entities' => [],
|
|
242
|
-
'sequence' => 0,
|
|
243
|
-
'activities' => ['driver_enroute'],
|
|
244
|
-
'internalId' => Str::uuid(),
|
|
245
|
-
'pod_method' => 'scan',
|
|
246
|
-
'require_pod' => false,
|
|
247
|
-
],
|
|
248
|
-
'driver_enroute_to_store' => [
|
|
249
|
-
'key' => 'driver_enroute',
|
|
250
|
-
'code' => 'driver_enroute_to_store',
|
|
251
|
-
'color' => '#1f2937',
|
|
252
|
-
'logic' => [],
|
|
253
|
-
'events' => [],
|
|
254
|
-
'status' => 'Driver en-route',
|
|
255
|
-
'actions' => [],
|
|
256
|
-
'details' => 'Driver en-route to store',
|
|
257
|
-
'options' => [],
|
|
258
|
-
'complete' => false,
|
|
259
|
-
'entities' => [],
|
|
260
|
-
'sequence' => 0,
|
|
261
|
-
'activities' => ['driver_picked_up'],
|
|
262
|
-
'internalId' => Str::uuid(),
|
|
263
|
-
'pod_method' => 'scan',
|
|
264
|
-
'require_pod' => false,
|
|
265
|
-
],
|
|
266
|
-
],
|
|
267
|
-
]
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
23
|
}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\Storefront\Http\Controllers;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Storefront\Models\AddonCategory;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
use Illuminate\Http\Request;
|
|
8
|
+
|
|
5
9
|
class AddonCategoryController extends StorefrontController
|
|
6
10
|
{
|
|
7
11
|
/**
|
|
@@ -10,4 +14,90 @@ class AddonCategoryController extends StorefrontController
|
|
|
10
14
|
* @var string
|
|
11
15
|
*/
|
|
12
16
|
public $resource = 'addon_category';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new record based on the provided request data.
|
|
20
|
+
*
|
|
21
|
+
* This method handles the creation of a new record using data from the request.
|
|
22
|
+
* It includes a validation step, creation of the record, and an optional closure
|
|
23
|
+
* to perform additional operations on the model and request data. The method
|
|
24
|
+
* returns an instance of a resource, which wraps the created record. Error handling
|
|
25
|
+
* is implemented to catch and respond to various exceptions that might occur during the process.
|
|
26
|
+
*
|
|
27
|
+
* @param Request $request the incoming HTTP request containing data for the new record
|
|
28
|
+
*
|
|
29
|
+
* @return mixed an instance of the resource class containing the created record, or an error response
|
|
30
|
+
*
|
|
31
|
+
* @throws \Exception general exceptions with a message
|
|
32
|
+
* @throws \Illuminate\Database\QueryException database query exceptions with a message
|
|
33
|
+
* @throws \Fleetbase\Exceptions\FleetbaseRequestValidationException custom validation exceptions with error details
|
|
34
|
+
*/
|
|
35
|
+
public function createRecord(Request $request)
|
|
36
|
+
{
|
|
37
|
+
try {
|
|
38
|
+
$this->validateRequest($request);
|
|
39
|
+
|
|
40
|
+
$record = $this->model->createRecordFromRequest($request, null, function (&$request, AddonCategory &$addonCategory) {
|
|
41
|
+
$addons = $request->array('addonCategory.addons');
|
|
42
|
+
$addonCategory->setAddons($addons);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (Http::isInternalRequest($request)) {
|
|
46
|
+
$this->resource::wrap($this->resourceSingularlName);
|
|
47
|
+
|
|
48
|
+
return new $this->resource($record);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return new $this->resource($record);
|
|
52
|
+
} catch (\Exception $e) {
|
|
53
|
+
return response()->error($e->getMessage());
|
|
54
|
+
} catch (\Illuminate\Database\QueryException $e) {
|
|
55
|
+
return response()->error($e->getMessage());
|
|
56
|
+
} catch (\Fleetbase\Exceptions\FleetbaseRequestValidationException $e) {
|
|
57
|
+
return response()->error($e->getErrors());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Updates an existing record based on the provided request data.
|
|
63
|
+
*
|
|
64
|
+
* This method updates a record identified by the provided ID using data from the request.
|
|
65
|
+
* It includes a validation step, updating of the record, and an optional closure
|
|
66
|
+
* to perform additional operations on the model and request data. The method returns
|
|
67
|
+
* an instance of a resource, which wraps the updated record. Error handling is implemented
|
|
68
|
+
* to catch and respond to various exceptions that might occur during the update process.
|
|
69
|
+
*
|
|
70
|
+
* @param Request $request the incoming HTTP request containing data for updating the record
|
|
71
|
+
* @param string $id the identifier of the record to be updated
|
|
72
|
+
*
|
|
73
|
+
* @return mixed an instance of the resource class containing the updated record, or an error response
|
|
74
|
+
*
|
|
75
|
+
* @throws \Exception general exceptions with a message
|
|
76
|
+
* @throws \Illuminate\Database\QueryException database query exceptions with a message
|
|
77
|
+
* @throws \Fleetbase\Exceptions\FleetbaseRequestValidationException custom validation exceptions with error details
|
|
78
|
+
*/
|
|
79
|
+
public function updateRecord(Request $request, string $id)
|
|
80
|
+
{
|
|
81
|
+
try {
|
|
82
|
+
$this->validateRequest($request);
|
|
83
|
+
$record = $this->model->updateRecordFromRequest($request, $id, function (&$request, AddonCategory &$addonCategory) {
|
|
84
|
+
$addons = $request->array('addonCategory.addons');
|
|
85
|
+
$addonCategory->setAddons($addons);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (Http::isInternalRequest($request)) {
|
|
89
|
+
$this->resource::wrap($this->resourceSingularlName);
|
|
90
|
+
|
|
91
|
+
return new $this->resource($record);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return new $this->resource($record);
|
|
95
|
+
} catch (\Exception $e) {
|
|
96
|
+
return response()->error($e->getMessage());
|
|
97
|
+
} catch (\Illuminate\Database\QueryException $e) {
|
|
98
|
+
return response()->error($e->getMessage());
|
|
99
|
+
} catch (\Fleetbase\Exceptions\FleetbaseRequestValidationException $e) {
|
|
100
|
+
return response()->error($e->getErrors());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
13
103
|
}
|