From 51566a301f52d0845c8afb39d652da5cebf2e0b4 Mon Sep 17 00:00:00 2001 From: Felix Ruf Date: Fri, 11 Aug 2023 16:31:35 +0200 Subject: [PATCH] added api routes for adding cash, getting the transaction history and the initial process for settlement. Also added corresponding services, views and components --- .../Controller/AccountingBookController.php | 15 ++-- .../Controller/CostSheetController.php | 19 ++++- .../Controller/Payment/CashController.php | 62 ++++++++++++++ .../Resources/config/routing.yml | 19 +++-- .../MealBundle/Resources/config/routing.yml | 8 ++ src/Resources/src/api/getProfileWithHash.ts | 16 ++++ .../src/api/getTransactionHistory.ts | 16 ++++ src/Resources/src/api/postCashPayment.ts | 13 +++ src/Resources/src/api/postSettlement.ts | 2 +- .../cashRegister/CashRegisterTable.vue | 76 +++++++++++++++++ .../src/components/costs/CashPaymentPanel.vue | 40 +++++++++ .../src/components/costs/CashRegisterLink.vue | 4 +- .../src/components/costs/CostsHeader.vue | 2 + .../src/components/costs/CostsTable.vue | 2 +- .../components/costs/CostsTableActions.vue | 22 ++++- src/Resources/src/components/misc/Table.vue | 26 ++++-- src/Resources/src/locales/de.json | 5 +- src/Resources/src/locales/en.json | 5 +- src/Resources/src/router.ts | 19 +++++ src/Resources/src/stores/accountingStore.ts | 85 +++++++++++++++++++ src/Resources/src/stores/costsStore.ts | 19 ++++- src/Resources/src/stores/profilesStore.ts | 19 ++++- src/Resources/src/views/CashRegister.vue | 31 +++++++ src/Resources/src/views/CostsSettlement.vue | 25 ++++++ 24 files changed, 512 insertions(+), 38 deletions(-) create mode 100644 src/Mealz/AccountingBundle/Controller/Payment/CashController.php create mode 100644 src/Resources/src/api/getProfileWithHash.ts create mode 100644 src/Resources/src/api/getTransactionHistory.ts create mode 100644 src/Resources/src/api/postCashPayment.ts create mode 100644 src/Resources/src/components/cashRegister/CashRegisterTable.vue create mode 100644 src/Resources/src/components/costs/CashPaymentPanel.vue create mode 100644 src/Resources/src/stores/accountingStore.ts create mode 100644 src/Resources/src/views/CashRegister.vue create mode 100644 src/Resources/src/views/CostsSettlement.vue diff --git a/src/Mealz/AccountingBundle/Controller/AccountingBookController.php b/src/Mealz/AccountingBundle/Controller/AccountingBookController.php index 10000fdcd..620222b42 100644 --- a/src/Mealz/AccountingBundle/Controller/AccountingBookController.php +++ b/src/Mealz/AccountingBundle/Controller/AccountingBookController.php @@ -11,6 +11,7 @@ use Qipsius\TCPDFBundle\Controller\TCPDFController; use ReflectionException; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; /** @@ -18,7 +19,7 @@ */ class AccountingBookController extends BaseController { - public function list(TransactionRepositoryInterface $transactionRepo): Response + public function list(TransactionRepositoryInterface $transactionRepo): JsonResponse { // Get first and last day of previous month $minDateFirst = new DateTime('first day of previous month'); @@ -42,12 +43,12 @@ public function list(TransactionRepositoryInterface $transactionRepo): Response // Get array of users with their amount of transactions in actual month $users = $transactionRepo->findUserDataAndTransactionAmountForGivenPeriod($minDate, $maxDate); - return $this->render('MealzAccountingBundle:Accounting/Admin:accountingBook.html.twig', [ - 'headingFirst' => $headingFirst, - 'heading' => $heading, - 'usersFirst' => $usersFirst, - 'users' => $users, - ]); + return new JsonResponse([ + 'lastMonth' => $headingFirst, + 'thisMonth' => $heading, + 'usersLastMonth' => $usersFirst, + 'usersThisMonth' => $users, + ], 200); } /** diff --git a/src/Mealz/AccountingBundle/Controller/CostSheetController.php b/src/Mealz/AccountingBundle/Controller/CostSheetController.php index f3dac7c5f..1e8630d1a 100644 --- a/src/Mealz/AccountingBundle/Controller/CostSheetController.php +++ b/src/Mealz/AccountingBundle/Controller/CostSheetController.php @@ -125,7 +125,7 @@ public function postSettlement(Profile $profile, Wallet $wallet): JsonResponse $this->sendSettlementRequestMail($profile, $urlEncodedHash); - return new JsonResponse($wallet->getBalance($profile), 200); + return new JsonResponse(null, 200); } elseif (null !== $profile->getSettlementHash() && $wallet->getBalance($profile) > 0.00) { return new JsonResponse(['message' => 'Settlement request already send'], 500); } else { @@ -133,6 +133,21 @@ public function postSettlement(Profile $profile, Wallet $wallet): JsonResponse } } + public function getProfileFromHash(string $hash, ProfileRepositoryInterface $profileRepository): JsonResponse + { + $queryResult = $profileRepository->findBy(['settlementHash' => urldecode($hash)]); + $profile = $queryResult[0]; + + if (null === $profile) { + return new JsonResponse(['message' => 'Not found'], 404); + } + return new JsonResponse([ + 'user' => $profile->getUsername(), + 'fullName' => $profile->getFullName(), + 'roles' => $profile->getRoles(), + ], 200); + } + public function renderConfirmButton(string $hash, ProfileRepositoryInterface $profileRepo): Response { $profile = null; @@ -218,7 +233,7 @@ private function sendSettlementRequestMail(Profile $profile, string $urlEncodedH '%admin%' => $this->getProfile()->getFullName(), '%fullname%' => $profile->getFullName(), '%link%' => rtrim($this->getParameter('app.base_url'), '/') . $this->generateUrl( - 'mealz_accounting_cost_sheet_redirect_to_confirm', + 'MealzMealBundle_costs_settlement_confirm', ['hash' => $urlEncodedHash] ), ], diff --git a/src/Mealz/AccountingBundle/Controller/Payment/CashController.php b/src/Mealz/AccountingBundle/Controller/Payment/CashController.php new file mode 100644 index 000000000..eec13c26f --- /dev/null +++ b/src/Mealz/AccountingBundle/Controller/Payment/CashController.php @@ -0,0 +1,62 @@ +setProfile($profile); + $amount = (float) $request->query->get('amount'); + + if ($amount > 0) { + $transaction->setAmount($amount); + + $entityManager = $this->getDoctrine()->getManager(); + $entityManager->persist($transaction); + $entityManager->flush(); + + $logger = $this->get('monolog.logger.balance'); + $logger->info('admin added {amount}€ into wallet of {profile} (Transaction: {transactionId})', [ + 'profile' => $transaction->getProfile(), + 'amount' => $transaction->getAmount(), + 'transactionId' => $transaction->getId(), + ]); + + return new JsonResponse($transaction->getAmount(), 200); + } else { + throw new Exception('Amount less than 0'); + } + + } catch (Exception $e) { + $logger = $this->get('monolog.logger.balance'); + $logger->info($e->getMessage()); + + return new JsonResponse(['message' => $e->getMessage()], 500); + } + } +} \ No newline at end of file diff --git a/src/Mealz/AccountingBundle/Resources/config/routing.yml b/src/Mealz/AccountingBundle/Resources/config/routing.yml index a95589ea7..13e96f501 100644 --- a/src/Mealz/AccountingBundle/Resources/config/routing.yml +++ b/src/Mealz/AccountingBundle/Resources/config/routing.yml @@ -11,9 +11,10 @@ mealz_accounting_payment_ecash_transaction_failure: path: /payment/ecash/transaction/failure defaults: { _controller: App\Mealz\AccountingBundle\Controller\Payment\EcashController::transactionFailure } -mealz_accounting_payment_cash_form_submit: - path: /payment/cash/form/submit - defaults: { _controller: App\Mealz\AccountingBundle\Controller\Payment\CashController::paymentFormHandling } +mealz_accounting_api_payment_cash: + path: /api/payment/cash/{profile} + defaults: { _controller: App\Mealz\AccountingBundle\Controller\Payment\CashController::postPaymentCash } + methods: [ POST ] mealz_accounting_payment_cash_form: path: /payment/cash/form/{profile} @@ -27,8 +28,8 @@ mealz_accounting_payment_transaction_history: path: /accounting/transactions defaults: { _controller: App\Mealz\AccountingBundle\Controller\Payment\CashController::showTransactionData } -mealz_accounting_accounting_book: - path: /accounting/book +mealz_accounting_api_accounting_book: + path: /api/accounting/book defaults: { _controller: App\Mealz\AccountingBundle\Controller\AccountingBookController::list } mealz_accounting_accounting_book_finance: @@ -52,10 +53,12 @@ mealz_accounting_api_costs_hide_user: mealz_accounting_api_costs_settlement: path: /api/costs/settlement/{profile} defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::postSettlement } + methods: [ POST ] -mealz_accounting_cost_sheet_redirect_to_confirm: - path: /print/costsheet/redirect/confirm/{hash} - defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::renderConfirmButton } +mealz_accounting_costs_settlement_get_profile: + path: /api/costs/profile/{hash} + defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::getProfileFromHash } + methods: [ GET ] mealz_accounting_cost_sheet_confirm_settlement_request: path: /print/costsheet/settlement/confirm/{hash} diff --git a/src/Mealz/MealBundle/Resources/config/routing.yml b/src/Mealz/MealBundle/Resources/config/routing.yml index 3afbcf5fc..59e072cac 100644 --- a/src/Mealz/MealBundle/Resources/config/routing.yml +++ b/src/Mealz/MealBundle/Resources/config/routing.yml @@ -66,6 +66,14 @@ MealzMealBundle_costs: path: /costs defaults: { _controller: App\Mealz\MealBundle\Controller\FrontendController::renderIndex } +MealzMealBundle_cash_register: + path: /cash-register + defaults: { _controller: App\Mealz\MealBundle\Controller\FrontendController::renderIndex } + +MealzMealBundle_costs_settlement_confirm: + path: /costs/settlement/confirm/{hash} + defaults: { _controller: App\Mealz\MealBundle\Controller\FrontendController::renderIndex } + MealzMealBundle_finance: path: /finance defaults: { _controller: App\Mealz\MealBundle\Controller\FrontendController::renderIndex } diff --git a/src/Resources/src/api/getProfileWithHash.ts b/src/Resources/src/api/getProfileWithHash.ts new file mode 100644 index 000000000..e7125f14a --- /dev/null +++ b/src/Resources/src/api/getProfileWithHash.ts @@ -0,0 +1,16 @@ +import { IMessage } from "@/interfaces/IMessage"; +import useApi from "./api"; +import { IProfile } from "@/stores/profilesStore"; +/** + * Fetches a profile that was requested for settlement by their settlement hash + */ +export default async function getTransactionHistory(hash: string) { + const { error, response: profile, request } = useApi( + 'GET', + `api/costs/profile/${hash}` + ); + + await request(); + + return { error, profile }; +} \ No newline at end of file diff --git a/src/Resources/src/api/getTransactionHistory.ts b/src/Resources/src/api/getTransactionHistory.ts new file mode 100644 index 000000000..043e17ae6 --- /dev/null +++ b/src/Resources/src/api/getTransactionHistory.ts @@ -0,0 +1,16 @@ +import useApi from "./api"; +import { ITransactionHistory } from "@/stores/accountingStore"; + +/** + * Fetches two lists of transactions per user for the past month and the current month + */ +export default async function getTransactionHistory() { + const { error, response: transactions, request } = useApi( + 'GET', + 'api/accounting/book' + ); + + await request(); + + return { error, transactions }; +} \ No newline at end of file diff --git a/src/Resources/src/api/postCashPayment.ts b/src/Resources/src/api/postCashPayment.ts new file mode 100644 index 000000000..cdcd1a0d3 --- /dev/null +++ b/src/Resources/src/api/postCashPayment.ts @@ -0,0 +1,13 @@ +import useApi from '@/api/api'; +import { IMessage } from '@/interfaces/IMessage'; + +export default async function postCashPayment(username: string, amount: number) { + const { error, request, response } = useApi( + 'POST', + `api/payment/cash/${username}?amount=${amount}` + ); + + await request(); + + return { error, response }; +} \ No newline at end of file diff --git a/src/Resources/src/api/postSettlement.ts b/src/Resources/src/api/postSettlement.ts index 40ed9a994..8404f7ea0 100644 --- a/src/Resources/src/api/postSettlement.ts +++ b/src/Resources/src/api/postSettlement.ts @@ -2,7 +2,7 @@ import useApi from '@/api/api'; import { IMessage } from '@/interfaces/IMessage'; export default async function postSettlement(username: string) { - const { error, request, response } = useApi( + const { error, request, response } = useApi( 'POST', `api/costs/settlement/${username}` ); diff --git a/src/Resources/src/components/cashRegister/CashRegisterTable.vue b/src/Resources/src/components/cashRegister/CashRegisterTable.vue new file mode 100644 index 000000000..c5d638923 --- /dev/null +++ b/src/Resources/src/components/cashRegister/CashRegisterTable.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/components/costs/CashPaymentPanel.vue b/src/Resources/src/components/costs/CashPaymentPanel.vue new file mode 100644 index 000000000..9c08a85bd --- /dev/null +++ b/src/Resources/src/components/costs/CashPaymentPanel.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/components/costs/CashRegisterLink.vue b/src/Resources/src/components/costs/CashRegisterLink.vue index f31347d43..3e873f63f 100644 --- a/src/Resources/src/components/costs/CashRegisterLink.vue +++ b/src/Resources/src/components/costs/CashRegisterLink.vue @@ -1,7 +1,7 @@