Create operations from Mirakl invoice

@param array $invoice
@param VendorInterface $vendor
@param DateTime $cycleDate
@return boolean
438445
private function createOperationsFromInvoice(array $invoice, VendorInterface $vendor, DateTime $cycleDate)
    {
        if ($invoice['summary']['amount_transferred'] > 0) {

            $operations = array();

            try {
                // Calculate adjusted amount (for past negative operations)
                $adjustedInfos = $this->getAdjustedAmount($invoice['summary']['amount_transferred'], $vendor);

                $this->logger->debug(
                    "Vendor origin amount " . $invoice['summary']['amount_transferred'],
                    array('miraklId' => $invoice['shop_id'], "action" => "Operations creation")
                );

                $this->logger->debug(
                    "Vendor adjusted amount " .
                    $adjustedInfos['adjustedAmount'] .
                    " (" .
                    count($adjustedInfos['adujstedOperationsIds']) .
                    " operations adjusted)",
                    array('miraklId' => $invoice['shop_id'], "action" => "Operations creation")
                );

                // Vendor operation
                $operations[] = $this->createOperation(
                    $adjustedInfos['adjustedAmount'],
                    $invoice['summary']['amount_transferred'],
                    $cycleDate,
                    $invoice['invoice_id'],
                    $vendor,
                    $adjustedInfos['adujstedOperationsIds']
                );

                // operator operation
                $operations[] = $this->createOperation(
                    $invoice['total_charged_amount'],
                    null,
                    $cycleDate,
                    $invoice['invoice_id'],
                    $this->operator
                );

                // save in memory for future saving in database
                $this->adjustedOperations = array_merge(
                    $this->adjustedOperations,
                    $adjustedInfos["adujstedOperations"]
                );

                return $operations;
            } catch (Exception $e) {
                $this->handleException($e);
                return false;
            }
        } else {
            $this->logger->warning(
                "Invoice n° " . $invoice['invoice_id'] . " has a negative amount, will not be treated",
                array('miraklId' => $invoice['shop_id'], "action" => "Operations creation")
            );
        }
    }
966747
public function process(DateTime $startDate, DateTime $endDate, DateTime $cycleDate)
    {
        $this->logger->info('Control Mirakl Settings', array('miraklId' => null, "action" => "Operations creation"));
        // control mirakl settings
        $boolControl = $this->getControlMiraklSettings($this->documentTypes);
        if ($boolControl === false) {
            // log critical
            $title = $this->criticalMessageMiraklSettings;
            $message = $this->formatNotification->formatMessage($title);
            $this->logger->critical($message, array('miraklId' => null, "action" => "Operations creation"));
        } else {
            $this->logger->info(
                'Control Mirakl Settings OK',
                array('miraklId' => null, "action" => "Operations creation")
            );
        }

        $this->logger->info('Cashout Initializer', array('miraklId' => null, "action" => "Operations creation"));

        //Fetch Invoices
        $this->logger->info(
            'Fetch invoices documents from Mirakl from ' .
            $startDate->format('Y-m-d H:i') .
            ' to ' .
            $endDate->format('Y-m-d H:i')
            ,
            array('miraklId' => null, "action" => "Operations creation")
        );

        // get invoices from Mirakl API
        $invoices = $this->getInvoices($startDate, $endDate);

        $this->logger->info(
            '[OK] Fetched ' . count($invoices) . ' invoices',
            array('miraklId' => null, "action" => "Operations creation")
        );

        $this->logger->info('Process invoices', array('miraklId' => null, "action" => "Operations creation"));

        $operations = $this->processInvoices($invoices, $cycleDate);

        $this->saveOperations($operations);

    }
1374000
public function create(array $aData = [], $bReturnObject = false)
    {
        $oDb = Factory::service('Database');

        try {

            if (empty($aData['customer_id']) && empty($aData['email'])) {
                throw new InvoiceException('Either "customer_id" or "email" field must be supplied.', 1);
            }

            $oDb->trans_begin();

            $this->prepareInvoice($aData);

            if (empty($aData['ref'])) {
                $aData['ref'] = $this->generateValidRef();
            }

            $aData['token'] = $this->generateToken();

            $aItems = $aData['items'];
            unset($aData['items']);

            $oInvoice = parent::create($aData, true);

            if (!$oInvoice) {
                throw new InvoiceException('Failed to create invoice.', 1);
            }

            if (!empty($aItems)) {
                $this->updateLineItems($oInvoice->id, $aItems);
            }

            $oDb->trans_commit();
            $this->triggerEvent(
                Events::INVOICE_CREATED,
                [$this->getInvoiceForEvent($oInvoice->id)]
            );

            return $bReturnObject ? $oInvoice : $oInvoice->id;

        } catch (\Exception $e) {
            $oDb->trans_rollback();
            $this->setError($e->getMessage());
            return false;
        }
    }
