Skip to content

Commit

Permalink
Add ability to link customers
Browse files Browse the repository at this point in the history
  • Loading branch information
bencroker committed Apr 26, 2024
1 parent 978ac8c commit f17e702
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 42 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Release Notes for Plugin Sales

## 3.1.0 - 2024-04-26

### Added

- Added the ability to link customers in the plugin settings.

### Changed

- Saving the plugin settings no longer automatically refreshes all plugin sales. Instead, a link is provided to perform a full refresh.

## 3.0.1 - 2024-04-23

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "putyourlightson/craft-plugin-sales",
"description": "Your Craft CMS plugin sales visualised in the control panel.",
"version": "3.0.1",
"version": "3.1.0",
"type": "craft-plugin",
"homepage": "https://putyourlightson.com/plugins/plugin-sales",
"license": "proprietary",
Expand Down
19 changes: 0 additions & 19 deletions src/PluginSales.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
use Craft;
use craft\base\Plugin;
use craft\events\PluginEvent;
use craft\helpers\Queue;
use craft\helpers\UrlHelper;
use craft\log\MonologTarget;
use craft\services\Plugins;
use craft\services\ProjectConfig;
use craft\web\twig\variables\CraftVariable;
use Monolog\Formatter\LineFormatter;
use Psr\Log\LogLevel;
use putyourlightson\pluginsales\jobs\RefreshSalesJob;
use putyourlightson\pluginsales\models\SettingsModel;
use putyourlightson\pluginsales\services\PluginsService;
use putyourlightson\pluginsales\services\ReportsService;
Expand Down Expand Up @@ -84,7 +82,6 @@ public function init(): void

$this->registerVariables();
$this->registerLogTarget();
$this->registerRefreshAfterSettingsSaved();

// Register control panel events
if (Craft::$app->getRequest()->getIsCpRequest()) {
Expand Down Expand Up @@ -181,20 +178,4 @@ function(PluginEvent $event) {
}
);
}

/**
* Registers a refresh after settings are saved.
*/
private function registerRefreshAfterSettingsSaved(): void
{
Event::on(Plugins::class, Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS,
function(PluginEvent $event) {
if ($event->plugin === $this) {
PluginSales::$plugin->sales->delete();

Queue::push(new RefreshSalesJob(), null, null, PluginSales::$plugin->settings->refreshSalesJobTtr);
}
}
);
}
}
42 changes: 30 additions & 12 deletions src/controllers/SalesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
namespace putyourlightson\pluginsales\controllers;

use Craft;
use craft\helpers\Queue;
use craft\web\Controller;
use putyourlightson\pluginsales\jobs\RefreshSalesJob;
use putyourlightson\pluginsales\PluginSales;
use yii\web\Response;

Expand All @@ -17,19 +19,35 @@ class SalesController extends Controller
*/
public function actionRefresh(): Response
{
$refreshed = PluginSales::$plugin->sales->refresh();

if ($refreshed !== false) {
Craft::$app->getSession()->setNotice(
Craft::t('plugin-sales', '{count} plugin sale(s) refreshed.', ['count' => $refreshed])
);
} else {
Craft::$app->getSession()->setError(
Craft::t('plugin-sales', 'Plugin sales could not be refreshed. Check the credentials and network connection.')
);
}
Queue::push(
job: new RefreshSalesJob(),
ttr: PluginSales::$plugin->settings->refreshSalesJobTtr,
);

return $this->asSuccess(
message: Craft::t('plugin-sales', 'Plugin sales queued for refreshing.'),
redirect: 'plugin-sales',
);
}

/**
* Refreshes all plugin sales.
*/
public function actionRefreshAll(): Response
{
$this->requireAdmin();

PluginSales::$plugin->sales->delete();

Queue::push(
job: new RefreshSalesJob(),
ttr: PluginSales::$plugin->settings->refreshSalesJobTtr,
);

return $this->redirect('plugin-sales');
return $this->asSuccess(
message: Craft::t('plugin-sales', 'Plugin sales successfully deleted and queued for refreshing.'),
redirect: 'settings/plugins/plugin-sales',
);
}

/**
Expand Down
8 changes: 3 additions & 5 deletions src/controllers/SlideoutController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,21 @@ class SlideoutController extends Controller
public function actionRender(): Response
{
$customer = $this->request->getRequiredParam('customer');
$linkedCustomers = PluginSales::$plugin->settings->getLinkedCustomers($customer);
$url = $this->getUrlFromCustomer($customer);
$sales = PluginSales::$plugin->reports->getSalesData($customer);

return $this->asCpScreen()
->contentTemplate('plugin-sales/_slideout', [
'customer' => $customer,
'linkedCustomers' => $linkedCustomers,
'url' => $url,
'sales' => $sales,
]);
}

private function getUrlFromCustomer(?string $customer): ?string
private function getUrlFromCustomer(string $customer): ?string
{
if ($customer === null) {
return null;
}

$domain = explode('@', $customer)[1] ?? null;

if ($domain === null) {
Expand Down
21 changes: 21 additions & 0 deletions src/models/SettingsModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,32 @@ class SettingsModel extends Model
*/
public array $colourPalette = ['3B82F6', '4ADE80', 'FBBF24', 'F43F5E', '7DD3FC', '059669', 'FB923C', 'D946EF', 'A16207', '94A3B8'];

