示例#1
0
 public function testSetSingleAddress()
 {
     $this->order->addProduct($this->products[0], 1);
     $this->controller->setOrder($this->order);
     $this->controller->setMultiAddress();
     $shipment1 = Shipment::getNewInstance($this->order);
     $shipment1->save();
     $shipment2 = Shipment::getNewInstance($this->order);
     $shipment2->save();
     $this->order->addProduct($this->products[0], 1, true, $shipment1);
     $this->order->addProduct($this->products[1], 2, true, $shipment2);
     $this->order->save();
     $order = $this->reloadOrder($this->order);
     $this->assertEqual($order->getShipments()->size(), 2);
     $this->assertEqual(count($order->getOrderedItems()), 3);
     $this->controller->setOrder($order = $this->reloadOrder($this->order));
     $response = $this->controller->setSingleAddress();
     $order = $this->reloadOrder($order);
     $this->assertIsA($response, 'ActionRedirectResponse');
     $this->assertEqual($order->isMultiAddress->get(), '0');
     $this->assertEqual($order->getShipments()->size(), 1);
     $this->assertEqual(count($order->getOrderedItems()), 2);
 }
示例#2
0
 /**
  *  Update product quantities
  */
 public function update()
 {
     // TOS
     if ($this->isTosInCartPage()) {
         $this->session->set('tos', $this->request->get('tos'));
     }
     // coupon code
     if ($this->request->get('coupon')) {
         $code = $this->request->get('coupon');
         if ($condition = DiscountCondition::getInstanceByCoupon($code)) {
             if (!$this->order->hasCoupon($code)) {
                 $coupon = OrderCoupon::getNewInstance($this->order, $code);
                 $coupon->save();
                 $this->order->getCoupons(true);
                 if ($this->order->hasCoupon($code)) {
                     $this->setMessage($this->makeText('_coupon_added', array($code)));
                 }
             }
         } else {
             $this->setErrorMessage($this->makeText('_coupon_not_found', array($code)));
         }
         $this->order->getCoupons(true);
     }
     $this->updateEstimateAddress();
     $this->order->loadItemData();
     $validator = $this->buildCartValidator($this->order, $this->getItemOptions());
     if (!$validator->isValid()) {
         return new ActionRedirectResponse('order', 'index');
     }
     $this->order->loadRequestData($this->request);
     foreach ($this->order->getOrderedItems() as $item) {
         if ($this->request->isValueSet('item_' . $item->getID())) {
             foreach ($item->getProduct()->getOptions(true) as $option) {
                 $this->modifyItemOption($item, $option, $this->request, $this->getFormFieldName($item, $option));
             }
             $item->save();
             $this->order->updateCount($item, $this->request->get('item_' . $item->getID(), 0));
         }
     }
     if ($this->order->isMultiAddress->get()) {
         $addresses = $this->user->getShippingAddressSet();
         $this->order->getShipments();
         foreach ($this->order->getOrderedItems() as $item) {
             if ($addressId = $this->request->get('address_' . $item->getID())) {
                 if (!$item->shipment->get() || !$item->shipment->get()->shippingAddress->get() || $item->shipment->get()->shippingAddress->get()->getID() != $addressId) {
                     foreach ($this->order->getShipments() as $shipment) {
                         if ($shipment->shippingAddress->get() && $shipment->shippingAddress->get()->getID() == $addressId) {
                             if (!$item->shipment->get() || $item->shipment->get()->getID() != $shipment->getID()) {
                                 if ($item->shipment->get()) {
                                     $item->shipment->get()->removeItem($item);
                                 }
                                 $shipment->addItem($item);
                                 break;
                             }
                         }
                         $shipment = null;
                     }
                     if (!isset($shipment) || !$shipment) {
                         $address = ActiveRecordModel::getInstanceById('UserAddress', $addressId, true);
                         $shipment = Shipment::getNewInstance($this->order);
                         $shipment->shippingAddress->set($address);
                         $shipment->save();
                         $this->order->addShipment($shipment);
                         $shipment->addItem($item);
                     }
                     $item->save();
                 }
             }
             if ($item->shipment->get()) {
                 $item->shipment->get()->shippingAmount->set(0);
                 $item->shipment->get()->shippingServiceData->set(null);
                 $item->shipment->get()->save();
             }
         }
     }
     $this->order->mergeItems();
     SessionOrder::save($this->order);
     // proceed with the checkout
     if ($this->request->get('proceed')) {
         return new ActionRedirectResponse('checkout', 'index');
     }
     // redirect to payment gateway
     if ($url = $this->request->get('redirect')) {
         return new RedirectResponse($url);
     }
     return new ActionRedirectResponse('order', 'index', array('query' => 'return=' . $this->request->get('return')));
 }
