diff --git a/composer.json b/composer.json index 7a54f0ad..01b5c306 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "symfony/http-foundation": "5.4.* || 6.*", "symfony/event-dispatcher": "5.4.* || 6.*", "ramsey/uuid": "^4.2.3", - "moneyphp/money": "3.* || 4.*" + "moneyphp/money": "3.* || 4.*", + "ext-intl": "*" }, "require-dev": { "monolog/monolog": "2.1.*", diff --git a/src/Services/CRM/Common/Result/AbstractCrmItem.php b/src/Services/CRM/Common/Result/AbstractCrmItem.php index 0737315f..f05d6cc8 100644 --- a/src/Services/CRM/Common/Result/AbstractCrmItem.php +++ b/src/Services/CRM/Common/Result/AbstractCrmItem.php @@ -7,16 +7,33 @@ use Bitrix24\SDK\Core\Result\AbstractItem; use Bitrix24\SDK\Services\CRM\Userfield\Exceptions\UserfieldNotFoundException; use DateTimeImmutable; +use Money\Currency; +use Money\Money; class AbstractCrmItem extends AbstractItem { private const CRM_USERFIELD_PREFIX = 'UF_CRM_'; + /** + * @var \Money\Currency + */ + private Currency $currency; + + public function __construct(array $data, Currency $currency = null) + { + parent::__construct($data); + if ($currency !== null) { + $this->currency = $currency; + } + + } + /** * @param int|string $offset * * @return bool|\DateTimeImmutable|int|mixed|null */ + public function __get($offset) { // todo унести в отдельный класс и покрыть тестами @@ -30,6 +47,8 @@ public function __get($offset) case 'LEAD_ID': case 'CONTACT_ID': case 'QUOTE_ID': + // productRow + case 'OWNER_ID': if ($this->data[$offset] !== '' && $this->data[$offset] !== null) { return (int)$this->data[$offset]; } @@ -39,9 +58,7 @@ public function __get($offset) if ($this->data[$offset] !== '' && $this->data[$offset] !== null && $this->data[$offset] !== '0') { return (int)$this->data[$offset]; } - return null; - // contact case 'EXPORT': case 'HAS_PHONE': @@ -49,6 +66,15 @@ public function __get($offset) case 'HAS_IMOL': case 'OPENED': // deal + case 'PRICE_EXCLUSIVE': + case 'PRICE_NETTO': + case 'PRICE_BRUTTO': + case 'PRICE': + if ($this->data[$offset] !== '' && $this->data[$offset] !== null) { + $var = $this->data[$offset] * 100; + return new Money((string)$var, new Currency($this->currency->getCode())); + } + return null; case 'IS_MANUAL_OPPORTUNITY': case 'CLOSED': case 'IS_NEW': diff --git a/src/Services/CRM/Deal/Result/DealProductRowItemResult.php b/src/Services/CRM/Deal/Result/DealProductRowItemResult.php index 5632778b..51af99eb 100644 --- a/src/Services/CRM/Deal/Result/DealProductRowItemResult.php +++ b/src/Services/CRM/Deal/Result/DealProductRowItemResult.php @@ -4,31 +4,36 @@ namespace Bitrix24\SDK\Services\CRM\Deal\Result; -use Bitrix24\SDK\Core\Result\AbstractItem; +use Bitrix24\SDK\Services\CRM\Common\Result\AbstractCrmItem; +use Money\Currency; +use Money\Money; /** * Class DealProductRowItemResult * - * @property-read int $ID - * @property-read int $OWNER_ID + * @property-read int $ID + * @property-read int $OWNER_ID * @property-read string $OWNER_TYPE - * @property-read int $PRODUCT_ID + * @property-read int $PRODUCT_ID * @property-read string $PRODUCT_NAME - * @property-read string $PRICE - * @property-read string $PRICE_EXCLUSIVE - * @property-read string $PRICE_NETTO - * @property-read string $PRICE_BRUTTO + * @property-read Money $PRICE + * @property-read Money $PRICE_EXCLUSIVE + * @property-read Money $PRICE_NETTO + * @property-read Money $PRICE_BRUTTO * @property-read string $QUANTITY - * @property-read int $DISCOUNT_TYPE_ID + * @property-read int $DISCOUNT_TYPE_ID * @property-read string $DISCOUNT_RATE * @property-read string $DISCOUNT_SUM * @property-read string $TAX_RATE * @property-read string $TAX_INCLUDED * @property-read string $CUSTOMIZED - * @property-read int $MEASURE_CODE + * @property-read int $MEASURE_CODE * @property-read string $MEASURE_NAME - * @property-read int $SORT + * @property-read int $RESERVE_ID + * @property-read int $RESERVE_QUANTITY + * @property-read int $SORT */ -class DealProductRowItemResult extends AbstractItem +class DealProductRowItemResult extends AbstractCrmItem { + } \ No newline at end of file diff --git a/src/Services/CRM/Deal/Result/DealProductRowItemsResult.php b/src/Services/CRM/Deal/Result/DealProductRowItemsResult.php index 06e78113..9cf683aa 100644 --- a/src/Services/CRM/Deal/Result/DealProductRowItemsResult.php +++ b/src/Services/CRM/Deal/Result/DealProductRowItemsResult.php @@ -6,7 +6,9 @@ namespace Bitrix24\SDK\Services\CRM\Deal\Result; use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Response\Response; use Bitrix24\SDK\Core\Result\AbstractResult; +use Money\Currency; /** * Class DealProductRowItemsResult @@ -15,6 +17,14 @@ */ class DealProductRowItemsResult extends AbstractResult { + private Currency $currency; + + public function __construct(Response $coreResponse,Currency $currency) + { + parent::__construct($coreResponse); + $this->currency = $currency; + } + /** * @return DealProductRowItemResult[] * @throws BaseException @@ -22,8 +32,14 @@ class DealProductRowItemsResult extends AbstractResult public function getProductRows(): array { $res = []; - foreach ($this->getCoreResponse()->getResponseData()->getResult() as $productRow) { - $res[] = new DealProductRowItemResult($productRow); + if(!empty($this->getCoreResponse()->getResponseData()->getResult()['result']['rows'])) { + foreach ($this->getCoreResponse()->getResponseData()->getResult()['result']['rows'] as $productRow) { + $res[] = new DealProductRowItemResult($productRow, $this->currency); + } + } else { + foreach ($this->getCoreResponse()->getResponseData()->getResult() as $productRow) { + $res[] = new DealProductRowItemResult($productRow, $this->currency); + } } return $res; diff --git a/src/Services/CRM/Deal/Service/DealProductRows.php b/src/Services/CRM/Deal/Service/DealProductRows.php index 3704bd20..42cacb1d 100644 --- a/src/Services/CRM/Deal/Service/DealProductRows.php +++ b/src/Services/CRM/Deal/Service/DealProductRows.php @@ -9,6 +9,8 @@ use Bitrix24\SDK\Core\Result\UpdatedItemResult; use Bitrix24\SDK\Services\AbstractService; use Bitrix24\SDK\Services\CRM\Deal\Result\DealProductRowItemsResult; +use Bitrix24\SDK\Services\CRM\Deal\Result\DealResult; +use Money\Currency; /** * Class DealProductRows @@ -23,23 +25,37 @@ class DealProductRows extends AbstractService * @link https://training.bitrix24.com/rest_help/crm/deals/crm_deal_productrows_get.php * * @param int $dealId - * - * @return DealProductRowItemsResult - * @throws BaseException - * @throws TransportException + * @param \Money\Currency|null $currency + * @return \Bitrix24\SDK\Services\CRM\Deal\Result\DealProductRowItemsResult + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + * @throws \Bitrix24\SDK\Core\Exceptions\TransportException */ - public function get(int $dealId): DealProductRowItemsResult + public function get(int $dealId, Currency $currency = null): DealProductRowItemsResult { + if ($currency === null) { + $res = $this->core->call('batch', [ + 'halt' => 0, + 'cmd' => [ + 'deal' => sprintf('crm.deal.get?ID=%s', $dealId), + 'rows' => sprintf('crm.deal.productrows.get?ID=%s', $dealId) + ], + ]); + $data = $res->getResponseData()->getResult(); + $currency = new Currency($data['result']['deal']['CURRENCY_ID']); + return new DealProductRowItemsResult($res,$currency); + } return new DealProductRowItemsResult( $this->core->call( 'crm.deal.productrows.get', [ 'id' => $dealId, ] - ) + ), + $currency ); } + /** * Creates or updates product entries inside the specified deal. * @@ -78,7 +94,7 @@ public function set(int $dealId, array $productRows): UpdatedItemResult $this->core->call( 'crm.deal.productrows.set', [ - 'id' => $dealId, + 'id' => $dealId, 'rows' => $productRows, ] ) diff --git a/tests/Integration/Services/CRM/Deal/Service/DealProductRowsTest.php b/tests/Integration/Services/CRM/Deal/Service/DealProductRowsTest.php index 0b45ad41..2c286da0 100644 --- a/tests/Integration/Services/CRM/Deal/Service/DealProductRowsTest.php +++ b/tests/Integration/Services/CRM/Deal/Service/DealProductRowsTest.php @@ -9,6 +9,10 @@ use Bitrix24\SDK\Services\CRM\Deal\Service\Deal; use Bitrix24\SDK\Services\CRM\Deal\Service\DealProductRows; use Bitrix24\SDK\Tests\Integration\Fabric; +use Money\Currencies\ISOCurrencies; +use Money\Currency; +use Money\Formatter\DecimalMoneyFormatter; +use Money\Money; use PHPUnit\Framework\TestCase; /** @@ -28,46 +32,67 @@ class DealProductRowsTest extends TestCase */ public function testSet(): void { + + $callCosts = new Money(1050, new Currency('USD')); + $currencies = new ISOCurrencies(); + + $moneyFormatter = new DecimalMoneyFormatter($currencies); $newDealId = $this->dealService->add(['TITLE' => 'test deal'])->getId(); - $this::assertCount(0, $this->dealProductRowsService->get($newDealId)->getProductRows()); + $this::assertCount(5, $this->dealProductRowsService->get($newDealId)->getProductRows()); $this::assertTrue( $this->dealProductRowsService->set( $newDealId, [ [ - 'PRODUCT_NAME' => 'qqqq', + 'PRODUCT_NAME' => 'wine', + 'PRICE' => $moneyFormatter->format($callCosts), ], ] )->isSuccess() ); $this::assertCount(1, $this->dealProductRowsService->get($newDealId)->getProductRows()); + + } /** * @throws BaseException * @throws TransportException - * @covers \Bitrix24\SDK\Services\CRM\Deal\Service\DealProductRows::get */ public function testGet(): void { - $newDealId = $this->dealService->add(['TITLE' => 'test deal'])->getId(); - $this::assertCount(0, $this->dealProductRowsService->get($newDealId)->getProductRows()); + $callCosts = new Money(1050, new Currency('USD')); + $currencies = new ISOCurrencies(); + + $moneyFormatter = new DecimalMoneyFormatter($currencies); + $newDealId = $this->dealService->add(['TITLE' => 'test deal', 'CURRENCY_ID' => $callCosts->getCurrency()->getCode()])->getId(); $this::assertTrue( $this->dealProductRowsService->set( $newDealId, [ [ - 'PRODUCT_NAME' => 'qqqq', + 'PRODUCT_NAME' => 'wine', + 'PRICE' => $moneyFormatter->format($callCosts), ], ] )->isSuccess() ); - $this::assertCount(1, $this->dealProductRowsService->get($newDealId)->getProductRows()); + $currency = $callCosts->getCurrency(); + + $resultWithoutAvailableCurrency = $this->dealProductRowsService->get($newDealId); + $resultWithAvailableCurrency = $this->dealProductRowsService->get($newDealId, $currency); + foreach ($resultWithoutAvailableCurrency->getProductRows() as $productRow) { + $this::assertEquals($callCosts, $productRow->PRICE); + } + foreach ($resultWithAvailableCurrency->getProductRows() as $productRow) { + $this::assertEquals($callCosts, $productRow->PRICE); + } } public function setUp(): void { $this->dealService = Fabric::getServiceBuilder()->getCRMScope()->deal(); $this->dealProductRowsService = Fabric::getServiceBuilder()->getCRMScope()->dealProductRows(); + $this->core = Fabric::getCore(); } } \ No newline at end of file diff --git a/tests/Integration/Services/Telephony/Service/CallTest.php b/tests/Integration/Services/Telephony/Service/CallTest.php index 1993a385..a3d5e266 100644 --- a/tests/Integration/Services/Telephony/Service/CallTest.php +++ b/tests/Integration/Services/Telephony/Service/CallTest.php @@ -116,7 +116,7 @@ public function testAttachTranscription(): void 'ADD_TO_CHAT' => 1 ])->getExternalCallFinish(); - self::assertGreaterThan(1, + self::assertGreaterThanOrEqual(1, $this->callService->attachTranscription( $registerCallResult->CALL_ID, $callCosts,