Clone quote data from source to destination

@param Quote $source
@param Quote $destination
@throws \Magento\Framework\Exception\AlreadyExistsException
@throws \Zend_Validate_Exception
544258
public function replicateQuoteData($source, $destination)
    {
        // Skip the replication if source and destination point to the same quote
        // E.g. delayed Save Order - immutable quote is cleared by cron and we use the parent instead
        if ($source->getId() == $destination->getId()) return;

        $destinationId = $destination->getId();
        $destinationActive = (bool)$destination->getIsActive();

        $destination->removeAllItems();

        $destination->merge($source);

        $destination->getBillingAddress()->setShouldIgnoreValidation(true);
        $this->transferData($source->getBillingAddress(), $destination->getBillingAddress());

        $destination->getShippingAddress()->setShouldIgnoreValidation(true);
        $this->transferData($source->getShippingAddress(), $destination->getShippingAddress());

        $this->transferData($source, $destination, false);

        $destination->setId($destinationId);
        $destination->setIsActive($destinationActive);

        $this->quoteResourceSave($destination);

        // If Amasty Gif Cart Extension is present clone applied gift cards
        $this->discountHelper->cloneAmastyGiftCards($source->getId(), $destination->getId());
    }
960057
public function request(
        QuoteTransfer $quoteTransfer,
        ComputopApiHeaderPaymentTransfer $computopApiHeaderPayment
    ): TransferInterface {
        $requestData = $this
            ->mapper
            ->buildRequest($quoteTransfer, $computopApiHeaderPayment);

        return $this->sendRequest($requestData);
    }
404825
public static function copyRecursive($source, $destination)
    {
        if (!is_dir($destination)) {
            mkdir($destination);
        }

        $dir = opendir($source);

        if (!$dir) {
            throw new RuntimeException("Cannot copy '$source' to '$destination'");
        }

        while (false !== ($file = readdir($dir))) {
            if ($file != '.' && $file != '..') {
                if (is_dir($source . DIRECTORY_SEPARATOR . $file)) {
                    static::copyRecursive(
                        $source . DIRECTORY_SEPARATOR . $file,
                        $destination . DIRECTORY_SEPARATOR . $file
                    );
                } else {
                    copy($source . DIRECTORY_SEPARATOR . $file, $destination . DIRECTORY_SEPARATOR . $file);
                }
            }
        }
        closedir($dir);
    }
513709
protected function compareStandards(Standard $source, Standard $destination)
    {
        return $source->getName() === $destination->getName()
            && sha1_file($source->getRuleSetXmlPath()) === sha1_file($destination->getRuleSetXmlPath());
    }
73810
public function getData(AbstractTransfer $quoteTransfer): QuoteTransfer
    {
        if ($quoteTransfer->getPayment() === null) {
            $paymentTransfer = new PaymentTransfer();
            $paymentTransfer->setPayone(new PayonePaymentTransfer());
            $quoteTransfer->setPayment($paymentTransfer);
        }

        return $quoteTransfer;
    }
391684
public function manageMandate(QuoteTransfer $quoteTransfer)
    {
        $manageMandateTransfer = new PayoneManageMandateTransfer();
        $manageMandateTransfer->setBankCountry($quoteTransfer->getPayment()->getPayoneDirectDebit()->getBankcountry());
        $manageMandateTransfer->setBankAccount($quoteTransfer->getPayment()->getPayoneDirectDebit()->getBankaccount());
        $manageMandateTransfer->setBankCode($quoteTransfer->getPayment()->getPayoneDirectDebit()->getBankcode());
        $manageMandateTransfer->setIban($quoteTransfer->getPayment()->getPayoneDirectDebit()->getIban());
        $manageMandateTransfer->setBic($quoteTransfer->getPayment()->getPayoneDirectDebit()->getBic());
        $personalData = new PayonePersonalDataTransfer();
        $customer = $quoteTransfer->getCustomer();
        $billingAddress = $quoteTransfer->getBillingAddress();
        $personalData->setCustomerId($customer->getIdCustomer());
        $personalData->setLastName($billingAddress->getLastName());
        $personalData->setFirstName($billingAddress->getFirstName());
        $personalData->setCompany($billingAddress->getCompany());
        $personalData->setCountry($billingAddress->getIso2Code());
        $personalData->setCity($billingAddress->getCity());
        $personalData->setStreet($billingAddress->getAddress1());
        $personalData->setZip($billingAddress->getZipCode());
        $personalData->setEmail($billingAddress->getEmail() ?? $customer->getEmail());
        $manageMandateTransfer->setPersonalData($personalData);

        return $this->getFactory()->createZedStub()->manageMandate($manageMandateTransfer);
    }