示例#3
0
 /**
  * @role update
  */
 public function create()
 {
     $order = CustomerOrder::getInstanceByID((int) $this->request->get('orderID'), true, array('BillingAddress', 'ShippingAddress'));
     $shipment = Shipment::getNewInstance($order);
     $history = new OrderHistory($order, $this->user);
     $response = $this->save($shipment);
     $history->saveLog();
     return $response;
 }
示例#4
0
 public function getDownloadShipment($createNew = true)
 {
     // look for a shipment that only contains downloadable items
     foreach ($this->getShipments() as $shipment) {
         if (!$shipment->isShippable()) {
             return $shipment;
         }
     }
     // look for an empty shipment
     foreach ($this->getShipments() as $shipment) {
         if (!count($shipment->getItems())) {
             return $shipment;
         }
     }
     if ($createNew) {
         $shipment = Shipment::getNewInstance($this);
         $shipment->save(true);
         $this->shipments->add($shipment);
         return $shipment;
     }
 }
 public function create()
 {
     $request = $this->getRequest();
     $query = $request->get('query');
     if (strlen($query)) {
         $products = $this->getProductsFromSearchQuery($query);
     } else {
         $products = new ARSet();
         $products->add(Product::getInstanceById((int) $this->request->get('productID'), true));
     }
     $saveResponse = array('errors' => array(), 'items' => array());
     $composite = new CompositeJSONResponse();
     $order = CustomerOrder::getInstanceByID((int) $this->request->get('orderID'), true);
     $order->loadAll();
     foreach ($products as $product) {
         if ($product->isDownloadable()) {
             $shipment = $order->getDownloadShipment();
         } else {
             if ((int) $this->request->get('shipmentID')) {
                 $shipment = Shipment::getInstanceById('Shipment', (int) $this->request->get('shipmentID'), true, array('Order' => 'CustomerOrder', 'ShippingService', 'ShippingAddress' => 'UserAddress', 'Currency'));
             }
         }
         if (empty($shipment)) {
             $shipment = $order->getShipments()->get(0);
         }
         if (!$shipment) {
             $shipment = Shipment::getNewInstance($order);
         }
         if (!$shipment->order->get()) {
             $shipment->order->set($order);
         }
         $history = new OrderHistory($order, $this->user);
         $existingItem = false;
         foreach ($shipment->getItems() as $item) {
             if ($item->getProduct() === $product) {
                 if (!$product->getOptions(true)) {
                     $existingItem = $item;
                 }
                 break;
             }
         }
         if ($existingItem) {
             $item = $existingItem;
             if ($product->isDownloadable()) {
                 return new JSONResponse(false, 'failure', $this->translate('_downloadable_item_already_exists_in_this_order'));
             } else {
                 $item->count->set($item->count->get() + 1);
             }
         } else {
             $currency = $shipment->getCurrency();
             $item = OrderedItem::getNewInstance($order, $product);
             $item->count->set(1);
             $item->price->set($currency->round($item->reduceBaseTaxes($product->getPrice($currency->getID()))));
             $order->addItem($item);
             $shipment->addItem($item);
             $shipment->save();
         }
         $resp = $this->save($item, $shipment, $existingItem ? true : false);
         if (array_key_exists('errors', $resp)) {
             $saveResponse['errors'] = array_merge($saveResponse['errors'], $resp['errors']);
         } else {
             if (array_key_exists('item', $resp)) {
                 $saveResponse['items'][] = $resp['item'];
             }
         }
     }
     // for each product
     if (count($saveResponse['errors']) == 0) {
         unset($saveResponse['errors']);
     }
     if (isset($saveResponse['errors'])) {
         $response = new JSONResponse(array('errors' => $validator->getErrorList()), 'failure', $this->translate('_unable_to_update_items_quantity'));
     } else {
         $response = new JSONResponse($saveResponse, 'success', $this->translate('_item_has_been_successfuly_saved'));
     }
     $composite->addResponse('data', $response, $this, 'create');
     $ids = array();
     foreach ($saveResponse['items'] as $item) {
         $ids[] = $item['ID'];
     }
     $composite->addAction('html', 'backend.orderedItem', 'items');
     $this->request->set('item_ids', implode(',', $ids));
     $history->saveLog();
     return $composite;
 }