493697
public function createForOrder(OrderInterface $order, $type = Invoice::TYPE_DEBIT)
    {
        $invoice = new Invoice();
        $number = $this->codeGenerator::generate($invoice);

        $data = [
            'order'        => $order,
            'number'       => $number,
            'date'         => date('d/m/Y'),
            'base_dir'     => $this->rootDir . '/../web',
            'invoice_type' => $type,
        ];

        $html = $this->templating->render($this->template, $data);
        $pdf = $this->pdfGenerator->getOutputFromHtml($html);

        $total = $type === Invoice::TYPE_DEBIT ?
            $order->getTotal() :
            $order->getTotal() * -1
        ;

        $order->addInvoice($invoice);
        $invoice->setOrder($order);
        $invoice->setNumber($number);
        $invoice->setMimeType('application/pdf');
        $invoice->setFile($pdf);
        $invoice->setType($type);
        $invoice->setTotal($total);

        return $invoice;
    }
188620
public function settleInvoice($invoice, $payment)
    {
        $success       = 0;
        $zbytek        = 'ne';
        $prijataCastka = (float) $payment->getDataValue('sumCelkem');
        $zbyvaUhradit  = $invoice->getDataValue('zbyvaUhradit');

        if ($prijataCastka < $zbyvaUhradit) { //Castecna uhrada
            $this->addStatusMessage(sprintf(_('Castecna uhrada - FAKTURA: prijato: %s %s ma byt zaplaceno %s %s'),
                    $prijataCastka,
                    \FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
                    $zbyvaUhradit,
                    \FlexiPeeHP\FlexiBeeRO::uncode($invoice->getDataValue('mena'))),
                'warning');
            $zbytek = 'castecnaUhrada';
        }
        if ($prijataCastka > $zbyvaUhradit) { //Castecna uhrada
            $this->addStatusMessage(sprintf(_('Přeplatek - FAKTURA: prijato: %s %s ma byt zaplaceno %s %s'),
                    $prijataCastka,
                    \FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
                    $zbyvaUhradit,
                    \FlexiPeeHP\FlexiBeeRO::uncode($invoice->getDataValue('mena'))),
                'warning');

            //$this->banker->insertToFlexiBee(['id'=>$payment->getDataValue('id'), 'stitky'=>$this->config['LABEL_CASTECNAUHRADA']]);
            $zbytek = 'ignorovat';
        }

        if ($invoice->sparujPlatbu($payment, $zbytek)) { //Jak se ma FlexiBee zachovat pri preplatku/nedoplatku
            $success = 1;
            $invoice->insertToFlexiBee(['id' => (string) $invoice, 'stavMailK' => 'stavMail.odeslat']);
            $invoice->addStatusMessage(sprintf(_('Platba %s  %s %s byla sparovana s fakturou %s'),
                    \FlexiPeeHP\FlexiBeeRO::uncode($payment->getRecordIdent()),
                    $prijataCastka,
                    \FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
                    \FlexiPeeHP\FlexiBeeRO::uncode($invoice->getRecordIdent())),
                'success');
        }

        return $success;
    }
1339746
private function createOrderInvoice($order, $transactionId, $amount)
    {
        if ($order->getTotalInvoiced() + $amount == $order->getGrandTotal()) {
            $invoice = $this->invoiceService->prepareInvoice($order);
        } else {
            $invoice = $this->invoiceService->prepareInvoiceWithoutItems($order, $amount);
        }

        $invoice->setRequestedCaptureCase(Invoice::CAPTURE_OFFLINE);
        $invoice->setTransactionId($transactionId);
        $invoice->setBaseGrandTotal($amount);
        $invoice->setGrandTotal($amount);
        $invoice->register();
        $invoice->save();

        $order->addRelatedObject($invoice);

        if (!$invoice->getEmailSent()) {
            $this->invoiceSender->send($invoice);
        }

        //Add notification comment to order
        $order->addStatusHistoryComment(
            __('Invoice #%1 is created. Notification email is sent to customer.', $invoice->getId())
        )->setIsCustomerNotified(true)->save();

        return $invoice;
    }
