This commit is contained in:
ludo
2025-01-03 03:46:45 +01:00
parent b3fbfc38e7
commit befaa40b48
44 changed files with 442 additions and 165 deletions

View File

@@ -25,6 +25,7 @@ class ContentsDataTable extends DataTable
protected function getColumns()
{
return [
Column::make('id')->title('id'),
Column::make('text')->title('Texte'),
$this->makeColumnButtons(),
];

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin\Shop;
use App\Datatables\Admin\Shop\InvoicePaymentsDataTable;
use App\Http\Controllers\Controller;
use App\Repositories\Shop\InvoicePayments;
use App\Repositories\Shop\Invoices;
use Illuminate\Http\Request;
class InvoicePaymentController extends Controller
@@ -14,18 +15,21 @@ class InvoicePaymentController extends Controller
return $dataTable->render('Admin.Shop.InvoicePayments.list');
}
public function create()
public function create($invoice_id)
{
$data = InvoicePayments::init();
$data['invoice_id'] = $invoice_id;
return view('Admin.Shop.InvoicePayments.create', $data);
return view('Admin.Shop.InvoicePayments.form', $data);
}
public function store(Request $request)
{
$ret = InvoicePayments::store($request->all());
$data = $request->all();
$ret = InvoicePayments::store($data);
Invoices::checkPayments($data['invoice_id']);
return redirect()->route('Admin.Shop.InvoicePayments.index');
return redirect()->route('Admin.Shop.Invoices.edit', ['id' => $request->input('invoice_id')]);
}
public function show($id)
@@ -40,12 +44,15 @@ class InvoicePaymentController extends Controller
{
$data = InvoicePayments::init();
$data['invoice_payment'] = InvoicePayments::getArray($id);
$data['invoice_id'] = $data['invoice_payment']['invoice_id'];
return view('Admin.Shop.InvoicePayments.edit', $data);
return view('Admin.Shop.InvoicePayments.form', $data);
}
public function destroy($id)
{
return InvoicePayments::destroy($id);
$payment = InvoicePayments::get($id);
InvoicePayments::destroy($id);
Invoices::checkPayments($payment->invoice_id);
}
}

View File

@@ -10,7 +10,6 @@ use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Sebastienheyd\Boilerplate\Rules\Password;
class RegisterController extends Controller
@@ -24,14 +23,6 @@ class RegisterController extends Controller
public function register(RegisterCustomer $request)
{
$request->validateWithBag('Errors', [
'last_name' => 'required|max:255',
'first_name' => 'required|max:255',
'email' => 'required|email|max:255|unique:shop_customers,email,NULL,id,deleted_at,NULL',
'password' => ['required', 'confirmed', new Password()],
]);
if (back()->getTargetUrl() === route('Shop.Orders.store')) {
$route = 'Shop.Orders.order';
} else {

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Shop;
use App\Repositories\Shop\CustomerAddresses;
use App\Repositories\Shop\Customers;
use Illuminate\Http\Request;
@@ -54,4 +55,11 @@ class CustomerController extends Controller
return redirect()->route('Shop.Customers.edit');
}
public function delete_address($id)
{
$ret = CustomerAddresses::destroy($id);
return redirect()->route('Shop.Customers.edit');
}
}

View File

