Total Complexity | 51 |
Total Lines | 382 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like SalesModalHTML often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SalesModalHTML, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
41 | class SalesModalHTML |
||
42 | { |
||
43 | /** @var string */ |
||
44 | protected static $codalmacen; |
||
45 | |||
46 | /** @var string */ |
||
47 | protected static $codcliente; |
||
48 | |||
49 | /** @var string */ |
||
50 | protected static $codfabricante; |
||
51 | |||
52 | /** @var string */ |
||
53 | protected static $codfamilia; |
||
54 | |||
55 | /** @var array */ |
||
56 | protected static $idatributovalores = []; |
||
57 | |||
58 | /** @var string */ |
||
59 | protected static $orden; |
||
60 | |||
61 | /** @var string */ |
||
62 | protected static $query; |
||
63 | |||
64 | /** @var bool */ |
||
65 | protected static $vendido; |
||
66 | |||
67 | public static function apply(SalesDocument &$model, array $formData) |
||
77 | } |
||
78 | |||
79 | public static function render(SalesDocument $model, string $url, User $user, ControllerPermissions $permissions): string |
||
85 | } |
||
86 | |||
87 | public static function renderProductList(): string |
||
88 | { |
||
89 | $tbody = ''; |
||
90 | $i18n = new Translator(); |
||
91 | foreach (static::getProducts() as $row) { |
||
92 | $cssClass = $row['nostock'] ? 'table-info clickableRow' : ($row['disponible'] > 0 ? 'clickableRow' : 'table-warning clickableRow'); |
||
93 | $description = Tools::textBreak($row['descripcion'], 120) |
||
94 | . static::idatributovalor($row['idatributovalor1']) |
||
95 | . static::idatributovalor($row['idatributovalor2']) |
||
96 | . static::idatributovalor($row['idatributovalor3']) |
||
97 | . static::idatributovalor($row['idatributovalor4']); |
||
98 | $tbody .= '<tr class="' . $cssClass . '" onclick="$(\'#findProductModal\').modal(\'hide\');' |
||
99 | . ' return salesFormAction(\'add-product\', \'' . $row['referencia'] . '\');">' |
||
100 | . '<td><b>' . $row['referencia'] . '</b> ' . $description . '</td>' |
||
101 | . '<td class="text-right">' . str_replace(' ', ' ', Tools::money($row['precio'])) . '</td>'; |
||
102 | |||
103 | if (self::$vendido) { |
||
104 | $tbody .= '<td class="text-right">' . str_replace(' ', ' ', Tools::money($row['ultimo_precio'])) . '</td>'; |
||
105 | } |
||
106 | |||
107 | $tbody .= '<td class="text-right">' . $row['disponible'] . '</td>' |
||
108 | . '</tr>'; |
||
109 | } |
||
110 | |||
111 | if (empty($tbody)) { |
||
112 | $tbody .= '<tr class="table-warning"><td colspan="4">' . $i18n->trans('no-data') . '</td></tr>'; |
||
113 | } |
||
114 | |||
115 | $extraTh = self::$vendido ? |
||
116 | '<th class="text-right">' . $i18n->trans('last-price-sale') . '</th>' : |
||
117 | ''; |
||
118 | return '<table class="table table-hover mb-0">' |
||
119 | . '<thead>' |
||
120 | . '<tr>' |
||
121 | . '<th>' . $i18n->trans('product') . '</th>' |
||
122 | . '<th class="text-right">' . $i18n->trans('price') . '</th>' |
||
123 | . $extraTh |
||
124 | . '<th class="text-right">' . $i18n->trans('stock') . '</th>' |
||
125 | . '</tr>' |
||
126 | . '</thead>' |
||
127 | . '<tbody>' . $tbody . '</tbody>' |
||
128 | . '</table>'; |
||
129 | } |
||
130 | |||
131 | protected static function fabricantes(Translator $i18n): string |
||
132 | { |
||
133 | $fabricante = new Fabricante(); |
||
134 | $options = '<option value="">' . $i18n->trans('manufacturer') . '</option>' |
||
135 | . '<option value="">------</option>'; |
||
136 | foreach ($fabricante->all([], ['nombre' => 'ASC'], 0, 0) as $man) { |
||
137 | $options .= '<option value="' . $man->codfabricante . '">' . $man->nombre . '</option>'; |
||
138 | } |
||
139 | |||
140 | return '<select name="fp_codfabricante" class="form-control" onchange="return salesFormAction(\'find-product\', \'0\');">' |
||
141 | . $options . '</select>'; |
||
142 | } |
||
143 | |||
144 | protected static function familias(Translator $i18n): string |
||
145 | { |
||
146 | $options = '<option value="">' . $i18n->trans('family') . '</option>' |
||
147 | . '<option value="">------</option>'; |
||
148 | |||
149 | $familia = new Familia(); |
||
150 | $where = [new DataBaseWhere('madre', null, 'IS')]; |
||
151 | $orderBy = ['descripcion' => 'ASC']; |
||
152 | foreach ($familia->all($where, $orderBy, 0, 0) as $fam) { |
||
153 | $options .= '<option value="' . $fam->codfamilia . '">' . $fam->descripcion . '</option>'; |
||
154 | |||
155 | // añadimos las subfamilias de forma recursiva |
||
156 | $options .= static::subfamilias($fam, $i18n); |
||
157 | } |
||
158 | |||
159 | return '<select name="fp_codfamilia" class="form-control" onchange="return salesFormAction(\'find-product\', \'0\');">' |
||
160 | . $options . '</select>'; |
||
161 | } |
||
162 | |||
163 | protected static function getClientes(User $user, ControllerPermissions $permissions): array |
||
193 | } |
||
194 | |||
195 | protected static function getProducts(): array |
||
196 | { |
||
197 | $dataBase = new DataBase(); |
||
198 | $sql = 'SELECT v.referencia, p.descripcion, v.idatributovalor1, v.idatributovalor2, v.idatributovalor3,' |
||
199 | . ' v.idatributovalor4, v.precio, COALESCE(s.disponible, 0) as disponible, p.nostock' |
||
200 | . ' FROM variantes v' |
||
201 | . ' LEFT JOIN productos p ON v.idproducto = p.idproducto' |
||
202 | . ' LEFT JOIN stocks s ON v.referencia = s.referencia AND s.codalmacen = ' . $dataBase->var2str(self::$codalmacen) |
||
203 | . ' WHERE p.sevende = true AND p.bloqueado = false'; |
||
204 | |||
205 | if (self::$codfabricante) { |
||
206 | $sql .= ' AND codfabricante = ' . $dataBase->var2str(self::$codfabricante); |
||
207 | } |
||
208 | |||
209 | if (self::$codfamilia) { |
||
210 | $codFamilias = [$dataBase->var2str(self::$codfamilia)]; |
||
211 | |||
212 | // buscamos las subfamilias |
||
213 | $familia = new Familia(); |
||
214 | if ($familia->loadFromCode(self::$codfamilia)) { |
||
215 | foreach ($familia->getSubfamilias() as $fam) { |
||
216 | $codFamilias[] = $dataBase->var2str($fam->codfamilia); |
||
217 | } |
||
218 | } |
||
219 | |||
220 | $sql .= ' AND codfamilia IN (' . implode(',', $codFamilias) . ')'; |
||
221 | } |
||
222 | |||
223 | if (self::$vendido) { |
||
224 | $sql .= ' AND v.referencia IN (SELECT referencia FROM lineasfacturascli' |
||
225 | . ' LEFT JOIN facturascli ON lineasfacturascli.idfactura = facturascli.idfactura' |
||
226 | . ' WHERE codcliente = ' . $dataBase->var2str(self::$codcliente) . ')'; |
||
227 | } |
||
228 | |||
229 | if (self::$query) { |
||
230 | $words = explode(' ', self::$query); |
||
231 | if (count($words) === 1) { |
||
232 | $sql .= " AND (LOWER(v.codbarras) = " . $dataBase->var2str(self::$query) |
||
233 | . " OR LOWER(v.referencia) LIKE '%" . self::$query . "%'" |
||
234 | . " OR LOWER(p.descripcion) LIKE '%" . self::$query . "%')"; |
||
235 | } elseif (count($words) > 1) { |
||
236 | $sql .= " AND (LOWER(v.referencia) LIKE '%" . self::$query . "%' OR ("; |
||
237 | foreach ($words as $wc => $word) { |
||
238 | $sql .= $wc > 0 ? |
||
239 | " AND LOWER(p.descripcion) LIKE '%" . $word . "%'" : |
||
240 | "LOWER(p.descripcion) LIKE '%" . $word . "%'"; |
||
241 | } |
||
242 | $sql .= "))"; |
||
243 | } |
||
244 | } |
||
245 | |||
246 | switch (self::$orden) { |
||
247 | case 'desc_asc': |
||
248 | $sql .= " ORDER BY 2 ASC"; |
||
249 | break; |
||
250 | |||
251 | case 'price_desc': |
||
252 | $sql .= " ORDER BY 7 DESC"; |
||
253 | break; |
||
254 | |||
255 | case 'ref_asc': |
||
256 | $sql .= " ORDER BY 1 ASC"; |
||
257 | break; |
||
258 | |||
259 | case 'stock_desc': |
||
260 | $sql .= " ORDER BY 8 DESC"; |
||
261 | break; |
||
262 | } |
||
263 | |||
264 | $results = $dataBase->selectLimit($sql); |
||
265 | if (self::$vendido) { |
||
266 | static::setProductsLastPrice($dataBase, $results); |
||
267 | } |
||
268 | |||
269 | return $results; |
||
270 | } |
||
271 | |||
272 | protected static function idatributovalor(?int $id): string |
||
285 | } |
||
286 | |||
287 | protected static function modalClientes(Translator $i18n, string $url, User $user, ControllerPermissions $permissions): string |
||
332 | } |
||
333 | |||
334 | protected static function modalProductos(Translator $i18n): string |
||
374 | } |
||
375 | |||
376 | protected static function orden(Translator $i18n): string |
||
377 | { |
||
378 | return '<div class="input-group">' |
||
379 | . '<div class="input-group-prepend"><span class="input-group-text"><i class="fas fa-sort-amount-down-alt"></i></span></div>' |
||
380 | . '<select name="fp_orden" class="form-control" onchange="return salesFormAction(\'find-product\', \'0\');">' |
||
381 | . '<option value="">' . $i18n->trans('sort') . '</option>' |
||
382 | . '<option value="">------</option>' |
||
383 | . '<option value="ref_asc">' . $i18n->trans('reference') . '</option>' |
||
384 | . '<option value="desc_asc">' . $i18n->trans('description') . '</option>' |
||
385 | . '<option value="price_desc">' . $i18n->trans('price') . '</option>' |
||
386 | . '<option value="stock_desc">' . $i18n->trans('stock') . '</option>' |
||
387 | . '</select>' |
||
388 | . '</div>'; |
||
389 | } |
||
390 | |||
391 | protected static function setProductsLastPrice(DataBase $db, array &$items): void |
||
407 | } |
||
408 | } |
||
409 | |||
410 | private static function subfamilias(Familia $family, Translator $i18n, int $level = 1): string |
||
423 | } |
||
424 | } |
||
425 |