示例#6
0
 public function testGenerateInvoices_longScenario()
 {
     // configruation
     $config = ActiveRecordModel::getApplication()->getConfig();
     $config->set('RECURRING_BILLING_GENERATE_INVOICE', 3);
     $config->set('RECURRING_BILLING_PAYMENT_DUE_DATE_DAYS', 7);
     $config->save();
     // other orders (as some information noise).
     for ($i = 0; $i < 3; $i++) {
         $order = CustomerOrder::getNewInstance($this->user);
         $product = $this->products[$i];
         $product->save();
         $order->addProduct($product, $i + 2);
         $order->save();
         $order->finalize();
     }
     //..
     // order with multiple shipments, multiple recurring periods (everyting multiple)
     $period1 = $this->createRecurringProductPeriod($this->products[0], 15, RecurringProductPeriod::TYPE_PERIOD_DAY, null);
     // infinite rebill count
     $period2 = $this->createRecurringProductPeriod($this->products[1], 15, RecurringProductPeriod::TYPE_PERIOD_DAY, 2);
     $period3 = $this->createRecurringProductPeriod($this->products[2], 1, RecurringProductPeriod::TYPE_PERIOD_WEEK, 3);
     // every week, for 3 weeks
     $order = CustomerOrder::getNewInstance($this->user);
     $order->isMultiAddress->set(true);
     $order->save(true);
     $shipment1 = Shipment::getNewInstance($order);
     $shipment1->save();
     $shipment2 = Shipment::getNewInstance($order);
     $shipment2->save();
     $shipment3 = Shipment::getNewInstance($order);
     $shipment3->save();
     $order->addShipment($shipment1);
     $order->addShipment($shipment2);
     $order->addShipment($shipment3);
     list($orderedItem1, $recurringItem1) = $this->addRecurringProduct($order, $this->products[0], 1, $period1, 33.01, 50.01, $shipment1);
     list($orderedItem2, $recurringItem2) = $this->addRecurringProduct($order, $this->products[1], 3, $period2, 44.02, 100.02, $shipment2);
     list($orderedItem3, $recurringItem3) = $this->addRecurringProduct($order, $this->products[2], 2, $period3, 0, 60.03, $shipment3);
     $order->save();
     $order->startDate->set('2010-01-01 00:00:00');
     $order->finalize();
     // $order->dateCompleted->set('2010-01-01 00:00:01');
     $order->save();
     $this->assertInvoices(array($order->getID()), array('count' => 1, 'totalPrice' => array(33.01 + 3 * 44.02, 'Setup price should be ' . (33.01 + 3 * 44.02) . ' (33.01 + 3 * 44.02)'), 'rebillsLeft' => array(-1)));
     // ** TIMELINE **
     // 2010-01-01 order created; period1 starts; period2 starts; period3 starts
     // 2010-01-02
     // 2010-01-03
     // 2010-01-04
     // 2010-01-05 3 days before period3 start
     // 2010-01-06
     // 2010-01-07
     // 2010-01-08 period3 starts
     // 2010-01-09
     // 2010-01-10
     // 2010-01-11
     // 2010-01-12 3 days before period3 start
     // 2010-01-13 3 days before period1 starts; 3 days before period2 starts
     // 2010-01-14
     // 2010-01-15 period3 starts
     // 2010-01-16 period 1 starts; period2 starts
     // 2010-01-17
     // 2010-01-18
     // 2010-01-19 3 days before period3 start
     // 2010-01-20
     // 2010-01-21
     // 2010-01-22 period3 starts
     // 2010-01-23
     // 2010-01-24
     // 2010-01-25
     // 2010-01-26 3 days before period3 start
     // 2010-01-27 3 days before period1 starts; 3 days before period2 starts
     // 2010-01-28
     // 2010-01-29 period3 starts
     // 2010-01-30
     // 2010-01-31 period 1 starts; period2 starts
     // 2010-02-01
     // 2010-02-02 3 days before period3 should start, but it has run out of rebills, should happen nothing.
     // 2010-02-03
     // 2010-02-04
     // 2010-02-05 period 3 rebill count expires
     // 2010-02-06
     // 2010-02-07
     // 2010-02-08
     // 2010-02-09
     // 2010-02-10
     // 2010-02-11
     // 2010-02-12
     // 2010-02-13
     // 2010-02-14
     // 2010-02-15
     // 2010-02-16
     // 2010-02-17
     // 2010-02-18
     // 2010-02-19
     // 2010-02-20
     // 2010-02-21
     // 2010-02-22
     // 2010-02-23
     // 2010-02-24
     // 2010-02-25
     // 2010-02-26
     // 2010-02-27
     // 2010-02-28
     // 2010-03-01
     $this->assertEquals(3, $order->getShipments()->size());
     $this->assertEquals(-1, $order->rebillsLeft->get());
     // from 2009-12-01 to 2010-01-04 there should be nothing to generate (see timeline above)
     $this->assertIntervalHasNoInvoicesToGenerate('2009-12-01', '2010-01-04');
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-05');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(1, 'Should generate invoice for period3 (3 days before period start)'), 'periods' => array(array('2010-01-08', '2010-01-14')), 'totalPrice' => 60.03 * 2, 'rebillsLeft' => array(2)));
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-05');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(0, 'When called second time for same date should not generate more invoices')));
     $this->assertIntervalHasNoInvoicesToGenerate('2010-01-06', '2010-01-11');
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-12');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(1, '3 days before period 3 starts, should generate invoice'), 'periods' => array(array('2010-01-15', '2010-01-21')), 'rebillsLeft' => array(1)));
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-13');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(2, 'Should generate invoices for period1 and period2'), 'orderedItemCount' => array(2, 'Should have 2 ordered items - one for product 1 other for product 2'), 'totalPrice' => array(50.01 + 100.02 * 3, 'total price should be 50.01 + 100.02 * 3'), 'periods' => array(array('2010-01-16', '2010-01-30'), array('2010-01-16', '2010-01-30'))));
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-13');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(0, 'When called second time for same date should not generate more invoices')));
     $this->assertIntervalHasNoInvoicesToGenerate('2010-01-14', '2010-01-18');
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-13');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(0, 'When called second time for same date should not generate more invoices')));
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-01-19');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(1, '3 days before period 3 starts, should generate invoice'), 'periods' => array(array('2010-01-22', '2010-01-28')), 'rebillsLeft' => array(0)));
     $generatedOrdersIDs = CustomerOrder::generateRecurringInvoices('2010-02-02');
     $this->assertInvoices($generatedOrdersIDs, array('count' => array(0, 'period 3 expired')));
 }
