3.00, 2 => 3.31, ]; public function __construct(EntityManagerInterface $em) { $this->em = $em; } /** * @param \Decimal $price * * @return int|mixed */ public function getInsurancePrice($price) { $multiplier = ceil($price->div(\Decimal::create(1000))->asFloat()); if ($this->totalWeight <= 10) { $iprice = $this->insurancePrices[1] * $multiplier; } elseif ($this->totalWeight > 10) { $iprice = $this->insurancePrices[2] * $multiplier; } else { $iprice = 0; } $iprice = \Decimal::create($iprice); $iprice = $iprice->addVat(getVat()); return $price->add($iprice); } /** * @param $price \Decimal * * @return \Decimal */ public function mulPrice($price) { $multiplier = \Decimal::ensureDecimal($this->priceMultiplier); return $price->mul($multiplier, 8); } public function checkWeightGroup() { $onMaxWeight = $this->getOnMaxWeight(); if ($onMaxWeight == 'divide') { $this->setDivide(true); } if ($this->getWeightGroupId()) { return true; } if ($onMaxWeight == 'divide') { if ($this->divide) { return 'divide'; } } return false; } /** @return \Decimal */ public function getPriceWithoutVat($vat, $priceWithVat = null) { if ($priceWithVat == null) { $price = $this->getPrice(); } else { $price = $priceWithVat; } $decimal = \Decimal::ensureDecimal($price); $withoutVat = $decimal->removeVat($vat); return $withoutVat; } /** @return \Decimal */ public function getValueVat($valWithoutVat, $priceWithVat = null) { if ($priceWithVat == null) { $price = $this->getPrice(); } else { $price = $priceWithVat; } $valueVat = $price->sub($valWithoutVat); return $valueVat; } /** @return \Decimal */ public function getPrice() { $repository = $this->em->getRepository(Price::class); $this->getRegionByCountry($this->country); $data = $repository->findOneBy(['priceList' => $this->pricelistId, 'weightGroup' => $this->getWeightGroupId(), 'region' => $this->regionId]); if ($data) { if ($this->divide) { // add insurance if (findModule('delivery_pricelist', 'insurance') && $this->hasCountryInsurance($this->country)) { return $this->getInsurancePrice($this->mulPrice($data->getPrice())); } return $this->mulPrice($data->getPrice()); } // add insurance if (findModule('delivery_pricelist', 'insurance') && $this->hasCountryInsurance($this->country)) { return $this->getInsurancePrice($data->getPrice()); } return $data->getPrice(); } return null; } /** * @param string $countryId * * @return bool */ public function hasCountryInsurance($countryId) { $qb = sqlQueryBuilder()->select('*')->from('delivery_pricelists_insurance') ->where('id_pricelist = :id_pricelist AND id_country = :id_country') ->setParameters([ 'id_pricelist' => $this->getPricelistId(), 'id_country' => $countryId, ])->execute(); if ($qb->rowCount() != 0) { return true; } return false; } public function isDeliverySupported() { return $this->getRegionByCountry($this->country); } public function getRegionByCountry($countryId) { $country = $this->em->getRepository(Country::class); $data = $country->findOneBy(['id' => $countryId]); if ($data) { $regionCountry = $this->em->getRepository(RegionCountry::class); /** @var RegionCountry $region */ $region = $regionCountry->findOneBy(['pricelist' => $this->pricelistId, 'country' => $countryId]); if ($region) { $this->regionId = $region->getRegion(); } else { return false; } } return true; } public function multiFetchDeliveryTime(array &$deliveries): void { $countryContext = Contexts::get(CountryContext::class); $regionCountry = $this->em->getRepository(RegionCountry::class); $items = Mapping::mapKeys( $regionCountry->findBy( [ 'country' => $countryContext->getActiveId(), 'pricelist' => array_map( function ($x) { return $x->id_pricelist; }, array_filter( $deliveries, function ($x) { return !empty($x->id_pricelist); } ) ), ] ), function ($k, $v) { return [$v->getPricelist()->getId(), $v]; } ); foreach ($deliveries as &$delivery) { if (!($item = $items[$delivery->id_pricelist] ?? null)) { continue; } $delivery->pricelistDeliveryTime = $this->prepareDeliveryTime($item); } } private function prepareDeliveryTime(?RegionCountry $item): ?array { if (!$item) { return null; } if ($item->getDeliveryTimeMin() === null && $item->getDeliveryTimeMax() === null) { return null; } return [ 'min' => $item->getDeliveryTimeMin(), 'max' => $item->getDeliveryTimeMax(), ]; } public function getDeliveryTime($countryId) { $qb = sqlQueryBuilder()->select('MIN(delivery_time_min) as deliveryMin', 'MAX(delivery_time_max) as deliveryMax') ->from('delivery_pricelists_regions_countries') ->where('id_country = ?')->setParameter(0, $countryId) ->execute()->fetch(); return [ 'min' => $qb['deliveryMin'], 'max' => $qb['deliveryMax'], ]; } /** * @return bool|int|null */ public function getWeightGroupId() { $weightGroupId = false; $repository = $this->em->getRepository(WeightGroup::class); $data = $repository->findBy(['priceList' => $this->pricelistId], ['maxWeight' => 'ASC']); if ($data) { /** @var WeightGroup $wg */ foreach ($data as $wg) { $groupMaxWeight = $wg->getMaxWeight(); if ($this->totalWeight <= $groupMaxWeight) { $weightGroupId = $wg->getId(); break; } } if ($weightGroupId) { return $weightGroupId; } // pokud je povolene rozdeleni baliku if ($this->divide == true) { $wg = end($data); $weight = $wg->getMaxWeight(); if ($this->maxItemWeight <= $weight) { $divide = $this->findWeightGroupForDivide($data); $weightGroupId = $divide['weightGroup'] ? $divide['weightGroup']->getId() : false; if ($divide['multiplier'] !== null) { $this->priceMultiplier = $divide['multiplier']; } } else { $this->setDivide(false); } } } return $weightGroupId; } public function getCountOfPackages() { $packagesWeight = null; $packagesCount = null; $repository = $this->em->getRepository(WeightGroup::class); $data = $repository->findBy(['priceList' => $this->pricelistId], ['maxWeight' => 'ASC']); if ($data) { $divide = $this->findWeightGroupForDivide($data); $packagesWeight = $divide['weightGroup'] ? $divide['weightGroup']->getMaxWeight() : null; $packagesCount = $divide['multiplier']; } return [ 'package_weight' => $packagesWeight, 'package_count' => $packagesCount, ]; } private function findWeightGroupForDivide($weightGroups) { $bestGroup = false; $bestMultiplier = null; /** @var WeightGroup $group */ foreach ($weightGroups as $group) { $multiplier = ceil($this->totalWeight / $group->getMaxWeight()); if ($bestMultiplier == null || $bestMultiplier > $multiplier) { $bestMultiplier = $multiplier; $bestGroup = $group; } } return [ 'weightGroup' => $bestGroup, 'multiplier' => $bestMultiplier, ]; } /** * @return string|null */ public function getPricelistCurrency($pricelistId) { $data = sqlQueryBuilder()->select('id_currency')->from('delivery_pricelists') ->where('id = ?')->setParameter(0, $pricelistId)->execute()->fetch(); if ($data) { return $data['id_currency']; } return false; } /** * @return int */ public function getPricelistId() { return $this->pricelistId; } /** * @return bool|string */ public function getOnMaxWeight() { $repository = $this->em->getRepository(PriceList::class); /** @var PriceList $data */ $data = $repository->findOneBy(['id' => $this->pricelistId]); if ($data) { return $data->getOnMaxWeight(); } return false; } /** * @param $id string */ public function setCountry($id) { $this->country = $id; } public function setDivide($bool) { $this->divide = $bool; } public function getDivide() { return $this->divide; } public function setRegionId($id) { $this->regionId = $id; } public function setPricelistId($id) { $this->pricelistId = $id; } public function setTotalWeight($weight) { $this->totalWeight = $weight; } public function setMaxItemWeight($weight) { $this->maxItemWeight = $weight; } public function setPriceMultiplier($mul) { $this->priceMultiplier = $mul; } public function getPriceMultiplier() { return $this->priceMultiplier; } }