classBasename() ->prepend('assert'); if (! method_exists(self::class, $method)) { throw new OutOfRangeException($resource); } call_user_func(self::class.'::'.$method, $json); } public static function assertResourceCollection(AssertableJson $json, string $resource): void { $json->each(static function (AssertableJson $json) use ($resource): void { self::assertResource($json, $resource); }); } protected static function assertStorageBatchResource(AssertableJson $json): bool { $json ->whereType('id', 'integer') ->whereSku('sku') ->whereDateTime('best_before_date', 'Y-m-d', false) ->whereDateTime('sellable_until', 'Y-m-d', false) ->whereType('stock', 'integer') ->where('stock', static function (int $stock): bool { return $stock >= 0; }) ->whereType('quantity', ['integer', 'double']) ->where('quantity', static function (float $quantity): bool { return $quantity >= 0; }) ->whereType('quantity_surplus', ['integer', 'double']) ->where('quantity_surplus', static function (float $surplus): bool { return $surplus >= 0; }) ->whereType('packing_position_name', 'string') ->whereType('approved_by', ['integer', 'null']) ->whereDateTime('approved_at', DateTimeInterface::RFC3339, false) ->whereDateTime('stocktaking_requested_at', DateTimeInterface::RFC3339, false) ->whereType('stocktaking_status', 'string') ->whereIn('stocktaking_status', StocktakingStatus::toValues()) ->whereResource('product', ProductResource::class, false) ->whereType('is_deletable', 'boolean'); return true; } }