示例#7
0
 public static function generateRecurringInvoices($forDate = null)
 {
     $generatedInvoiceIDs = array();
     // return only ids for generated invoice, because 1000+ CustomerOrder instances are expensive
     if ($forDate == null) {
         $ts = time();
     } else {
         if (is_numeric($forDate)) {
             $ts = $forDate;
         } else {
             $ts = strtotime($forDate);
         }
     }
     $count = 0;
     $orderIDrecurringItemIDMapping = self::getRecurringPeriodsEndingTodayArray($ts);
     $orders = self::getRecurringOrders($orderIDrecurringItemIDMapping);
     if ($orders->size() == 0) {
         return $generatedInvoiceIDs;
     }
     /*
     echo "date: ", date('Y-m-d', $ts), "\n";
     print_r($orderIDrecurringItemIDMapping);
     echo "\n";
     */
     $config = self::getApplication()->getConfig();
     $daysDue = $config->get('RECURRING_BILLING_PAYMENT_DUE_DATE_DAYS');
     $daysBefore = $config->get('RECURRING_BILLING_GENERATE_INVOICE');
     foreach ($orders as $order) {
         $mainOrder = $order;
         $foundOrderID = $order->getID();
         // order found with sql, this id is used in customerOrder+recurringItem mapping as key.
         $parent = $order->parentID->get();
         if ($parent) {
             $mainOrder = $parent;
         } else {
             // echo 'generating from first invoice (could contain multiple plans merged!)';
         }
         $mainOrderID = $mainOrder->getID();
         $mainOrder->isRecurring->set(true);
         $mainOrder->save();
         // group by recurring period type, length, (rebill count?)
         $groupedRecurringItems = array();
         foreach ($mainOrder->getOrderedItems() as $item) {
             $recurringItem = RecurringItem::getInstanceByOrderedItem($item);
             $recurringItemID = $recurringItem->getID();
             if (isset($orderIDrecurringItemIDMapping[$foundOrderID]) && in_array($recurringItemID, $orderIDrecurringItemIDMapping[$foundOrderID])) {
                 $rpp = $recurringItem->recurringID->get();
                 $groupedRecurringItems[sprintf('%s_%s_%s', $rpp->periodType->get(), $rpp->periodLength->get(), $rpp->rebillCount->get() === null ? 'NULL' : $rpp->rebillCount->get())][] = array('item' => $item, 'recurringItem' => $recurringItem);
             }
         }
         foreach ($groupedRecurringItems as $itemGroups) {
             $recurringItemIDs = array();
             $newOrder = clone $mainOrder;
             $newOrder->parentID->set($mainOrder);
             $newOrder->isFinalized->set(false);
             $newOrder->invoiceNumber->set($newOrder->getCalculatedRecurringInvoiceNumber());
             $newOrder->dateDue->set(date('Y-m-d H:i:s', strtotime('+' . ($daysBefore + $daysDue) . ' day', $ts)));
             $newOrder->isRecurring->set(true);
             $newOrder->save(true);
             // order must be saved for setting recurringItem lastInvoiceID.
             // !! don't save order while it dont have any item or order will be deleted.
             foreach ($newOrder->getOrderedItems() as $itemToRemove) {
                 $newOrder->removeItem($itemToRemove);
             }
             foreach ($newOrder->getShipments() as $shipment) {
                 //echo '{Shipment ID:'.$shipment->getID().'}';
                 $newOrder->removeShipment($shipment);
             }
             foreach ($itemGroups as $itemGroup) {
                 $item = $itemGroup['item'];
                 $recurringItem = $itemGroup['recurringItem'];
                 $newOrderShipment = Shipment::getNewInstance($newOrder);
                 // ~ should have multiple shipments?
                 $recurringItem->saveLastInvoice($newOrder);
                 $periodLength = $recurringItem->periodLength->get();
                 $periodType = $recurringItem->periodType->get();
                 $recurringItemIDs[] = $recurringItem->getID();
                 // collect IDs for batch processedRebillCount update.
                 $clone = clone $item;
                 $clone->recurringParentID->set($item);
                 $clone->shipmentID->set(null);
                 $clone->save();
                 $newOrderShipment->addItem($clone);
                 $newOrder->addShipment($newOrderShipment);
             }
             if (count($itemGroups) > 0) {
                 $newOrder->updateStartAndEndDates($order, array_map(array(__CLASS__, '_filterRecurringItems'), $itemGroups));
             }
             if ($newOrder->isExistingRecord()) {
                 $generatedInvoiceIDs[] = $newOrder->getID();
             }
             if (count($recurringItemIDs)) {
                 // nedd to be done before CustomerOrder::finalize() because finalize() also updates CustomerOrder.rebillsLeft field.
                 // therefore can't really do batch for all, need to do for every order. still, can reuse batch method.
                 RecurringItem::batchIncreaseProcessedRebillCount($recurringItemIDs);
             }
             $newOrder->save();
             $newOrder->finalize();
         }
     }
     return $generatedInvoiceIDs;
 }
