diff --git a/CHANGELOG.md b/CHANGELOG.md index be7371e4..ba8339a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ### Added +- Added service `Services\CRM\Lead\Service\LeadProductRows` with support methods, + see [add crm.lead.productrows* methods](https://github.com/bitrix24/b24phpsdk/issues/175): + - `set` Adds products to a lead + - `get` Returns the products of a lead - Added service `Services\CRM\Quote\Service\Quote` with support methods, see [crm.quote.* methods](https://github.com/bitrix24/b24phpsdk/issues/179): - `fields` returns a list of fields for the quote diff --git a/Makefile b/Makefile index 50b45041..5c0bd4f9 100644 --- a/Makefile +++ b/Makefile @@ -195,6 +195,14 @@ integration_tests_scope_crm_currency: integration_tests_deal_recurring: docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_deal_recurring +.PHONY: integration_tests_scope_automation +integration_tests_scope_automation: + docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_scope_automation + +.PHONY: integration_tests_lead_productrows +integration_tests_lead_productrows: + docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_lead_productrows + .PHONY: integration_tests_crm_quote integration_tests_crm_quote: docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_crm_quote diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 10e8babd..c302fa63 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -11,6 +11,7 @@ parameters: - tests/Integration/Services/IMOpenLines - tests/Integration/Services/Main - tests/Integration/Services/Placement + - tests/Integration/Services/CRM/Lead/Service/LeadProductRowsTest.php - tests/Integration/Services/CRM/Quote/Service/QuoteTest.php - tests/Integration/Services/CRM/Quote/Service/BatchTest.php - tests/Integration/Services/CRM/Quote/Service/QuoteContactTest.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index aa8ba6a7..884c18ed 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -43,6 +43,9 @@ ./tests/Integration/Services/AI/ + + ./tests/Integration/Services/CRM/Lead/Service/LeadProductRowsTest.php + ./tests/Integration/Services/CRM/Lead/Service/LeadUserfieldTest.php diff --git a/rector.php b/rector.php index 8509a1de..062d8e01 100644 --- a/rector.php +++ b/rector.php @@ -36,6 +36,8 @@ __DIR__ . '/tests/Integration/Services/Main', __DIR__ . '/src/Services/Placement', __DIR__ . '/tests/Integration/Services/Placement', + __DIR__ . '/src/Services/CRM/Lead', + __DIR__ . '/tests/Integration/Services/CRM/Lead/Service', __DIR__ . '/src/Services/CRM/Quote', __DIR__ . '/tests/Integration/Services/CRM/Quote/Service', __DIR__ . '/src/Services/CRM/Currency', diff --git a/src/Services/CRM/CRMServiceBuilder.php b/src/Services/CRM/CRMServiceBuilder.php index 42f77abd..31ead3e8 100644 --- a/src/Services/CRM/CRMServiceBuilder.php +++ b/src/Services/CRM/CRMServiceBuilder.php @@ -311,6 +311,18 @@ public function lead(): Lead\Service\Lead return $this->serviceCache[__METHOD__]; } + + /** + * @return Lead\Service\LeadProductRows + */ + public function leadProductRows(): Lead\Service\LeadProductRows + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new Lead\Service\LeadProductRows($this->core, $this->log); + } + + return $this->serviceCache[__METHOD__]; + } public function leadUserfield(): Lead\Service\LeadUserfield { diff --git a/src/Services/CRM/Lead/Result/LeadItemResult.php b/src/Services/CRM/Lead/Result/LeadItemResult.php index 3c1b6e86..32097fa1 100644 --- a/src/Services/CRM/Lead/Result/LeadItemResult.php +++ b/src/Services/CRM/Lead/Result/LeadItemResult.php @@ -86,7 +86,6 @@ class LeadItemResult extends AbstractCrmItem { /** - * @param string $userfieldName * * @return mixed|null * @throws \Bitrix24\SDK\Services\CRM\Userfield\Exceptions\UserfieldNotFoundException diff --git a/src/Services/CRM/Lead/Result/LeadProductRowItemResult.php b/src/Services/CRM/Lead/Result/LeadProductRowItemResult.php new file mode 100644 index 00000000..08a89e37 --- /dev/null +++ b/src/Services/CRM/Lead/Result/LeadProductRowItemResult.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\CRM\Lead\Result; + +use Money\Money; +use MoneyPHP\Percentage\Percentage; +use Bitrix24\SDK\Services\CRM\Common\Result\DiscountType; +use Carbon\CarbonImmutable; +use Bitrix24\SDK\Services\CRM\Common\Result\AbstractCrmItem; + +/** + * @property-read int $ID + * @property-read int $OWNER_ID + * @property-read string $OWNER_TYPE + * @property-read int $PRODUCT_ID + * @property-read string $PRODUCT_NAME + * @property-read string|null $ORIGINAL_PRODUCT_NAME + * @property-read string|null $PRODUCT_DESCRIPTION + * @property-read Money $PRICE price with taxes and discounts + * @property-read Money $PRICE_EXCLUSIVE without taxes but with discounts + * @property-read Money $PRICE_NETTO without taxes and discounts + * @property-read Money $PRICE_BRUTTO without discounts but with taxes + * @property-read Money $PRICE_ACCOUNT formatted price + * @property-read string $QUANTITY + * @property-read DiscountType $DISCOUNT_TYPE_ID + * @property-read Percentage $DISCOUNT_RATE + * @property-read Money $DISCOUNT_SUM + * @property-read string $TAX_RATE + * @property-read bool $TAX_INCLUDED + * @property-read string $CUSTOMIZED + * @property-read int $MEASURE_CODE + * @property-read string $MEASURE_NAME + * @property-read int $SORT + * @property-read string|null $XML_ID + * @property-read int $TYPE + * @property-read int|null $STORE_ID + * @property-read int|null $RESERVE_ID + * @property-read CarbonImmutable|null $DATE_RESERVE_END + * @property-read int|null $RESERVE_QUANTITY + */ +class LeadProductRowItemResult extends AbstractCrmItem +{ +} diff --git a/src/Services/CRM/Lead/Result/LeadProductRowItemsResult.php b/src/Services/CRM/Lead/Result/LeadProductRowItemsResult.php new file mode 100644 index 00000000..e43ae6fa --- /dev/null +++ b/src/Services/CRM/Lead/Result/LeadProductRowItemsResult.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\CRM\Lead\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Response\Response; +use Bitrix24\SDK\Core\Result\AbstractResult; +use Money\Currency; + +/** + * Class LeadProductRowItemsResult + * + * @package Bitrix24\SDK\Services\CRM\Lead\Result + */ +class LeadProductRowItemsResult extends AbstractResult +{ + public function __construct(Response $coreResponse, private readonly Currency $currency) + { + parent::__construct($coreResponse); + } + + /** + * @return LeadProductRowItemResult[] + * @throws BaseException + */ + public function getProductRows(): array + { + $res = []; + if (!empty($this->getCoreResponse()->getResponseData()->getResult()['result']['rows'])) { + foreach ($this->getCoreResponse()->getResponseData()->getResult()['result']['rows'] as $productRow) { + $res[] = new LeadProductRowItemResult($productRow, $this->currency); + } + } else { + foreach ($this->getCoreResponse()->getResponseData()->getResult() as $productRow) { + $res[] = new LeadProductRowItemResult($productRow, $this->currency); + } + } + + return $res; + } +} diff --git a/src/Services/CRM/Lead/Service/Batch.php b/src/Services/CRM/Lead/Service/Batch.php index 734152a8..7bea200c 100644 --- a/src/Services/CRM/Lead/Service/Batch.php +++ b/src/Services/CRM/Lead/Service/Batch.php @@ -27,19 +27,11 @@ #[ApiBatchServiceMetadata(new Scope(['crm']))] class Batch { - protected BatchOperationsInterface $batch; - protected LoggerInterface $log; - /** * Batch constructor. - * - * @param BatchOperationsInterface $batch - * @param LoggerInterface $log */ - public function __construct(BatchOperationsInterface $batch, LoggerInterface $log) + public function __construct(protected BatchOperationsInterface $batch, protected LoggerInterface $log) { - $this->batch = $batch; - $this->log = $log; } /** @@ -133,7 +125,6 @@ public function __construct(BatchOperationsInterface $batch, LoggerInterface $lo * UTM_TERM?: string, * } $filter * @param array $select = ['ID','TITLE','TYPE_ID','CATEGORY_ID','STAGE_ID','STAGE_SEMANTIC_ID','IS_NEW','IS_RECURRING','IS_RETURN_CUSTOMER','IS_REPEATED_APPROACH','PROBABILITY','CURRENCY_ID','OPPORTUNITY','IS_MANUAL_OPPORTUNITY','TAX_VALUE','COMPANY_ID','CONTACT_ID','CONTACT_IDS','QUOTE_ID','BEGINDATE','CLOSEDATE','OPENED','CLOSED','COMMENTS','ASSIGNED_BY_ID','CREATED_BY_ID','MODIFY_BY_ID','DATE_CREATE','DATE_MODIFY','SOURCE_ID','SOURCE_DESCRIPTION','LEAD_ID','ADDITIONAL_INFO','LOCATION_ID','ORIGINATOR_ID','ORIGIN_ID','UTM_SOURCE','UTM_MEDIUM','UTM_CAMPAIGN','UTM_CONTENT','UTM_TERM'] - * @param int|null $limit * * @return Generator * @throws BaseException @@ -222,6 +213,7 @@ public function add(array $leads): Generator 'fields' => $lead, ]; } + foreach ($this->batch->addEntityItems('crm.lead.add', $items) as $key => $item) { yield $key => new AddedItemBatchResult($item); } diff --git a/src/Services/CRM/Lead/Service/Lead.php b/src/Services/CRM/Lead/Service/Lead.php index c2f0824a..c0eea108 100644 --- a/src/Services/CRM/Lead/Service/Lead.php +++ b/src/Services/CRM/Lead/Service/Lead.php @@ -31,19 +31,12 @@ #[ApiServiceMetadata(new Scope(['crm']))] class Lead extends AbstractService { - public Batch $batch; - /** * Lead constructor. - * - * @param Batch $batch - * @param CoreInterface $core - * @param LoggerInterface $log */ - public function __construct(Batch $batch, CoreInterface $core, LoggerInterface $log) + public function __construct(public Batch $batch, CoreInterface $core, LoggerInterface $logger) { - parent::__construct($core, $log); - $this->batch = $batch; + parent::__construct($core, $logger); } /** @@ -113,7 +106,6 @@ public function __construct(Batch $batch, CoreInterface $core, LoggerInterface $ * REGISTER_SONET_EVENT?: string * } $params * - * @return AddedItemResult * @throws BaseException * @throws TransportException */ @@ -140,9 +132,7 @@ public function add(array $fields, array $params = []): AddedItemResult * * @link https://training.bitrix24.com/rest_help/crm/leads/crm_lead_delete.php * - * @param int $id * - * @return DeletedItemResult * @throws BaseException * @throws TransportException */ @@ -168,7 +158,6 @@ public function delete(int $id): DeletedItemResult * * @link https://training.bitrix24.com/rest_help/crm/leads/crm_lead_fields.php * - * @return FieldsResult * @throws BaseException * @throws TransportException */ @@ -187,9 +176,7 @@ public function fields(): FieldsResult * * @link https://training.bitrix24.com/rest_help/crm/leads/crm_lead_get.php * - * @param int $id * - * @return LeadResult * @throws BaseException * @throws TransportException */ @@ -215,7 +202,6 @@ public function get(int $id): LeadResult * * @throws BaseException * @throws TransportException - * @return LeadsResult */ #[ApiEndpointMetadata( 'crm.lead.list', @@ -242,7 +228,6 @@ public function list(array $order, array $filter, array $select, int $startItem * * @link https://training.bitrix24.com/rest_help/crm/leads/crm_lead_update.php * - * @param int $id * @param array{ * ID?: int, * TITLE?: string, @@ -305,7 +290,6 @@ public function list(array $order, array $filter, array $select, int $startItem * REGISTER_SONET_EVENT?: string * } $params * - * @return UpdatedItemResult * @throws BaseException * @throws TransportException */ @@ -389,7 +373,6 @@ public function update(int $id, array $fields, array $params = []): UpdatedItemR * LINK?: string * } $filter * - * @return int * @throws \Bitrix24\SDK\Core\Exceptions\BaseException * @throws \Bitrix24\SDK\Core\Exceptions\TransportException */ diff --git a/src/Services/CRM/Lead/Service/LeadProductRows.php b/src/Services/CRM/Lead/Service/LeadProductRows.php new file mode 100644 index 00000000..256352e6 --- /dev/null +++ b/src/Services/CRM/Lead/Service/LeadProductRows.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\CRM\Lead\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\UpdatedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\CRM\Lead\Result\LeadProductRowItemsResult; +use Money\Currency; + +#[ApiServiceMetadata(new Scope(['crm']))] +class LeadProductRows extends AbstractService +{ + /** + * Returns products inside the specified lead. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/leads/crm-lead-get.html + * + * @param Currency|null $currency + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'crm.lead.productrows.get', + 'https://apidocs.bitrix24.com/api-reference/crm/leads/crm-lead-get.html', + 'Returns products inside the specified lead.' + )] + public function get(int $leadId, Currency $currency = null): LeadProductRowItemsResult + { + if (!$currency instanceof \Money\Currency) { + $res = $this->core->call('batch', [ + 'halt' => 0, + 'cmd' => [ + 'lead' => sprintf('crm.lead.get?ID=%s', $leadId), + 'rows' => sprintf('crm.lead.productrows.get?ID=%s', $leadId) + ], + ]); + $data = $res->getResponseData()->getResult(); + $currency = new Currency($data['result']['lead']['CURRENCY_ID']); + return new LeadProductRowItemsResult($res, $currency); + } + + return new LeadProductRowItemsResult( + $this->core->call( + 'crm.lead.productrows.get', + [ + 'id' => $leadId, + ] + ), + $currency + ); + } + + + /** + * Creates or updates product entries inside the specified lead. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/leads/crm-lead-productrows-set.html + * + * @param array $productRows + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'crm.lead.productrows.set', + 'https://apidocs.bitrix24.com/api-reference/crm/leads/crm-lead-productrows-set.html', + 'Creates or updates product entries inside the specified lead.' + )] + public function set(int $leadId, array $productRows): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call( + 'crm.lead.productrows.set', + [ + 'id' => $leadId, + 'rows' => $productRows, + ] + ) + ); + } +} diff --git a/tests/Integration/Services/CRM/Lead/Service/BatchTest.php b/tests/Integration/Services/CRM/Lead/Service/BatchTest.php index 23bfd35c..c4404010 100644 --- a/tests/Integration/Services/CRM/Lead/Service/BatchTest.php +++ b/tests/Integration/Services/CRM/Lead/Service/BatchTest.php @@ -24,16 +24,16 @@ * * @package Bitrix24\SDK\Tests\Integration\Services\CRM\Lead\Service */ +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Lead\Service\Batch::class)] class BatchTest extends TestCase { protected Lead $leadService; /** - * @testdox Batch list leads - * @covers \Bitrix24\SDK\Services\CRM\Lead\Service\Batch::list() * @throws BaseException * @throws TransportException */ + #[\PHPUnit\Framework\Attributes\TestDox('Batch list leads')] public function testBatchList(): void { $itemId = $this->leadService->add(['TITLE' => 'test lead'])->getId(); @@ -42,64 +42,69 @@ public function testBatchList(): void foreach ($this->leadService->batch->list([], ['ID' => $itemId], ['ID', 'NAME'], 1) as $item) { $cnt++; } + self::assertGreaterThanOrEqual(1, $cnt); $this->leadService->delete($itemId); } /** - * @testdox Batch add lead - * @covers \Bitrix24\SDK\Services\CRM\Lead\Service\Batch::add() * @throws \Bitrix24\SDK\Core\Exceptions\BaseException */ + #[\PHPUnit\Framework\Attributes\TestDox('Batch add lead')] public function testBatchAdd(): void { $items = []; for ($i = 1; $i < 60; $i++) { $items[] = ['TITLE' => 'TITLE-' . $i]; } + $cnt = 0; $itemId = []; foreach ($this->leadService->batch->add($items) as $item) { $cnt++; $itemId[] = $item->getId(); } + self::assertEquals(count($items), $cnt); $cnt = 0; foreach ($this->leadService->batch->delete($itemId) as $cnt => $deleteResult) { $cnt++; } + self::assertEquals(count($items), $cnt); } /** - * @testdox Batch delete deals - * @covers \Bitrix24\SDK\Services\CRM\Deal\Service\Batch::add() * @throws \Bitrix24\SDK\Core\Exceptions\BaseException */ + #[\PHPUnit\Framework\Attributes\TestDox('Batch delete leads')] public function testBatchDelete(): void { - $deals = []; + $leads = []; for ($i = 1; $i < 60; $i++) { - $deals[] = ['TITLE' => 'TITLE-' . $i]; + $leads[] = ['TITLE' => 'TITLE-' . $i]; } + $cnt = 0; $dealId = []; - foreach ($this->leadService->batch->add($deals) as $item) { + foreach ($this->leadService->batch->add($leads) as $item) { $cnt++; $dealId[] = $item->getId(); } - self::assertEquals(count($deals), $cnt); + + self::assertEquals(count($leads), $cnt); $cnt = 0; foreach ($this->leadService->batch->delete($dealId) as $cnt => $deleteResult) { $cnt++; } - self::assertEquals(count($deals), $cnt); + + self::assertEquals(count($leads), $cnt); } - public function setUp(): void + protected function setUp(): void { $this->leadService = Fabric::getServiceBuilder()->getCRMScope()->lead(); } diff --git a/tests/Integration/Services/CRM/Lead/Service/LeadProductRowsTest.php b/tests/Integration/Services/CRM/Lead/Service/LeadProductRowsTest.php new file mode 100644 index 00000000..02963a86 --- /dev/null +++ b/tests/Integration/Services/CRM/Lead/Service/LeadProductRowsTest.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Integration\Services\CRM\Lead\Service; + +use Money\Currencies\ISOCurrencies; +use Money\Currency; +use Money\Formatter\DecimalMoneyFormatter; +use Money\Money; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\CRM\Common\Result\DiscountType; +use Bitrix24\SDK\Services\CRM\Lead\Result\LeadProductRowItemResult; +use Bitrix24\SDK\Services\CRM\Lead\Service\Lead; +use Bitrix24\SDK\Services\CRM\Lead\Service\LeadProductRows; +use Bitrix24\SDK\Tests\Builders\DemoDataGenerator; +use Bitrix24\SDK\Tests\Integration\Fabric; +use MoneyPHP\Percentage\Percentage; +use PHPUnit\Framework\TestCase; +use Typhoon\Reflection\TyphoonReflector; + +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Lead\Service\LeadProductRows::class)] +class LeadProductRowsTest extends TestCase +{ + private Lead $leadService; + + private LeadProductRows $leadProductRowsService; + + private DecimalMoneyFormatter $decimalMoneyFormatter; + + private TyphoonReflector $typhoonReflector; + + public function testAllSystemPropertiesAnnotated(): void + { + $leadId = $this->leadService->add(['TITLE' => 'test lead'])->getId(); + $this->leadProductRowsService->set( + $leadId, + [ + [ + 'PRODUCT_NAME' => sprintf('product name %s', time()), + 'PRICE' => $this->decimalMoneyFormatter->format(new Money(100000, DemoDataGenerator::getCurrency())), + ], + ] + ); + // get response from server with actual keys + $propListFromApi = array_keys($this->leadProductRowsService->get($leadId)->getCoreResponse()->getResponseData()->getResult()['result']['rows'][0]); + // parse keys from phpdoc annotation + $collection = $this->typhoonReflector->reflectClass(LeadProductRowItemResult::class)->properties(); + $propsFromAnnotations = []; + foreach ($collection as $meta) { + if ($meta->isAnnotated() && !$meta->isNative()) { + $propsFromAnnotations[] = $meta->id->name; + } + } + + $this->assertEquals($propListFromApi, $propsFromAnnotations, + sprintf('in phpdocs annotations for class %s cant find fields from actual api response: %s', + LeadProductRowItemResult::class, + implode(', ', array_values(array_diff($propListFromApi, $propsFromAnnotations))) + )); + + $this->leadService->delete($leadId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testSet(): void + { + $leadId = $this->leadService->add(['TITLE' => sprintf('test lead %s', time())])->getId(); + $lead = $this->leadService->get($leadId)->lead(); + $price = new Money(100000, $lead->CURRENCY_ID); + $discount = new Money(50012, $lead->CURRENCY_ID); + $this::assertTrue( + $this->leadProductRowsService->set( + $leadId, + [ + [ + 'PRODUCT_NAME' => sprintf('product name %s', time()), + 'PRICE' => $this->decimalMoneyFormatter->format($price), + 'DISCOUNT_TYPE_ID' => 1, + 'DISCOUNT_SUM' => $this->decimalMoneyFormatter->format($discount) + ], + ] + )->isSuccess() + ); + $leadProductRowItemsResult = $this->leadProductRowsService->get($leadId); + $this->assertCount(1, $leadProductRowItemsResult->getProductRows()); + $productRow = $leadProductRowItemsResult->getProductRows()[0]; + $this->assertEquals($price, $productRow->PRICE); + $this->assertEquals(DiscountType::monetary, $productRow->DISCOUNT_TYPE_ID); + $this->assertEquals($discount, $productRow->DISCOUNT_SUM); + $discount = $discount->multiply(100)->divide($this->decimalMoneyFormatter->format($price->add($discount))); + $calculatedPercentage = new Percentage((string)((int)$discount->getAmount() / 100)); + $this->assertEquals($calculatedPercentage, $productRow->DISCOUNT_RATE); + + $this->leadService->delete($leadId); + } + + public function testGet(): void + { + $leadId = $this->leadService->add(['TITLE' => sprintf('test lead %s', time())])->getId(); + $lead = $this->leadService->get($leadId)->lead(); + $price = new Money(100000, $lead->CURRENCY_ID); + $discount = new Money(0, $lead->CURRENCY_ID); + $this::assertTrue( + $this->leadProductRowsService->set( + $leadId, + [ + [ + 'PRODUCT_NAME' => sprintf('product name %s', time()), + 'PRICE' => $this->decimalMoneyFormatter->format($price), + ], + ] + )->isSuccess() + ); + $leadProductRowItemsResult = $this->leadProductRowsService->get($leadId); + $this->assertCount(1, $leadProductRowItemsResult->getProductRows()); + $productRow = $leadProductRowItemsResult->getProductRows()[0]; + $this->assertEquals($price, $productRow->PRICE); + $this->assertEquals(DiscountType::percentage, $productRow->DISCOUNT_TYPE_ID); + $this->assertEquals($discount, $productRow->DISCOUNT_SUM); + $this->assertEquals(Percentage::zero(), $productRow->DISCOUNT_RATE); + + $this->leadService->delete($leadId); + } + + protected function setUp(): void + { + $this->leadService = Fabric::getServiceBuilder()->getCRMScope()->lead(); + $this->leadProductRowsService = Fabric::getServiceBuilder()->getCRMScope()->leadProductRows(); + $this->decimalMoneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies()); + $this->typhoonReflector = TyphoonReflector::build(); + } +} \ No newline at end of file diff --git a/tests/Integration/Services/CRM/Lead/Service/LeadTest.php b/tests/Integration/Services/CRM/Lead/Service/LeadTest.php index 2c356d7a..eb020fa0 100644 --- a/tests/Integration/Services/CRM/Lead/Service/LeadTest.php +++ b/tests/Integration/Services/CRM/Lead/Service/LeadTest.php @@ -36,6 +36,7 @@ #[CoversMethod(Lead::class,'list')] #[CoversMethod(Lead::class,'fields')] #[CoversMethod(Lead::class,'update')] +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Lead\Service\Lead::class)] class LeadTest extends TestCase { use CustomBitrix24Assertions; @@ -51,9 +52,7 @@ public function testAllSystemFieldsHasValidTypeAnnotation():void { $allFields = $this->leadService->fields()->getFieldsDescription(); $systemFieldsCodes = (new Core\Fields\FieldsFilter())->filterSystemFields(array_keys($allFields)); - $systemFields = array_filter($allFields, static function ($code) use ($systemFieldsCodes) { - return in_array($code, $systemFieldsCodes, true); - }, ARRAY_FILTER_USE_KEY); + $systemFields = array_filter($allFields, static fn($code): bool => in_array($code, $systemFieldsCodes, true), ARRAY_FILTER_USE_KEY); $this->assertBitrix24AllResultItemFieldsHasValidTypeAnnotation( $systemFields, @@ -72,7 +71,6 @@ public function testAdd(): void /** * @throws BaseException * @throws TransportException - * @covers Lead::delete */ public function testDelete(): void { @@ -80,7 +78,6 @@ public function testDelete(): void } /** - * @covers Lead::fields * @throws BaseException * @throws TransportException */ @@ -92,7 +89,6 @@ public function testFields(): void /** * @throws BaseException * @throws TransportException - * @covers Lead::get */ public function testGet(): void { @@ -105,7 +101,6 @@ public function testGet(): void /** * @throws BaseException * @throws TransportException - * @covers Lead::list */ public function testList(): void { @@ -116,21 +111,19 @@ public function testList(): void /** * @throws BaseException * @throws TransportException - * @covers Lead::update */ public function testUpdate(): void { - $deal = $this->leadService->add(['TITLE' => 'test lead']); + $addedItemResult = $this->leadService->add(['TITLE' => 'test lead']); $newTitle = 'test2'; - self::assertTrue($this->leadService->update($deal->getId(), ['TITLE' => $newTitle], [])->isSuccess()); - self::assertEquals($newTitle, $this->leadService->get($deal->getId())->lead()->TITLE); + self::assertTrue($this->leadService->update($addedItemResult->getId(), ['TITLE' => $newTitle], [])->isSuccess()); + self::assertEquals($newTitle, $this->leadService->get($addedItemResult->getId())->lead()->TITLE); } /** * @throws \Bitrix24\SDK\Core\Exceptions\BaseException * @throws \Bitrix24\SDK\Core\Exceptions\TransportException - * @covers \Bitrix24\SDK\Services\CRM\Deal\Service\Deal::countByFilter */ public function testCountByFilter(): void { @@ -141,10 +134,12 @@ public function testCountByFilter(): void for ($i = 1; $i <= $newItemsCount; $i++) { $items[] = ['TITLE' => 'TITLE-' . $i]; } + $cnt = 0; foreach ($this->leadService->batch->add($items) as $item) { $cnt++; } + self::assertEquals(count($items), $cnt); $after = $this->leadService->countByFilter(); @@ -152,7 +147,7 @@ public function testCountByFilter(): void $this->assertEquals($before + $newItemsCount, $after); } - public function setUp(): void + protected function setUp(): void { $this->leadService = Fabric::getServiceBuilder()->getCRMScope()->lead(); }