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();
}