示例#8
0
 /**
  *  Import or update an ordered product
  */
 protected function set_OrderedItem_sku($instance, $value, $record, CsvImportProfile $profile)
 {
     if (!$value) {
         return;
     }
     $product = Product::getInstanceBySKU($value);
     if (!$product) {
         return;
     }
     $items = $instance->getItemsByProduct($product);
     // create initial shipment
     if (!$instance->getShipments()->size()) {
         $shipment = Shipment::getNewInstance($instance);
         $shipment->save();
     }
     // any particular shipment?
     $shipment = $item = null;
     if ($profile->isColumnSet('OrderedItem.shipment')) {
         // internal indexes are 0-based, but the import references are 1-based
         $shipmentNo = $this->getColumnValue($record, $profile, 'OrderedItem.shipment') - 1;
         if (is_numeric($this->getColumnValue($record, $profile, 'OrderedItem.shipment'))) {
             foreach ($instance->getShipments() as $key => $shipment) {
                 if ($key == $shipmentNo) {
                     break;
                 }
                 $shipment = null;
             }
             // create a new shipment
             if (!$shipment) {
                 $shipment = Shipment::getNewInstance($instance);
                 $shipment->save();
             }
             foreach ($items as $item) {
                 if ($item->shipment->get() == $shipment) {
                     break;
                 }
                 unset($item);
             }
         }
     }
     if (!$item) {
         $item = array_shift($items);
     }
     if (!$item) {
         $count = $this->getColumnValue($record, $profile, 'OrderedItem.count');
         $item = OrderedItem::getNewInstance($instance, $product, max(1, $count));
         $instance->addItem($item);
     }
     if ($profile->isColumnSet('OrderedItem.count')) {
         $count = $this->getColumnValue($record, $profile, 'OrderedItem.count');
         $item->count->set(max(1, $count));
     }
     if ($profile->isColumnSet('OrderedItem.price')) {
         $item->price->set($this->getColumnValue($record, $profile, 'OrderedItem.price'));
     }
     if (!$shipment) {
         $shipment = $instance->getShipments()->get(0);
     }
     $item->shipment->set($shipment);
     $item->save();
     $instance->finalize(array('customPrice' => true, 'allowRefinalize' => true));
 }