1247549
protected function copy($source, $target): void
    {
        // skip, if not exists
        if (!file_exists($source)) {
            return;
        }
        // skip, if target exists
        if (is_file($target) && !is_dir($target)) {
            $this->installer->getIo()->write(
                sprintf('  - File <comment>%s</comment> already exists', $target),
                true,
                IOInterface::VERBOSE
            );
            return;
        }

        // Check the renaming of file for direct moving (file-to-file)
        $isRenameFile = substr($target, -1) !== '/' && !is_dir($source);

        if (file_exists($target) && !is_dir($target) && !$isRenameFile) {
            throw new \InvalidArgumentException('Destination directory is not a directory');
        }

        try {
            if ($isRenameFile) {
                $this->getFilesystem()->mkdir(\dirname($target));
            } else {
                $this->getFilesystem()->mkdir($target);
            }
        } catch (IOException $e) {
            throw new \InvalidArgumentException(
                sprintf('Could not create directory `%s`', $target)
            );
        }

        if (false === file_exists($source)) {
            throw new \InvalidArgumentException(
                sprintf('Source directory or file `%s` does not exist', $source)
            );
        }

        if (is_dir($source)) {
            $finder = new Finder;
            $finder->files()->in($source);

            foreach ($finder as $file) {
                try {
                    $this->getFilesystem()->copy($file, $target . DS . $file->getRelativePathname());
                } catch (IOException $e) {
                    throw new \InvalidArgumentException(
                        sprintf('Could not copy `%s`', $file->getBaseName())
                    );
                }
            }
        } else {
            try {
                if ($isRenameFile) {
                    $this->getFilesystem()->copy($source, $target);
                } else {
                    $this->getFilesystem()->copy($source, $target . '/' . basename($source));
                }
            } catch (IOException $e) {
                throw new \InvalidArgumentException(sprintf('Could not copy `%s`', $source));
            }
        }

        $this->installer->getIo()->write(
            sprintf('  - Copied file(s) from <comment>%s</comment> to <comment>%s</comment>', $source, $target),
            true,
            IOInterface::VERBOSE
        );
    }
614917
protected function verifyAndSymlinkDirectory(string $source, string $destination, OutputInterface $output): void
    {
        if ($this->fileSystem->exists($destination) && !is_link($destination)) {
            $output->writeln('<comment>' . basename($destination) . '</comment> already exists in <comment>' . dirname($destination) . '/</comment> and is not a symlink. Skipping...');

            return;
        }

        if ($this->forceSymlinks && is_link($destination)) {
            $this->fileSystem->remove($destination);
        }

        if ($this->fileSystem->exists($destination)) {
            $output->writeln('Skipped creating the symlink for <comment>' . basename($destination) . '</comment> in <comment>' . dirname($destination) . '/</comment>. Symlink already exists!');

            return;
        }

        $this->fileSystem->symlink(
            $this->fileSystem->makePathRelative(
                $source,
                realpath(dirname($destination))
            ),
            $destination
        );
    }
415823
private function deactivateQuote($quote)
    {
        $quoteId = $quote->getId();
        if ($this->sessCustomer->isLoggedIn()) {
            $this->daoWrhsQuote->deleteById($quoteId);
        } else {
            $quoteReg = $this->sessCustomer->getData(AQuoteRepo::SESS_QUOTE_REGISTRY);
            if (
                is_array($quoteReg) &&
                isset($quoteReg[$quoteId])
            ) {
                unset($quoteReg[$quoteId]);
                $this->sessCustomer->setData(AQuoteRepo::SESS_QUOTE_REGISTRY, $quoteReg);
            }
        }
    }