590801
private static function updatePaymentStatus($invoice)
    {
        if (! $invoice->payment || $invoice->getStatus() === 'payed') {
            return $invoice;
        }
        $receipt = $invoice->get_payment();
        Bank_Service::update($receipt);
        if ($invoice->get_payment()->isPayed()){
            $invoice->setStatus('payed');
            $invoice->update();
        }
        return $invoice;
    }
117488
public function settle(IncomingInvoice $invoiceA, IncomingInvoice $invoiceB)
    {
        return $this->connector->settle($invoiceA, $invoiceB);
    }
30600
public function sendPurchaseNotification($invoice)
    {
        $templateName = 'PaymentBundle:Email:sale.notification.admin.html.twig';

        if($invoice->getTransaction()->getItems()->first()->getProduct() instanceof Product){
            $product = $invoice->getTransaction()->getItems()->first()->getProduct();
        }
        
        $sellerEmails = array();
        if($invoice->getTransaction()->getItems()->first()->getProduct()->getActor() instanceof Actor){
            $sellerEmails[] = $invoice->getTransaction()->getItems()->first()->getProduct()->getActor()->getEmail();
        } 
            
        $context = array(
            'order_number'    => $invoice->getTransaction()->getTransactionKey(),
            'invoice_date'      => $invoice->getCreated(),
            'user_email'        => $invoice->getTransaction()->getActor()->getEmail(),
            'seller_email'        => implode(',', $sellerEmails),
            'order_details_url' => $this->router->generate('payment_checkout_showinvoice', array('number' => $invoice->getInvoiceNumber()), UrlGeneratorInterface::ABSOLUTE_URL),
        );

        $this->sendMessage($templateName, $context, $this->twigGlobal->getParameter('admin_email'), $this->twigGlobal->getParameter('admin_email'));
    }
810073
public function deleteLock(Source $invoiceSource)
    {
        $entry = $this->getByInvoiceSource($invoiceSource, false);
        if ($entry === null) {
            // - The process that had the lock may have failed sending the
            //   invoice to Acumulus and has removed the lock (e.g. a connection
            //   timeout, with the timeout being longer than our lock expiry).
            // - Yet another process already cleared the lock.
            return AcumulusEntry::Lock_NoLongerExists;
        }
        if ($entry->isSendLock()) {
            // The lock is still there: remove it.
            $this->delete($entry);
            return AcumulusEntry::Lock_Deleted;
        }
        // The AcumulusEntry became a real entry: apparently the process that
        // had the lock, successfully finished sending the invoice after all.
        return AcumulusEntry::Lock_BecameRealEntry;
    }
28261
private void useExistingCBAFromTransaction(final BigDecimal accountCBA,
                                               final List<Tag> invoicesTags,
                                               final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory,
                                               final InternalCallContext context) throws InvoiceApiException, EntityPersistenceException {
        if (accountCBA.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }

        // PERF: Computing the invoice balance is difficult to do in the DB, so we effectively need to retrieve all invoices on the account and filter the unpaid ones in memory.
        // This should be infrequent though because of the account CBA check above.
        final List<InvoiceModelDao> allInvoices = invoiceDaoHelper.getAllInvoicesByAccountFromTransaction(false, invoicesTags, entitySqlDaoWrapperFactory, context);
        final List<InvoiceModelDao> unpaidInvoices = invoiceDaoHelper.getUnpaidInvoicesByAccountFromTransaction(allInvoices, null);
        // We order the same os BillingStateCalculator-- should really share the comparator
        final List<InvoiceModelDao> orderedUnpaidInvoices = Ordering.from(new Comparator<InvoiceModelDao>() {
            @Override
            public int compare(final InvoiceModelDao i1, final InvoiceModelDao i2) {
                return i1.getInvoiceDate().compareTo(i2.getInvoiceDate());
            }
        }).immutableSortedCopy(unpaidInvoices);

        BigDecimal remainingAccountCBA = accountCBA;
        for (final InvoiceModelDao unpaidInvoice : orderedUnpaidInvoices) {
            remainingAccountCBA = computeCBAComplexityAndCreateCBAItem(remainingAccountCBA, unpaidInvoice, entitySqlDaoWrapperFactory, context);
            if (remainingAccountCBA.compareTo(BigDecimal.ZERO) <= 0) {
                break;
            }
        }
    }
