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.

329 lines
10KB

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