]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Repository/PaymentTypes.php
Add scheduled payments feature
[galette.git] / galette / lib / Galette / Repository / PaymentTypes.php
1 <?php
2
3 /**
4 * Copyright © 2003-2024 The Galette Team
5 *
6 * This file is part of Galette (https://galette.eu).
7 *
8 * Galette is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Galette is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 namespace Galette\Repository;
23
24 use Laminas\Db\ResultSet\ResultSet;
25 use Throwable;
26 use Analog\Analog;
27 use Laminas\Db\Sql\Expression;
28 use Galette\Entity\PaymentType;
29
30 /**
31 * Payment types
32 *
33 * @author Johan Cwiklinski <johan@x-tnd.be>
34 */
35 class PaymentTypes extends Repository
36 {
37 /**
38 * Get payments types
39 *
40 * @param boolean $schedulable Types that can be used in schedules only
41 *
42 * @return array<int, PaymentType>
43 */
44 public static function getAll(bool $schedulable = true): array
45 {
46 global $zdb, $preferences, $login;
47 $ptypes = new self($zdb, $preferences, $login);
48 return $ptypes->getList($schedulable);
49 }
50
51 /**
52 * Get list
53 *
54 * @param boolean $schedulable Types that can be used in schedules only
55 *
56 * @return array<int, PaymentType>|ResultSet
57 */
58 public function getList(bool $schedulable = true): array|ResultSet
59 {
60 try {
61 $select = $this->zdb->select(PaymentType::TABLE, 'a');
62 $select->order(PaymentType::PK);
63
64 if ($schedulable === false) {
65 $select->where->notEqualTo('a.' . PaymentType::PK, PaymentType::SCHEDULED);
66 }
67
68 $types = array();
69 $results = $this->zdb->execute($select);
70 foreach ($results as $row) {
71 $types[$row->type_id] = new PaymentType($this->zdb, $row);
72 }
73 return $types;
74 } catch (Throwable $e) {
75 Analog::log(
76 'Cannot list payment types | ' . $e->getMessage(),
77 Analog::WARNING
78 );
79 throw $e;
80 }
81 }
82
83 /**
84 * Add default payment types in database
85 *
86 * @param boolean $check_first Check first if it seems initialized
87 *
88 * @return boolean
89 */
90 public function installInit(bool $check_first = true): bool
91 {
92 try {
93 $ent = $this->entity;
94 //first of all, let's check if data seem to have already
95 //been initialized
96 $proceed = false;
97 if ($check_first === true) {
98 $select = $this->zdb->select(PaymentType::TABLE);
99 $select->columns(
100 array(
101 'counter' => new Expression('COUNT(' . $ent::PK . ')')
102 )
103 );
104
105 $results = $this->zdb->execute($select);
106 $result = $results->current();
107 $count = $result->counter;
108 if ($count == 0) {
109 //if we got no values in table, let's proceed
110 $proceed = true;
111 } else {
112 if ($count < count($this->defaults)) {
113 return $this->checkUpdate();
114 }
115 return false;
116 }
117 } else {
118 $proceed = true;
119 }
120
121 if ($proceed === true) {
122 $this->zdb->connection->beginTransaction();
123
124 //first, we drop all values
125 $delete = $this->zdb->delete($ent::TABLE);
126 $this->zdb->execute($delete);
127
128 $this->zdb->handleSequence(
129 $ent::TABLE,
130 count($this->defaults)
131 );
132 $this->insert($ent::TABLE, $this->defaults);
133
134 $this->zdb->connection->commit();
135 return true;
136 }
137 } catch (Throwable $e) {
138 if ($this->zdb->connection->inTransaction()) {
139 $this->zdb->connection->rollBack();
140 }
141 throw $e;
142 }
143 }
144
145 /**
146 * Checks for missing payment types in the database
147 *
148 * @return boolean
149 */
150 protected function checkUpdate(): bool
151 {
152 try {
153 $ent = $this->entity;
154 $select = $this->zdb->select($ent::TABLE);
155 $list = $this->zdb->execute($select);
156 $list->buffer();
157
158 $missing = array();
159 foreach ($this->defaults as $key => $value) {
160 $exists = false;
161 foreach ($list as $type) {
162 if ($type->type_id == $key) {
163 $exists = true;
164 break;
165 }
166 }
167
168 if ($exists === false) {
169 //model does not exists in database, insert it.
170 $missing[$key] = $value;
171 }
172 }
173
174 if (count($missing) > 0) {
175 $this->zdb->connection->beginTransaction();
176 $this->insert($ent::TABLE, $missing);
177 Analog::log(
178 'Missing payment types were successfully stored into database.',
179 Analog::INFO
180 );
181 $this->zdb->connection->commit();
182 return true;
183 }
184 } catch (Throwable $e) {
185 if ($this->zdb->connection->inTransaction()) {
186 $this->zdb->connection->rollBack();
187 }
188 throw $e;
189 }
190 return false;
191 }
192
193 /**
194 * Insert values in database
195 *
196 * @param string $table Table name
197 * @param array<string,mixed> $values Values to insert
198 *
199 * @return void
200 */
201 private function insert(string $table, array $values): void
202 {
203 $insert = $this->zdb->insert($table);
204 $insert->values(
205 array(
206 'type_id' => ':type_id',
207 'type_name' => ':type_name'
208 )
209 );
210 $stmt = $this->zdb->sql->prepareStatementForSqlObject($insert);
211
212 foreach ($values as $k => $v) {
213 $value = [
214 ':type_id' => $k,
215 ':type_name' => $v
216 ];
217 $stmt->execute($value);
218 }
219 }
220
221 /**
222 * Get defaults values
223 *
224 * @return array<string, mixed>
225 */
226 protected function loadDefaults(): array
227 {
228 if (!count($this->defaults)) {
229 $paytype = new PaymentType($this->zdb);
230 $this->defaults = $paytype->getSystemTypes(false);
231 }
232 return parent::loadDefaults();
233 }
234 }