diff --git a/src/Model/Request/AliExpress/Data/MultipleProductInventoriesUpdateListQuery.php b/src/Model/Request/AliExpress/Data/MultipleProductInventoriesUpdateListQuery.php new file mode 100644 index 0000000..f9604d9 --- /dev/null +++ b/src/Model/Request/AliExpress/Data/MultipleProductInventoriesUpdateListQuery.php @@ -0,0 +1,39 @@ +") + * @JMS\SerializedName("multiple_sku_update_list") + * @Assert\NotNull() + */ + public $multipleSkuUpdateList; +} diff --git a/src/Model/Request/AliExpress/Data/MultipleProductUpdateListQuery.php b/src/Model/Request/AliExpress/Data/MultipleProductUpdateListQuery.php new file mode 100644 index 0000000..1c9f2c0 --- /dev/null +++ b/src/Model/Request/AliExpress/Data/MultipleProductUpdateListQuery.php @@ -0,0 +1,36 @@ +") + * @JMS\SerializedName("multiple_sku_update_list") + */ + public $multipleSkuUpdateList; +} diff --git a/src/Model/Request/AliExpress/Data/ProductGetQuery.php b/src/Model/Request/AliExpress/Data/ProductGetQuery.php new file mode 100644 index 0000000..fe9fa08 --- /dev/null +++ b/src/Model/Request/AliExpress/Data/ProductGetQuery.php @@ -0,0 +1,160 @@ +") + * @JMS\SerializedName("gmt_create_end") + * @TopAssert\Timezone("PST") + */ + public $gmtCreateEnd; + + /** + * @var DateTime $gmtCreateStart + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("gmt_create_start") + * @TopAssert\Timezone("PST") + */ + public $gmtCreateStart; + + /** + * @var DateTime $gmtModifiedStart + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("gmt_modified_start") + * @TopAssert\Timezone("PST") + */ + public $modifiedDateStart; + + /** + * @var int $pageSize + * + * @JMS\Type("int") + * @JMS\SerializedName("page_size") + * @Assert\GreaterThan(0) + */ + public $pageSize; + + /** + * @var DateTime $gmtModifiedEnd + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("gmt_modified_end") + * @TopAssert\Timezone("PST") + */ + public $gmtModifiedEnd; + + /** + * @var int $currentPage + * + * @JMS\Type("int") + * @JMS\SerializedName("current_page") + * @Assert\GreaterThan(0) + */ + public $currentPage; + + /** + * @var string $skuCode + * + * @JMS\Type("string") + * @JMS\SerializedName("sku_code") + */ + public $skuCode; + + /** + * @var int $productId + * + * @JMS\Type("int") + * @JMS\SerializedName("product_id") + */ + public $productId; + + /** + * @var int $groupId + * + * @JMS\Type("int") + * @JMS\SerializedName("group_id") + */ + public $groupId; + + /** + * @var string $productStatusType + * + * @JMS\Type("string") + * @JMS\SerializedName("product_status_type") + * @Assert\Choice({"onSelling", "offline", "auditing", "editingRequired"}) + * @Assert\NotBlank() + */ + public $productStatusType; + + /** + * @var string $subject + * + * @JMS\Type("string") + * @JMS\SerializedName("subject") + */ + + public $subject; + /** + * @var string $wsDisplay + * + * @JMS\Type("string") + * @JMS\SerializedName("ws_display") + */ + + public $wsDisplay; + /** + * @var string $haveNationalQuote + * + * @JMS\Type("string") + * @JMS\SerializedName("have_national_quote") + */ + + public $haveNationalQuote; + /** + * @var string $ownerMemberId + * + * @JMS\Type("string") + * @JMS\SerializedName("owner_member_id") + */ + public $ownerMemberId; + + /** + * @var int $offlineTime + * + * @JMS\Type("int") + * @JMS\SerializedName("off_line_time") + */ + public $offlineTime; + + /** + * @var int[] $exceptedProductIds + * + * @JMS\Type("array") + * @JMS\SerializedName("excepted_product_ids") + */ + public $exceptedProductIds; +} diff --git a/src/Model/Request/AliExpress/SolutionBatchProductInventoryUpdate.php b/src/Model/Request/AliExpress/SolutionBatchProductInventoryUpdate.php new file mode 100644 index 0000000..f5e9ed8 --- /dev/null +++ b/src/Model/Request/AliExpress/SolutionBatchProductInventoryUpdate.php @@ -0,0 +1,50 @@ +") + * @JMS\SerializedName("ws_offline_date") + */ + public $wsOfflineDate; + + /** + * @var DateTime $gmtModified + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("gmt_modified") + */ + public $gmtModified; + + /** + * @var DateTime $gmtCreate + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("gmt_create") + */ + public $gmtCreate; + + /** + * @var DateTime $couponStartDate + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("coupon_start_date") + */ + public $couponStartDate; + + /** + * @var DateTime $couponEndDate + * + * @JMS\Type("DateTime<'Y-m-d H:i:s'>") + * @JMS\SerializedName("coupon_end_date") + */ + public $couponEndDate; + + /** + * @var string $wsDisplay + * + * @JMS\Type("string") + * @JMS\SerializedName("ws_display") + */ + public $wsDisplay; + + /** + * @var string $subject + * + * @JMS\Type("string") + * @JMS\SerializedName("subject") + */ + public $subject; + + /** + * @var string $src + * + * @JMS\Type("string") + * @JMS\SerializedName("src") + */ + public $src; + + /** + * @var string $productMinPrice + * + * @JMS\Type("string") + * @JMS\SerializedName("product_min_price") + */ + public $productMinPrice; + + /** + * @var string $productMaxPrice + * + * @JMS\Type("string") + * @JMS\SerializedName("product_max_price") + */ + public $productMaxPrice; + + /** + * @var string $ownerMemberSeq + * + * @JMS\Type("string") + * @JMS\SerializedName("owner_member_seq") + */ + public $ownerMemberSeq; + + /** + * @var string $ownerMemberId + * + * @JMS\Type("string") + * @JMS\SerializedName("owner_member_id") + */ + public $ownerMemberId; + + /** + * @var string $imageUrls + * + * @JMS\Type("string") + * @JMS\SerializedName("image_u_r_ls") + */ + public $imageUrls; + + /** + * @var string $currencyCode + * + * @JMS\Type("string") + * @JMS\SerializedName("currency_code") + */ + public $currencyCode; + + /** + * @var int $productId + * + * @JMS\Type("int") + * @JMS\SerializedName("product_id") + */ + public $productId; + + /** + * @var int $groupId + * + * @JMS\Type("int") + * @JMS\SerializedName("group") + */ + public $groupId; + + /** + * @var int $freightTemplateId + * + * @JMS\Type("int") + * @JMS\SerializedName("freight_template_id") + */ + public $freightTemplateId; +} diff --git a/src/Model/Response/AliExpress/Result/Entity/ItemDisplayDtoList.php b/src/Model/Response/AliExpress/Result/Entity/ItemDisplayDtoList.php new file mode 100644 index 0000000..48e31a1 --- /dev/null +++ b/src/Model/Response/AliExpress/Result/Entity/ItemDisplayDtoList.php @@ -0,0 +1,28 @@ +") + * @JMS\SerializedName("item_display_dto") + */ + public $itemDisplayDto; +} diff --git a/src/Model/Response/AliExpress/Result/Entity/ProductSkuDto.php b/src/Model/Response/AliExpress/Result/Entity/ProductSkuDto.php new file mode 100644 index 0000000..fef7ffa --- /dev/null +++ b/src/Model/Response/AliExpress/Result/Entity/ProductSkuDto.php @@ -0,0 +1,28 @@ +") + * @JMS\SerializedName("global_aeop_ae_product_sku") + */ + public $globalAeopAEProductSku; +} diff --git a/src/Model/Response/AliExpress/Result/Entity/SynchronizeProductResponseDto.php b/src/Model/Response/AliExpress/Result/Entity/SynchronizeProductResponseDto.php new file mode 100644 index 0000000..ef3b891 --- /dev/null +++ b/src/Model/Response/AliExpress/Result/Entity/SynchronizeProductResponseDto.php @@ -0,0 +1,42 @@ +") + * @JMS\SerializedName("synchronize_product_response_dto") + */ + public $synchronizeProductResponseDto; +} diff --git a/src/Model/Response/AliExpress/Result/SolutionProductInfoGetResponseResult.php b/src/Model/Response/AliExpress/Result/SolutionProductInfoGetResponseResult.php new file mode 100644 index 0000000..cc312ce --- /dev/null +++ b/src/Model/Response/AliExpress/Result/SolutionProductInfoGetResponseResult.php @@ -0,0 +1,70 @@ +errorCode; + } + + /** + * ErrorInterface implementation. + * + * @return ?string + */ + public function getErrorMessage(): ?string + { + return $this->errorMsg; + } +} diff --git a/src/Model/Response/AliExpress/Result/SolutionProductListGetResponseResult.php b/src/Model/Response/AliExpress/Result/SolutionProductListGetResponseResult.php new file mode 100644 index 0000000..5ed9bd1 --- /dev/null +++ b/src/Model/Response/AliExpress/Result/SolutionProductListGetResponseResult.php @@ -0,0 +1,92 @@ +errorCode; + } + + /** + * ErrorInterface implementation. + * + * @return ?string + */ + public function getErrorMessage(): ?string + { + return $this->errorMsg; + } + + /** + * @var \RetailCrm\Model\Response\AliExpress\Result\Entity\ItemDisplayDtoList $aeopAEProductDisplayDtoList + * + * @JMS\Type("RetailCrm\Model\Response\AliExpress\Result\Entity\ItemDisplayDtoList") + * @JMS\SerializedName("aeop_a_e_product_display_d_t_o_list") + */ + public $aeopAEProductDisplayDtoList; +} diff --git a/src/Model/Response/AliExpress/SolutionBatchProductInventoryUpdateResponse.php b/src/Model/Response/AliExpress/SolutionBatchProductInventoryUpdateResponse.php new file mode 100644 index 0000000..58c82e0 --- /dev/null +++ b/src/Model/Response/AliExpress/SolutionBatchProductInventoryUpdateResponse.php @@ -0,0 +1,29 @@ +responseData->shopType); self::assertEquals('//www.aliexpress.com/store/1234321', $response->responseData->shopUrl); } + + public function testAliexpressSolutionProductListGet() + { + $json = <<<'EOF' +{ + "aliexpress_solution_product_list_get_response":{ + "result":{ + "error_message":"", + "error_code":16009999, + "total_page":100, + "success":true, + "product_count":1201, + "error_msg":"0", + "current_page":10, + "aeop_a_e_product_display_d_t_o_list":{ + "item_display_dto":[ + { + "ws_offline_date":"2021-01-01 12:13:14", + "ws_display":"0", + "subject":"knew odd", + "src":"0", + "product_min_price":"0", + "product_max_price":"0", + "product_id":23453463456346546, + "owner_member_seq":0, + "owner_member_id":"0", + "image_u_r_ls":"0", + "group_id":123, + "gmt_modified":"2021-01-01 12:13:14", + "gmt_create":"2021-01-01 12:13:14", + "freight_template_id":0, + "currency_code":"USD;RUB", + "coupon_start_date":"2021-01-01 12:13:14", + "coupon_end_date":"2021-01-01 12:13:14" + } + ] + } + } + } +} +EOF; + $mock = self::getMockClient(); + $mock->on( + RequestMatcher::createMatcher('api.taobao.com') + ->setPath('/router/rest') + ->setOptionalPostFields([ + 'app_key' => self::getEnvAppKey(), + 'method' => 'aliexpress.solution.product.list.get', + 'session' => self::getEnvToken() + ]), + $this->responseJson(200, $json) + ); + + $client = TopClientBuilder::create() + ->setContainer($this->getContainer($mock)) + ->setAppData($this->getEnvAppData()) + ->setAuthenticator($this->getEnvTokenAuthenticator()) + ->build(); + + /** @var \RetailCrm\Model\Response\AliExpress\SolutionProductListGetResponse $response */ + $response = $client->sendAuthenticatedRequest(new SolutionProductListGet()); + + self::assertEquals(true, $response->responseData->result->success); + self::assertEquals(1201, $response->responseData->result->productCount); + $items = $response->responseData->result->aeopAEProductDisplayDtoList->itemDisplayDto; + self::assertIsArray($items); + self::assertCount(1, $items); + self::assertEquals(23453463456346546, $items[0]->productId); + } + + public function testAliexpressSolutionProductInfoGet() + { + $json = <<<'EOF' +{ + "aliexpress_solution_product_info_get_response":{ + "result":{ + "add_unit":11, + "add_weight":"11.11", + "aeop_a_e_multimedia":{ + "aeop_a_e_videos":{ + "global_aeop_ae_video":[ + { + "ali_member_id":1006680305, + "media_id":12345678, + "media_status":"approved", + "media_type":"video", + "poster_url":"http:\/\/img01.taobaocdn.com\/bao\/uploaded\/TB1rNdGIVXXXXbTXFXXXXXXXXXX.jpg" + } + ] + } + }, + "aeop_ae_product_propertys":{ + "global_aeop_ae_product_property":[ + { + "attr_name":"size", + "attr_name_id":200000043, + "attr_value":"2 - 5 kg", + "attr_value_id":493, + "attr_value_unit":"0" + } + ] + }, + "aeop_ae_product_s_k_us":{ + "global_aeop_ae_product_sku":[ + { + "aeop_s_k_u_property_list":{ + "global_aeop_sku_property":[ + { + "property_value_definition_name":"pink", + "property_value_id":366, + "sku_image":"http:\/\/ae01.alicdn.com\/kf\/HTB19KVYX6LuK1Rjy0Fhq6xpdFXac.jpg", + "sku_property_id":14 + } + ] + }, + "barcode":"0", + "currency_code":"USD", + "id":"\"200000182:193;200007763:201336100\"", + "ipm_sku_stock":1234, + "sku_code":"ffff00978", + "sku_price":"200.07", + "sku_stock":true, + "sku_discount_price":"10.01" + }, + { + "aeop_s_k_u_property_list":{ + "global_aeop_sku_property":[ + { + "property_value_definition_name":"pink", + "property_value_id":366, + "sku_image":"http:\/\/ae01.alicdn.com\/kf\/HTB19KVYX6LuK1Rjy0Fhq6xpdFXac.jpg", + "sku_property_id":14 + } + ] + }, + "barcode":"0", + "currency_code":"USD", + "id":"\"200000182:193;200007763:201336100\"", + "ipm_sku_stock":1234, + "sku_code":"cfas00978", + "sku_price":"200.07", + "sku_stock":true, + "sku_discount_price":"10.01" + } + ] + }, + "base_unit":2, + "bulk_discount":90, + "bulk_order":10, + "category_id":123456, + "currency_code":"USD", + "delivery_time":60, + "detail":"
<\/div>", + "freight_template_id":12345, + "gmt_create":"2018-12-03 15:17:33", + "gmt_modified":"2018-12-18 17:11:08", + "gross_weight":"40.12", + "group_id":10023, + "group_ids":{ + "number":[ + [1002141, + 10024524] + ] + }, + "image_u_r_ls":"http:\/\/g01.a.alicdn.com\/kf\/HTB13GKLJXXXXXbYaXXXq6xXFXXXi.jpg;http:\/\/g02.a.alicdn.com\/kf\/HTB1DkaWJXXXXXb6XFXXq6xXFXXXp.jpg;http:\/\/g02.a.alicdn.com\/kf\/HTB1pMCQJXXXXXcvXVXXq6xXFXXXm.jpg;http:\/\/g03.a.alicdn.com\/kf\/HTB1QhORJXXXXXbiXVXXq6xXFXXXx.jpg;http:\/\/g02.a.alicdn.com\/kf\/HTB1q1aLJXXXXXcfaXXXq6xXFXXXv.jpg", + "is_pack_sell":true, + "lot_num":1, + "mobile_detail":"balalaba", + "owner_member_id":"aliqatest01", + "owner_member_seq":1006680305, + "package_height":30, + "package_length":10, + "package_width":20, + "product_id":1234, + "product_price":"10.23", + "product_status_type":"onSelling", + "product_unit":100000015, + "promise_template_id":100, + "reduce_strategy":"place_order_withhold或payment_success_deduct", + "sizechart_id":123, + "subject":"English description", + "ws_offline_date":"2018-12-19 11:24:27", + "package_type":true, + "multi_language_subject_list":{ + "global_subject":[ + { + "locale":"es_ES", + "subject":"Versión Global Xiaomi Redmi Note 5" + } + ] + }, + "multi_language_description_list":{ + "global_description":[ + { + "locale":"es_ES", + "mobile_detail":"{\"version\":\"2.0.0\",\"moduleList\":[{\"type\":\"html\",\"html\":{\"content\":\"Versión Global Xiaomi Redmi Note 5\"}}]}", + "web_detail":"{\"version\":\"2.0.0\",\"moduleList\":[{\"type\":\"html\",\"html\":{\"content\":\"Versión Global Xiaomi Redmi Note 5\"}}]}" + } + ] + }, + "multi_country_price_configuration":{ + "price_type":"absolute", + "country_price_list":{ + "single_country_price_dto":[ + { + "ship_to_country":"ES", + "sku_price_by_country_list":{ + "single_sku_price_by_country_dto":[ + { + "sku_code":"abc123", + "price":"16", + "discount_price":"12.99" + } + ] + } + } + ] + } + } + } + } +} +EOF; + $mock = self::getMockClient(); + $mock->on( + RequestMatcher::createMatcher('api.taobao.com') + ->setPath('/router/rest') + ->setOptionalPostFields([ + 'app_key' => self::getEnvAppKey(), + 'method' => 'aliexpress.solution.product.info.get', + 'session' => self::getEnvToken() + ]), + $this->responseJson(200, $json) + ); + + $client = TopClientBuilder::create() + ->setContainer($this->getContainer($mock)) + ->setAppData($this->getEnvAppData()) + ->setAuthenticator($this->getEnvTokenAuthenticator()) + ->build(); + + /** @var \RetailCrm\Model\Response\AliExpress\SolutionProductInfoGetResponse $response */ + $response = $client->sendAuthenticatedRequest(new SolutionProductInfoGet()); + + $skuList = $response->responseData->result->aeopAEProductSkus->globalAeopAEProductSku; + self::assertIsArray($skuList); + self::assertCount(2, $skuList); + self::assertNotNull($skuList[0]->skuCode); + self::assertNotNull($skuList[1]->skuCode); + } + + public function testAliexpressSolutionBatchProductInventoryUpdate() + { + $json = <<<'EOF' +{ + "aliexpress_solution_batch_product_inventory_update_response":{ + "update_error_code":"", + "update_error_message":"", + "update_success": true, + "update_failed_list":{ + "synchronize_product_response_dto":[ + { + "error_code":"", + "error_message":"message", + "product_id": 123 + }, + { + "error_code":"", + "error_message":"message", + "product_id":1234 + } + ] + }, + "update_successful_list":{ + "synchronize_product_response_dto":[ + { + "product_id": 123 + } + ] + } + } +} +EOF; + $mock = self::getMockClient(); + $mock->on( + RequestMatcher::createMatcher('api.taobao.com') + ->setPath('/router/rest') + ->setOptionalPostFields([ + 'app_key' => self::getEnvAppKey(), + 'method' => 'aliexpress.solution.batch.product.inventory.update', + 'session' => self::getEnvToken() + ]), + $this->responseJson(200, $json) + ); + + $client = TopClientBuilder::create() + ->setContainer($this->getContainer($mock)) + ->setAppData($this->getEnvAppData()) + ->setAuthenticator($this->getEnvTokenAuthenticator()) + ->build(); + + /** @var \RetailCrm\Model\Response\AliExpress\SolutionBatchProductInventoryUpdateResponse $response */ + $response = $client->sendAuthenticatedRequest(new SolutionBatchProductInventoryUpdate()); + + self::assertTrue($response->responseData->updateSuccess); + $updateSuccessfulList = $response->responseData->updateSuccessfulList->synchronizeProductResponseDto; + $updateFailedList = $response->responseData->updateFailedList->synchronizeProductResponseDto; + self::assertIsArray($updateSuccessfulList); + self::assertIsArray($updateFailedList); + self::assertCount(1, $updateSuccessfulList); + self::assertCount(2, $updateFailedList); + self::assertNotNull($updateFailedList[0]->productId); + self::assertNotNull($updateFailedList[0]->errorMessage); + self::assertNotNull($updateFailedList[1]->productId); + self::assertNotNull($updateFailedList[1]->errorMessage); + self::assertNotNull($updateSuccessfulList[0]->productId); + } + + public function testAliexpressSolutionBatchProductPriceUpdate() + { + $json = <<<'EOF' +{ + "aliexpress_solution_batch_product_price_update_response":{ + "update_error_code":"", + "update_error_message":"", + "update_success": true, + "update_failed_list":{ + "synchronize_product_response_dto":[ + { + "error_code":"", + "error_message":"message", + "product_id": 123 + }, + { + "error_code":"", + "error_message":"message", + "product_id":1234 + } + ] + }, + "update_successful_list":{ + "synchronize_product_response_dto":[ + { + "product_id": 123 + } + ] + } + } +} +EOF; + $mock = self::getMockClient(); + $mock->on( + RequestMatcher::createMatcher('api.taobao.com') + ->setPath('/router/rest') + ->setOptionalPostFields([ + 'app_key' => self::getEnvAppKey(), + 'method' => 'aliexpress.solution.batch.product.price.update', + 'session' => self::getEnvToken() + ]), + $this->responseJson(200, $json) + ); + + $client = TopClientBuilder::create() + ->setContainer($this->getContainer($mock)) + ->setAppData($this->getEnvAppData()) + ->setAuthenticator($this->getEnvTokenAuthenticator()) + ->build(); + + /** @var \RetailCrm\Model\Response\AliExpress\SolutionBatchProductPriceUpdateResponse $response */ + $response = $client->sendAuthenticatedRequest(new SolutionBatchProductPriceUpdate()); + + self::assertTrue($response->responseData->updateSuccess); + $updateSuccessfulList = $response->responseData->updateSuccessfulList->synchronizeProductResponseDto; + $updateFailedList = $response->responseData->updateFailedList->synchronizeProductResponseDto; + self::assertIsArray($updateSuccessfulList); + self::assertIsArray($updateFailedList); + self::assertCount(1, $updateSuccessfulList); + self::assertCount(2, $updateFailedList); + self::assertNotNull($updateFailedList[0]->productId); + self::assertNotNull($updateFailedList[0]->errorMessage); + self::assertNotNull($updateFailedList[1]->productId); + self::assertNotNull($updateFailedList[1]->errorMessage); + self::assertNotNull($updateSuccessfulList[0]->productId); + } }