fix: make the selected channel apply changes to product each time

This commit is contained in:
Valentin Lab
2025-10-05 12:33:08 +02:00
parent cc8dfa29b4
commit a5b2196b32
6 changed files with 131 additions and 30 deletions

View File

@@ -8,6 +8,7 @@ use App\Repositories\Shop\CustomerAddresses;
use App\Repositories\Shop\Customers;
use App\Repositories\Shop\Offers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;
class CustomerController extends Controller
@@ -81,14 +82,33 @@ class CustomerController extends Controller
}
}
$customerId = $data['id'] ?? Customers::getId();
$requestedDefaultSaleChannelId = $data['default_sale_channel_id'] ?? null;
$hasDefaultSaleChannelColumn = Schema::hasColumn('shop_customers', 'default_sale_channel_id');
if (! $hasDefaultSaleChannelColumn) {
unset($data['default_sale_channel_id']);
}
$customer = Customers::store($data);
if ($customer) {
Customers::guard()->setUser($customer->fresh(['sale_channels']));
if (array_key_exists('default_sale_channel_id', $data)) {
session(['shop.default_sale_channel_id' => $data['default_sale_channel_id']]);
Baskets::refreshPrices((int) $data['default_sale_channel_id']);
}
if (! $customer) {
return response()->json([
'error' => 1,
'message' => __('Impossible de mettre à jour votre profil pour le moment.'),
], 422);
}
if ($hasDefaultSaleChannelColumn && $requestedDefaultSaleChannelId !== null) {
Customers::setDefaultSaleChannel($customerId, $requestedDefaultSaleChannelId);
}
$freshCustomer = Customers::get($customerId, ['sale_channels']);
Customers::guard()->setUser($freshCustomer);
if ($requestedDefaultSaleChannelId !== null) {
session(['shop.default_sale_channel_id' => $requestedDefaultSaleChannelId]);
Baskets::refreshPrices((int) $requestedDefaultSaleChannelId);
}
return response()->json(['error' => 0]);

View File

@@ -6,6 +6,8 @@ use App\Models\Shop\Article;
use App\Repositories\Botanic\Species;
use App\Repositories\Botanic\Varieties;
use App\Repositories\Shop\SaleChannels;
use App\Repositories\Shop\Customers;
use Illuminate\Support\Facades\Schema;
use App\Repositories\Core\Comments;
use App\Traits\Model\Basic;
use App\Traits\Repository\Imageable;
@@ -72,12 +74,31 @@ class Articles
public static function getArticleToSell($id, $saleChannelId = false)
{
$saleChannelId = $saleChannelId ?: SaleChannels::getDefaultID();
$sessionSaleChannelId = session('shop.default_sale_channel_id');
$customer = Customers::getAuth();
$hasDefaultSaleChannelColumn = Schema::hasColumn('shop_customers', 'default_sale_channel_id');
$customerDefaultSaleChannelId = ($customer && $hasDefaultSaleChannelColumn)
? $customer->default_sale_channel_id
: null;
$customerSaleChannelIds = [];
if ($customer) {
$customer->loadMissing('sale_channels:id');
$customerSaleChannelIds = $customer->sale_channels->pluck('id')->toArray();
}
$data = self::getArticle($id);
$data['offers'] = self::getOffersGroupedByNature($id, $saleChannelId);
$currentSaleChannel = $saleChannelId ? SaleChannels::get($saleChannelId) : null;
$data['current_sale_channel'] = $currentSaleChannel ? $currentSaleChannel->toArray() : null;
$data['available_sale_channels'] = Offers::getSaleChannelsForArticle($id);
$data['debug_sale_channel'] = [
'session_default_sale_channel_id' => $sessionSaleChannelId,
'customer_default_sale_channel_id' => $customerDefaultSaleChannelId,
'customer_linked_sale_channel_ids' => $customerSaleChannelIds,
'resolved_sale_channel_id' => $saleChannelId,
'has_default_sale_channel_column' => $hasDefaultSaleChannelColumn,
];
return $data;
}

View File

@@ -179,6 +179,24 @@ class Customers
return $customer->sale_channels()->sync($saleChannels);
}
public static function setDefaultSaleChannel($customerId, $saleChannelId)
{
if (! $customerId) {
return false;
}
$customer = self::get($customerId);
if (! $customer) {
return false;
}
$customer->default_sale_channel_id = $saleChannelId ?: null;
$customer->save();
return $customer->fresh(['sale_channels']);
}
public static function create($data)
{
$data['uuid'] = Str::uuid();

View File

@@ -182,27 +182,45 @@ class Offers
$offers = Offer::query()
->byArticle($articleId)
->with('article')
->with([
'article',
'tariff:id,status_id',
])
->get();
return $channels->map(function ($channel) use ($offers) {
$priceValue = null;
$candidateOffer = null;
foreach ($offers as $offer) {
$priceCandidate = self::getPrice($offer->id, 1, $channel->id);
if ($priceCandidate && (float) $priceCandidate->price_taxed > 0) {
$priceValue = $priceCandidate;
$candidateOffer = $offer;
break;
}
}
$offerId = $candidateOffer ? $candidateOffer->id : null;
$offerStock = $candidateOffer ? (int) $candidateOffer->stock_current : null;
$offerIsActive = $candidateOffer ? (int) $candidateOffer->status_id === 1 : false;
$offerTariffStatus = $candidateOffer && $candidateOffer->tariff ? (int) $candidateOffer->tariff->status_id : null;
$offerHasStock = $candidateOffer && $candidateOffer->stock_current !== null
? (float) $candidateOffer->stock_current > 0
: null;
return [
'id' => $channel->id,
'name' => $channel->name,
'code' => $channel->code,
'price_taxed' => $priceValue ? (float) $priceValue->price_taxed : null,
'quantity' => $priceValue ? (int) $priceValue->quantity : null,
'offer_id' => $offerId,
'offer_is_active' => $offerIsActive,
'offer_stock_current' => $offerStock,
'offer_has_stock' => $offerHasStock,
'tariff_status_id' => $offerTariffStatus,
];
})->toArray();
}

