'DE', 'phone' => '49', 'en' => 'Germany', 'de' => 'Deutschland', 'es' => 'Alemania', 'fr' => 'Allemagne', 'it' => 'Germania', 'ru' => 'Германия', ]); $shipping = Shipping::create(['name' => 'Standard', 'active' => true]); ShippingPrice::create([ 'shipping_id' => $shipping->id, 'price' => 4.90, 'price_comp' => 0, 'num_comp' => 0, 'tax_rate' => 19, 'weight_from' => 1, 'weight_to' => 1000, ]); ShippingPrice::create([ 'shipping_id' => $shipping->id, 'price' => 9.90, 'price_comp' => 0, 'num_comp' => 0, 'tax_rate' => 19, 'weight_from' => 1001, 'weight_to' => 2000, ]); return ShippingCountry::create(['shipping_id' => $shipping->id, 'country_id' => $country->id]); } function makeShopEnvWithCompWeightTiers(): ShippingCountry { $country = Country::create([ 'code' => 'DE', 'phone' => '49', 'en' => 'Germany', 'de' => 'Deutschland', 'es' => 'Alemania', 'fr' => 'Allemagne', 'it' => 'Germania', 'ru' => 'Германия', ]); $shipping = Shipping::create(['name' => 'Standard', 'active' => true]); ShippingPrice::create([ 'shipping_id' => $shipping->id, 'price' => 4.90, 'price_comp' => 4.90, 'num_comp' => 0, 'tax_rate' => 19, 'weight_from' => 1, 'weight_to' => 1000, ]); ShippingPrice::create([ 'shipping_id' => $shipping->id, 'price' => 9.90, 'price_comp' => 9.90, 'num_comp' => 2, 'tax_rate' => 19, 'weight_from' => 1001, 'weight_to' => 2000, ]); return ShippingCountry::create(['shipping_id' => $shipping->id, 'country_id' => $country->id]); } describe('Yard Maximalgewicht', function () { beforeEach(function () { $this->shippingCountry = makeShopEnvWithWeightTiers(); }); it('liefert das höchste weight_to als Maximalgewicht', function () { $yard = Yard::instance('test-maxweight'); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id); expect($yard->getMaxWeight())->toBe(2000); $yard->destroy(); }); it('erkennt das Überschreiten des Maximalgewichts', function () { $yard = Yard::instance('test-maxweight'); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id); $yard->add(1, 'A', 1, 10.0, false, false, ['weight' => 1500]); expect($yard->exceedsMaxWeight(0))->toBeFalse() ->and($yard->exceedsMaxWeight(500))->toBeFalse() ->and($yard->exceedsMaxWeight(501))->toBeTrue(); $yard->destroy(); }); it('nutzt bei Überschreitung die teuerste Stufe statt der günstigsten', function () { $yard = Yard::instance('test-maxweight'); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id); // Gewicht 3000 g liegt über der höchsten Stufe (2000 g) $yard->add(1, 'A', 1, 10.0, false, false, ['weight' => 3000]); $yard->reCalculateShippingPrice(); expect((float) $yard->getShippingPrice())->toBe(9.90); $yard->destroy(); }); }); describe('AboOrderCart Maximalgewicht', function () { beforeEach(function () { makeShopEnvWithWeightTiers(); $this->service = new AboOneTimeService; }); it('berechnet das kombinierte Gewicht aus Einmal-Artikeln', function () { $abo = makeMeAbo(); $product = makeProduct(['2']); // weight 500 $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]); expect(AboOrderCart::combinedWeight($abo->fresh()))->toBe(500); }); it('stoppt das Hinzufügen, wenn das Maximalgewicht überschritten würde', function () { $abo = makeMeAbo(); $product = makeProduct(['2']); // weight 500, max 2000 => max 4 Stück for ($i = 0; $i < 4; $i++) { $message = $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]); expect($message)->toBeNull(); } // 5. Stück => 2500 g > 2000 g $message = $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]); expect($message)->toBe(__('msg.cart_max_weight_reached')) ->and(UserAboOneTimeItem::where('user_abo_id', $abo->id)->first()->qty)->toBe(4); }); it('stoppt das Hochsetzen der Menge bei Überschreitung, erlaubt aber gültige Mengen', function () { $abo = makeMeAbo(); $product = makeProduct(['2']); // weight 500 $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]); $item = UserAboOneTimeItem::where('user_abo_id', $abo->id)->first(); // qty 4 => 2000 g (ok) $okMessage = $this->service->handleAction($abo, ['action' => 'update', 'one_time_item_id' => $item->id, 'qty' => 4]); expect($okMessage)->toBeNull() ->and($item->fresh()->qty)->toBe(4); // qty 5 => 2500 g (zu schwer) $failMessage = $this->service->handleAction($abo, ['action' => 'update', 'one_time_item_id' => $item->id, 'qty' => 5]); expect($failMessage)->toBe(__('msg.cart_max_weight_reached')) ->and($item->fresh()->qty)->toBe(4); }); it('erlaubt das Reduzieren der Menge immer', function () { $abo = makeMeAbo(); $product = makeProduct(['2']); $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]); $item = UserAboOneTimeItem::where('user_abo_id', $abo->id)->first(); $this->service->handleAction($abo, ['action' => 'update', 'one_time_item_id' => $item->id, 'qty' => 4]); $message = $this->service->handleAction($abo, ['action' => 'update', 'one_time_item_id' => $item->id, 'qty' => 2]); expect($message)->toBeNull() ->and($item->fresh()->qty)->toBe(2); }); }); describe('AboOrderCart Kompensationsprodukte', function () { beforeEach(function () { $this->shippingCountry = makeShopEnvWithCompWeightTiers(); Setting::setContentBySlug('is_comp_me_abo', true, 'bool'); }); it('erhöht die Kompensationsprodukte, wenn die höhere Versandstufe mehr verlangt', function () { $abo = makeMeAbo(); $compProduct = makeProduct(['12']); DB::table('products')->where('id', $compProduct->id)->update(['shipping_addon' => true, 'pos' => 100]); $yard = Yard::instance(AboOrderCart::INSTANCE); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id, 'abo-me'); $yard->add(1, 'Abo-Produkt', 1, 10.0, false, false, ['weight' => 1500]); $yard->reCalculateShippingPrice(); AboOrderCart::checkNumOfCompProducts($abo); expect(UserAboItem::where('user_abo_id', $abo->id)->where('comp', '>', 0)->count())->toBe(2) ->and(UserAboItem::where('user_abo_id', $abo->id)->where('comp', '>', 0)->pluck('comp')->all())->toBe([1, 2]); $yard->destroy(); }); it('entfernt Kompensationsprodukte wieder, wenn keine mehr benötigt werden', function () { $abo = makeMeAbo(); $compProduct = makeProduct(['12']); DB::table('products')->where('id', $compProduct->id)->update(['shipping_addon' => true, 'pos' => 100]); UserAboItem::create(['user_abo_id' => $abo->id, 'product_id' => $compProduct->id, 'comp' => 1, 'qty' => 1, 'status' => 1]); UserAboItem::create(['user_abo_id' => $abo->id, 'product_id' => $compProduct->id, 'comp' => 2, 'qty' => 1, 'status' => 1]); $yard = Yard::instance(AboOrderCart::INSTANCE); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id, 'abo-me'); $yard->add(1, 'Abo-Produkt', 1, 10.0, false, false, ['weight' => 500]); $yard->reCalculateShippingPrice(); AboOrderCart::checkNumOfCompProducts($abo); expect(UserAboItem::where('user_abo_id', $abo->id)->where('comp', '>', 0)->count())->toBe(0); $yard->destroy(); }); it('zeigt einen Hinweis für Kompensationsprodukte aus Zusatzprodukten', function () { $compProduct = makeProduct(['12']); $yard = Yard::instance(AboOrderCart::INSTANCE); $yard->destroy(); $yard->setShippingCountryWithPrice($this->shippingCountry->id, 'abo-me'); $yard->add(1, 'Abo-Produkt', 1, 10.0, false, false, ['weight' => 1500]); $yard->reCalculateShippingPrice(); $html = view('user.order.comp_product', [ 'comp_products' => collect([$compProduct]), 'cart_instance' => AboOrderCart::INSTANCE, 'base_comp_count' => 0, ])->render(); expect($html)->toContain(__('order.comp_required_by_additional_products')); $yard->destroy(); }); });