@param Money $money

@return OrderInterface
423261
public function setPaymentMethodFee(Money $money = null): OrderInterface
    {
        $this->paymentMethodFee = $money->getAmount();

        return $this;
    }
795191
public function subtract(Money $money) : Money
    {
        $this->verifySameCurrency(__METHOD__, $money);

        return $this->add($money->negate());
    }
810984
public function printMoney(MoneyInterface $money = null)
    {
        if (!($money instanceof MoneyInterface)) {
            return '';
        }

        if (!($money->getCurrency() instanceof CurrencyInterface)) {
            return $money->getAmount();
        }

        $moneyFormatter = new NumberFormatter(
            $this->locale->getIso(),
            NumberFormatter::CURRENCY
        );

        /**
         * The precision of the integer amount for a given Money
         * (cents, thousandths, 10-thousandths, etc) should be
         * stored in the Currency object. We assume amounts are
         * represented in cents.
         *
         * Loss of precision due to conversion is possible, but only when
         * displaying prices. This operation does not affect amounts
         */

        return $moneyFormatter
            ->formatCurrency(
                $money->getAmount() / 100,
                $money->getCurrency()->getIso()
            );
    }
271386
public function localizeMoneyFilter(Money $money, string $locale = null): string
    {
        $formatter      = twig_get_number_formatter($locale, 'currency');
        $moneyFormatter = new IntlMoneyFormatter($formatter, $this->currencies);

        /** @var \Money\Money $formattingMoney */
        $formattingMoney = $money->getValueObject();

        return $moneyFormatter->format($formattingMoney);
    }
668040
public function PaymentOrderCancel($paymentOrderId, $amount, $currency)
    {
        $request = new Request();
        $request->setMethod('POST');

        foreach (array('paymentOrderId', 'amount', 'currency') as $param) {
            if (null == $$param) {
                throw new InvalidArgumentException($param);
            }
        }

        $params = array(
            'PaymentOrderId' => $paymentOrderId,
            'CancelAmount'   => $amount,
            'Currency'       => $currency
        );

        $request->setContent(json_encode($params));

        return $this->doRequest('PaymentOrder/Cancel', $request)->getContentJson();
    }
1303279
public function localizeMoneyFromArrFilter(array $money, string $locale = null): string
    {
        if (isset($money['humanAmount'], $money['baseAmount'])) {
            unset($money['humanAmount']);
        }

        $formattingMoney = new Money($money);

        return $this->localizeMoneyFilter($formattingMoney, $locale);
    }
886662
public function subtract(MoneyContainer $money) : MoneyBag
    {
        foreach ($money->getAmounts() as $currencyCode => $amount) {
            $this->amounts[$currencyCode] = $this->getAmount($currencyCode)->minus($amount);
        }

        return $this;
    }
1215094
public function subtract(Money $money)
    {
        $diff = new Money($this->getAmount() - $money->getAmount());
        $this->setWhole($diff->getAmount());
        $this->setFraction($diff->getAmount());
        return $this;
    }
694863
protected function addOrder(array $params, $money, array $options)
    {
        $params['items'][] = [
            'id'          => Arr::get($options, 'reference'),
            'title'       => Arr::get($options, 'description'),
            'description' => Arr::get($options, 'description'),
            'unit_price'  => (float) $this->gateway->amount($money),
            'quantity'    => 1,
            'currency_id' => Arr::get($options, 'currency'),
        ];

        return array_merge($params, [
            'currency_id'        => Arr::get($options, 'currency'),
            'external_reference' => Arr::get($options, 'reference'),
            'expires'            => Arr::get($options, 'expires', false),
        ]);
    }
724624
public function negated() : Money
    {
        return new Money($this->amount->negated(), $this->currency, $this->context);
    }
814936
public function executePayment($amount, &$order)
    {
        $success = parent::executePayment($amount, $order);
        $session = $this->getSession();

        if ( ($session->getVariable('paymentid') == 'oxidpaypal')
             || ($session->getBasket()->getPaymentId() == 'oxidpaypal')
        ) {
            $this->setPayPalOxOrder($order);
            $success = $this->doExpressCheckoutPayment();
        }

        return $success;
    }