View File

@@ -48,35 +48,53 @@
</div>
<div class="col-lg-3 col-xs-12">
@if (config('app.debug') && ($article['current_sale_channel'] ?? false))
@if (config('app.debug') && !empty($article['available_sale_channels']))
<div class="alert alert-info p-2 mb-3">
<strong>Canal actif :</strong>
{{ $article['current_sale_channel']['name'] ?? 'N/A' }}
<span class="d-block small text-muted">
ID {{ $article['current_sale_channel']['id'] ?? '' }} · Code {{ $article['current_sale_channel']['code'] ?? '' }}
</span>
@if (!empty($article['available_sale_channels']))
<hr class="my-2">
<strong class="d-block">Offres disponibles dans :</strong>
<ul class="list-unstyled mb-0 small">
@foreach ($article['available_sale_channels'] as $channel)
<li class="d-flex justify-content-between align-items-start">
<span>
<strong class="d-block">Offres :</strong>
<ul class="list-unstyled mb-0 small">
@php
$currentSaleChannelId = $article['current_sale_channel']['id'] ?? null;
@endphp
@foreach ($article['available_sale_channels'] as $channel)
@php
$isCurrentChannel = $currentSaleChannelId === $channel['id'];
$priceTaxed = $channel['price_taxed'] ?? null;
$quantity = $channel['quantity'] ?? null;
$offerStock = $channel['offer_stock_current'] ?? null;
$offerIsActive = $channel['offer_is_active'] ?? false;
$offerHasStock = $channel['offer_has_stock'] ?? null;
$highlightStyle = $isCurrentChannel ? 'background-color: rgba(0, 0, 0, 0.06);' : '';
$nameClass = ($offerIsActive && $offerHasStock !== false) ? '' : 'text-muted';
$flags = [];
if (! $offerIsActive) {
$flags[] = 'inactive';
}
if ($offerHasStock === false) {
$flags[] = 'no-stock';
}
@endphp
<li style="{{ $highlightStyle }}">
<div class="d-flex justify-content-between align-items-start">
<span class="{{ $nameClass }}">
{{ $channel['name'] }}
<span class="d-block text-muted" style="font-size: 0.85em; padding-left: 0.9em;">code {{ $channel['code'] }}</span>
<span class="d-block text-muted" style="font-size: 0.85em; padding-left: 0.9em;">
Code {{ $channel['code'] }}{!! $flags ? ' · <strong class="text-dark">'.implode('</strong> · <strong class="text-dark">', $flags).'</strong>' : '' !!}
</span>
</span>
@if (isset($channel['price_taxed']))
<span class="ml-2 text-nowrap text-right">
{{ number_format($channel['price_taxed'], 2, ',', ' ') }} TTC
@if (! empty($channel['quantity']))
<span class="d-block text-muted" style="font-size: 0.85em;">Qté min. {{ $channel['quantity'] }}</span>
@if ($priceTaxed !== null)
<span class="ml-2 text-nowrap text-right {{ $nameClass }}">
{{ number_format($priceTaxed, 2, ',', ' ') }} TTC
@if (! empty($quantity))
<span class="d-block text-muted" style="font-size: 0.85em;">Qté min. {{ $quantity }}</span>
@endif
</span>
@else
<span class="ml-2 text-muted"></span>
@endif
</li>
@endforeach
</ul>
@endif
</div>
</li>
@endforeach
</ul>
</div>
@endif
@include('Shop.Articles.partials.ArticleAddBasket')

View File

@@ -157,6 +157,12 @@
? xhr.responseJSON.message
: "{{ __('Une erreur est survenue lors de l\'enregistrement du canal de vente préféré.') }}";
console.error('Sale channel update failed', {
status: xhr.status,
response: xhr.responseJSON || xhr.responseText,
selectedSaleChannel
});
alert(message);
if (currentSaleChannelId) {