411613
protected function query2Sources(array $args, $invoiceSourceType, $sort = true)
    {
        $this->getLog()->info('WooCommerce\InvoiceManager::query2Sources: args = %s', str_replace(array(' ', "\r", "\n", "\t"), '', var_export($args, true)));
        // Add default arguments.
        $args = $args + array(
                'fields' => 'ids',
                'posts_per_page' => -1,
                'post_type' => $this->sourceTypeToShopType($invoiceSourceType),
                'post_status' => array_keys(wc_get_order_statuses()),
            );
        $query = new WP_Query($args);
        $ids = $query->get_posts();
        if ($sort) {
            sort($ids);
        }
        return $this->getSourcesByIdsOrSources($invoiceSourceType, $ids);
    }
430435
public function product($invoiceLineHandle, $product)
    {
        $products = new Product($this->client_raw);
        $productHandle = $products->getHandle($product);

        $this->client
            ->CurrentInvoiceLine_SetProduct(
                array(
                    'currentInvoiceLineHandle' => $invoiceLineHandle,
                    'valueHandle' => $productHandle
                )
            );

        return true;
    }
1335800
public function unit($invoiceLineHandle, $unit)
    {
        $units      = new Unit($this->client_raw);
        $unitHandle = $units->getHandle($unit);

        $this->client
            ->CurrentInvoiceLine_SetUnit(
                array(
                    'currentInvoiceLineHandle' => $invoiceLineHandle,
                    'valueHandle'              => $unitHandle
                )
            );

        return true;
    }
1018456
protected function triggerInvoiceSendBefore(array &$invoice, Source $invoiceSource, Result $localResult)
    {
        /** @noinspection PhpUnhandledExceptionInspection */
        Hook::exec('actionAcumulusInvoiceSendBefore', array('invoice' => &$invoice, 'source' => $invoiceSource, 'localResult' => $localResult));
    }
231634
public function saveInvoice(Invoice $invoice): bool
    {
        if ($invoice->id) {
            $record = InvoiceRecord::findOne($invoice->id);

            if (!$record) {
                throw new Exception(Craft::t('commerce-stripe', 'No invoice exists with the ID “{id}”', ['id' => $invoice->id]));
            }
        } else {
            $record = new InvoiceRecord();
        }

        // Only allow this for new invoices
        if (!$invoice->id) {
            $record->reference = $invoice->reference;
            $record->subscriptionId = $invoice->subscriptionId;
        }

        $record->invoiceData = $invoice->invoiceData;

        if ($invoice->validate()) {
            $event = new SaveInvoiceEvent(['invoice' => $invoice]);

            // Fire a 'beforeSaveInvoice' event.
            $this->trigger(self::EVENT_BEFORE_SAVE_INVOICE, $event);

            if (!$event->isValid) {
                return false;
            }

            $record->save(false);
            $invoice->id = $record->id;

            // Fire a 'afterSaveInvoice' event.
            if ($this->hasEventHandlers(self::EVENT_SAVE_INVOICE)) {
                $this->trigger(self::EVENT_SAVE_INVOICE, new SaveInvoiceEvent(['invoice' => $invoice]));
            }

            return true;
        }

        return false;
    }
743905
public function createOperation(
        $amount,
        $originAmount,
        DateTime $cycleDate,
        $paymentVoucher,
        $vendor,
        $adjustedOperationsIds = null
    ) {
        //Set hipay id
        $hipayId = $vendor->getHiPayId();

        //Call implementation function
        $operation = $this->operationManager->create($amount, $cycleDate, $paymentVoucher, $vendor->getMiraklId());

        $operation->setHiPayId($hipayId);

        //Sets mandatory values
        $operation->setMiraklId($vendor->getMiraklId());
        $operation->setStatus(new Status(Status::CREATED));
        $operation->setUpdatedAt(new DateTime());
        $operation->setAmount($amount);
        $operation->setOriginAmount($originAmount);
        $operation->setCycleDate($cycleDate);
        $operation->setPaymentVoucher((string)$paymentVoucher);

        // if adjustments were made, save adjusted operations
        if ($adjustedOperationsIds !== null) {
            $operation->setAdjustmentIds(json_encode($adjustedOperationsIds));
        }

        $this->isOperationValid($operation);

        $this->operationsLogs[] = $this->logOperationsManager->create(
            $vendor->getMiraklId(),
            $hipayId,
            (string)$paymentVoucher,
            $amount,
            $originAmount,
            $this->hipay->getBalance($vendor)
        );
        return $operation;
    }