67588
public function updateFromApiResponse(array $data): OrderInterface
    {
        $order = $this->orderRepository->findOneByExternalId($data['id']);
        if (!$order) {
            $order = new Order();
        }

        // we start by syncing the currency, since we use the currency to create Money objects
        $currency = $this->currencyRepository->findOneByCode($data['currencyCode']);
        if (!$currency) {
            $currency = $this->currencySynchronizer->syncOne([
                'code' => $data['currencyCode'],
            ]);

            // this means that the currency does not exist anymore
            // @todo create placeholder
            if (!$currency) {
                throw new \RuntimeException('Could not sync currency `'.$data['currencyCode'].'`. Try again');
            }
        }

        $currencyCode = $currency->getIsoCodeAlpha();

        // set shortcuts for embedded objects
        $orderLinesData = $data['orderLines'] ?? [];
        $paymentData = $data['paymentInfo'] ?? [];
        $shippingData = $data['shippingInfo'] ?? [];

        $createdDate = DateTimeImmutable::createFromJson($data['createdDate']);
        $modifiedDate = $data['modifiedDate'] ? DateTimeImmutable::createFromJson($data['modifiedDate']) : null;

        $giftCertificateAmount = DandomainFoundation\createMoneyFromFloat($currencyCode, $data['giftCertificateAmount']);
        $totalPrice = DandomainFoundation\createMoneyFromFloat($currencyCode, $data['totalPrice']);
        $salesDiscount = DandomainFoundation\createMoneyFromFloat($currencyCode, $data['salesDiscount']);
        $paymentMethodFee = DandomainFoundation\createMoneyFromFloat($currencyCode, $paymentData['fee'] ?? 0.0);
        $shippingMethodFee = DandomainFoundation\createMoneyFromFloat($currencyCode, $shippingData['fee'] ?? 0.0);

        $order
            ->setExternalId($data['id'])
            ->setCurrency($currency)
            ->setComment($data['comment'])
            ->setCreatedDate($createdDate)
            ->setCustomerComment($data['customerComment'])
            ->setGiftCertificateAmount($giftCertificateAmount)
            ->setGiftCertificateNumber($data['giftCertificateNumber'])
            ->setIncomplete($data['incomplete'])
            ->setIp($data['ip'])
            ->setModified($data['modified'])
            ->setModifiedDate($modifiedDate)
            ->setReferenceNumber($data['referenceNumber'])
            ->setReferrer($data['referrer'])
            ->setReservedField1($data['reservedField1'])
            ->setReservedField2($data['reservedField2'])
            ->setReservedField3($data['reservedField3'])
            ->setReservedField4($data['reservedField4'])
            ->setReservedField5($data['reservedField5'])
            ->setSalesDiscount($salesDiscount)
            ->setTotalPrice($totalPrice)
            ->setTotalWeight($data['totalWeight'])
            ->setTrackingNumber($data['trackingNumber'])
            ->setTransactionNumber($data['transactionNumber'])
            ->setVatPct((float) $data['vatPct'])
            ->setVatRegNumber($data['vatRegNumber'])
            ->setXmlParams($data['xmlParams'])
            ->setShippingMethodFee($shippingMethodFee)
            ->setPaymentMethodFee($paymentMethodFee)
        ;

        // populate customer info
        $customer = $this->customerUpdater->updateFromEmbeddedApiResponse($data['customerInfo']);
        $order->setCustomer($customer);

        // populate delivery info
        $delivery = $this->deliveryUpdater->updateFromEmbeddedApiResponse($data['deliveryInfo'], $order->getDelivery());
        $order->setDelivery($delivery);

        // populate invoice info
        $invoice = $this->invoiceUpdater->updateFromEmbeddedApiResponse($data['invoiceInfo'], $order->getInvoice());
        $order->setInvoice($invoice);

        // populate payment info
        $paymentMethod = $this->paymentMethodUpdater->updateFromEmbeddedApiResponse($data['paymentInfo'], $currencyCode, $order->getPaymentMethod());
        $order->setPaymentMethod($paymentMethod);

        // populate shipping info
        $shippingMethod = $this->shippingMethodUpdater->updateFromEmbeddedApiResponse($data['shippingInfo'], $currencyCode, $order->getShippingMethod());
        $order->setShippingMethod($shippingMethod);

        // populate site
        $site = $this->siteRepository->findOneByExternalId($data['siteId']);
        if (!$site) {
            $site = $this->siteSynchronizer->syncOne([
                'externalId' => $data['siteId'],
            ]);

            // this means that the site does not exist anymore so we create a placeholder
            if (!$site) {
                $site = new Site();
                $site->setExternalId($data['siteId'])
                    ->setName((string) $data['siteId'])
                    ->setCurrency($currency)
                ;

                // we soft delete the site because it does not exist anymore
                $site->delete();

                $this->siteRepository->save($site);
            }
        }
        $order->setSite($site);

        // populate state
        $state = $this->stateRepository->findOneByExternalId($data['orderState']['id']);
        if(!$state) {
            $state = $this->stateSynchronizer->syncOne([
                'externalId' => $data['orderState']['id']
            ]);

            if(!$state) {
                // @todo create placeholder
                throw new \InvalidArgumentException('The order state `'.$data['orderState']['name'].'` (id: '.$data['orderState']['id'].') does not exist');
            }
        }
        $order->setState($state);

        if (count($orderLinesData)) {
            // first remove order lines that are not present anymore
            $removeOrderLines = [];
            foreach ($order->getOrderLines() as $orderLineEntity) {
                $found = false;
                foreach ($orderLinesData as $orderLineData) {
                    if ($orderLineData['id'] === $orderLineEntity->getExternalId()) {
                        $found = true;
                    }
                }

                if (!$found) {
                    $removeOrderLines[] = $orderLineEntity;
                }
            }

            foreach ($removeOrderLines as $removeOrderLine) {
                $order->removeOrderLine($removeOrderLine);
            }

            // then update the rest of the order lines
            foreach ($orderLinesData as $orderLineData) {
                if (!$orderLineData['id']) {
                    continue;
                }

                $collection = $order
                    ->getOrderLines()
                    ->matching(
                        Criteria::create()->where(Criteria::expr()->eq('externalId', $orderLineData['id']))
                    );

                if ($collection->count()) {
                    $orderLineEntity = $collection->first();
                } else {
                    $orderLineEntity = new OrderLine();
                    $order->addOrderLine($orderLineEntity);
                }

                $orderLineUnitPrice = DandomainFoundation\createMoneyFromFloat($currencyCode, $orderLineData['unitPrice'] ?? 0.0);
                $orderLineTotalPrice = DandomainFoundation\createMoneyFromFloat($currencyCode, $orderLineData['totalPrice'] ?? 0.0);

                $orderLineEntity
                    ->setExternalId((int) $orderLineData['id'])
                    ->setFileUrl($orderLineData['fileUrl'])
                    ->setProductNumber($orderLineData['productId'])
                    ->setProductName($orderLineData['productName'])
                    ->setQuantity((int) $orderLineData['quantity'])
                    ->setTotalPrice($orderLineTotalPrice)
                    ->setUnitPrice($orderLineUnitPrice)
                    ->setVatPct((float) $orderLineData['vatPct'])
                    ->setVariant($orderLineData['variant'])
                    ->setXmlParams($orderLineData['xmlParams'])
                ;

                $product = $this->getProductFromOrderLine($orderLineEntity);
                if ($product) {
                    $orderLineEntity->setProduct($product);
                }
            }
        } else {
            $order->clearOrderLines();
        }

        return $order;
    }
241795
public function setUnitPrice(Money $unitPrice): PriceInterface
    {
        // @todo change type from int to string
        $this->unitPrice = (int) $unitPrice->getAmount();

        return $this;
    }
512488
public function equals(Money $money)
    {
        if (!$money instanceof MultiCurrencyMoney) {
            return false;
        }

        return $money->currency == $this->currency && $money->getAmount() == $this->getAmount();
    }
495682
public function amount($money)
    {
        if (null === $money) {
            return;
        }

        if (is_string($money) || $money < 0) {
            throw new InvalidArgumentException('Money amount must be a positive number.');
        }

        if ($this->getMoneyFormat() === 'cents') {
            return number_format($money, 0, '', '');
        }

        return sprintf('%.2f', number_format($money, 2, '.', '') / 100);
    }
712234
public function add(Money\Money $money1, Money\Money $money2)
    {
        return $this->accountant->add($money1, $money2);
    }
643785
public function setAmount(\Elcodi\Component\Currency\Entity\Interfaces\MoneyInterface $amount)
    {
        $this->amount = $amount->getAmount();
        $this->currency = $amount->getCurrency();

        return $this;
    }