ldc-tregalette/app/Http/Controllers/Fo/Klub/MesBrController.php
Vincent BRIDIER 6d4500c360 Bump CRM V4
2024-07-16 15:55:49 +00:00

371 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers\Fo\Klub;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\MesBr\PrintCouponsRequest;
use App\Models\Customer;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use Symfony\Component\HttpFoundation\StreamedResponse;
class MesBrController extends Controller
{
/**
* Show customer BR list
*
* @return \Illuminate\Contracts\View\View
*/
public function showCustomerBrList(): View
{
/** @var \App\Models\Customer $customer */
$customer = auth('frontend')->user();
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->api_data;
$mesBr = $this->fetchActiveBr($crmCustomer);
return view('fo.pages.klub.mesbr', compact('crmCustomer', 'mesBr'));
}
/**
* Fetch PDF BR
*
* @param \App\Http\Requests\Fo\MesBr\PrintCouponsRequest $request
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function fetchBrPdf(PrintCouponsRequest $request): StreamedResponse
{
/** @var \App\Models\Customer $customer */
$customer = auth('frontend')->user();
$pdf = $this->fetchBrPdfFromMesBr($customer, $request->post('coupon'));
if ($pdf === null) {
\back()->withErrors([
'coupon' => trans('Impossible de récupérer le fichier pdf')
])->throwResponse();
}
return response()->streamDownload(function () use ($pdf) {
echo $pdf;
}, trans('mes-bons-de-reduction-:date.pdf', [
'date' => now()->isoFormat('DD-MM-Y-HH\hmm')
]), [
'Cache-Control' => 'public, must-revalidate, max-age=0',
'Content-Description' => 'File Transfer',
'Content-Type' => 'application/pdf',
'Expires' => 'Sat, 26 Jul 1997 05:00:00 GMT',
'Last-Modified' => gmdate('D, d M Y H:i:s') . ' GMT',
// For glory.
'X-Generator' => 'mPDF'
]);
}
/**
* Fetch coupons PDF
*
* @param \App\Models\Customer $customer
* @param array $coupons
* @return string|null
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
private function fetchBrPdfFromMesBr(Customer $customer, array $coupons): string|null
{
// phpcs:enable
// * Phase - 1 Recupération des informations CRM
/** @var \LDC\LDCCRM\Models\Customer*/
$crmUser = $this->fetchCrmCustomer($customer);
// * Phase - 2 Mise à jour du coupon dans MesBr
try {
/** @var \LDC\MESBR\MesBr */
$mesBr = app('mesBrAPI');
// * MaJ Customer
/** @var integer */
retry(3, function () use ($mesBr, $crmUser) {
/**
* Parce que MesBr n'est pas fiable il faut retenter pour avoir
* l'id client, des fois cet id sera dans hashcode...
*
* Id est necessaire pour update panier..
*/
$result = $mesBr->updateCustomer($crmUser->hashcode, $crmUser->email, $crmUser->country->label());
if (optional($result)->status !== "OK") {
throw new \RuntimeException(
\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
$result->code ?? 'Undefined',
$result->message ?? 'Undefined'
)
);
}
/** @var object|null */
$crm_customer = optional($result)->customer;
if (empty(optional($crm_customer)->id)) {
throw new \RuntimeException(
'MESBR : Une erreur est survenue. Update Customer n\'as pas retourné le customer id'
);
}
return intval($crm_customer->id);
}, 100);
// * Maj Panier
$result = $mesBr->printCoupons($crmUser->hashcode, $coupons);
$result = \is_object($result) ? (array)$result : $result;
if (Arr::get($result, 'status') !== "OK") {
report(new \RuntimeException(
\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
Arr::get($result, 'code') ?? 'Undefined',
Arr::get($result, 'message') ?? 'Undefined',
)
));
return null;
}
// * La réponse est conforme ?
$needed_fields = ['pdf'];
if (!Arr::has($result, $needed_fields)) {
report(new \RuntimeException(sprintf(
'MESBR : Il manques des champs dans la réponse, attendu => %s, donné => %s',
json_encode($needed_fields),
json_encode($result),
)));
return null;
}
// * Tout est OK
return \base64_decode(Arr::get($result, 'pdf')) ?: null;
} catch (\RuntimeException $e) {
report($e);
// * Retenter ?
return null;
} //end try
}
/**
* Fetch customer BRs
*
* This should be an object like
*
* +"status": "OK"
* +"name": "Test tregalette"
* +"limited_printing": 0
* +"total": 15
* +"available_amount": 10.5
* +"total_amount": 10.5
* +"coupons": array{
* +"code": "2950675055365"
* +"name": "Webcoupon 1€ Filet de canard Confit"
* +"value": 1
* +"used": false
* +"desktop_image_available": "https://dev.mesbr.eu/coupons/96kjV1ZwGb7Z4m8wyzBCuurEFPlSLHFaAGVWuO8F.png"
* +"desktop_image_unavailable": "https://dev.mesbr.eu/coupons/K7BSVFOCs2K1XCi78wR2YgEfGyFH6AJthyupTEYz.png"
* +"mobile_image_available": "https://dev.mesbr.eu/coupons/KE3YodVeDPSG7pVzPQZhPEpVGlxwjTPWCJ8WGN29.png"
* +"mobile_image_unavailable": "https://dev.mesbr.eu/coupons/FOFhdT0d2X1AURQfYm9O7ac2ca9SGUk3IHCTWJiZ.png"
* }
*
* @param \LDC\LDCCRM\Models\Customer $customer
* @return object|null
*/
private function fetchActiveBr(\LDC\LDCCRM\Models\Customer $customer): object|null
{
if (!$this->createOrUpdateMesBrCustomer($customer)) {
return null;
}
/** @var \LDC\MESBR\MesBr */
$mesBr = app('mesBrAPI');
$message = null;
try {
$res = $mesBr->getMurCustomer($customer->hashcode);
if (!$res) {
$message = "ERROR MesBR API : getMurCustomer on api failed {$customer->hashcode}";
} elseif (Arr::get((array)$res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
'message',
"ERROR MesBR API : getMurCustomer on api failed (no message) {$customer->hashcode}"
);
}
if ($message === null) {
// * Replace local picture urls for dev Env
if (config('app.env') === 'local') {
$res = self::replaceCouponsPictureHost($res);
}
return $res;
}
report(new \RuntimeException($message));
return null;
} catch (\Exception $e) {
report($e);
return null;
} //end try
}
/**
* Report for sure true if the customer is set in mesBr
*
* @param \LDC\LDCCRM\Models\Customer $customer
* @return boolean
*/
private function createOrUpdateMesBrCustomer(\LDC\LDCCRM\Models\Customer $customer): bool
{
// * Ajout du customer sur mes BR
/** @var \LDC\MESBR\MesBr */
$mesBr = app('mesBrAPI');
$message = null;
/**
* Observed behavior,
* calling multiple times createCustomer results in
* create or update the customer.
*/
try {
// * Create (or update) the customer
$res = $mesBr->createCustomer($customer->hashcode, $customer->email, 'France');
if (!$res) {
$message = "ERROR MesBR API : createCustomer on api failed {$customer->hashcode}";
} elseif (Arr::get((array)$res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
'message',
"ERROR MesBR API : createCustomer on api failed (no message) {$customer->hashcode}"
);
}
if ($message === null) {
return true;
}
report(new \RuntimeException($message));
return false;
} catch (\Exception $e) {
report($e);
return false;
} //end try
}
/**
* Fetch Crm Customer
*
* @param \App\Models\Customer $customer
* @return \LDC\LDCCRM\Models\Customer
* @throws \Illuminate\Http\Exceptions\HttpResponseException In case of failure or customer not activated.
*/
private function fetchCrmCustomer(Customer $customer): \LDC\LDCCRM\Models\Customer
{
try {
$crmUser = $customer->api_data;
// ? Le compte est vérifié ?
if (!$crmUser->status) {
// * Doit avoir un compte vérifié pour imprimer.
response()->redirectToRoute('fo.verification.notice')
->with('error', trans('Votre compte doit être activé'))
->throwResponse();
}
return $crmUser;
} catch (ApiErrorException $e) {
// * Customer is not found.
if ($e->getApiError()->equals(ApiError::modelNotFound)) {
// * Déconnexion immédiate et retour maison.
auth('frontend')->logout();
response()->redirectToRoute('fo.homepage')
->with('error', trans('Une erreur est survenue, compte introuvable.'))
->throwResponse();
}
report($e);
Log::error('Unhandled response ' . $e->getApiError()->label());
// * Retenter ?
back()->with('error', trans('Une erreur est survenue, veuillez réssayer.'))->throwResponse();
} catch (HttpResponseException $e) {
// * continue this
throw $e;
} catch (CrmException | \Exception $e) {
report($e);
// * Retenter ?
back()->with('error', trans('Une erreur est survenue, veuillez réssayer.'))->throwResponse();
} //end try
}
// * STATIC Fetch BR
/**
* Static method to fetch br List
*
* ! see fetchActiveBr for output object definition
*
* @return object|null
*/
public static function getStaticBr(): object|null
{
/** @var \LDC\MESBR\MesBr */
$mesBr = app('mesBrAPI');
$message = null;
try {
$res = $mesBr->getMur();
if (!$res) {
$message = 'ERROR MesBR API : getMur on api failed';
} elseif (Arr::get((array)$res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
'message',
'ERROR MesBR API : getMur on api failed (no message)'
);
}
if ($message === null) {
// * Replace local picture urls for dev Env
if (config('app.env') === 'local') {
$res = self::replaceCouponsPictureHost($res);
}
return $res;
}
report(new \RuntimeException($message));
return null;
} catch (\Exception $e) {
report($e);
return null;
} //end try
}
/**
* Replace coupons picture host
*
* @param object $res
* @return object
*/
private static function replaceCouponsPictureHost(object $res): object
{
$replaceUrl = fn (?string $url) => $url ? Str::replace(
'https://dev.mesbr.eu',
config('mesbr.endpoint'),
$url
) : $url;
$res->coupons = collect($res->coupons)->map(fn (object $coupon) =>
(object)array_merge((array)$coupon, [
'desktop_image_available' => $replaceUrl($coupon->desktop_image_available),
'desktop_image_unavailable' => $replaceUrl($coupon->desktop_image_unavailable),
'mobile_image_available' => $replaceUrl($coupon->mobile_image_available),
'mobile_image_unavailable' => $replaceUrl($coupon->mobile_image_unavailable),
]))->all();
return $res;
}
}