123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\CSV;
- use Magento\Framework\Phrase;
- use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\LocationDirectory;
- /**
- * Row parser.
- */
- class RowParser
- {
- /**
- * @var LocationDirectory
- */
- private $locationDirectory;
- /**
- * RowParser constructor.
- * @param LocationDirectory $locationDirectory
- */
- public function __construct(LocationDirectory $locationDirectory)
- {
- $this->locationDirectory = $locationDirectory;
- }
- /**
- * Retrieve columns.
- *
- * @return array
- */
- public function getColumns()
- {
- return [
- 'website_id',
- 'dest_country_id',
- 'dest_region_id',
- 'dest_zip',
- 'condition_name',
- 'condition_value',
- 'price',
- ];
- }
- /**
- * Parse provided row data.
- *
- * @param array $rowData
- * @param int $rowNumber
- * @param int $websiteId
- * @param string $conditionShortName
- * @param string $conditionFullName
- * @param ColumnResolver $columnResolver
- * @return array
- * @throws ColumnNotFoundException
- * @throws RowException
- */
- public function parse(
- array $rowData,
- $rowNumber,
- $websiteId,
- $conditionShortName,
- $conditionFullName,
- ColumnResolver $columnResolver
- ) {
- // validate row
- if (count($rowData) < 5) {
- throw new RowException(
- __(
- 'The Table Rates File Format is incorrect in row number "%1". Verify the format and try again.',
- $rowNumber
- )
- );
- }
- $countryId = $this->getCountryId($rowData, $rowNumber, $columnResolver);
- $regionIds = $this->getRegionIds($rowData, $rowNumber, $columnResolver, $countryId);
- $zipCode = $this->getZipCode($rowData, $columnResolver);
- $conditionValue = $this->getConditionValue($rowData, $rowNumber, $conditionFullName, $columnResolver);
- $price = $this->getPrice($rowData, $rowNumber, $columnResolver);
- $rates = [];
- foreach ($regionIds as $regionId) {
- $rates[] = [
- 'website_id' => $websiteId,
- 'dest_country_id' => $countryId,
- 'dest_region_id' => $regionId,
- 'dest_zip' => $zipCode,
- 'condition_name' => $conditionShortName,
- 'condition_value' => $conditionValue,
- 'price' => $price,
- ];
- }
- return $rates;
- }
- /**
- * Get country id from provided row data.
- *
- * @param array $rowData
- * @param int $rowNumber
- * @param ColumnResolver $columnResolver
- * @return null|string
- * @throws ColumnNotFoundException
- * @throws RowException
- */
- private function getCountryId(array $rowData, $rowNumber, ColumnResolver $columnResolver)
- {
- $countryCode = $columnResolver->getColumnValue(ColumnResolver::COLUMN_COUNTRY, $rowData);
- // validate country
- if ($this->locationDirectory->hasCountryId($countryCode)) {
- $countryId = $this->locationDirectory->getCountryId($countryCode);
- } elseif ($countryCode === '*' || $countryCode === '') {
- $countryId = '0';
- } else {
- throw new RowException(
- __(
- 'The "%1" country in row number "%2" is incorrect. Verify the country and try again.',
- $countryCode,
- $rowNumber
- )
- );
- }
- return $countryId;
- }
- /**
- * Retrieve region id from provided row data.
- *
- * @param array $rowData
- * @param int $rowNumber
- * @param ColumnResolver $columnResolver
- * @param int $countryId
- * @return array
- * @throws ColumnNotFoundException
- * @throws RowException
- */
- private function getRegionIds(array $rowData, $rowNumber, ColumnResolver $columnResolver, $countryId)
- {
- $regionCode = $columnResolver->getColumnValue(ColumnResolver::COLUMN_REGION, $rowData);
- if ($countryId !== '0' && $this->locationDirectory->hasRegionId($countryId, $regionCode)) {
- $regionIds = $this->locationDirectory->getRegionIds($countryId, $regionCode);
- } elseif ($regionCode === '*' || $regionCode === '') {
- $regionIds = [0];
- } else {
- throw new RowException(
- __(
- 'The "%1" region or state in row number "%2" is incorrect. '
- . 'Verify the region or state and try again.',
- $regionCode,
- $rowNumber
- )
- );
- }
- return $regionIds;
- }
- /**
- * Retrieve zip code from provided row data.
- *
- * @param array $rowData
- * @param ColumnResolver $columnResolver
- * @return float|int|null|string
- * @throws ColumnNotFoundException
- */
- private function getZipCode(array $rowData, ColumnResolver $columnResolver)
- {
- $zipCode = $columnResolver->getColumnValue(ColumnResolver::COLUMN_ZIP, $rowData);
- if ($zipCode === '') {
- $zipCode = '*';
- }
- return $zipCode;
- }
- /**
- * Get condition value form provided row data.
- *
- * @param array $rowData
- * @param int $rowNumber
- * @param string $conditionFullName
- * @param ColumnResolver $columnResolver
- * @return bool|float
- * @throws ColumnNotFoundException
- * @throws RowException
- */
- private function getConditionValue(array $rowData, $rowNumber, $conditionFullName, ColumnResolver $columnResolver)
- {
- // validate condition value
- $conditionValue = $columnResolver->getColumnValue($conditionFullName, $rowData);
- $value = $this->_parseDecimalValue($conditionValue);
- if ($value === false) {
- throw new RowException(
- __(
- 'Please correct %1 "%2" in the Row #%3.',
- $conditionFullName,
- $conditionValue,
- $rowNumber
- )
- );
- }
- return $value;
- }
- /**
- * Retrieve price from provided row data.
- *
- * @param array $rowData
- * @param int $rowNumber
- * @param ColumnResolver $columnResolver
- * @return bool|float
- * @throws ColumnNotFoundException
- * @throws RowException
- */
- private function getPrice(array $rowData, $rowNumber, ColumnResolver $columnResolver)
- {
- $priceValue = $columnResolver->getColumnValue(ColumnResolver::COLUMN_PRICE, $rowData);
- $price = $this->_parseDecimalValue($priceValue);
- if ($price === false) {
- throw new RowException(
- __(
- 'The "%1" shipping price in row number "%2" is incorrect. Verify the shipping price and try again.',
- $priceValue,
- $rowNumber
- )
- );
- }
- return $price;
- }
- /**
- * Parse and validate positive decimal value
- *
- * Return false if value is not decimal or is not positive
- *
- * @param string $value
- * @return bool|float
- */
- private function _parseDecimalValue($value)
- {
- $result = false;
- if (is_numeric($value)) {
- $value = (double)sprintf('%.4F', $value);
- if ($value >= 0.0000) {
- $result = $value;
- }
- }
- return $result;
- }
- }
|