示例#9
0
 public function testTaxAmountChange()
 {
     $tax = Tax::getNewInstance('GST');
     $tax->save();
     // shipment delivery zone
     $zone = DeliveryZone::getNewInstance();
     $zone->name->set('Canada');
     $zone->isEnabled->set(true);
     $zone->save();
     $country = DeliveryZoneCountry::getNewInstance($zone, 'US');
     $country->save();
     // taxes
     TaxRate::getNewInstance($zone, $tax, 10)->save();
     $this->order->save(true);
     $shipment = Shipment::getNewInstance($this->order);
     $shipment->save();
     $this->order->addShipment($shipment);
     $item = $this->order->addProduct($this->products[0], 1, false, $shipment);
     // $100
     $shipment->recalculateAmounts();
     $this->order->save();
     $this->assertEqual($shipment->taxAmount->get(), 10);
     $this->order->updateCount($item, 2);
     $shipment->recalculateAmounts();
     $this->assertEqual($shipment->taxAmount->get(), 20);
     $this->order->save();
     $shipment->save();
     // there should only be one ShipmentTax instance for this shipment
     $this->assertEqual($shipment->getRelatedRecordSet('ShipmentTax')->size(), 1);
     // reload order and add more items
     ActiveRecord::clearPool();
     $order = CustomerOrder::getInstanceByID($this->order->getID(), true);
     $order->loadAll();
     $shipment = $order->getShipments()->get(0);
     $order->addProduct($this->products[1], 1, false, $shipment);
     // $200
     $shipment->recalculateAmounts(false);
     $shipment->save();
     // @todo: fix failing assertion
     // 2 ShipmentTax records are created for the same tax type (1st is not deleted, before the 2nd is created)
     $this->assertEquals(1, $shipment->getRelatedRecordSet('ShipmentTax')->size(), 'expecting one ShipmentTax');
     $order->save();
     $this->order->finalize();
     /* debug
     		echo "\n Order is finalized!\n";
     		foreach($shipment->getRelatedRecordSet('ShipmentTax') as $item)
     		{
     			echo
     				'shipment tax id:', $item->getID(),
     				', type:', $item->type->get(),
     				', amount:', $item->getAmount(), ' ('. 	$item->shipmentID->get()->getTaxAmount() .')',
     				', shipment id:', $item->shipmentID->get()->getID(),
     				', taxRate id:', $item->taxRateID->get()->getID(),
     				', taxClass:', implode(';', $item->taxRateID->get()->taxID->get()->name->get()).'('. $item->taxRateID->get()->taxID->get()->getID() .')',
     				', zone:',  $item->taxRateID->get()->deliveryZoneID->get()->name->get(),'(', $item->taxRateID->get()->deliveryZoneID->get()->getID() ,')', // blame canada!!
     				"\n";
     		}
     		*/
     $this->assertEquals(1, $order->getShipments()->size(), 'expecting one shipment');
     $this->assertEqual(40, $shipment->getRelatedRecordSet('ShipmentTax')->get(0)->shipmentID->get()->getTaxAmount(), 40);
     // @todo: fix failing assertion
     $this->assertEquals(1, $shipment->getRelatedRecordSet('ShipmentTax')->size(), 'expecting one ShipmentTax');
     $this->assertEqual($shipment->getRelatedRecordSet('ShipmentTax')->get(0)->amount->get(), 40);
 }