'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' => 100000, ]); $shippingCountry = ShippingCountry::create(['shipping_id' => $shipping->id, 'country_id' => $country->id]); $consultant = User::forceCreate([ 'email' => 'consultant-'.uniqid('', true).'@example.com', 'password' => bcrypt('secret'), 'lang' => 'de', ]); $userShop = UserShop::create([ 'user_id' => $consultant->id, 'name' => 'TS'.substr(uniqid('', true), 0, 8), 'slug' => 'ts-'.uniqid(), 'active' => true, ]); $shoppingUser = ShoppingUser::create([ 'auth_user_id' => $consultant->id, 'member_id' => $consultant->id, 'billing_country_id' => $country->id, 'shipping_country_id' => $country->id, 'billing_email' => 'cust-'.uniqid('', true).'@example.com', 'is_for' => 'ot', 'is_from' => 'shopping', ]); return [ 'user' => $consultant, 'shoppingUser' => $shoppingUser, 'shippingCountry' => $shippingCountry, 'userShop' => $userShop, ]; } /** * Abo-Erstbestellung mit einem regulären Abo-Artikel (90,00 €) und einem * Einmal-Artikel (25,50 € x 2, is_abo_addon) plus bezahlter ShoppingPayment (100,00 €). * * @return array{order: ShoppingOrder, payment: ShoppingPayment, aboProductId: int, addonProductId: int} */ function aboCreateOrderWithAddon(array $fixture): array { $aboProduct = makeProduct(['12'], 90, 19); $addonProduct = makeProduct(['3'], 25.50, 19); $order = ShoppingOrder::create([ 'shopping_user_id' => $fixture['shoppingUser']->id, 'auth_user_id' => $fixture['user']->id, 'member_id' => $fixture['user']->id, 'country_id' => $fixture['shippingCountry']->id, 'user_shop_id' => $fixture['userShop']->id, 'payment_for' => 6, 'points' => 10, 'is_abo' => true, 'abo_interval' => 15, 'paid' => false, 'txaction' => 'prev', 'mode' => 'test', 'total' => 141, 'subtotal' => 118.49, 'total_shipping' => 145.90, ]); ShoppingOrderItem::create([ 'shopping_order_id' => $order->id, 'row_id' => 'row-abo', 'product_id' => $aboProduct->id, 'comp' => 0, 'qty' => 1, 'price' => 90, 'price_net' => 75.63, 'tax_rate' => 19, 'tax' => 14.37, 'slug' => $aboProduct->slug, 'is_abo_addon' => false, ]); ShoppingOrderItem::create([ 'shopping_order_id' => $order->id, 'row_id' => 'row-addon', 'product_id' => $addonProduct->id, 'comp' => 0, 'qty' => 2, 'price' => 25.50, 'price_net' => 21.43, 'tax_rate' => 19, 'tax' => 4.07, 'slug' => $addonProduct->slug, 'is_abo_addon' => true, ]); $payment = ShoppingPayment::create([ 'shopping_order_id' => $order->id, 'reference' => 'ref-'.uniqid(), 'amount' => 10000, 'currency' => 'EUR', 'clearingtype' => 'cc', 'abo_interval' => 15, 'mode' => 'test', ]); PaymentTransaction::create([ 'shopping_payment_id' => $payment->id, 'request' => 'transaction', 'txid' => 123456, 'userid' => 987654, 'status' => 'PAYONE', 'txaction' => 'paid', 'mode' => 'test', ]); return [ 'order' => $order, 'payment' => $payment, 'aboProductId' => $aboProduct->id, 'addonProductId' => $addonProduct->id, ]; } it('persistiert die Cart-Option abo_addon als is_abo_addon auf der Checkout-Bestellung', function () { $fixture = aboCreateOneTimeFixture(); $aboProduct = makeProduct(['12'], 90, 19); $addonProduct = makeProduct(['3'], 25.50, 19); $yard = Yard::instance('shopping'); $yard->destroy(); $yard->setShippingCountryWithPrice($fixture['shippingCountry']->id); $yard->add($aboProduct->id, 'Abo-Produkt', 1, 90.0, false, false, [ 'slug' => $aboProduct->slug, 'weight' => 500, 'points' => 10, 'no_commission' => false, 'no_free_shipping' => false, 'show_on' => ['12'], ]); $yard->add($addonProduct->id, 'Einmal-Produkt', 2, 25.50, false, false, [ 'slug' => $addonProduct->slug, 'weight' => 200, 'points' => 4, 'no_commission' => false, 'no_free_shipping' => false, 'show_on' => ['3'], 'abo_addon' => true, ]); $order = (new PaymentHelper)->makeShoppingOrder($fixture['user'], $fixture['shoppingUser']); $aboItem = $order->shopping_order_items()->where('product_id', $aboProduct->id)->first(); $addonItem = $order->shopping_order_items()->where('product_id', $addonProduct->id)->first(); expect($aboItem)->not->toBeNull() ->and((bool) $aboItem->is_abo_addon)->toBeFalse() ->and($addonItem)->not->toBeNull() ->and((bool) $addonItem->is_abo_addon)->toBeTrue() ->and((int) $addonItem->qty)->toBe(2); $yard->destroy(); }); it('übernimmt Einmal-Artikel bei der Abo-Anlage NICHT in die dauerhaften Abo-Positionen', function () { $fixture = aboCreateOneTimeFixture(); $orderData = aboCreateOrderWithAddon($fixture); AboHelper::createNewAbo($orderData['payment']); $userAbo = UserAbo::first(); expect($userAbo)->not->toBeNull(); $items = UserAboItem::where('user_abo_id', $userAbo->id)->get(); expect($items)->toHaveCount(1) ->and((int) $items->first()->product_id)->toBe($orderData['aboProductId']); }); it('setzt user_abos.amount bei der Anlage ohne den Einmal-Artikel-Anteil', function () { $fixture = aboCreateOneTimeFixture(); $orderData = aboCreateOrderWithAddon($fixture); AboHelper::createNewAbo($orderData['payment']); // Zahlung 100,00 € (10000 Cent) minus Addon-Brutto 2 x 25,50 € = 51,00 € -> 4900 Cent expect((int) UserAbo::first()->amount)->toBe(4900); }); it('lässt amount unverändert wenn die Erstbestellung keine Einmal-Artikel enthält', function () { $fixture = aboCreateOneTimeFixture(); $orderData = aboCreateOrderWithAddon($fixture); ShoppingOrderItem::where('shopping_order_id', $orderData['order']->id) ->where('is_abo_addon', true) ->delete(); AboHelper::createNewAbo($orderData['payment']); expect((int) UserAbo::first()->amount)->toBe(10000); }); it('gruppiert Erstrechnung und Lieferschein der Anlage-Bestellung nach Einmal-Artikeln', function () { $fixture = aboCreateOneTimeFixture(); $orderData = aboCreateOrderWithAddon($fixture); $order = $orderData['order']->fresh('shopping_order_items.product'); $invoiceHtml = view('pdf.invoice-detail', ['shopping_order' => $order])->render(); $deliveryHtml = view('pdf.delivery-detail', ['shopping_order' => $order])->render(); foreach ([$invoiceHtml, $deliveryHtml] as $html) { expect($html)->toContain(__('pdf.abo_items_heading')) ->and($html)->toContain(__('pdf.abo_addon_items_heading')); expect(strpos($html, __('pdf.abo_items_heading'))) ->toBeLessThan(strpos($html, __('pdf.abo_addon_items_heading'))); } }); it('überspringt Einmal-Artikel auch bei ensureUserAboItemsFromLatestOrder', function () { $fixture = aboCreateOneTimeFixture(); $orderData = aboCreateOrderWithAddon($fixture); $userAbo = UserAbo::create([ 'user_id' => $fixture['user']->id, 'member_id' => $fixture['user']->id, 'shopping_user_id' => $fixture['shoppingUser']->id, 'email' => $fixture['shoppingUser']->billing_email, 'is_for' => 'ot', 'payone_userid' => 987654, 'clearingtype' => 'cc', 'status' => 1, 'abo_interval' => 15, 'next_date' => now()->addDays(20)->toDateString(), ]); UserAboOrder::create([ 'user_abo_id' => $userAbo->id, 'shopping_order_id' => $orderData['order']->id, 'status' => 1, ]); expect(AboHelper::ensureUserAboItemsFromLatestOrder($userAbo))->toBeTrue(); $items = UserAboItem::where('user_abo_id', $userAbo->id)->get(); expect($items)->toHaveCount(1) ->and((int) $items->first()->product_id)->toBe($orderData['aboProductId']); });