23106
protected function _copy(Model $source, Model $destination, array $references, array $exclusions)
    {
        try {
            // Perhaps source was already copied, then simply load destination model and return
            if (isset($this->mapping[$source->table]) && isset($this->mapping[$source->table][$source->id])) {
                $this->debug('Skipping '.get_class($source));

                $destination->load($this->mapping[$source->table][$source->id]);
            } else {
                $this->debug('Copying '.get_class($source));

                // TODO transform data from source to destination with a possible callback
                // $data = $source->get(); transformData($data);
                $data = $source->get();
                unset($data[$source->id_field]);
                foreach ($this->extractKeys($exclusions) as $key => $val) {
                    unset($data[$key]);
                }

                // TODO add a way here to look for duplicates based on unique fields
                // foreach($destination->unique fields) { try load by

                // Copy fields as they are
                foreach ($data as $key => $val) {
                    if (
                        ($field = $destination->hasField($key)) &&
                        $field->isEditable()
                    ) {
                        $destination->set($key, $val);
                    }
                }
            }
            $destination->hook('afterCopy', [$source]);

            // Look for hasOne references that needs to be mapped. Make sure records can be mapped, or copy them
            foreach ($this->extractKeys($references) as $ref_key => $ref_val) {
                $this->debug("Considering $ref_key");

                if (($ref = $source->hasRef($ref_key)) && $ref instanceof HasOne) {
                    $this->debug("Proceeding with $ref_key");

                    // load destination model through $source
                    $source_table = $ref->refModel()->table;

                    if (
                        isset($this->mapping[$source_table]) &&
                        array_key_exists($source[$ref_key], $this->mapping[$source_table])
                    ) {
                        // no need to deep copy, simply alter ID
                        $destination[$ref_key] = $this->mapping[$source_table][$source[$ref_key]];
                        $this->debug(' already copied '.$source[$ref_key].' as '.$destination[$ref_key]);
                    } else {
                        // hasOne points to null!
                        $this->debug('Value is '.$source[$ref_key]);
                        if (!$source[$ref_key]) {
                            $destination[$ref_key] = $source[$ref_key];
                            continue;
                        }

                        // pointing to non-existent record. Would need to copy
                        try {
                            $destination[$ref_key] = $this->_copy(
                                $source->ref($ref_key),
                                $destination->refModel($ref_key),
                                $ref_val,
                                $exclusions[$ref_key] ?? []
                            )->id;
                            $this->debug(' ... mapped into '.$destination[$ref_key]);
                        } catch (DeepCopyException $e) {
                            $this->debug('escalating a problem from '.$ref_key);

                            throw $e->addDepth($ref_key);
                        }
                    }
                }
            }

            // Next copy our own data
            $destination->save();

            // Store mapping
            $this->mapping[$source->table][$source->id] = $destination->id;
            $this->debug(' .. copied '.get_class($source).' '.$source->id.' '.$destination->id);

            // Next look for hasMany relationships and copy those too

            foreach ($this->extractKeys($references) as $ref_key => $ref_val) {
                if (($ref = $source->hasRef($ref_key)) && $ref instanceof HasMany) {

                    // No mapping, will always copy
                    foreach ($source->ref($ref_key) as $ref_model) {
                        $this->_copy(
                            $ref_model,
                            $destination->ref($ref_key),
                            $ref_val,
                            $exclusions[$ref_key] ?? []
                        );
                    }
                }
            }

            return $destination;
        } catch (DeepCopyException $e) {
            throw $e;
        } catch (\atk4\core\Exception $e) {
            $this->debug('noticed a problem');

            throw new DeepCopyException([
                'Problem cloning model',
                'source'          => $source,
                'source_info'     => $source->__debugInfo(),
                'source_data'     => $source->get(),
                'destination'     => $destination,
                'destination_info'=> $destination->__debugInfo(),
                'depth'           => $e->getParams()['field'] ?? '?',
                ], null, $e);
        }
    }
