• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

AJenbo / agcms / 20972494104

13 Jan 2026 09:02PM UTC coverage: 53.72% (+0.2%) from 53.541%
20972494104

push

github

AJenbo
Upgrade codebase to support PHP 8.5 compatibility

247 of 340 new or added lines in 40 files covered. (72.65%)

6 existing lines in 5 files now uncovered.

2780 of 5175 relevant lines covered (53.72%)

13.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/application/inc/Http/Controllers/Admin/InvoiceController.php
1
<?php
2

3
namespace App\Http\Controllers\Admin;
4

5
use App\Countries;
6
use App\DTO\InvoiceFilter;
7
use App\Enums\InvoiceAction;
8
use App\Exceptions\Exception;
9
use App\Exceptions\InvalidInput;
10
use App\Http\Request;
11
use App\Models\Invoice;
12
use App\Models\User;
13
use App\Services\ConfigService;
14
use App\Services\DbService;
15
use App\Services\InvoicePdfService;
16
use App\Services\InvoiceService;
17
use App\Services\OrmService;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Response;
20

21
class InvoiceController extends AbstractAdminController
22
{
23
    /**
24
     * List of invoices.
25
     *
26
     * @throws Exception
27
     */
28
    public function index(Request $request): Response
29
    {
NEW
30
        $momssats = valstring($request->get('momssats'));
×
31
        if (!$momssats) {
×
32
            $momssats = null;
×
33
        }
34
        $selected = new InvoiceFilter(
×
35
            $request->query->getInt('id') ?: null,
×
36
            $request->query->getInt('y'),
×
37
            $request->query->getInt('m'),
×
NEW
38
            valstring($request->get('department') ?? ''),
×
NEW
39
            valstring($request->get('status', 'activ')),
×
NEW
40
            valstring($request->get('name') ?? ''),
×
NEW
41
            valstring($request->get('tlf') ?? ''),
×
NEW
42
            valstring($request->get('email') ?? ''),
×
43
            $momssats,
NEW
44
            valstring($request->get('clerk') ?? ''),
×
45
        );
46

47
        $user = $request->user();
×
48
        if (!$user) {
×
49
            throw new Exception('You need to be logged in to access invoices.');
×
50
        }
51

52
        $where = $this->generateFilterInvoiceBySelection($selected, $user);
×
53

54
        $db = app(DbService::class);
×
55

56
        $db->addLoadedTable('fakturas');
×
57
        $oldest = $db->fetchOne('SELECT `date` FROM `fakturas` ORDER BY `date`')['date'] ?? 'now';
×
58
        $oldest = strtotime($oldest);
×
59
        if ($oldest === false) {
×
60
            throw new Exception('Unable to get time from database server');
×
61
        }
62
        $oldest = date('Y', $oldest);
×
63

64
        $orm = app(OrmService::class);
×
65

66
        $invoices = $orm->getByQuery(Invoice::class, 'SELECT * FROM `fakturas`' . $where . ' ORDER BY `id` DESC');
×
67

68
        $data = [
×
69
            'title'         => _('Invoice list'),
×
70
            'currentUser'   => $user,
71
            'selected'      => $selected,
72
            'countries'     => Countries::getOrdered(),
×
73
            'departments'   => array_keys(ConfigService::getEmailConfigs()),
×
74
            'users'         => $orm->getByQuery(User::class, 'SELECT * FROM `users` ORDER BY `fullname`'),
×
75
            'invoices'      => $invoices,
76
            'years'         => range($oldest, date('Y')),
×
77
            'statusOptions' => [
78
                ''         => _('All'),
×
79
                'activ'    => _('Current'),
×
80
                'inactiv'  => _('Finalized'),
×
81
                'new'      => _('New'),
×
82
                'locked'   => _('Locked'),
×
83
                'pbsok'    => _('Ready'),
×
84
                'accepted' => _('Processed'),
×
85
                'giro'     => _('Giro'),
×
86
                'cash'     => _('Cash'),
×
87
                'pbserror' => _('Error'),
×
88
                'canceled' => _('Canceled'),
×
89
                'rejected' => _('Rejected'),
×
90
            ],
91
        ] + $this->basicPageData($request);
×
92

93
        return $this->render('admin/fakturas', $data);
×
94
    }
95

96
    /**
97
     * Generate an SQL where clause from a select array.
98
     */
99
    private function generateFilterInvoiceBySelection(InvoiceFilter $selected, User $user): string
100
    {
101
        if ($selected->id) {
×
102
            return 'WHERE `id` = ' . $selected->id;
×
103
        }
104

105
        $clerk = $selected->clerk;
×
106
        if (!$clerk && !$user->hasAccess(User::ADMINISTRATOR)) {
×
107
            $clerk = $user->getFullName();
×
108
        }
109

110
        $where = [];
×
111

112
        if ($selected->month && $selected->year) {
×
113
            $where[] = "`date` >= '" . $selected->year . '-' . $selected->month . "-01'";
×
114
            $where[] = "`date` <= '" . $selected->year . '-' . $selected->month . "-31'";
×
115
        } elseif ($selected->year) {
×
116
            $where[] = "`date` >= '" . $selected->year . "-01-01'";
×
117
            $where[] = "`date` <= '" . $selected->year . "-12-31'";
×
118
        }
119

120
        $db = app(DbService::class);
×
121

122
        if ($selected->department) {
×
123
            $where[] = '`department` = ' . $db->quote($selected->department);
×
124
        }
125
        if ($clerk
126
            && (!$user->hasAccess(User::ADMINISTRATOR) || $user->getFullName() === $clerk)
×
127
        ) {
128
            //Viewing your self
129
            $where[] = '(`clerk` = ' . $db->quote($clerk) . " OR `clerk` = '')";
×
130
        } elseif ($clerk) {
×
131
            //Viewing some one else
132
            $where[] = '`clerk` = ' . $db->quote($clerk);
×
133
        }
134

135
        if ('activ' === $selected->status) {
×
136
            $where[] = "`status` IN('new', 'locked', 'pbsok', 'pbserror')";
×
137
        } elseif ('inactiv' === $selected->status) {
×
138
            $where[] = "`status` NOT IN('new', 'locked', 'pbsok', 'pbserror')";
×
139
        } elseif ($selected->status) {
×
140
            $where[] = '`status` = ' . $db->quote($selected->status);
×
141
        }
142

143
        if ($selected->name) {
×
144
            $where[] = '`navn` LIKE ' . $db->quote('%' . $selected->name . '%');
×
145
        }
146

147
        if ($selected->tlf) {
×
148
            $where[] = '(`tlf1` LIKE ' . $db->quote('%' . $selected->tlf . '%')
×
149
                . ' OR `tlf2` LIKE ' . $db->quote('%' . $selected->tlf . '%') . ')';
×
150
        }
151

152
        if ($selected->email) {
×
153
            $where[] = '`email` LIKE ' . $db->quote('%' . $selected->email . '%');
×
154
        }
155

156
        if (null !== $selected->momssats) {
×
157
            $where[] = '`momssats` = ' . $db->quote($selected->momssats);
×
158
        }
159

160
        if (!$where) {
×
161
            return '';
×
162
        }
163

164
        return ' WHERE ' . implode(' AND ', $where);
×
165
    }
166

167
    /**
168
     * List of invoices.
169
     */
170
    public function validationList(Request $request): Response
171
    {
172
        $invoices = app(OrmService::class)->getByQuery(
×
173
            Invoice::class,
174
            "
175
            SELECT * FROM `fakturas`
176
            WHERE `transferred` = 0 AND `status` = 'accepted'
177
            ORDER BY `paydate` DESC, `id` DESC
178
            "
179
        );
180

181
        $data = [
×
182
            'title'    => _('Invoice validation'),
×
183
            'invoices' => $invoices,
184
        ] + $this->basicPageData($request);
×
185

186
        return $this->render('admin/fakturasvalidate', $data);
×
187
    }
188

189
    /**
190
     * Set payment transferred status.
191
     */
192
    public function validate(Request $request, int $id): JsonResponse
193
    {
194
        $user = $request->user();
×
195
        if (!$user || !$user->hasAccess(User::ADMINISTRATOR)) {
×
196
            throw new InvalidInput(_('You do not have permission to validate payments.'), Response::HTTP_FORBIDDEN);
×
197
        }
198

199
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
200
        if (!$invoice) {
×
201
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
202
        }
203

204
        $invoice->setTransferred($request->request->getBoolean('transferred'))->save();
×
205

206
        return new JsonResponse([]);
×
207
    }
208

209
    /**
210
     * Create a new invoice.
211
     *
212
     * @throws Exception
213
     */
214
    public function create(Request $request): JsonResponse
215
    {
216
        $user = $request->user();
×
217
        if (!$user) {
×
218
            throw new Exception('You need to be logged in to access invoices.');
×
219
        }
220

221
        $action = $request->getRequestString('action') ?? 'save';
×
222
        $action = InvoiceAction::from($action);
×
223
        $data = $request->request->all();
×
224
        unset($data['action']);
×
225

226
        $invoice = new Invoice(['clerk' => $user->getFullName()]);
×
227

228
        $invoiceService = new InvoiceService();
×
229
        $invoiceService->invoiceBasicUpdate($invoice, $user, $action, $data);
×
230

231
        if (InvoiceAction::Email === $action) {
×
232
            $invoiceService->sendInvoice($invoice);
×
233
        }
234

235
        return new JsonResponse(['id' => $invoice->getId()]);
×
236
    }
237

238
    /**
239
     * @throws Exception
240
     */
241
    public function update(Request $request, int $id): JsonResponse
242
    {
243
        $action = $request->getRequestString('action') ?? 'save';
×
244
        $action = InvoiceAction::from($action);
×
245

246
        $data = $request->request->all();
×
247
        unset($data['action']);
×
248

249
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
250
        if (!$invoice) {
×
251
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
252
        }
253

254
        $user = $request->user();
×
255
        if (!$user) {
×
256
            throw new Exception('You need to be logged in to access invoices.');
×
257
        }
258

259
        $invoiceService = new InvoiceService();
×
260
        $invoiceService->invoiceBasicUpdate($invoice, $user, $action, $data);
×
261

262
        if (InvoiceAction::Email === $action) {
×
263
            $invoiceService->sendInvoice($invoice);
×
264
        }
265

266
        return new JsonResponse(['type' => $action, 'status' => $invoice->getStatus()]);
×
267
    }
268

269
    /**
270
     * @throws Exception
271
     */
272
    public function clone(Request $request, int $id): JsonResponse
273
    {
274
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
275
        if (!$invoice) {
×
276
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
277
        }
278

279
        $invoice = clone $invoice;
×
280
        $user = $request->user();
×
281
        if (!$user) {
×
282
            throw new Exception('You need to be logged in to access invoices.');
×
283
        }
284

285
        $invoice->setClerk($user->getFullName())->save();
×
286

287
        return new JsonResponse(['id' => $invoice->getId()]);
×
288
    }
289

290
    /**
291
     * Send payment reminder.
292
     */
293
    public function sendReminder(Request $request, int $id): JsonResponse
294
    {
295
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
296
        if (!$invoice) {
×
297
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
298
        }
299

300
        $invoiceService = new InvoiceService();
×
301
        $invoiceService->sendInvoice($invoice);
×
302

303
        return new JsonResponse([]);
×
304
    }
305

306
    /**
307
     * Accept payment.
308
     */
309
    public function capturePayment(Request $request, int $id): JsonResponse
310
    {
311
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
312
        if (!$invoice) {
×
313
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
314
        }
315

316
        $invoiceService = new InvoiceService();
×
317
        $invoiceService->capturePayment($invoice);
×
318

319
        return new JsonResponse([]);
×
320
    }
321

322
    /**
323
     * Cancle payment.
324
     */
325
    public function annulPayment(Request $request, int $id): JsonResponse
326
    {
327
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
328
        if (!$invoice) {
×
329
            throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
330
        }
331

332
        $invoiceService = new InvoiceService();
×
333
        $invoiceService->annulPayment($invoice);
×
334

335
        return new JsonResponse([]);
×
336
    }
337

338
    /**
339
     * Display invoice.
340
     *
341
     * @throws Exception
342
     */
343
    public function invoice(Request $request, ?int $id = null): Response
344
    {
345
        $orm = app(OrmService::class);
×
346

347
        $invoice = null;
×
348
        if (null !== $id) {
×
349
            $invoice = $orm->getOne(Invoice::class, $id);
×
350
            if (!$invoice) {
×
351
                throw new InvalidInput(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
352
            }
353
        }
354

355
        $user = $request->user();
×
356
        if (!$user) {
×
357
            throw new Exception('You need to be logged in to access invoices.');
×
358
        }
359

360
        if ($invoice && !$invoice->getClerk()) {
×
361
            $invoice->setClerk($user->getFullName());
×
362
        }
363

364
        $data = [
×
365
            'title'       => $invoice ? _('Online Invoice #') . $invoice->getId() : _('Create invoice'),
×
366
            'invoice'     => $invoice,
367
            'currentUser' => $user,
368
            'users'       => $orm->getByQuery(User::class, 'SELECT * FROM `users` ORDER BY fullname'),
×
369
            'departments' => array_keys(ConfigService::getEmailConfigs()),
×
370
            'countries'   => Countries::getOrdered(),
×
371
        ] + $this->basicPageData($request);
×
372

373
        return $this->render('admin/faktura', $data);
×
374
    }
375

376
    /**
377
     * Show a pdf version of the invoice.
378
     */
379
    public function pdf(Request $request, int $id): Response
380
    {
381
        $invoice = app(OrmService::class)->getOne(Invoice::class, $id);
×
382
        if (!$invoice) {
×
383
            return new Response(_('Invoice not found.'), Response::HTTP_NOT_FOUND);
×
384
        }
385

386
        $invoicePdfService = new InvoicePdfService($invoice);
×
387
        $pdfData = $invoicePdfService->getStream();
×
388

389
        $header = [
×
390
            'Content-Type'        => 'application/pdf',
391
            'Content-Disposition' => 'inline; filename="Faktura-' . $invoice->getId() . '.pdf"',
×
392
        ];
393

394
        return new Response($pdfData, Response::HTTP_OK, $header);
×
395
    }
396
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc