Feature: Adding Customer Recovery Consent to core, assigning it to the customer

This commit is contained in:
2026-09-25 14:12:55 +03:00
parent 8fdaeda0ba
commit 935b1d02f9
4 changed files with 83 additions and 0 deletions
@@ -13,6 +13,7 @@ use Modules\Core\Customer\Events\CustomerAddressCreated;
use Modules\Core\Customer\Events\CustomerAddressDeleted;
use Modules\Core\Customer\Events\CustomerAddressUpdated;
use Modules\Core\Customer\Events\CustomerProfileUpdated;
use Modules\Core\Customer\Events\CustomerRecoveryConsentSet;
use Modules\Core\Customer\Exceptions\AddressNotFoundException;
use Modules\Core\Customer\Exceptions\OrderNotFoundException;
use Modules\Core\Customer\Models\Customer;
@@ -235,6 +236,43 @@ class CustomerAccountService
return $customer;
}
/**
* The account's standing "email me a reminder if I don't finish my
* order" opt-in — same meta shape Checkout\Services\CheckoutService::
* setRecoveryConsent() writes on the current CART (recovery_consent,
* recovery_consent_at, recovery_consent_policy_version), written here
* onto the CUSTOMER instead, so it survives across carts/sessions as a
* standing account preference. The two are independent: opting out on
* the customer doesn't retroactively change a cart already opted in,
* and vice versa — a caller that wants both kept in sync (e.g. 3dealer
* applying a customer's standing preference to the current cart too)
* calls both services itself.
*
* A no-op (no write, no event) when $consent already matches what's
* stored — unlike updateProfile()'s address/profile writes, which
* always write and dispatch even when nothing actually changed.
*/
public function setRecoveryConsent(Authenticatable $user, bool $consent): Customer
{
$customer = $this->customerOrFail($user);
if ((bool) data_get($customer->meta, 'recovery_consent') === $consent) {
return $customer;
}
$customer->meta = [
...($customer->meta?->toArray() ?? []),
'recovery_consent' => $consent,
'recovery_consent_at' => $consent ? now()->toIso8601String() : null,
'recovery_consent_policy_version' => $consent ? config('legal.privacy_policy_version') : null,
];
$customer->save();
Event::dispatch(new CustomerRecoveryConsentSet($customer, $consent, $user));
return $customer;
}
/**
* @throws LogicException if $user has no paired Customer at all —
* distinct from AddressNotFoundException/OrderNotFoundException