@@ -3,8 +3,10 @@
namespace App\Http\Controllers\Shop;
use App\Datatables\Shop\CustomerOrdersDataTable;
use App\Http\Requests\Shop\StoreOrderPost;
use App\Repositories\Core\User\ShopCart;
use App\Repositories\Shop\Baskets;
use App\Repositories\Shop\Contents;
use App\Repositories\Shop\Customers;
use App\Repositories\Shop\Deliveries;
use App\Repositories\Shop\DeliveryTypes;
@@ -61,13 +63,14 @@ class OrderController extends Controller
return redirect()->route('home');
}
public function store(Request $request)
public function store(StoreOrderPost $request)
{
$data = $request->all();
$data['customer_id'] = Customers::getId();
$data['sale_channel_id'] = $data['sale_channel_id'] ?? SaleChannels::getDefaultID();
$data['basket'] = Baskets::getBasketSummary($data['sale_channel_id'], $data['delivery_type_id'] ?? false);
$order = Orders::saveOrder($data);
if ($order) {
if ($data['payment_type'] === '1') {
return Paybox::makeAuthorizationRequest($order);
@@ -83,8 +86,9 @@ class OrderController extends Controller
public function confirmed()
{
ShopCart::clear();
$content = Contents::getOrderConfirmedContent();
return view('Shop.Orders.confirmed');
return view('Shop.Orders.confirmed', ['content' => $content]);
}
public function getPdf($uuid)

View File

@@ -3,38 +3,33 @@
namespace App\Http\Controllers\Shop;
use App\Http\Controllers\Controller;
use App\Repositories\Shop\Contents;
use Illuminate\Http\Request;
class PayboxController extends Controller
{
public function accepted()
{
return view('paybox.accepted');
return view('paybox.paybox', ['content' => Contents::getPayboxConfirmedContent()]);
}
public function refused(Request $request)
{
dump($request->all());
exit;
return view('paybox.refused');
return view('paybox.paybox', ['content' => Contents::getPayboxRefusedContent()]);
}
public function aborted()
{
return view('paybox.aborted');
return view('paybox.paybox', ['content' => Contents::getPayboxAbortedContent()]);
}
public function waiting()
{
return view('paybox.waiting');
return view('paybox.waiting', ['content' => Contents::getPayboxWaitingContent()]);
}
public function process(Request $request)
{
dump($request);
exit;
return view('paybox.send');
}
}

View File

@@ -2,7 +2,9 @@
namespace App\Http\Requests\Shop;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\ValidationException;
use Sebastienheyd\Boilerplate\Rules\Password;
class RegisterCustomer extends FormRequest
@@ -21,4 +23,14 @@ class RegisterCustomer extends FormRequest
'password' => ['required', 'confirmed', new Password()],
];
}
protected function failedValidation(Validator $validator)
{
$response = redirect()
->back()
->withInput()
->withErrors($validator->errors(), 'registration');
throw new ValidationException($validator, $response);
}
}

View File

@@ -14,7 +14,19 @@ class StoreOrderPost extends FormRequest
public function rules()
{
return [
'user_id' => 'required',
'invoice.invoice_address_id' => 'required',
'delivery_id' => 'required',
'payment_type' => 'required',
'agree' => 'required',
];
}
public function messages()
{
return [
'delivery_id.required' => 'Il est nécessaire de choisir un mode de livraison',
'payment_type.required' => 'Il est nécessaire de choisir un mode de paiement',
'agree.required' => 'Il est nécessaire d\'adhérer à nos conditions de vente',
];
}
}

View File

@@ -42,14 +42,16 @@ class ConfirmationCommande extends TemplateMailable
public function __construct($order)
{
$facturation_address = $order->invoice->address ? $order->invoice->address : $customer;
$delivery_address = $order->delivery_address ? $order->delivery_address : $customer;
$this->prenom = $order->customer->first_name;
$this->nom = $order->customer->last_name;
$this->facturation_adresse = $order->address->address;
$this->facturation_cp = $order->address->zipcode;
$this->facturation_ville = $order->address->city;
$this->livraison_adresse = $order->delivery_address->address;
$this->livraison_cp = $order->delivery_address->zipcode;
$this->livraison_ville = $order->delivery_address->city;
$this->facturation_adresse = $facturation_address->address;
$this->facturation_cp = $facturation_address->zipcode;
$this->facturation_ville = $facturation_address->city;
$this->livraison_adresse = $delivery_address->address;
$this->livraison_cp = $delivery_address->zipcode;
$this->livraison_ville = $delivery_address->city;
$this->societe = $order->customer->company;
$this->email = $order->customer->email;
$this->numero_commande = $order->ref;

View File

@@ -47,4 +47,18 @@ class Specie extends Model implements HasMedia
{
return $query->where($this->table.'.name', $name);
}
public function scopeByTag($query, $tagId)
{
return $tagId ? $query->whereHas('tags', function ($query) use ($tagId) {
$query->byId($tagId);
}) : $query;
}
public function scopeByTags($query, $tags)
{
return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
$query->byIds($tags);
}) : $query;
}
}

View File

@@ -37,4 +37,22 @@ class Variety extends Model implements HasMedia
{
return $this->morphToMany(Tag::class, 'taggable');
}
public function scopeByTag($query, $tagId)
{
return $tagId ? $query->whereHas('tags', function ($query) use ($tagId) {
$query->byId($tagId);
})->orWhereHas('Specie', function($query) use ($tagId) {
$query->byTag($tagId);
}) : $query;
}
public function scopeByTags($query, $tags)
{
return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
$query->byIds($tags);
})->orWhereHas('Specie', function($query) use ($tags) {
$query->byTags($tags);
}) : $query;
}
}

View File

