PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.21
ووسلام – همگام سازی ووکامرس و باسلام v1.10.21
1.10.21 1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 All 54 releases
← All changes | includes/Admin/Product/Data/Services/PriceService.php +119 -58 1.8.81.10.21 View file →
@@ -1,25 +1,27 @@
1 1 <?php
2 2
3 -namespace SyncBasalam\Admin\Product\Data\Services;
4 -
5 -use SyncBasalam\Admin\Product\elements\SingleProduct\PriceIncreaseField;
6 -use SyncBasalam\Admin\Settings\SettingsConfig;
7 -use SyncBasalam\Services\Products\FetchCommission;
3 +namespace SyncBasalam\Admin\Product\Data\Services;
8 4
5 +use SyncBasalam\Admin\Product\elements\SingleProduct\PriceChangeField;
6 +use SyncBasalam\Admin\Settings\SettingsConfig;
7 +use SyncBasalam\Logger\Logger;
8 +use SyncBasalam\Services\Products\FetchCommission;
9 +use SyncBasalam\Utilities\ProductMetaKey;
10 +use SyncBasalam\Utilities\PriceAdjustment;
11 +
9 12 defined('ABSPATH') || exit;
10 13
11 14 class PriceService
12 15 {
13 - public function calculateFinalPrice($product): ?int
14 - {
15 - $price = $this->getBasePrice($product);
16 - if (!$price) return null;
17 -
18 - $categoryIds = $this->getCategoryIds($product);
19 - return $this->applyPriceCalculations($price, $categoryIds, $product);
20 - }
16 + public function calculateFinalPrice($product): ?int
17 + {
18 + $price = $this->getBasePrice($product);
19 + if (!$price) return null;
21 20
21 + return $this->applyPriceCalculations($price, $product);
22 + }
23 +
22 24 private function getBasePrice($product)
23 25 {
24 26 $priceField = syncBasalamSettings()->getSettings(SettingsConfig::PRODUCT_PRICE_FIELD);
25 27 $regularPrice = $product->get_regular_price();
@@ -36,54 +38,54 @@
36 38
37 39 return null;
38 40 }
39 41
40 - private function applyPriceCalculations(float $price, array $categoryIds, $product): ?int
41 - {
42 - $increaseValue = $this->getIncreaseValue($product);
43 - $roundMode = syncBasalamSettings()->getSettings(SettingsConfig::ROUND_PRICE);
44 - $currency = get_woocommerce_currency();
42 + private function applyPriceCalculations(float $price, $product): ?int
43 + {
44 + $priceChangeValue = $this->getPriceChangeValue($product);
45 + $roundMode = syncBasalamSettings()->getSettings(SettingsConfig::ROUND_PRICE);
46 + $currency = get_woocommerce_currency();
45 47
46 48 $finalPrice = $this->convertToRial($price, $currency);
47 49 if (!$finalPrice) return null;
48 50
49 - if ($increaseValue) $finalPrice = $this->applyIncrease($finalPrice, $increaseValue, $categoryIds);
51 +
52 + if ($priceChangeValue !== '' && $priceChangeValue !== '0') $finalPrice = $this->applyPriceChange($finalPrice, $priceChangeValue, $product);
53 +
50 54 if ($roundMode && $roundMode != 'none') $finalPrice = $this->applyRounding($finalPrice, $roundMode);
51 55
52 56 if ($finalPrice < 1000) return null;
53 57
54 - return intval($finalPrice);
55 - }
56 -
57 - private function getIncreaseValue($product): int
58 - {
59 - $productId = method_exists($product, 'get_id') ? intval($product->get_id()) : 0;
60 -
61 - if ($productId > 0) {
62 - $productIncrease = $this->getProductIncreaseMeta($productId);
63 -
64 - if ($productIncrease !== '' && is_numeric($productIncrease)) {
65 - return intval($productIncrease);
66 - }
67 -
68 - if (method_exists($product, 'get_parent_id')) {
69 - $parentId = intval($product->get_parent_id());
70 - $parentIncrease = $parentId > 0 ? $this->getProductIncreaseMeta($parentId) : '';
71 -
72 - if ($parentIncrease !== '' && is_numeric($parentIncrease)) {
73 - return intval($parentIncrease);
74 - }
75 - }
76 - }
77 -
78 - return intval(syncBasalamSettings()->getSettings(SettingsConfig::INCREASE_PRICE_VALUE));
79 - }
80 -
81 - private function getProductIncreaseMeta(int $productId): string
82 - {
83 - return (string) get_post_meta($productId, PriceIncreaseField::META_KEY, true);
84 - }
58 + return intval($finalPrice);
59 + }
85 60
61 + private function getPriceChangeValue($product): string
62 + {
63 + $productId = method_exists($product, 'get_id') ? intval($product->get_id()) : 0;
64 +
65 + if ($productId > 0) {
66 + $productValue = PriceAdjustment::normalize($this->getProductPriceChangeMeta($productId));
67 +
68 + if ($productValue !== null) return $productValue;
69 +
70 + if (method_exists($product, 'get_parent_id')) {
71 + $parentId = intval($product->get_parent_id());
72 + $parentValue = $parentId > 0
73 + ? PriceAdjustment::normalize($this->getProductPriceChangeMeta($parentId))
74 + : null;
75 +
76 + if ($parentValue !== null) return $parentValue;
77 + }
78 + }
79 +
80 + return (string) (PriceAdjustment::normalize(syncBasalamSettings()->getSettings(SettingsConfig::PRICE_CHANGE_VALUE)) ?? '0');
81 + }
82 +
83 + private function getProductPriceChangeMeta(int $productId): string
84 + {
85 + return (string) get_post_meta($productId, PriceChangeField::META_KEY, true);
86 + }
87 +
86 88 private function convertToRial(float $price, string $currency)
87 89 {
88 90 if ($currency === 'IRT') return $price * 10;
89 91 if ($currency === 'IRHT') return $price * 10000;
@@ -91,24 +93,83 @@
91 93
92 94 return $price;
93 95 }
94 96
95 - private function applyIncrease(float $price, int $increaseValue, array $categoryIds): float
97 + private function applyPriceChange(float $price, string $priceChangeValue, $product = null): float
96 98 {
97 - if ($increaseValue === -1) return $this->applyCommissionCalculation($price, $categoryIds);
99 + if (PriceAdjustment::isCommission($priceChangeValue)) return $this->applyCommissionCalculation($price, $product);
98 100
99 - if ($increaseValue <= 100) return $price + ($price * ($increaseValue / 100));
101 + $value = intval($priceChangeValue);
100 102
101 - return $price + ($increaseValue * 10);
103 + if (PriceAdjustment::isPercent($value)) return $price + ($price * ($value / 100));
104 +
105 + return $price + ($value * 10);
102 106 }
103 107
104 - private function applyCommissionCalculation(float $price, array $categoryIds): float
108 + private function applyCommissionCalculation(float $price, $product = null): float
105 109 {
106 - $categoryPercent = FetchCommission::fetchCategoryCommission($categoryIds);
110 + $basalamProductId = $this->getBasalamProductId($product);
111 + $categoryIds = [];
107 112
108 - if ($categoryPercent > 0 && $categoryPercent < 100) return $price / (1 - ($categoryPercent / 100));
109 - else return $price;
113 + if ($basalamProductId !== null) {
114 + $commissionPercent = FetchCommission::fetchProductCommission($basalamProductId);
115 + } else {
116 + $categoryIds = $this->getCategoryIds($product);
117 + $commissionPercent = FetchCommission::fetchCategoryCommission($categoryIds);
118 + }
110 119
120 + $commissionPercent = floatval($commissionPercent);
121 +
122 + if ($commissionPercent <= 0 || $commissionPercent >= 100) return $price;
123 +
124 + $multiplier = 1 / (1 - ($commissionPercent / 100));
125 + $maxMultiplier = 1 + (PriceAdjustment::MAX_PERCENT / 100);
126 +
127 + if ($multiplier > $maxMultiplier) {
128 + Logger::warning('کارمزد دسته‌بندی باسلام خارج از بازه منطقی بود و افزایش قیمت به سقف مجاز محدود شد.', [
129 + 'category_ids' => $categoryIds,
130 + 'commission_percent' => $commissionPercent,
131 + 'max_percent' => PriceAdjustment::MAX_PERCENT,
132 + ]);
133 +
134 + $multiplier = $maxMultiplier;
135 + }
136 +
137 + return $price * $multiplier;
138 + }
139 +
140 + /**
141 + * Resolve the remote product id used by the product commission endpoint.
142 + * Variations inherit the connection from their parent product.
143 + */
144 + private function getBasalamProductId($product): ?int
145 + {
146 + if (!is_object($product)) return null;
147 +
148 + $postIds = [];
149 +
150 + if (method_exists($product, 'get_parent_id')) {
151 + $parentId = intval($product->get_parent_id());
152 + if ($parentId > 0) {
153 + $postIds[] = $parentId;
154 + }
155 + }
156 +
157 + if (empty($postIds) && method_exists($product, 'get_id')) {
158 + $productId = intval($product->get_id());
159 + if ($productId > 0) $postIds[] = $productId;
160 + }
161 +
162 + $metaKey = ProductMetaKey::basalamProductId();
163 + foreach (array_unique($postIds) as $postId) {
164 + $basalamProductId = get_post_meta($postId, $metaKey, true);
165 +
166 + if (is_numeric($basalamProductId) && intval($basalamProductId) > 0) {
167 + return intval($basalamProductId);
168 + }
169 + }
170 +
171 + return null;
111 172 }
112 173
113 174 private function applyRounding(float $price, $mode): float
114 175 {