/**
* @var array
*/
public array $linkedCustomers = [];

/**
* @var int
*/
public int $refreshSalesJobTtr = 3600;

/**
* Returns linked customers for the given customer.
*/
public function getLinkedCustomers(string $customer): array
{
$linkedCustomers = [];

foreach ($this->linkedCustomers as $linkedCustomer) {
if ($linkedCustomer['canonical'] === $customer) {
$linkedCustomers[] = $linkedCustomer['linked'];
}
}

return $linkedCustomers;
}

/**
* @inheritdoc
*/
Expand Down
23 changes: 22 additions & 1 deletion src/services/SalesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ public function refresh(callable $setProgressHandler = null): bool|int
}
}

$this->updateLinkedCustomers();
$this->updateFirstSales();

$refreshRecord = new RefreshRecord();
Expand Down Expand Up @@ -309,7 +310,7 @@ private function saveSales(array $sales): int
'saleId' => $sale['id'],
'pluginId' => $sale['plugin']['id'],
'edition' => $sale['edition']['handle'],
'renewal' => ($sale['purchasableType'] == 'craftnet\\plugins\\PluginRenewal'),
'renewal' => ($sale['purchasableType'] === 'craftnet\\plugins\\PluginRenewal'),
'grossAmount' => $sale['grossAmount'],
'netAmount' => $sale['netAmount'],
'customer' => $sale['customer']['ownerReference'],
Expand All @@ -325,6 +326,26 @@ private function saveSales(array $sales): int
return $count;
}

/**
* Updates all linked customers.
*/
private function updateLinkedCustomers(): void
{
$linkedCustomers = PluginSales::$plugin->settings->linkedCustomers;

foreach ($linkedCustomers as $linkedCustomer) {
Db::update(
SaleRecord::tableName(),
[
'customer' => $linkedCustomer['canonical'],
],
[
'customer' => $linkedCustomer['linked'],
]
);
}
}

/**
* Updates all first sale records.
*/
Expand Down
9 changes: 9 additions & 0 deletions src/templates/_slideout.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<h2>
{{ customer }}
{% if linkedCustomers %}
<span class="info">
Linked to from
{% for linkedCustomer in linkedCustomers %}
<code>{{ linkedCustomer }}</code>
{{- not loop.last ? ',' }}
{% endfor %}
</span>
{% endif %}
{% if url %}
<a href="{{ url }}" title="{{ url }}" target="_blank" rel="noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" style="display: inline; width: 20px; height: 20px;">
Expand Down
51 changes: 47 additions & 4 deletions src/templates/settings.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{% import '_includes/forms' as forms %}

<p class='warning with-icon first'>
Saving these settings does
<em>not</em> trigger a job to refresh your plugin sales. To perform a full refresh,
<a href="{{ actionUrl('plugin-sales/sales/refresh-all') }}">click here</a>.
</p>

{{ forms.autosuggestField({
label: 'Craft Console Username/Email'|t('plugin-sales'),
instructions: 'The username or email address you use to login to your Craft Console account.'|t('plugin-sales'),
Expand All @@ -8,7 +14,6 @@
value: settings.email,
errors: settings.getErrors('email'),
required: true,
first: true,
}) }}

{{ forms.autosuggestField({
Expand Down Expand Up @@ -91,6 +96,44 @@
required: true,
}, input) }}

<p class='warning with-icon'>
Saving these settings will trigger a job to refresh your plugin sales. Once complete they will be visible at the <a href='{{ url('plugin-sales') }}' class='go'>plugin page</a>
</p>
{% set cols = {
heading: {
type: 'heading',
heading: "Site"|t('blitz'),
},
cacheFolderPath: {
type: 'html',
heading: "Cache Folder Path"|t('blitz'),
class: 'code',
},
pages: {
type: 'html',
heading: "Pages"|t('blitz'),
},
includes: {
type: 'html',
heading: "Includes"|t('blitz'),
},
} %}

{{ forms.editableTableField({
label: 'Linked Customers'|t('plugin-sales'),
instructions: 'Customers can be linked together, useful to ease the transition from Craft ID to Craft Console, which added support for organisations.'|t('plugin-sales'),
name: 'linkedCustomers',
id: 'linkedCustomers',
cols: {
canonical: {
type: 'singleline',
heading: 'Canonical customer'|t('plugin-sales'),
},
linked: {
type: 'singleline',
heading: 'Linked customer'|t('plugin-sales'),
},
},
rows: settings.linkedCustomers,
addRowLabel: 'Add a linked customer'|t('plugin-sales'),
allowAdd: true,
allowDelete: true,
allowReorder: true,
}) }}

0 comments on commit f17e702

Please sign in to comment.