PluginProbe
Moloni / trunk
Moloni vtrunk
5.0.10 5.0.09 5.0.08 5.0.07 5.0.06 trunk 0.4.0.00 0.4.8.1 3.0.10 3.0.11 3.0.35 3.0.36 3.0.37 3.0.38 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.0.46 3.0.47 3.0.48 3.0.49 3.0.50 All 98 releases
moloni / src / Plugin.php

Plugin.php in Moloni trunk, at src/Plugin.php

352 lines 10.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /** @noinspection PhpPropertyOnlyWrittenInspection */
4
5 namespace Moloni;
6
7 use Exception;
8 use WC_Order;
9 use Moloni\Exceptions\Core\MoloniException;
10 use Moloni\Exceptions\DocumentError;
11 use Moloni\Exceptions\DocumentWarning;
12 use Moloni\Helpers\Context;
13 use Moloni\Helpers\Logger;
14 use Moloni\Hooks\Ajax;
15 use Moloni\Models\Logs;
16 use Moloni\Services\Documents\DownloadDocument;
17 use Moloni\Services\Documents\OpenDocument;
18 use Moloni\Services\Orders\CreateMoloniDocument;
19 use Moloni\Services\Orders\DiscardOrder;
20 use Moloni\Services\Stocks\SyncStockFromMoloni;
21
22 /**
23 * Main constructor
24 * Class Plugin
25 * @package Moloni
26 */
27 class Plugin
28 {
29 private $action = '';
30 private $activeTab = '';
31
32 /**
33 * Constructor
34 */
35 public function __construct()
36 {
37 $this->onStart();
38 $this->actions();
39 $this->crons();
40 }
41
42 // Privates //
43
44 /**
45 * Place to run code before starting
46 *
47 * @return void
48 */
49 private function onStart()
50 {
51 $this->action = sanitize_text_field($_REQUEST['action'] ?? '');
52 $this->activeTab = sanitize_text_field($_GET['tab'] ?? '');
53
54 Storage::$USES_NEW_ORDERS_SYSTEM = Context::isNewOrdersSystemEnabled();
55 Storage::$LOGGER = new Logger();
56 }
57
58 /**
59 * Start actions
60 *
61 * @return void
62 */
63 private function actions(): void
64 {
65 /** Admin pages */
66 new Menus\Admin($this);
67 new Ajax($this);
68
69 /** Hooks */
70 new Hooks\WoocommerceInitialize($this);
71 new Hooks\ProductUpdate($this);
72 new Hooks\ProductView($this);
73 new Hooks\OrderView($this);
74 new Hooks\OrderStatusChanged($this);
75 new Hooks\OrderList($this);
76 new Hooks\OrderRefunded($this);
77 new Hooks\OrderDetails($this);
78 new Hooks\UpgradeProcess($this);
79 }
80
81 /**
82 * Setting up the crons if needed
83 */
84 private function crons(): void
85 {
86 add_filter('cron_schedules', '\Moloni\Crons::addCronInterval');
87 add_action('moloniProductsSync', '\Moloni\Crons::productsSync');
88
89 if (!wp_next_scheduled('moloniProductsSync')) {
90 wp_schedule_event(time(), 'everyficeminutes', 'moloniProductsSync');
91 }
92 }
93
94 // Publics //
95
96 /**
97 * Main function
98 * This will run when accessing the page "moloni" and the routing should be done here with and $_GET['action']
99 */
100 public function run(): void
101 {
102 try {
103 $authenticated = Start::login();
104
105 /** If the user is not logged in show the login form */
106 if ($authenticated) {
107 switch ($this->action) {
108 case 'remInvoice':
109 $this->removeOrder();
110 break;
111 case 'remInvoiceAll':
112 $this->removeOrdersAll();
113 break;
114 case 'genInvoice':
115 $this->createDocument();
116 break;
117 case 'syncStocks':
118 $this->syncStocks();
119 break;
120 case 'remLogs':
121 $this->removeLogs();
122 break;
123 case 'getInvoice':
124 $this->openDocument();
125 break;
126 case 'downloadDocument':
127 $this->downloadDocument();
128 break;
129 }
130 }
131 } catch (MoloniException $error) {
132 $pluginErrorException = $error;
133 }
134
135 if (isset($authenticated) && $authenticated && !wp_doing_ajax()) {
136 include MOLONI_TEMPLATE_DIR . 'MainContainer.php';
137 }
138 }
139
140 // Actions //
141
142 /**
143 * Create a single document from order
144 *
145 * @throws DocumentError
146 * @throws DocumentWarning
147 */
148 private function createDocument(): void
149 {
150 $service = new CreateMoloniDocument((int)$_REQUEST['id']);
151 $orderName = $service->getOrderNumber();
152
153 try {
154 $service->run();
155 } catch (DocumentWarning $e) {
156 Storage::$LOGGER->alert(
157 str_replace('{0}', $orderName, __('Houve um alerta ao gerar o documento ({0})')),
158 [
159 'message' => $e->getMessage(),
160 'request' => $e->getData()
161 ]
162 );
163
164 throw $e;
165 } catch (DocumentError $e) {
166 Storage::$LOGGER->error(
167 str_replace('{0}', $orderName, __('Houve um erro ao gerar o documento ({0})')),
168 [
169 'message' => $e->getMessage(),
170 'request' => $e->getData()
171 ]
172 );
173
174 throw $e;
175 }
176
177 if ($service->getDocumentId()) {
178 $adminUrl = admin_url('admin.php?page=moloni&action=getInvoice&id=' . $service->getDocumentId());
179
180 $html = ' <a href="' . $adminUrl . '" target="_BLANK">';
181 $html .= ' Ver documento';
182 $html .= '</a>';
183
184 add_settings_error('moloni', 'moloni-document-created-success', __('O documento foi gerado!') . $html, 'updated');
185 }
186 }
187
188 /**
189 * Open Moloni document
190 *
191 * @return void
192 */
193 private function openDocument(): void
194 {
195 $documentId = (int)$_REQUEST['id'];
196
197 if ($documentId > 0) {
198 new OpenDocument($documentId);
199 }
200
201 add_settings_error('moloni', 'moloni-document-not-found', __('Documento não encontrado'));
202 }
203
204 /**
205 * Download Moloni document
206 *
207 * @return void
208 */
209 private function downloadDocument(): void
210 {
211 $documentId = (int)$_REQUEST['id'];
212
213 if ($documentId > 0) {
214 new DownloadDocument($documentId);
215 }
216 }
217
218 /**
219 * Delete logs
220 *
221 * @return void
222 */
223 private function removeLogs(): void
224 {
225 Logs::removeOlderLogs();
226
227 add_settings_error('moloni', 'moloni-rem-logs', __('A limpeza de logs foi concluída.'), 'updated');
228 }
229
230 /**
231 * Discard single order from pending list
232 *
233 * @return void
234 */
235 private function removeOrder(): void
236 {
237 $orderId = (int)$_GET['id'];
238
239 if (isset($_GET['confirm']) && sanitize_text_field($_GET['confirm']) === 'true') {
240 $order = wc_get_order($orderId);
241
242 $service = new DiscardOrder($order);
243 $service->run();
244 $service->saveLog();
245
246 add_settings_error(
247 'moloni',
248 'moloni-order-remove-success',
249 sprintf(__('A encomenda foi descartada (%s)'), $orderId),
250 'updated'
251 );
252 } else {
253 add_settings_error(
254 'moloni',
255 'moloni-order-remove',
256 __('Confirma que pretende marcar a encomenda ' . $orderId . " como paga? <a href='" . admin_url('admin.php?page=moloni&action=remInvoice&confirm=true&id=' . $orderId) . "'>Sim confirmo!</a>")
257 );
258 }
259 }
260
261 /**
262 * Discard all orders from pending list
263 *
264 * @return void
265 */
266 private function removeOrdersAll(): void
267 {
268 if (isset($_GET['confirm']) && sanitize_text_field($_GET['confirm']) === 'true') {
269 /** @var WC_Order[] $allOrders */
270 $allOrders = Models\PendingOrders::getAllAvailable();
271
272 if (!empty($allOrders)) {
273 foreach ($allOrders as $order) {
274 $order->add_meta_data('_moloni_sent', '-1');
275 $order->add_order_note(__('Encomenda marcada como gerada'));
276 $order->save();
277 }
278
279 $msg = __('Todas as encomendas foram marcadas como geradas!');
280
281 Storage::$LOGGER->info($msg);
282 add_settings_error('moloni', 'moloni-order-all-remove-success', $msg, 'updated');
283 } else {
284 add_settings_error('moloni', 'moloni-order-all-remove-not-found', __('Não foram encontradas encomendas por gerar'));
285 }
286 } else {
287 add_settings_error(
288 'moloni', 'moloni-order-remove', __("Confirma que pretende marcar todas as encomendas como já geradas? <a href='" . admin_url('admin.php?page=moloni&action=remInvoiceAll&confirm=true') . "'>Sim confirmo!</a>")
289 );
290 }
291 }
292
293 /**
294 * Force stock synchronization
295 *
296 * @return void
297 */
298 private function syncStocks(): void
299 {
300 $date = isset($_GET['since']) ? sanitize_text_field($_GET['since']) : gmdate('Y-m-d', strtotime('-1 week'));
301
302 try {
303 $service = new SyncStockFromMoloni($date);
304 $service->run();
305
306 if ($service->countUpdated() > 0) {
307 $message = sprintf(__('Foram atualizados %d artigos.'), $service->countUpdated());
308
309 add_settings_error('moloni', 'moloni-sync-stocks-updated', $message, 'updated');
310 }
311
312 if ($service->countEqual() > 0) {
313 $message = sprintf(__('Existem %d artigos com stock igual.'), $service->countEqual());
314
315 add_settings_error('moloni', 'moloni-sync-stocks-equal', $message, 'updated');
316 }
317
318 if ($service->countNotFound() > 0) {
319 $message = sprintf(__('Não foram encontrados no WooCommerce %d artigos.'), $service->countNotFound());
320
321 add_settings_error('moloni', 'moloni-sync-stocks-not-found', $message);
322 }
323
324 if ($service->countLocked() > 0) {
325 $message = sprintf(__('Foram bloqueados %d artigos.'), $service->countLocked());
326
327 add_settings_error('moloni', 'moloni-sync-stocks-locked', $message);
328 }
329
330 if ($service->countFoundRecord() > 0) {
331 Storage::$LOGGER->info(__('Sincronização de stock manual'), [
332 'action' => 'stock:sync:manual',
333 'since' => $service->getSince(),
334 'equal' => $service->getEqual(),
335 'not_found' => $service->getNotFound(),
336 'get_updated' => $service->getUpdated(),
337 'get_locked' => $service->getLocked(),
338 ]);
339 }
340 } catch (Exception $ex) {
341 $message = __('Erro fatal');
342
343 add_settings_error('moloni', 'moloni-sync-stocks-error', $message);
344
345 Storage::$LOGGER->critical($message, [
346 'action' => 'stock:sync:manual:error',
347 'exception' => $ex->getMessage()
348 ]);
349 }
350 }
351 }
352