@@ -191,6 +191,10 @@ class Article extends Model implements HasMedia
{
return $tagId ? $query->whereHas('tags', function ($query) use ($tagId) {
$query->byId($tagId);
})->orWhereHasMorph('product', [Variety::class], function($query) use ($tagId) {
$query->whereHas('tags', function ($query) use ($tagId) {
$query->where('id', $tagId);
});
}) : $query;
}
@@ -198,6 +202,10 @@ class Article extends Model implements HasMedia
{
return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
$query->byIds($tags);
})->orWhereHasMorph('product', [Variety::class], function($query) use ($tags) {
$query->whereHas('tags', function ($query) use ($tags) {
$query->whereIntegerInRaw('id', $tags);
});
}) : $query;
}

View File

@@ -2,6 +2,7 @@
namespace App\Models\Shop;
use App\Repositories\Core\DateTime;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Venturecraft\Revisionable\RevisionableTrait;
@@ -47,4 +48,14 @@ class InvoicePayment extends Model
{
return $query->where('payment_type', $paymentType);
}
public function getDateAttribute($value)
{
return DateTime::dateToLocale($value);
}
public function setDateAttribute($value)
{
$this->attributes['date'] = DateTime::convert($value);
}
}

View File

@@ -6,6 +6,7 @@ use App\Models\Botanic\Specie;
use App\Models\Botanic\Variety;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Support\Facades\DB;
use Rinvex\Tags\Models\Tag as parentTag;
class Tag extends parentTag
@@ -78,6 +79,65 @@ class Tag extends parentTag
]);
}
public static function countArticles($categoryId)
{
DB::table('tags')
// Articles directement liés au tag, filtrés par catégorie
->leftJoin('taggables as direct', function ($join) {
$join->on('tags.id', '=', 'direct.tag_id')
->where('direct.taggable_type', '=', Article::class);
})
->leftJoin('shop_articles', 'direct.taggable_id', '=', 'shop_articles.id')
->whereExists(function ($query) use ($categoryId) {
$query->select(DB::raw(1))
->from('categories')
->whereColumn('categories.id', 'shop_articles.category_id')
->where('_lft', '>=', DB::raw("(SELECT _lft FROM categories WHERE id = {$categoryId})"))
->where('_rgt', '<=', DB::raw("(SELECT _rgt FROM categories WHERE id = {$categoryId})"));
})
// Articles liés via une variété ayant le tag, filtrés par catégorie
->leftJoin('taggables as via_variety', function ($join) {
$join->on('tags.id', '=', 'via_variety.tag_id')
->where('via_variety.taggable_type', '=', Variety::class);
})
->leftJoin('botanic_varieties', 'via_variety.taggable_id', '=', 'botanic_varieties.id')
->leftJoin('shop_articles as indirect_articles', function ($join) {
$join->on('varieties.id', '=', 'indirect_articles.product_id')
->where('indirect_articles.product_type', '=', Variety::class);
})
->whereExists(function ($query) use ($categoryId) {
$query->select(DB::raw(1))
->from('categories')
->whereColumn('categories.id', 'indirect_articles.category_id')
->where('_lft', '>=', DB::raw("(SELECT _lft FROM categories WHERE id = {$categoryId})"))
->where('_rgt', '<=', DB::raw("(SELECT _rgt FROM categories WHERE id = {$categoryId})"));
})
// Combinaison des deux types de liens et comptage
->select('tags.id', 'tags.name', DB::raw('COUNT(DISTINCT shop_articles.id) + COUNT(DISTINCT indirect_articles.id) as article_count'))
->groupBy('tags.id', 'tags.name')
->get();
}
public function scopeWithFilteredArticleCounts($query, $categoryId)
{
return $query->withCount([
// Articles directement liés au tag et filtrés par catégorie
'articles as direct_article_count' => function ($query) use ($categoryId) {
$query->byCategoryParent($categoryId);
},
// Articles liés via Variety et filtrés par catégorie sur les articles eux-mêmes
'articles as indirect_article_count' => function ($query) use ($categoryId) {
$query->whereHasMorph('product', [Variety::class], function ($subQuery) {
// Pas de catégorie sur Variety, pas de filtre ici
})->byCategoryParent($categoryId);
},
])
->havingRaw('(COALESCE(direct_article_count, 0) + COALESCE(indirect_article_count, 0)) > 0'); // Filtre les tags avec au moins un article
}
public function scopeById($query, $id)
{
return $query->where($this->table.'.id', $id);
@@ -85,6 +145,6 @@ class Tag extends parentTag
public function scopeByIds($query, $ids)
{
return $query->whereIn($this->table.'.id', $ids);
return $query->whereIntegerInRaw($this->table.'.id', $ids);
}
}

View File

