@fleetbase/registry-bridge-engine 0.0.9 → 0.0.11
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/extension-form.hbs +2 -3
- package/addon/components/extension-monetize-form.hbs +64 -44
- package/addon/components/extension-monetize-form.js +18 -0
- package/addon/components/modals/extension-details.hbs +1 -1
- package/addon/controllers/developers/extensions/edit/monetize.js +1 -5
- package/addon/controllers/developers/payments/index.js +12 -0
- package/addon/routes/developers/payments/index.js +2 -7
- package/addon/templates/developers/payments/index.hbs +32 -24
- package/composer.json +2 -2
- package/extension.json +1 -1
- package/package.json +2 -2
- package/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php +21 -15
- package/server/src/Models/RegistryExtension.php +7 -3
|
@@ -106,11 +106,10 @@
|
|
|
106
106
|
@name={{t "registry-bridge.developers.extensions.extension-form.extension-promotional-text"}}
|
|
107
107
|
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-promotional-text-help-text"}}
|
|
108
108
|
>
|
|
109
|
-
<
|
|
109
|
+
<TipTapEditor
|
|
110
110
|
@value={{@extension.promotional_text}}
|
|
111
|
+
@onChange={{fn (mut @extension.promotional_text)}}
|
|
111
112
|
placeholder={{t "registry-bridge.developers.extensions.extension-form.extension-promotional-text"}}
|
|
112
|
-
class="form-input w-full"
|
|
113
|
-
rows="3"
|
|
114
113
|
/>
|
|
115
114
|
</InputGroup>
|
|
116
115
|
<InputGroup
|
|
@@ -1,55 +1,75 @@
|
|
|
1
1
|
<ContentPanel @title={{t "registry-bridge.developers.extensions.extension-form.extension-payment-details"}} @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
|
|
2
|
-
|
|
3
|
-
<
|
|
4
|
-
@
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
{{#if this.lookupStripeConnectAccount.isRunning}}
|
|
3
|
+
<div class="flex items-center justify-center flex-1 p-4">
|
|
4
|
+
<Spinner @loadingMessage="Loading monetization settings..." @loadingMessageClass="ml-2 text-black dark:text-white" @wrapperClass="flex flex-row items-center" />
|
|
5
|
+
</div>
|
|
6
|
+
{{else}}
|
|
7
|
+
{{#if this.hasStripeConnectAccount}}
|
|
8
|
+
<InputGroup @wrapperClass={{unless @extension.payment_required "mb-0i"}}>
|
|
9
|
+
<Toggle
|
|
10
|
+
@isToggled={{@extension.payment_required}}
|
|
11
|
+
@onToggle={{fn (mut @extension.payment_required)}}
|
|
12
|
+
@label={{t "registry-bridge.developers.extensions.extension-form.extension-payment-required"}}
|
|
13
|
+
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-payment-required-help-text"}}
|
|
14
|
+
/>
|
|
15
|
+
</InputGroup>
|
|
16
|
+
{{#if @extension.payment_required}}
|
|
17
|
+
{{!-- <InputGroup>
|
|
12
18
|
<Toggle
|
|
13
19
|
@isToggled={{@extension.subscription_required}}
|
|
14
20
|
@onToggle={{fn (mut @extension.subscription_required)}}
|
|
15
21
|
@label={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-required"}}
|
|
16
22
|
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-required-help-text"}}
|
|
17
23
|
/>
|
|
18
|
-
</InputGroup>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
</InputGroup> --}}
|
|
25
|
+
{{#if @extension.subscription_required}}
|
|
26
|
+
<InputGroup
|
|
27
|
+
@name={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-billing-period"}}
|
|
28
|
+
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-billing-period-help-text"}}
|
|
29
|
+
>
|
|
30
|
+
<Select
|
|
31
|
+
@value={{@extension.subscription_billing_period}}
|
|
32
|
+
@options={{this.billingPeriodOptions}}
|
|
33
|
+
@onSelect={{fn (mut @extension.subscription_billing_period)}}
|
|
34
|
+
@placeholder={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-billing-period-placeholder"}}
|
|
35
|
+
class="w-full"
|
|
36
|
+
/>
|
|
37
|
+
</InputGroup>
|
|
38
|
+
<InputGroup
|
|
39
|
+
@name={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-amount"}}
|
|
40
|
+
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-subscription-amount-help-text"}}
|
|
41
|
+
@wrapperClass="mb-0i"
|
|
42
|
+
>
|
|
43
|
+
<MoneyInput @value={{@extension.subscription_amount}} @currency="USD" />
|
|
44
|
+
</InputGroup>
|
|
45
|
+
{{else}}
|
|
46
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
|
|
47
|
+
<InputGroup
|
|
48
|
+
@name={{t "registry-bridge.developers.extensions.extension-form.extension-price"}}
|
|
49
|
+
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-price-help-text"}}
|
|
50
|
+
>
|
|
51
|
+
<MoneyInput @value={{@extension.price}} @currency="USD" />
|
|
52
|
+
</InputGroup>
|
|
53
|
+
<InputGroup
|
|
54
|
+
@name={{t "registry-bridge.developers.extensions.extension-form.extension-sale-price"}}
|
|
55
|
+
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-sale-price-help-text"}}
|
|
56
|
+
>
|
|
57
|
+
<MoneyInput @value={{@extension.sale_price}} @currency="USD" />
|
|
58
|
+
</InputGroup>
|
|
59
|
+
</div>
|
|
60
|
+
{{/if}}
|
|
61
|
+
{{/if}}
|
|
39
62
|
{{else}}
|
|
40
|
-
<div class="
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
>
|
|
51
|
-
<MoneyInput @value={{@extension.sale_price}} @currency="USD" />
|
|
52
|
-
</InputGroup>
|
|
63
|
+
<div class="container">
|
|
64
|
+
<div class="max-w-3xl mx-auto mt-4">
|
|
65
|
+
<div class="content">
|
|
66
|
+
<div class="flex flex-col items-center justify-center">
|
|
67
|
+
<h1 class="text-lg font-semibold mb-1">Your account is not setup to accept payments yet.</h1>
|
|
68
|
+
<p class="text-sm mb-2">To accept payments for extensions, you must complete the onboard process via Stripe.</p>
|
|
69
|
+
<Button @type="primary" @size="lg" @text="Start payments onboard" @onClick={{transition-to "developers.payments.onboard"}} />
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
53
73
|
</div>
|
|
54
74
|
{{/if}}
|
|
55
75
|
{{/if}}
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { task } from 'ember-concurrency';
|
|
3
5
|
|
|
4
6
|
export default class ExtensionMonetizeFormComponent extends Component {
|
|
7
|
+
@service fetch;
|
|
5
8
|
@tracked subscriptionModelOptions = ['flat_rate', 'tiered', 'usage'];
|
|
6
9
|
@tracked billingPeriodOptions = ['daily', 'weekly', 'monthly', 'quarterly', 'yearly'];
|
|
10
|
+
@tracked hasStripeConnectAccount = false;
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.lookupStripeConnectAccount.perform();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@task *lookupStripeConnectAccount() {
|
|
18
|
+
try {
|
|
19
|
+
const { hasStripeConnectAccount } = yield this.fetch.get('payments/has-stripe-connect-account', {}, { namespace: '~registry/v1' });
|
|
20
|
+
this.hasStripeConnectAccount = hasStripeConnectAccount;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
this.hasStripeConnectAccount = false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
7
25
|
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<h3 class="dark:text-white font-semibold mb-1">Overview</h3>
|
|
32
32
|
<div class="space-y-1">
|
|
33
33
|
<p class="dark:text-gray-200 text-sm">{{this.extension.description}}</p>
|
|
34
|
-
<p class="dark:text-gray-200 text-sm">{{this.extension.promotional_text}}</p>
|
|
34
|
+
<p class="dark:text-gray-200 text-sm">{{html-safe this.extension.promotional_text}}</p>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
<div>
|
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
import Controller from '@ember/controller';
|
|
2
|
-
import { tracked } from '@glimmer/tracking';
|
|
3
2
|
|
|
4
|
-
export default class DevelopersExtensionsEditMonetizeController extends Controller {
|
|
5
|
-
@tracked subscriptionModelOptions = ['flat_rate', 'tiered', 'usage'];
|
|
6
|
-
@tracked billingPeriodOptions = ['daily', 'weekly', 'monthly', 'quarterly', 'yearly'];
|
|
7
|
-
}
|
|
3
|
+
export default class DevelopersExtensionsEditMonetizeController extends Controller {}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import Controller from '@ember/controller';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { task } from 'ember-concurrency';
|
|
3
5
|
|
|
4
6
|
export default class DevelopersPaymentsIndexController extends Controller {
|
|
7
|
+
@service fetch;
|
|
5
8
|
@tracked hasStripeConnectAccount = true;
|
|
6
9
|
@tracked table;
|
|
7
10
|
@tracked page = 1;
|
|
@@ -37,4 +40,13 @@ export default class DevelopersPaymentsIndexController extends Controller {
|
|
|
37
40
|
width: '20%',
|
|
38
41
|
},
|
|
39
42
|
];
|
|
43
|
+
|
|
44
|
+
@task *lookupStripeConnectAccount() {
|
|
45
|
+
try {
|
|
46
|
+
const { hasStripeConnectAccount } = yield this.fetch.get('payments/has-stripe-connect-account', {}, { namespace: '~registry/v1' });
|
|
47
|
+
this.hasStripeConnectAccount = hasStripeConnectAccount;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
this.hasStripeConnectAccount = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
40
52
|
}
|
|
@@ -15,12 +15,7 @@ export default class DevelopersPaymentsIndexRoute extends Route {
|
|
|
15
15
|
return this.fetch.get('payments/author-received', {}, { namespace: '~registry/v1' });
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const { hasStripeConnectAccount } = await this.fetch.get('payments/has-stripe-connect-account', {}, { namespace: '~registry/v1' });
|
|
21
|
-
controller.hasStripeConnectAccount = hasStripeConnectAccount;
|
|
22
|
-
} catch (error) {
|
|
23
|
-
controller.hasStripeConnectAccount = false;
|
|
24
|
-
}
|
|
18
|
+
setupController(controller) {
|
|
19
|
+
controller.lookupStripeConnectAccount.perform();
|
|
25
20
|
}
|
|
26
21
|
}
|
|
@@ -1,34 +1,42 @@
|
|
|
1
1
|
<Layout::Section::Header @title="Payments">
|
|
2
|
-
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
{{#if this.hasStripeConnectAccount}}
|
|
3
|
+
<div class="flex flex-row space-x-1">
|
|
4
|
+
<span class="text-sm text-black dark:text-white font-bold">Total Amount:</span>
|
|
5
|
+
<span class="text-sm text-black dark:text-white">{{format-currency @model.total_amount "USD"}}</span>
|
|
6
|
+
</div>
|
|
7
|
+
{{/if}}
|
|
6
8
|
</Layout::Section::Header>
|
|
7
9
|
|
|
8
10
|
<Layout::Section::Body class="overflow-y-scroll h-full">
|
|
9
|
-
{{#if this.
|
|
10
|
-
<
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
@selectable={{false}}
|
|
14
|
-
@canSelectAll={{false}}
|
|
15
|
-
@onSetup={{fn (mut this.table)}}
|
|
16
|
-
@pagination={{true}}
|
|
17
|
-
@paginationMeta={{@model.meta}}
|
|
18
|
-
@page={{this.page}}
|
|
19
|
-
@onPageChange={{fn (mut this.page)}}
|
|
20
|
-
/>
|
|
11
|
+
{{#if this.lookupStripeConnectAccount.isRunning}}
|
|
12
|
+
<div class="flex items-center justify-center flex-1 p-4">
|
|
13
|
+
<Spinner @loadingMessage="Loading monetization settings..." @loadingMessageClass="ml-2 text-black dark:text-white" @wrapperClass="flex flex-row items-center" />
|
|
14
|
+
</div>
|
|
21
15
|
{{else}}
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
{{#if this.hasStripeConnectAccount}}
|
|
17
|
+
<Table
|
|
18
|
+
@rows={{@model.data}}
|
|
19
|
+
@columns={{this.columns}}
|
|
20
|
+
@selectable={{false}}
|
|
21
|
+
@canSelectAll={{false}}
|
|
22
|
+
@onSetup={{fn (mut this.table)}}
|
|
23
|
+
@pagination={{true}}
|
|
24
|
+
@paginationMeta={{@model.meta}}
|
|
25
|
+
@page={{this.page}}
|
|
26
|
+
@onPageChange={{fn (mut this.page)}}
|
|
27
|
+
/>
|
|
28
|
+
{{else}}
|
|
29
|
+
<div class="container">
|
|
30
|
+
<div class="max-w-3xl mx-auto mt-4">
|
|
31
|
+
<div class="content">
|
|
32
|
+
<div class="flex flex-col items-center justify-center">
|
|
33
|
+
<h1 class="text-lg font-semibold mb-1">Your account is not setup to accept payments yet.</h1>
|
|
34
|
+
<p class="text-sm mb-2">To accept payments for extensions, you must complete the onboard process via Stripe.</p>
|
|
35
|
+
<Button @type="primary" @size="lg" @text="Start payments onboard" @onClick={{transition-to "developers.payments.onboard"}} />
|
|
36
|
+
</div>
|
|
29
37
|
</div>
|
|
30
38
|
</div>
|
|
31
39
|
</div>
|
|
32
|
-
|
|
40
|
+
{{/if}}
|
|
33
41
|
{{/if}}
|
|
34
42
|
</Layout::Section::Body>
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/registry-bridge",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"require": {
|
|
22
22
|
"php": "^8.0",
|
|
23
|
-
"fleetbase/core-api": "^1.5.
|
|
23
|
+
"fleetbase/core-api": "^1.5.1",
|
|
24
24
|
"laravel/cashier": "^15.2.1",
|
|
25
25
|
"php-http/guzzle7-adapter": "^1.0",
|
|
26
26
|
"psr/http-factory-implementation": "*",
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/registry-bridge-engine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "extensions"
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@babel/core": "^7.23.2",
|
|
42
42
|
"@fleetbase/ember-core": "^0.2.14",
|
|
43
|
-
"@fleetbase/ember-ui": "^0.2.
|
|
43
|
+
"@fleetbase/ember-ui": "^0.2.20",
|
|
44
44
|
"@fortawesome/ember-fontawesome": "^2.0.0",
|
|
45
45
|
"@fortawesome/fontawesome-svg-core": "6.4.0",
|
|
46
46
|
"@fortawesome/free-solid-svg-icons": "6.4.0",
|
|
@@ -40,21 +40,27 @@ class RegistryAuthController extends Controller
|
|
|
40
40
|
return response()->error('Invalid registry token provided for authentication.', 401);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
$
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
// Init unauthorized extensions
|
|
44
|
+
$unauthorizedExtensionNames = collect();
|
|
45
|
+
|
|
46
|
+
// Unless admin the registry user is only allowed access to their extensions
|
|
47
|
+
if ($registryUser->isNotAdmin()) {
|
|
48
|
+
// Fetch unauthorized extensions
|
|
49
|
+
$unauthorizedExtensions = RegistryExtension::where('payment_required', true)
|
|
50
|
+
->whereDoesntHave('purchases', function ($query) use ($registryUser) {
|
|
51
|
+
$query->where('company_uuid', $registryUser->company_uuid);
|
|
52
|
+
})
|
|
53
|
+
->whereHas('currentBundle')
|
|
54
|
+
->with('currentBundle')
|
|
55
|
+
->get();
|
|
56
|
+
|
|
57
|
+
// Map to unathorized to package names
|
|
58
|
+
$unauthorizedExtensionNames = $unauthorizedExtensions->map(function ($registryExtension) {
|
|
59
|
+
$composerJson = $registryExtension->currentBundle->meta['composer.json'] ?? [];
|
|
60
|
+
|
|
61
|
+
return $composerJson['name'] ?? null;
|
|
62
|
+
})->filter()->values();
|
|
63
|
+
}
|
|
58
64
|
|
|
59
65
|
// Done
|
|
60
66
|
return response()->json([
|
|
@@ -553,7 +553,11 @@ class RegistryExtension extends Model
|
|
|
553
553
|
}
|
|
554
554
|
|
|
555
555
|
// Update stripe product id
|
|
556
|
-
$this->
|
|
556
|
+
if ($this->exists) {
|
|
557
|
+
$this->update(['stripe_product_id' => $product->id]);
|
|
558
|
+
} else {
|
|
559
|
+
$this->setAttribute('stripe_product_id', $product->id);
|
|
560
|
+
}
|
|
557
561
|
|
|
558
562
|
return $product;
|
|
559
563
|
}
|
|
@@ -576,8 +580,8 @@ class RegistryExtension extends Model
|
|
|
576
580
|
$this->getStripeProduct();
|
|
577
581
|
}
|
|
578
582
|
|
|
579
|
-
$stripe
|
|
580
|
-
$price
|
|
583
|
+
$stripe = Utils::getStripeClient();
|
|
584
|
+
$price = null;
|
|
581
585
|
if ($stripe) {
|
|
582
586
|
$prices = $stripe->prices->all(['product' => $this->stripe_product_id, 'limit' => 1, 'active' => true]);
|
|
583
587
|
$price = is_array($prices->data) && count($prices->data) ? $prices->data[0] : null;
|