PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.20
ووسلام – همگام سازی ووکامرس و باسلام v1.10.20
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/Services/Products/UpdateSingleProductService.php +60 -1 1.10.131.10.20 View file →
@@ -53,24 +53,44 @@
53 53 $url = sprintf(Endpoints::PRODUCT_UPDATE, $syncBasalamProductId);
54 54
55 55 $maxDescriptionRetries = 3;
56 56 $descriptionRetry = 0;
57 + $skuRetry = false;
57 58
58 59 while (true) {
59 60 try {
60 61 $request = $this->apiservice->patch($url, $productData);
61 - break;
62 62 } catch (RetryableException $e) {
63 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
64 + continue;
65 + }
66 +
63 67 throw $e;
64 68 } catch (NonRetryableException $e) {
69 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
70 + continue;
71 + }
72 +
65 73 if ($descriptionRetry < $maxDescriptionRetries && $this->stripForbiddenDescription($e, $productData, $productId, $descriptionRetry)) {
66 74 $descriptionRetry++;
67 75 continue;
68 76 }
77 +
69 78 throw $e;
70 79 } catch (\Exception $e) {
80 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
81 + continue;
82 + }
83 +
71 84 throw new \Exception(esc_html('خطا در ارتباط با API باسلام: ' . $e->getMessage()));
72 85 }
86 +
87 + // Some API adapters return a non-2xx response instead of throwing it.
88 + if ($this->retryWithoutDuplicateSku($productData, $request, $skuRetry)) {
89 + continue;
90 + }
91 +
92 + break;
73 93 }
74 94
75 95 $body = $request['body'] ?? '';
76 96
@@ -96,8 +116,17 @@
96 116 }
97 117
98 118 if (is_wp_error($request)) throw NonRetryableException::permanent('خطایی در ارتباط با سرور رخ داد.');
99 119
120 + // Basalam may return a successful response with a stale/null product SKU
121 + // when another product field (most commonly a long description) is
122 + // present in the same patch. Send the SKU on its own when the response
123 + // does not contain the value we requested, so the product-level SKU is
124 + // not lost for variable products.
125 + // When the duplicate-SKU fallback was used, deliberately keep the
126 + // second request SKU-free; do not issue a follow-up SKU-only patch.
127 + if (!$skuRetry) $this->ensureProductSkuUpdated($url, $productData, $body);
128 +
100 129 $product = \wc_get_product($productId);
101 130 if ($product && $product->is_type('variable')) {
102 131 $variations = $product->get_children();
103 132 if (isset($body['variants'])) {
@@ -210,8 +239,19 @@
210 239
211 240 return true;
212 241 }
213 242
243 + private function retryWithoutDuplicateSku(array &$productData, $error, bool &$retried): bool
244 + {
245 + if ($retried || !ProductSkuRetry::hasSku($productData)) return false;
246 + if (!ProductSkuRetry::isDuplicateSkuError($error)) return false;
247 +
248 + $productData = ProductSkuRetry::withoutSkus($productData);
249 + $retried = true;
250 +
251 + return true;
252 + }
253 +
214 254 public function updateProductStatus($productId, $status)
215 255 {
216 256 $vendorSyncPolicy = syncBasalamContainer()->get(VendorSyncPolicy::class);
217 257 if (!$vendorSyncPolicy->canUpdateProductStatus()) {
@@ -255,6 +295,25 @@
255 295 return $result;
256 296 }
257 297
258 298 throw NonRetryableException::permanent("تغییر وضعیت محصول در باسلام ناموفق بود.");
299 + }
300 +
301 + private function ensureProductSkuUpdated(string $url, array $productData, $responseBody): void
302 + {
303 + if (!array_key_exists('sku', $productData) || $productData['sku'] === null) return;
304 +
305 + $requestedSku = (string) $productData['sku'];
306 + $responseSku = null;
307 +
308 + if (is_array($responseBody) && array_key_exists('sku', $responseBody)) {
309 + $responseSku = $responseBody['sku'];
310 + }
311 +
312 + if ($responseSku !== null && (string) $responseSku === $requestedSku) return;
313 +
314 + $skuRequest = $this->apiservice->patch($url, ['sku' => $productData['sku']]);
315 + if (!is_array($skuRequest) || (int) ($skuRequest['status_code'] ?? 0) !== 200) {
316 + throw NonRetryableException::permanent('بروزرسانی شناسه محصول (SKU) در باسلام ناموفق بود.');
317 + }
259 318 }
260 319 }