@@ -36,6 +36,32 @@ class Contents
return self::get(4)->text ?? '';
}
public static function getOrderConfirmedContent()
{
return self::get(5)->text ?? 'Votre commande a été confirmée';
}
public static function getPayboxConfirmedContent()
{
return self::get(6)->text ?? 'Merci pour votre règlement. Votre commande sera traitée sous peu.';
}
public static function getPayboxRefusedContent()
{
return self::get(7)->text ?? 'Le paiement a été refusé.';
}
public static function getPayboxAbortedContent()
{
return self::get(8)->text ?? 'Le paiement a été annulé.';
}
public static function getPayboxWaitingContent()
{
return self::get(9)->text ?? 'Votre paiement est en attente. Cela peut prendre un certain temps jusqu\'à ce qu\'il soit terminé.';
}
public static function getModel()
{
return Content::query();

View File

@@ -10,18 +10,44 @@ class CustomerAddresses
use Basic;
public static function add($userId, $data)
{
self::addDeliveryAddress($userId, $data);
self::addInvoiceAddress($userId, $data);
}
public static function addDeliveryAddress($userId, $data)
{
$name = $data['company'] ? $data['company'] : $data['first_name'].' '.$data['last_name'];
$delivery = $data['use_for_delivery'] ?? false;
return self::store([
$data = [
'customer_id' => $userId,
'type' => 2,
'name' => $name,
'address' => $delivery ? $data['delivery_address'] : $data['address'],
'address2' => $delivery ? $data['delivery_address2'] : $data['address2'],
'zipcode' => $delivery ? $data['delivery_zipcode'] : $data['zipcode'],
'city' => $delivery ? $data['delivery_city'] : $data['city'],
]);
];
return self::store($data);
}
public static function addInvoiceAddress($userId, $data)
{
$name = $data['company'] ? $data['company'] : $data['first_name'].' '.$data['last_name'];
$data = [
'customer_id' => $userId,
'type' => 1,
'name' => $name,
'address' => $data['address'],
'address2' => $data['address2'],
'zipcode' => $data['zipcode'],
'city' => $data['city'],
];
return self::store($data);
}
public static function getInvoiceAddress($customerId)

View File

@@ -43,6 +43,31 @@ class Invoices
return $data;
}
public static function checkPayments($invoice_id)
{
$invoice = self::get($invoice_id);
$total = self::getPayments($invoice_id);
if ($total) {
$status = $total === (float) $invoice->total_shipped ? 2 : 1;
} else {
$status = 0;
}
$invoice->status = $status;
$invoice->save();
}
public static function getPayments($invoice_id)
{
$total = 0;
$invoice = self::get($invoice_id);
$payments = $invoice->payments;
foreach ($payments as $payment) {
$total += $payment->amount;
}
return $total;
}
public static function getFullByUUID($id)
{
return self::getByUUID($id, self::full());
@@ -61,6 +86,7 @@ class Invoices
'order.delivery_address',
'order.detail',
'order.sale_channel',
'order.customer',
'payments',
];
}
@@ -106,7 +132,7 @@ class Invoices
public static function statuses()
{
return ['En attente', 'Paiement partiel', 'Soldée', 'Paiement rejeté'];
return ['En attente', 'Paiement partiel', 'Soldée'];
}
public static function getModel()

View File

@@ -2,6 +2,7 @@
namespace App\Repositories\Shop;
use App\Models\Botanic\Variety;
use App\Models\Shop\Tag;
use App\Models\Shop\TagGroup;
use App\Traits\Model\Basic;
@@ -15,6 +16,8 @@ class TagGroups
{
$data = [];
$tags = Tag::withCountArticlesByCategory($category_id)->get()->toArray();
dump($tags);
exit;
$tagGroups = TagGroup::pluck('name', 'id')->toArray();
foreach ($tags as $tag) {
if (! $tag['articles_count']) {
@@ -31,6 +34,30 @@ class TagGroups
return $data;
}
public static function getWithTagsAndCountOffers2($categoryId = false)
{
return Tag::withCount([
'articles as direct_article_count' => function ($query) use ($categoryId) {
$query->byCategoryParent($categoryId);
},
'articles as indirect_article_count' => function ($query) use ($categoryId) {
$query->whereHasMorph('product', [Variety::class], function ($subQuery) use ($categoryId) {
$subQuery->whereHas('categories', function ($categoryQuery) use ($categoryId) {
$categoryQuery->byCategoryParent($categoryId);
});
});
},
])
->get()
->map(function ($tag) {
$tag->total_articles = $tag->direct_article_count + $tag->indirect_article_count;
return $tag;
})
->filter(function ($tag) {
return $tag->total_articles > 0; // Garde uniquement les tags ayant des articles
});
}
public static function isTagGroupHaveSelected($tagsSelected, $tags)
{
foreach ($tags as $tag) {