1078895
public function updateLastQuoteId($quoteId, $email, $websiteId)
    {
        if ($this->isEnabled($websiteId)) {
            $client = $this->getWebsiteApiClient($websiteId);
            //last quote id config data mapped
            $quoteIdField = $this->getLastQuoteId();

            $data[] = [
                'Key' => $quoteIdField,
                'Value' => $quoteId,
            ];
            //update datafields for conctact
            $client->updateContactDatafieldsByEmail($email, $data);
        }
    }
388851
public function setAddress(MageQuote $quote)
    {
        $billing = $this->sgBase->getInvoiceAddress();
        if (!empty($billing)) {
            $data = $this->sgCustomer->createAddressData($this->sgBase, $billing, $quote->getCustomerId());
            $quote->getBillingAddress()
                  ->addData($data)
                  ->setCustomerAddressId($billing->getId())
                  ->setCustomerId($this->sgBase->getExternalCustomerId())
                  ->setData('should_ignore_validation', true);
        }

        $shipping = $this->sgBase->getDeliveryAddress();
        if (!empty($shipping)) {
            $data = $this->sgCustomer->createAddressData($this->sgBase, $shipping, $quote->getCustomerId());
            $quote->getShippingAddress()
                  ->addData($data)
                  ->setCustomerAddressId($shipping->getId())
                  ->setCustomerId($this->sgBase->getExternalCustomerId())
                  ->setData('should_ignore_validation', true);
        }

        if (!$quote->getShippingAddress()->getCountryId()) {
            $defaultCountryItem = $this->sgCoreConfig->getConfigByPath(Custom::XML_PATH_GENERAL_COUNTRY_DEFAULT);
            $quote->getShippingAddress()->setCountryId($defaultCountryItem->getValue());
        }
    }
732018
public function addToDataClass(Request $request, AbstractTransfer $quoteTransfer): QuoteTransfer
    {
        return $this->getFactory()->createPayoneHandler()->addPaymentToQuote($request, $quoteTransfer);
    }
1245434
protected function hydrateQuoteWithShipment($quoteTransfer)
    {
        if ($quoteTransfer->getShipment()) {
            return $quoteTransfer;
        }

        $shipmentTransfer = new ShipmentTransfer();

        $methods = $this->shipmentClient->getAvailableMethods($quoteTransfer)->getMethods();

        if ($shippingMethod = reset($methods)) {
            $shippingMethod->setStoreCurrencyPrice(static::DEFAULT_SHIPPING_PRICE);
            $shipmentTransfer->setMethod($shippingMethod);
            $shipmentTransfer->setShipmentSelection($shippingMethod->getIdShipmentMethod());
            $quoteTransfer->setShipment($shipmentTransfer);

            return $quoteTransfer;
        }

        $shipmentTransfer->setMethod(
            (new ShipmentMethodTransfer())
                ->setCarrierName(static::CARRIER_NAME)
                ->setStoreCurrencyPrice(static::DEFAULT_SHIPPING_PRICE)
        );
        $quoteTransfer->setShipment($shipmentTransfer);

        return $quoteTransfer;
    }
584265
public function replaceInFile($source, $original, $replacement) {
    $source_path = $this->getRepoRoot() . '/' . $source;
    if ($this->getFileSystem()->exists($source)) {
      $contents = file_get_contents($source_path);
      $new_contents = str_replace($original, $replacement, $contents);
      file_put_contents($source_path, $new_contents);
    }
  }
168989
public function cloneProperties($target, $source)
    {
        $this->validaObjects($target, $source);

        $reflection = new \ReflectionClass($target);
        foreach ($reflection->getProperties() as $property) {

            $this->propertyAccessor->setValue(
                $target,
                $property->getName(),
                $this->propertyAccessor->getValue($source, $property->getName())
            );
        }
    }
351564
public function unzip($source, $destination)
    {
        @mkdir($destination, 0777, true);

        foreach ((array) glob($source.'/*.zip') as $key => $value) {
            if ($this->zip->open(str_replace('//', '/', $value)) === true) {
                $this->zip->extractTo($destination);
                echo $this->ZipStatusString($this->zip);
                $this->zip->close();
            }
        }
    }