BF stock calculation

This commit is contained in:
Fabian @ Blax Software 2026-05-18 11:54:11 +02:00
parent 0bb3b63a32
commit ab8ea6afec
4 changed files with 10 additions and 8 deletions

View File

@ -3,8 +3,8 @@
# Laravel Shop # Laravel Shop
[![Tests](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml/badge.svg)](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml) [![Tests](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml/badge.svg)](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml)
[![Tests Count](https://img.shields.io/badge/tests-1228%20passing-success?style=flat-square)](#testing) [![Tests Count](https://img.shields.io/badge/tests-1349%20passing-success?style=flat-square)](#testing)
[![Assertions](https://img.shields.io/badge/assertions-3291-blue?style=flat-square)](#testing) [![Assertions](https://img.shields.io/badge/assertions-3641-blue?style=flat-square)](#testing)
[![Latest Version](https://img.shields.io/packagist/v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop) [![Latest Version](https://img.shields.io/packagist/v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
[![License](https://img.shields.io/packagist/l/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop) [![License](https://img.shields.io/packagist/l/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
[![PHP Version](https://img.shields.io/packagist/php-v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop) [![PHP Version](https://img.shields.io/packagist/php-v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
@ -192,7 +192,7 @@ booking, Stripe sync and the event surface — so host applications can lean
on the behaviour with confidence. on the behaviour with confidence.
``` ```
Tests: 1228, Assertions: 3291 Tests: 1349, Assertions: 3641
``` ```
CI runs the full suite on every push (see the badge above). To run it CI runs the full suite on every push (see the badge above). To run it

View File

@ -663,7 +663,7 @@ class Product extends Model implements Purchasable, Cartable
// Use base stock at the START of the booking period and subtract all overlapping reservations // Use base stock at the START of the booking period and subtract all overlapping reservations
// We check availability at $from because claims that expire before then should not affect availability // We check availability at $from because claims that expire before then should not affect availability
// Note: overlappingBookings is already negative (DECREASE entries), so we add it // Note: overlappingBookings is already negative (DECREASE entries), so we add it
$availableStock = $this->getAvailableStock($from) - abs($overlappingClaims) + $overlappingBookings; $availableStock = $this->getAvailableStock($from) - abs((int) $overlappingClaims) + (int) $overlappingBookings;
return $availableStock >= $quantity; return $availableStock >= $quantity;
} }

View File

@ -503,7 +503,9 @@ trait HasStocks
*/ */
public function getCurrentlyClaimedStock(): int public function getCurrentlyClaimedStock(): int
{ {
return abs($this->stocks() // SQL SUM comes back as a numeric string under PDO mysql; cast
// before abs() so strict types accept it.
return abs((int) $this->stocks()
->whereIn('type', StockType::claimTypeValues()) ->whereIn('type', StockType::claimTypeValues())
->where('status', StockStatus::PENDING->value) ->where('status', StockStatus::PENDING->value)
->willExpire() ->willExpire()
@ -523,7 +525,7 @@ trait HasStocks
*/ */
public function getActiveAndPlannedClaimedStock(): int public function getActiveAndPlannedClaimedStock(): int
{ {
return abs($this->stocks() return abs((int) $this->stocks()
->whereIn('type', StockType::claimTypeValues()) ->whereIn('type', StockType::claimTypeValues())
->where('status', StockStatus::PENDING->value) ->where('status', StockStatus::PENDING->value)
->willExpire() ->willExpire()
@ -552,7 +554,7 @@ trait HasStocks
}); });
} }
return abs($query->sum('quantity')); return abs((int) $query->sum('quantity'));
} }

View File

@ -326,7 +326,7 @@ trait MayBePoolProduct
// Get available stock at the START of the booking period // Get available stock at the START of the booking period
// This ensures claims that will expire before the booking starts don't reduce availability // This ensures claims that will expire before the booking starts don't reduce availability
$available = max(0, $item->getAvailableStock($from) - abs($overlappingClaims)); $available = max(0, $item->getAvailableStock($from) - abs((int) $overlappingClaims));
} }
} elseif (!$item->isBooking()) { } elseif (!$item->isBooking()) {
$available = $item->getAvailableStock(); $available = $item->getAvailableStock();