· 5 years ago · Oct 12, 2019, 02:46 PM
1<?php
2
3namespace Guilty\Poweroffice\Services;
4
5use GuzzleHttp\Psr7\Response;
6use Guilty\Poweroffice\Exceptions\InvalidClientException;
7use Guilty\Poweroffice\Exceptions\TooManyRequestsException;
8use Guilty\Poweroffice\Exceptions\UnauthorizedException;
9use Guilty\Poweroffice\Sessions\SessionInterface;
10use GuzzleHttp\Client;
11
12class PowerofficeService
13{
14 /**
15 * @var \GuzzleHttp\Client
16 */
17 protected $client;
18
19 /**
20 * @var \Guilty\Poweroffice\Sessions\SessionInterface
21 */
22 protected $session;
23
24 protected $apiBaseUrl;
25 protected $authBaseUrl;
26
27 protected $applicationKey;
28 protected $clientKey;
29
30 protected $accessTokenPath = "/OAuth/Token";
31 protected $testMode;
32
33 /**
34 * @param \GuzzleHttp\Client $client
35 * @param string $applicationKey The application key
36 * @param string $clientKey The client key
37 * @param bool $testMode Should the service hit the test api or the live api, defaults to test mode (true)
38 */
39 public function __construct(Client $client, SessionInterface $session, $applicationKey, $clientKey, $testMode = true)
40 {
41 $this->client = $client;
42 $this->session = $session;
43 $this->applicationKey = $applicationKey;
44 $this->clientKey = $clientKey;
45
46 $testMode
47 ? $this->useTestMode()
48 : $this->useLiveMode();
49 }
50
51 public function isTestMode()
52 {
53 return $this->testMode;
54 }
55
56 protected function useLiveMode()
57 {
58 $this->testMode = false;
59 $this->apiBaseUrl = "https://api.poweroffice.net";
60 $this->authBaseUrl = "https://go.poweroffice.net";
61 }
62
63 protected function useTestMode()
64 {
65 $this->testMode = true;
66 $this->apiBaseUrl = "https://api-demo.poweroffice.net";
67 $this->authBaseUrl = "https://godemo.poweroffice.net";
68 }
69
70 protected function getAccessTokenUrl()
71 {
72 return $this->authBaseUrl . $this->accessTokenPath;
73 }
74
75 protected function getApiUrl($path)
76 {
77 return $this->apiBaseUrl . "/" . trim($path, "/");
78 }
79
80 protected function getAuthenticationCredentials()
81 {
82 return [$this->applicationKey, $this->clientKey];
83 }
84
85 protected function getAuthorizationHeader()
86 {
87 return [
88 'Authorization' => 'Bearer ' . $this->session->getAccessToken(),
89 ];
90 }
91
92 public function refreshIfExpired()
93 {
94 if ($this->session->hasExpired() && $this->session->canRefresh()) {
95 $this->refreshAccessCode();
96 }
97 }
98
99 /**
100 * @throws \Guilty\Poweroffice\Exceptions\InvalidClientException
101 */
102 public function refreshAccessCode()
103 {
104 $this->performAuthenticationRequest([
105 "grant_type" => "refresh_token",
106 "refresh_token" => $this->session->getRefreshToken(),
107 ]);
108 }
109
110 /**
111 * @throws \Guilty\Poweroffice\Exceptions\InvalidClientException
112 */
113 public function getAccessToken()
114 {
115 $this->performAuthenticationRequest([
116 "grant_type" => "client_credentials",
117 ]);
118 }
119
120 /**
121 * @param array $params
122 * @throws \Guilty\Poweroffice\Exceptions\InvalidClientException
123 */
124 public function performAuthenticationRequest($params)
125 {
126 $request = $this->client->post($this->getAccessTokenUrl(), [
127 'http_errors' => false,
128 'Accept' => 'application/json',
129 "auth" => $this->getAuthenticationCredentials(),
130 "form_params" => $params,
131 ]);
132
133 $response = json_decode($request->getBody(), true);
134
135 if ($request->getStatusCode() === 400 && $response["error"] == "invalid_client") {
136 throw new InvalidClientException("The client is invalid");
137 }
138
139 $this->session->setFromResponse($response);
140 }
141
142 /**
143 * @param string $method
144 * @param string $path
145 * @param array|null $params
146 * @throws \Guilty\PowerOffice\Exceptions\UnauthorizedException
147 * @throws \Guilty\PowerOffice\Exceptions\TooManyRequestsException
148 * @throws \GuzzleHttp\Exception\GuzzleException
149 * @return array
150 */
151 public function performRequest($method, $path, $params = [])
152 {
153 $options = array_merge([
154 'headers' => $this->getAuthorizationHeader(),
155 'Accept' => 'application/json',
156 'http_errors' => false,
157 ], $params);
158
159 /** @var \GuzzleHttp\Psr7\Response $request */
160 $request = $this->client->requestAsync($method, $this->getApiUrl($path), $options);
161 $response = json_decode($request->getBody(), true);
162
163 if ($request->getStatusCode() == 401) {
164 throw new UnauthorizedException("The request was denied because you were not authorized");
165 }
166
167 if ($request->getStatusCode() == 429) {
168 throw new TooManyRequestsException("Too many requests");
169 }
170
171 return $response;
172 }
173
174
175 // Customer
176 //--------------------------------------------------------------------------------------------------
177 public function createCustomer($params)
178 {
179 return $this->performRequest("post", "/Customer", $params);
180 }
181
182 public function getCustomers($params = [])
183 {
184 return $this->performRequest("get", "/Customer", $params);
185 }
186
187 public function getCustomer($id)
188 {
189 return $this->performRequest("get", "/Customer/$id");
190 }
191
192 public function deleteCustomer($id)
193 {
194 return $this->performRequest("delete", "/Customer/$id");
195 }
196
197
198 // Outgoing Invoice
199 //--------------------------------------------------------------------------------------------------
200 public function createOutgoingInvoice($params)
201 {
202 return $this->performRequest("post", "/OutgoingInvoice", $params);
203 }
204
205 public function getOutgoingInvoices($params = [])
206 {
207 return $this->performRequest("get", "/OutgoingInvoice/List", $params);
208 }
209
210 public function deleteOutgoingInvoice($id)
211 {
212 return $this->performRequest("delete", "/OutgoingInvoice/{$id}");
213 }
214
215 public function getOutgoingInvoice($id)
216 {
217 return $this->performRequest("get", "/OutgoingInvoice/$id");
218 }
219
220
221 // Recurring Invoice
222 //--------------------------------------------------------------------------------------------------
223 public function createRecurringInvoice($params)
224 {
225 return $this->performRequest("post", "/RecurringInvoice", $params);
226 }
227
228 public function getRecurringInvoices($params = [])
229 {
230 return $this->performRequest("get", "/RecurringInvoice/List", $params);
231 }
232
233 public function deleteRecurringInvoice($id)
234 {
235 return $this->performRequest("delete", "/RecurringInvoice/{$id}");
236 }
237
238 public function getRecurringInvoice($id)
239 {
240 return $this->performRequest("get", "/RecurringInvoice/$id");
241 }
242
243
244 // Product
245 //--------------------------------------------------------------------------------------------------
246 public function getProducts($params = [])
247 {
248 return $this->performRequest("get", "/Product", $params);
249 }
250
251 public function getProduct($id)
252 {
253 return $this->performRequest("get", "/Product/$id");
254 }
255
256 public function createProduct($params)
257 {
258 return $this->performRequest("post", "/Product", $params);
259 }
260
261 public function deleteProduct($id)
262 {
263 return $this->performRequest("delete", "/Product/$id");
264 }
265
266
267 // Product Group
268 //--------------------------------------------------------------------------------------------------
269 public function getProductGroups($params = [])
270 {
271 return $this->performRequest("get", "/ProductGroup", $params);
272 }
273
274 public function getProductGroup($id)
275 {
276 return $this->performRequest("get", "/ProductGroup/$id");
277 }
278
279 public function createProductGroup($params)
280 {
281 return $this->performRequest("post", "/ProductGroup", $params);
282 }
283
284 public function deleteProductGroup($id)
285 {
286 return $this->performRequest("delete", "/ProductGroup/$id");
287 }
288
289
290 // Contact Group
291 //--------------------------------------------------------------------------------------------------
292 public function getContactGroups($params = [])
293 {
294 return $this->performRequest("get", "/ContactGroup", $params);
295 }
296
297 public function getContactGroup($id)
298 {
299 return $this->performRequest("get", "/ContactGroup/$id");
300 }
301
302 public function createContactGroup($params)
303 {
304 return $this->performRequest("post", "/ContactGroup", $params);
305 }
306
307 public function deleteContactGroup($id)
308 {
309 return $this->performRequest("delete", "/ContactGroup/$id");
310 }
311
312 // Journal Entry Voucher
313 //--------------------------------------------------------------------------------------------------
314 public function getJournalEntryVouchers($params = [])
315 {
316 return $this->performRequest("get", "/JournalEntryVoucher", $params);
317 }
318
319 public function getJournalEntryVoucher($id)
320 {
321 return $this->performRequest("get", "/JournalEntryVoucher/$id");
322 }
323
324 public function createJournalEntryVoucher($params)
325 {
326 return $this->performRequest("post", "/JournalEntryVoucher", $params);
327 }
328
329 public function deleteJournalEntryVoucher($id)
330 {
331 return $this->performRequest("delete", "/JournalEntryVoucher/$id");
332 }
333
334
335 // Client Bank Account
336 //--------------------------------------------------------------------------------------------------
337 public function getClientBankAccounts($params = [])
338 {
339 return $this->performRequest("get", "/ClientBankAccount", $params);
340 }
341
342 public function getClientBankAccount($id)
343 {
344 return $this->performRequest("get", "/ClientBankAccount/$id");
345 }
346
347 public function createClientBankAccount($params)
348 {
349 return $this->performRequest("post", "/ClientBankAccount", $params);
350 }
351
352 public function deleteClientBankAccount($id)
353 {
354 return $this->performRequest("delete", "/ClientBankAccount/$id");
355 }
356
357
358 // Branding Theme
359 //--------------------------------------------------------------------------------------------------
360 public function getBrandingThemes($params = [])
361 {
362 return $this->performRequest("get", "/BrandingTheme", $params);
363 }
364
365 public function getBrandingTheme($id)
366 {
367 return $this->performRequest("get", "/BrandingTheme/{$id}");
368 }
369
370
371 // Client
372 //--------------------------------------------------------------------------------------------------
373 public function getClient($params = [])
374 {
375 return $this->performRequest("get", "/BrandingTheme", $params);
376 }
377
378 public function updateClient($params = [])
379 {
380 return $this->performRequest("get", "/BrandingTheme", $params);
381 }
382
383
384 // Vat Code
385 //--------------------------------------------------------------------------------------------------
386 public function getVatCodes($params = [])
387 {
388 return $this->performRequest("get", "/VatCode", $params);
389 }
390
391 public function getVatCode($id)
392 {
393 return $this->performRequest("get", "/VatCode/{$id}");
394 }
395
396 public function getVatCodeChartOfAccount($vatCode, $params = [])
397 {
398 return $this->performRequest("get", "VatCode/chartofaccount/{$vatCode}", $params);
399 }
400
401
402 // Party Bank Account
403 //--------------------------------------------------------------------------------------------------
404 public function getPartyBankAccounts($params = [])
405 {
406 return $this->performRequest("get", "/PartyBankAccount", $params);
407 }
408
409
410 // Party Contact Person
411 //--------------------------------------------------------------------------------------------------
412 public function getPartyContactPeople($params = [])
413 {
414 return $this->performRequest("get", "/PartyContactPerson", $params);
415 }
416
417
418 // General Account Ledger
419 //--------------------------------------------------------------------------------------------------
420 public function getGeneralLedgerAccounts($params = [])
421 {
422 return $this->performRequest("get", "/GeneralLedgerAccount", $params);
423 }
424
425 public function createGeneralLedgerAccount($params = [])
426 {
427 return $this->performRequest("post", "/GeneralLedgerAccount", $params);
428 }
429
430 public function getGeneralLedgerAccount($id)
431 {
432 return $this->performRequest("get", "/GeneralLedgerAccount/{$id}");
433 }
434
435 public function deleteGeneralLedgerAccount($id)
436 {
437 return $this->performRequest("delete", "/GeneralLedgerAccount/{$id}");
438 }
439
440
441 // General Account Ledger
442 //--------------------------------------------------------------------------------------------------
443 public function getInvoiceAttachments($params = [])
444 {
445 return $this->performRequest("get", "/InvoiceAttachment", $params);
446 }
447
448 public function createInvoiceAttachment($params = [])
449 {
450 return $this->performRequest("post", "/InvoiceAttachment", $params);
451 }
452
453 public function getInvoiceAttachment($id)
454 {
455 return $this->performRequest("get", "/InvoiceAttachment/{$id}");
456 }
457
458 public function deleteInvoiceAttachment($id)
459 {
460 return $this->performRequest("delete", "/InvoiceAttachment/{$id}");
461 }
462
463
464 // Payroll Pay Item
465 //--------------------------------------------------------------------------------------------------
466 public function getPayrollPayItem($params = [])
467 {
468 return $this->performRequest("get", "/Payroll/PayItem", $params);
469 }
470
471
472 // Payroll Salary Line
473 //--------------------------------------------------------------------------------------------------
474 public function getPayrollSalaryLines($params = [])
475 {
476 return $this->performRequest("get", "/Payroll/SalaryLine", $params);
477 }
478
479 public function createPayrollSalaryLine($params = [])
480 {
481 return $this->performRequest("post", "/Payroll/SalaryLine", $params);
482 }
483
484 public function getPayrollSalaryLine($id)
485 {
486 return $this->performRequest("get", "/Payroll/SalaryLine/{$id}");
487 }
488
489 public function deletePayrollSalaryLine($id)
490 {
491 return $this->performRequest("delete", "/Payroll/SalaryLine/{$id}");
492 }
493
494
495 // Reporting Account Transactions
496 //--------------------------------------------------------------------------------------------------
497 public function getAccountTransactions(\DateTime $fromDate, \DateTime $toDate, $params = [])
498 {
499 $params["query"]["fromDate"] = $fromDate->format("Y-m-d H:i:s");
500 $params["query"]["toDate"] = $toDate->format("Y-m-d H:i:s");
501
502 return $this->performRequest("get", "/Reporting/AccountTransactions", $params);
503 }
504
505 public function getAccountTransactionsForAccountCode($accountCode, \DateTime $fromDate, \DateTime $toDate, $params = [])
506 {
507 $params["query"]["fromDate"] = $fromDate->format("Y-m-d H:i:s");
508 $params["query"]["toDate"] = $toDate->format("Y-m-d H:i:s");
509
510 return $this->performRequest("get", "/Reporting/AccountTransactions/{$accountCode}", $params);
511 }
512
513
514 // Blob
515 //--------------------------------------------------------------------------------------------------
516 public function getBlobVoucherEhf($voucherNumber)
517 {
518 return $this->performRequest("get", "/Blob/VoucherEhf/{$voucherNumber}/");
519 }
520
521 public function getBlobVoucherEhfPage($voucherNumber, $pageNumber)
522 {
523 return $this->performRequest("get", "/Blob/VoucherEhf/{$voucherNumber}/{$pageNumber}");
524 }
525
526
527 // Externally Deliverable Invoice
528 //--------------------------------------------------------------------------------------------------
529 public function getExternallyDeliverableInvoices($params = [])
530 {
531 return $this->performRequest("get", "/ExternallyDeliverableInvoice", $params);
532 }
533
534 // TODO(12 mar 2019) ~ Helge: Make helper for sending this
535 public function markExternallyDeliverableInvoiceAsDelivered($params = [])
536 {
537 return $this->performRequest("post", "/ExternallyDeliverableInvoice/delivered/", $params);
538 }
539
540 public function getExternallyDeliverableInvoicesEhf($invoiceId)
541 {
542 return $this->performRequest("get", "/ExternallyDeliverableInvoice/InvoiceEhf/{$invoiceId}");
543 }
544
545
546
547 // Reporting Usage
548 //--------------------------------------------------------------------------------------------------
549 public function getReportingUsage(\DateTime $fromDate, \DateTime $toDate, $params = [])
550 {
551 $params["query"]["fromDate"] = $fromDate->format("Y-m-d H:i:s");
552 $params["query"]["toDate"] = $toDate->format("Y-m-d H:i:s");
553
554 return $this->performRequest("get", "/Reporting/Usage", $params);
555 }
556
557
558 // Reporting Trial
559 //--------------------------------------------------------------------------------------------------
560 public function getReportingTrialBalance(\DateTime $date = null, $params = [])
561 {
562 $params["query"]["date"] = $date->format("Y-m-d H:i:s");
563
564 return $this->performRequest("get", "/Reporting/TrialBalance/", $params);
565 }
566
567
568 // Bank Transfer
569 //--------------------------------------------------------------------------------------------------
570 public function getBankTransfers($params = [])
571 {
572 return $this->performRequest("get", "/Bank/BankTransfer", $params);
573 }
574
575 public function getBankTransfer($id)
576 {
577 return $this->performRequest("get", "/Bank/BankTransfer/{$id}");
578 }
579
580 public function createBankTransfer($params = [])
581 {
582 return $this->performRequest("post", "/Bank/BankTransfer", $params);
583 }
584
585 public function deleteBankTransfer($id)
586 {
587 return $this->performRequest("delete", "/Bank/BankTransfer/{$id}");
588 }
589
590
591 // Department
592 //--------------------------------------------------------------------------------------------------
593 public function getDepartments($params = [])
594 {
595 return $this->performRequest("get", "/Department", $params);
596 }
597
598 public function getDepartment($id)
599 {
600 return $this->performRequest("get", "/Department/{$id}");
601 }
602
603 public function createDepartment($params = [])
604 {
605 return $this->performRequest("post", "/Department", $params);
606 }
607
608 public function deleteDepartment($id)
609 {
610 return $this->performRequest("delete", "/Department/{$id}");
611 }
612
613
614 // Project Activity
615 //--------------------------------------------------------------------------------------------------
616 public function getProjectActivities($params = [])
617 {
618 return $this->performRequest("get", "/ProjectActivity", $params);
619 }
620
621 public function getProjectActivity($id)
622 {
623 return $this->performRequest("get", "/ProjectActivity/{$id}");
624 }
625
626
627 // Project Team Member
628 //--------------------------------------------------------------------------------------------------
629 public function getProjectTeamMembers($params = [])
630 {
631 return $this->performRequest("get", "/ProjectTeamMember", $params);
632 }
633
634 public function getProjectTeamMember($id)
635 {
636 return $this->performRequest("get", "/ProjectTeamMember/{$id}");
637 }
638
639
640 // Location
641 //--------------------------------------------------------------------------------------------------
642 public function getLocations($params = [])
643 {
644 return $this->performRequest("get", "/Location", $params);
645 }
646
647 public function getLocation($id)
648 {
649 return $this->performRequest("get", "/Location/{$id}");
650 }
651
652 public function createLocation($params = [])
653 {
654 return $this->performRequest("post", "/Location", $params);
655 }
656
657 public function deleteLocation($id)
658 {
659 return $this->performRequest("delete", "/Location/{$id}");
660 }
661
662
663 // Time Tracking Activity
664 //--------------------------------------------------------------------------------------------------
665 public function getTimeTrackingActivities($params = [])
666 {
667 return $this->performRequest("get", "/TimeTracking/Activity", $params);
668 }
669
670 public function getTimeTrackingActivity($id)
671 {
672 return $this->performRequest("get", "/TimeTracking/Activity/{$id}");
673 }
674
675 public function createTimeTrackingActivity($params = [])
676 {
677 return $this->performRequest("post", "/TimeTracking/Activity", $params);
678 }
679
680 public function deleteTimeTrackingActivity($id)
681 {
682 return $this->performRequest("delete", "/TimeTracking/Activity/{$id}");
683 }
684
685
686 // Time Tracking Hour Type
687 //--------------------------------------------------------------------------------------------------
688 public function getTimeTrackingHourTypes($params = [])
689 {
690 return $this->performRequest("get", "/TimeTracking/HourType", $params);
691 }
692
693 public function getTimeTrackingHourType($id)
694 {
695 return $this->performRequest("get", "/TimeTracking/HourType/{$id}");
696 }
697
698 public function createTimeTrackingHourType($params = [])
699 {
700 return $this->performRequest("post", "/TimeTracking/HourType", $params);
701 }
702
703 public function deleteTimeTrackingHourType($id)
704 {
705 return $this->performRequest("delete", "/TimeTracking/HourType/{$id}");
706 }
707
708
709 // Time Tracking Entry
710 //--------------------------------------------------------------------------------------------------
711 public function getTimeTrackingEntries($params = [])
712 {
713 return $this->performRequest("get", "/TimeTracking/TimeTrackingEntry", $params);
714 }
715
716 public function getTimeTrackingEntry($id)
717 {
718 return $this->performRequest("get", "/TimeTracking/TimeTrackingEntry/{$id}");
719 }
720
721 public function createTimeTrackingEntry($params = [])
722 {
723 return $this->performRequest("post", "/TimeTracking/TimeTrackingEntry", $params);
724 }
725
726 public function deleteTimeTrackingEntry($id)
727 {
728 return $this->performRequest("delete", "/TimeTracking/TimeTrackingEntry/{$id}");
729 }
730
731
732 // Subledger Number Serie
733 //--------------------------------------------------------------------------------------------------
734 public function getSubledgerNumberSeries($params = [])
735 {
736 return $this->performRequest("get", "/SubledgerNumberSeries", $params);
737 }
738
739 public function getSubledgerNumberSerie($id)
740 {
741 return $this->performRequest("get", "/SubledgerNumberSeries/{$id}");
742 }
743
744
745 // Misc
746 //--------------------------------------------------------------------------------------------------
747 public function getInvoiceDeliveryTypes()
748 {
749 return [
750 [
751 "name" => "None",
752 "value" => 0,
753 "description" => "No delivery type - error report value only",
754 ],
755 [
756 "name" => "PdfByEmail",
757 "value" => 1,
758 "description" => "Invoice will be delivered as email with PDF as attachment",
759 ],
760 [
761 "name" => "Print",
762 "value" => 2,
763 "description" => "Invoice will be printed",
764 ],
765 [
766 "name" => "EHF",
767 "value" => 3,
768 "description" => "Invoice will be delivered over EHF",
769 ],
770 [
771 "name" => "AvtaleGiro",
772 "value" => 4,
773 "description" => "The will be delivered over AvtaleGiro",
774 ],
775 [
776 "name" => "External",
777 "value" => 5,
778 "description" => "The will be delivered over an external third party integration",
779 ],
780 ];
781 }
782}