IM product purchase process

This commit is contained in:
a6a2f5842 2025-11-22 15:13:30 +01:00
parent afe7359ea4
commit 2c31b6ea98
4 changed files with 26 additions and 21 deletions

View File

@ -179,7 +179,7 @@ return new class extends Migration
// Product stock logs table
if (!Schema::hasTable(config('shop.tables.product_stock_logs', 'product_stock_logs'))) {
Schema::create(config('shop.tables.product_stock_logs', 'product_stock_logs'), function (Blueprint $table) {
$table->uuid('id')->primary();
$table->id();
$table->uuid('product_id');
$table->integer('quantity_change');
$table->integer('quantity_after');

View File

@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class Product extends Model implements Purchasable
{
@ -25,15 +26,11 @@ class Product extends Model implements Purchasable
'description',
'type',
'stripe_product_id',
'price',
'regular_price',
'sale_price',
'sale_start',
'sale_end',
'manage_stock',
'stock_quantity',
'low_stock_threshold',
'in_stock',
'stock_status',
'weight',
'length',
@ -298,7 +295,7 @@ class Product extends Model implements Purchasable
protected function logStockChange(int $quantityChange, string $type): void
{
\DB::table('product_stock_logs')->insert([
DB::table('product_stock_logs')->insert([
'product_id' => $this->id,
'quantity_change' => $quantityChange,
'quantity_after' => $this->stock_quantity,

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rapidez\Shop\Services;
namespace Blax\Shop\Services;
use Blax\Shop\Models\Product;
use Illuminate\Support\Collection;

View File

@ -4,6 +4,7 @@ namespace Blax\Shop\Traits;
use Blax\Shop\Models\ProductPurchase;
use Blax\Shop\Models\Product;
use Blax\Shop\Models\ProductPrice;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Collection;
@ -41,12 +42,25 @@ trait HasShoppingCapabilities
*
* @param Product $product
* @param int $quantity
* @param array $options Additional options (price_id, meta, etc.)
*
* @return ProductPurchase
* @throws \Exception
*/
public function purchase(Product $product, int $quantity = 1, array $options = []): ProductPurchase
{
public function purchase(
ProductPrice|string $productPrice,
int $quantity = 1,
): ProductPurchase {
if ($productPrice instanceof ProductPrice) {
} else {
$productPrice = ProductPrice::findOrFail($productPrice);
}
if (!$productPrice?->product?->id) {
throw new \Exception("Price does not belong to the specified product");
}
$product = $productPrice->product;
// Validate stock availability
if ($product->manage_stock) {
$available = $product->getAvailableStock();
@ -65,27 +79,21 @@ trait HasShoppingCapabilities
throw new \Exception("Unable to decrease stock");
}
// Determine price
$priceId = $options['price_id'] ?? null;
$price = $this->determinePurchasePrice($product, $priceId);
// Create purchase record
$purchase = $this->purchases()->create([
'product_id' => $product->id,
'quantity' => $quantity,
'status' => $options['status'] ?? 'completed',
'status' => 'unpaid',
'meta' => array_merge([
'price_id' => $priceId,
'price' => $price,
'amount' => $price * $quantity,
'charge_id' => $options['charge_id'] ?? null,
], $options['meta'] ?? []),
'price_id' => $productPrice->id,
'price' => $productPrice->price,
'amount' => $productPrice->price * $quantity,
]),
]);
// Trigger product actions
$product->callActions('purchased', $purchase, [
'purchaser' => $this,
...$options,
]);
return $purchase;