DolibarrApiService.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service\Dolibarr;
  4. use App\Entity\Organization\Organization;
  5. use App\Service\Rest\ApiRequestService;
  6. use JetBrains\PhpStorm\Pure;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\HttpKernel\Exception\HttpException;
  9. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  10. use Symfony\Contracts\HttpClient\HttpClientInterface;
  11. /**
  12. * Service d'appel à l'API dolibarr.
  13. *
  14. * @see https://prod-erp.2iopenservice.com/api/index.php/explorer/
  15. */
  16. class DolibarrApiService extends ApiRequestService
  17. {
  18. /** @noinspection SenselessProxyMethodInspection Method shall be kept to allow dependency injections, even if empty */
  19. #[Pure]
  20. public function __construct(HttpClientInterface $dolibarr_client)
  21. {
  22. parent::__construct($dolibarr_client);
  23. }
  24. /**
  25. * Get a dolibarr society by its opentalent organization id.
  26. *
  27. * @return array<mixed>|null
  28. *
  29. * @throws \JsonException
  30. */
  31. public function getSociety(int $organizationId): ?array
  32. {
  33. // impossible to retrieve a society by its extrafield 2iopen_organization_id (thanks dolibarr), so
  34. // we need to store the organization id in two fields: 2iopen_organization_id and ref_int :(
  35. try {
  36. return $this->getJsonContent(
  37. 'thirdparties',
  38. [
  39. 'limit' => '1',
  40. 'sqlfilters' => '(ef.2iopen_organization_id:=:'.$organizationId.')',
  41. ]
  42. )[0];
  43. } catch (HttpException $e) {
  44. if ($e->getStatusCode() === 404) {
  45. // /!\ The dolibarr API will return a 404 error if no results are found...
  46. return null;
  47. }
  48. throw $e;
  49. }
  50. }
  51. /**
  52. * Get the first active contract for the given dolibarr society.
  53. *
  54. * @return array<mixed>|null
  55. */
  56. public function getActiveContract(int $socId): ?array
  57. {
  58. try {
  59. return $this->getJsonContent(
  60. 'contracts',
  61. ['limit' => '1', 'sqlfilters' => 'statut:=:1', 'thirdparty_ids' => $socId]
  62. )[0];
  63. } catch (HttpException $e) {
  64. if ($e->getStatusCode() === 404) {
  65. // /!\ The dolibarr API will return a 404 error if no results are found...
  66. return null;
  67. }
  68. throw $e;
  69. }
  70. }
  71. /**
  72. * Get a society bills by their society id.
  73. *
  74. * @return array<mixed>
  75. */
  76. public function getBills(int $socId): array
  77. {
  78. try {
  79. return $this->getJsonContent(
  80. 'invoices',
  81. ['sortfield' => 'datef', 'sortorder' => 'DESC', 'limit' => 5, 'sqlfilters' => 'fk_soc:=:'.$socId]);
  82. } catch (HttpException $e) {
  83. if ($e->getStatusCode() === 404) {
  84. // /!\ The dolibarr API will return a 404 error if no results are found...
  85. return [];
  86. }
  87. throw $e;
  88. }
  89. }
  90. /**
  91. * Get all the societies which are Opentalent client.
  92. *
  93. * @return array<mixed>
  94. *
  95. * @throws HttpException
  96. */
  97. public function getAllClients(): array
  98. {
  99. return $this->getJsonContent(
  100. 'thirdparties',
  101. ['limit' => '1000000', 'sqlfilters' => 'client:=:1']
  102. );
  103. }
  104. /**
  105. * Get the society contacts.
  106. *
  107. * @return array<mixed>
  108. *
  109. * @throws HttpException
  110. */
  111. public function getContacts(int $socId): array
  112. {
  113. try {
  114. return $this->getJsonContent(
  115. 'contacts',
  116. ['limit' => 1000, 'thirdparty_ids' => $socId],
  117. );
  118. } catch (HttpException $e) {
  119. if ($e->getStatusCode() === 404) {
  120. // /!\ The dolibarr API will return a 404 error if no results are found...
  121. return [];
  122. }
  123. throw $e;
  124. }
  125. }
  126. /**
  127. * Get the society contacts that have a non-null personId.
  128. *
  129. * @return array<mixed>
  130. *
  131. * @throws HttpException
  132. */
  133. public function getActiveOpentalentContacts(int $socId): array
  134. {
  135. // On est obligé ici de passer la query en dur, sinon les parenthèses sont encodées,
  136. // et dolibarr est pas content :(
  137. try {
  138. return $this->getJsonContent(
  139. 'contacts?limit=1000&t.statut=1&thirdparty_ids='.$socId.'&sqlfilters:=:(te.2iopen_person_id%3A%3E%3A0)'
  140. );
  141. } catch (HttpException $e) {
  142. if ($e->getStatusCode() === 404) {
  143. // /!\ The dolibarr API will return a 404 error if no results are found...
  144. return [];
  145. }
  146. throw $e;
  147. }
  148. }
  149. /**
  150. * Get the society tags.
  151. *
  152. * @param int $socId The society ID
  153. *
  154. * @return array<int> The array of tags associated with the society
  155. *
  156. * @throws HttpException|\JsonException if an HTTP error occurs
  157. */
  158. public function getSocietyTagsIds(int $socId): array
  159. {
  160. try {
  161. return array_map(
  162. function ($x) { return (int) $x['id']; },
  163. $this->getJsonContent("/thirdparties/$socId/categories")
  164. );
  165. } catch (HttpException $e) {
  166. if ($e->getStatusCode() === 404) {
  167. // /!\ The dolibarr API will return a 404 error if no results are found...
  168. return [];
  169. }
  170. throw $e;
  171. }
  172. }
  173. /**
  174. * Créé une société dans la DB dolibarr, et retourne l'id de celle-ci.
  175. */
  176. public function createSociety(Organization $organization, bool $client = false): mixed
  177. {
  178. $body = [
  179. 'name' => $organization->getName(),
  180. 'client' => $client ? 1 : 2,
  181. 'code_client' => -1,
  182. 'import_key' => 'crm',
  183. 'array_options' => ['options_2iopen_organization_id' => $organization->getId()],
  184. ];
  185. /** @var Response $response */
  186. $response = $this->post('/thirdparties', $body);
  187. return json_decode($response->getContent(), true);
  188. }
  189. /**
  190. * Delete the organization from Dolibarr.
  191. *
  192. * @throws \JsonException
  193. * @throws TransportExceptionInterface
  194. */
  195. public function switchSocietyToProspect(int $organizationId): void
  196. {
  197. $socId = $this->getSociety($organizationId)['id'];
  198. $res = $this->put(
  199. "thirdparties/$socId",
  200. ['client' => 2],
  201. );
  202. if ($res->getStatusCode() !== 200) {
  203. throw new HttpException($res->getStatusCode(), 'Error while updating the society in Dolibarr');
  204. }
  205. }
  206. }