You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
10.0KB

  1. <?php
  2. namespace domain\User\User;
  3. use common\helpers\GlobalParam;
  4. use domain\PointSale\PointSale\PointSale;
  5. use domain\Producer\Producer\Producer;
  6. use domain\User\UserProducer\UserProducerRepository;
  7. use domain\_\AbstractRepository;
  8. use yii\base\ErrorException;
  9. use yii\db\Query;
  10. class UserRepository extends AbstractRepository
  11. {
  12. protected UserRepositoryQuery $query;
  13. protected UserProducerRepository $userProducerRepository;
  14. protected UserSolver $userSolver;
  15. public function loadDependencies(): void
  16. {
  17. $this->loadQuery(UserRepositoryQuery::class);
  18. $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
  19. $this->userSolver = $this->loadService(UserSolver::class);
  20. }
  21. /**
  22. * Retourne les options de base nécessaires à la fonction de recherche.
  23. *
  24. * @return array
  25. */
  26. public function getDefaultOptionsSearch(): array
  27. {
  28. return [
  29. self::WITH => [],
  30. self::JOIN_WITH => ['userProducer', 'userUserGroup'],
  31. self::ORDER_BY => 'user.name ASC, user.lastname ASC',
  32. self::ATTRIBUTE_ID_PRODUCER => ''
  33. ];
  34. }
  35. public function findOneUserById($id)
  36. {
  37. return $this->createDefaultQuery()
  38. ->filterById($id)
  39. ->findOne();
  40. }
  41. public function findUsers(): array
  42. {
  43. return $this->queryUsersBy()->all();
  44. }
  45. public function populateUserDropdownList()
  46. {
  47. $usersArray = $this->findUsers();
  48. $usersArrayDropdown = ['' => '--'];
  49. foreach ($usersArray as $user) {
  50. $usersArrayDropdown[$user['user_id']] = $this->userSolver->getUsernameFromArray($user, true);
  51. }
  52. return $usersArrayDropdown;
  53. }
  54. /**
  55. * Retourne le montant de la cagnotte de l'utilisateur pour un producteur donné.
  56. *
  57. */
  58. public function getCredit(User $user, bool $reloadUserProducer = false): float
  59. {
  60. if($reloadUserProducer) {
  61. $userProducer = $this->userProducerRepository->findOneUserProducer($user);
  62. }
  63. else {
  64. $userProducer = $this->userSolver->getUserProducer($user);
  65. }
  66. return $userProducer ? $userProducer->credit : 0;
  67. }
  68. public function getCreditActive(User $user): bool
  69. {
  70. $userProducer = $this->userSolver->getUserProducer($user);
  71. return $userProducer ? $userProducer->credit_active : false;
  72. }
  73. /**
  74. * Recherche des utilisateurs suivant les paramètres : id_etablissement,
  75. * inactifs, id_point_vente, nom, prenom, email, telephone.
  76. *
  77. * @param array $params
  78. * @return Query
  79. */
  80. public function queryUsersBy(array $params = [])
  81. {
  82. if (!isset($params['id_producer'])) {
  83. $params['id_producer'] = $this->getProducerContextId();
  84. }
  85. $query = (new Query())
  86. ->select(['user.id AS user_id', 'user.type', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person'])
  87. ->from('user');
  88. $active = (isset($params['inactive']) && $params['inactive']) ? 0 : 1;
  89. $filterNewsletter = (isset($params['newsletter']) && $params['newsletter']) ? 'AND user_producer.newsletter = 1' : '';
  90. $query->innerJoin('user_producer', 'user.id = user_producer.id_user AND user_producer.active = ' . $active . ' '.$filterNewsletter.' AND user_producer.id_producer = :id_producer', [':id_producer' => $params['id_producer']]);
  91. if (isset($params['id_point_sale']) && $params['id_point_sale']) {
  92. $point_sale = PointSale::findOne(['id' => $params['id_point_sale']]);
  93. $conditionLinkUserPointSale = 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale';
  94. $usersPointSaleLink = false;
  95. $usersPointSaleHasOrder = false;
  96. if (isset($params['users_point_sale_link']) && $params['users_point_sale_link']) {
  97. $usersPointSaleLink = true;
  98. } elseif (isset($params['users_point_sale_has_order']) && $params['users_point_sale_has_order']) {
  99. $usersPointSaleHasOrder = true;
  100. } elseif ($point_sale->restricted_access) {
  101. $usersPointSaleLink = true;
  102. } else {
  103. $usersPointSaleHasOrder = true;
  104. }
  105. if ($usersPointSaleLink) {
  106. $query->innerJoin('user_point_sale', 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale', [':id_point_sale' => $params['id_point_sale']]);
  107. } elseif ($usersPointSaleHasOrder) {
  108. $query->innerJoin(
  109. 'order',
  110. 'user.id = order.id_user AND order.id_point_sale = :id_point_sale',
  111. [':id_point_sale' => $params['id_point_sale']]
  112. )->groupBy('user.id');
  113. }
  114. }
  115. if (isset($params['subscribers']) && $params['subscribers']) {
  116. $query->innerJoin(
  117. 'subscription',
  118. 'user.id = subscription.id_user AND subscription.id_producer = :id_producer',
  119. [':id_producer' => GlobalParam::getCurrentProducerId()]
  120. )->groupBy('user.id');
  121. }
  122. if (isset($params['inactive']) && $params['inactive']) {
  123. $query->innerJoin(
  124. 'order',
  125. 'user.id = order.id_user'
  126. )
  127. ->groupBy('user.id');
  128. }
  129. if (isset($params['name'])) {
  130. $query->andFilterWhere(['like', 'name', $params['name']]);
  131. }
  132. if (isset($params['lastname'])) {
  133. $query->andFilterWhere(['like', 'lastname', $params['lastname']]);
  134. }
  135. if (isset($params['email'])) {
  136. $query->andFilterWhere(['like', 'email', $params['email']]);
  137. }
  138. if (isset($params['phone'])) {
  139. $query->andFilterWhere(['like', 'phone', $params['phone']]);
  140. }
  141. $query->orderBy('user.type DESC, user.lastname ASC, user.name ASC');
  142. return $query;
  143. }
  144. public function queryUsersWithNegativeCredit()
  145. {
  146. return $this->queryUsersBy()
  147. ->andWhere('user_producer.credit < 0')
  148. ->orderBy('lastname, name ASC');
  149. }
  150. public function findUsersWithNegativeCredit()
  151. {
  152. return $this->queryUsersWithNegativeCredit()->all();
  153. }
  154. public function queryUsersWithPositiveCredit()
  155. {
  156. return $this->queryUsersBy()
  157. ->andWhere('user_producer.credit > 0')
  158. ->orderBy('lastname, name ASC');
  159. }
  160. public function findUsersWithPositiveCredit()
  161. {
  162. return $this->queryUsersWithPositiveCredit()->all();
  163. }
  164. /**
  165. * Finds user by password reset token
  166. */
  167. public function findOneUserByPasswordResetToken(string $token)
  168. {
  169. if (!$this->userSolver->isPasswordResetTokenValid($token)) {
  170. return null;
  171. }
  172. return $this->createDefaultQuery()
  173. ->filterByPasswordResetToken($token)
  174. ->findOne();
  175. }
  176. /**
  177. * Recherche un utilisateur via son adresse email.
  178. */
  179. public function findOneUserByEmail(string $email): ?User
  180. {
  181. return User::searchOne(
  182. ['email' => $email],
  183. [
  184. 'conditions' => 'type LIKE :type_individual OR type LIKE :type_legal_person',
  185. 'params' => [':type_individual' => User::TYPE_INDIVIDUAL, ':type_legal_person' => User::TYPE_LEGAL_PERSON]
  186. ]
  187. );
  188. }
  189. public function findOneUserByUsername(string $username): ?User
  190. {
  191. return $this->createDefaultQuery()
  192. ->filterByUsername($username)
  193. ->findOne();
  194. }
  195. public function findUsersByProducer(Producer $producer)
  196. {
  197. return $this->createDefaultQuery()
  198. ->isStatusProducer()
  199. ->filterByProducer($producer)
  200. ->find();
  201. }
  202. public function findUsersByStatus(string $status)
  203. {
  204. return $this->createDefaultQuery()
  205. ->filterByStatus($status)
  206. ->find();
  207. }
  208. public function countUsersActiveLastThreeMonths()
  209. {
  210. $connection = \Yii::$app->getDb();
  211. $command = $connection->createCommand(
  212. '
  213. SELECT `user`.id, COUNT(`order`.id) AS count_orders
  214. FROM `user`
  215. LEFT JOIN `order` ON `user`.id = `order`.`id_user` AND `order`.`date` >= :date_limit
  216. GROUP BY `user`.id
  217. HAVING count_orders > 0;',
  218. [
  219. ':date_limit' => date('Y-m-d', strtotime("-3 month")),
  220. ]
  221. );
  222. $results = $command->query();
  223. return count($results);
  224. }
  225. public function isActive(User $user)
  226. {
  227. $userProducer = $this->userProducerRepository->findOneUserProducer($user);
  228. return $userProducer ? $userProducer->active : false;
  229. }
  230. public function findUsersWithStatusProducerAndOnline(): array
  231. {
  232. return $this->createDefaultQuery()
  233. ->isStatusProducer()
  234. ->filterByDateLastConnectionLessThanFewMinutes()
  235. ->find();
  236. }
  237. public function countUsersStatusProducerOnline(): int
  238. {
  239. return count($this->findUsersWithStatusProducerAndOnline());
  240. }
  241. public function findUsersWithStatusUserAndOnline(): array
  242. {
  243. return $this->createDefaultQuery()
  244. ->isStatusUser()
  245. ->filterByDateLastConnectionLessThanFewMinutes()
  246. ->find();
  247. }
  248. public function countUsersStatusUserOnline(): int
  249. {
  250. return count($this->findUsersWithStatusUserAndOnline());
  251. }
  252. public function countUsersOnline(): int
  253. {
  254. return $this->countUsersStatusUserOnline() + $this->countUsersStatusProducerOnline();
  255. }
  256. public function findOneUserSystem(): User
  257. {
  258. $userSystem = $this->findOneUserById(User::ID_USER_SYSTEM);
  259. if(!$userSystem) {
  260. throw new ErrorException("L'utilisateur système n'existe pas dans la base de données.");
  261. }
  262. return $userSystem;
  263. }
  264. }