diff --git a/src/Mealz/AccountingBundle/Controller/CostSheetController.php b/src/Mealz/AccountingBundle/Controller/CostSheetController.php index 5d14060cc..f3dac7c5f 100644 --- a/src/Mealz/AccountingBundle/Controller/CostSheetController.php +++ b/src/Mealz/AccountingBundle/Controller/CostSheetController.php @@ -83,37 +83,18 @@ public function list( ]); } - public function hideUserRequest( - Profile $profile, - ParticipantRepositoryInterface $participantRepo, - TransactionRepositoryInterface $transactionRepo - ): Response { - $this->denyAccessUnlessGranted('ROLE_KITCHEN_STAFF'); - + public function hideUser(Profile $profile): JsonResponse + { if (!$profile->isHidden()) { $entityManager = $this->getDoctrine()->getManager(); $profile->setHidden(true); $entityManager->persist($profile); $entityManager->flush(); - $message = $this->get('translator')->trans( - 'payment.costsheet.hide_user.request.success', - ['%name%' => $profile->getFullName()], - 'messages' - ); - $severity = 'success'; + return new JsonResponse(null, 200); } else { - $message = $this->get('translator')->trans( - 'payment.costsheet.hide_user.request.info', - ['%name%' => $profile->getFullName()], - 'messages' - ); - $severity = 'info'; + return new JsonResponse(['message' => 'Profile is already hidden'], 500); } - - $this->addFlashMessage($message, $severity); - - return $this->list($participantRepo, $transactionRepo); } private function getRemainingCosts($costs, &$transactions) @@ -129,46 +110,27 @@ private function getRemainingCosts($costs, &$transactions) return ($result < 0) ? 0 : $result * -1; } - public function sendSettlementRequest( - Profile $userProfile, - Wallet $wallet, - ParticipantRepositoryInterface $participantRepo, - TransactionRepositoryInterface $transactionRepo - ): Response { - if (null === $userProfile->getSettlementHash() && $wallet->getBalance($userProfile) > 0.00) { - $username = $userProfile->getUsername(); + public function postSettlement(Profile $profile, Wallet $wallet): JsonResponse + { + if (null === $profile->getSettlementHash() && $wallet->getBalance($profile) > 0.00) { + $username = $profile->getUsername(); $secret = $this->getParameter('app.secret'); $hashCode = str_replace('/', '', crypt($username, $secret)); $urlEncodedHash = urlencode($hashCode); $entityManager = $this->getDoctrine()->getManager(); - $userProfile->setSettlementHash($hashCode); - $entityManager->persist($userProfile); + $profile->setSettlementHash($hashCode); + $entityManager->persist($profile); $entityManager->flush(); - $this->sendSettlementRequestMail($userProfile, $urlEncodedHash); + $this->sendSettlementRequestMail($profile, $urlEncodedHash); - $message = $this->get('translator')->trans( - 'payment.costsheet.account_settlement.request.success', - ['%name%' => $userProfile->getFullName()], - 'messages' - ); - $severity = 'success'; - } elseif (null !== $userProfile->getSettlementHash() && $wallet->getBalance($userProfile) > 0.00) { - $message = $this->get('translator')->trans( - 'payment.costsheet.account_settlement.request.already_sent', - ['%name%' => $userProfile->getFullName()], - 'messages' - ); - $severity = 'danger'; + return new JsonResponse($wallet->getBalance($profile), 200); + } elseif (null !== $profile->getSettlementHash() && $wallet->getBalance($profile) > 0.00) { + return new JsonResponse(['message' => 'Settlement request already send'], 500); } else { - $message = $this->get('translator')->trans('payment.costsheet.account_settlement.request.failure'); - $severity = 'danger'; + return new JsonResponse(['message' => 'Settlement request failed'], 500); } - - $this->addFlashMessage($message, $severity); - - return $this->list($participantRepo, $transactionRepo); } public function renderConfirmButton(string $hash, ProfileRepositoryInterface $profileRepo): Response diff --git a/src/Mealz/AccountingBundle/Resources/config/routing.yml b/src/Mealz/AccountingBundle/Resources/config/routing.yml index 4ddbb31cc..a95589ea7 100644 --- a/src/Mealz/AccountingBundle/Resources/config/routing.yml +++ b/src/Mealz/AccountingBundle/Resources/config/routing.yml @@ -44,13 +44,14 @@ mealz_accounting_api_costs: defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::list } methods: [ GET ] -mealz_accounting_cost_sheet_hide_user_request: - path: /print/costsheet/hideuser/request/{profile} - defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::hideUserRequest } - -mealz_accounting_cost_sheet_send_settlement_request: - path: /print/costsheet/settlement/request/{username} - defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::sendSettlementRequest } +mealz_accounting_api_costs_hide_user: + path: /api/costs/hideuser/{profile} + defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::hideUser } + methods: [ POST ] + +mealz_accounting_api_costs_settlement: + path: /api/costs/settlement/{profile} + defaults: { _controller: App\Mealz\AccountingBundle\Controller\CostSheetController::postSettlement } mealz_accounting_cost_sheet_redirect_to_confirm: path: /print/costsheet/redirect/confirm/{hash} diff --git a/src/Resources/src/api/postHideUser.ts b/src/Resources/src/api/postHideUser.ts new file mode 100644 index 000000000..83aa9dc9f --- /dev/null +++ b/src/Resources/src/api/postHideUser.ts @@ -0,0 +1,13 @@ +import { IMessage } from "@/interfaces/IMessage"; +import useApi from "./api"; + +export default async function postHideUser(username: string) { + const { error, request, response } = useApi( + 'POST', + `api/costs/hideuser/${username}` + ); + + 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 new file mode 100644 index 000000000..40ed9a994 --- /dev/null +++ b/src/Resources/src/api/postSettlement.ts @@ -0,0 +1,13 @@ +import useApi from '@/api/api'; +import { IMessage } from '@/interfaces/IMessage'; + +export default async function postSettlement(username: string) { + const { error, request, response } = useApi( + 'POST', + `api/costs/settlement/${username}` + ); + + await request(); + + return { error, response }; +} \ No newline at end of file diff --git a/src/Resources/src/components/costs/CostsActionSettlement.vue b/src/Resources/src/components/costs/CostsActionSettlement.vue new file mode 100644 index 000000000..da0db617c --- /dev/null +++ b/src/Resources/src/components/costs/CostsActionSettlement.vue @@ -0,0 +1,55 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/components/costs/CostsHeader.vue b/src/Resources/src/components/costs/CostsHeader.vue index 051a4f6ec..70a1653a7 100644 --- a/src/Resources/src/components/costs/CostsHeader.vue +++ b/src/Resources/src/components/costs/CostsHeader.vue @@ -1,15 +1,32 @@ @@ -18,14 +35,17 @@ import { useI18n } from 'vue-i18n'; import CashRegisterLink from './CashRegisterLink.vue'; import InputLabel from '../misc/InputLabel.vue'; import { computed } from 'vue'; +import Switch from "@/components/misc/Switch.vue" +import { SwitchGroup, SwitchLabel } from '@headlessui/vue'; const { t } = useI18n(); const props = defineProps<{ - modelValue: string + modelValue: string, + showHidden: boolean }>(); -const emit = defineEmits(['update:modelValue']); +const emit = defineEmits(['update:modelValue', 'change:showHidden']); const filter = computed({ get() { diff --git a/src/Resources/src/components/costs/CostsTable.vue b/src/Resources/src/components/costs/CostsTable.vue index e5b6db934..0c1a1ac36 100644 --- a/src/Resources/src/components/costs/CostsTable.vue +++ b/src/Resources/src/components/costs/CostsTable.vue @@ -24,7 +24,10 @@ {{ new Intl.NumberFormat(locale, { style: 'currency', currency: 'EUR' }).format(costs.costs['total']) }} - Actions to be implemented + @@ -35,28 +38,37 @@ import Table from '@/components/misc/Table.vue'; import { useCosts } from '@/stores/costsStore'; import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; +import CostsTableActions from './CostsTableActions.vue'; const { t, locale } = useI18n(); const { CostsState, getColumnNames } = useCosts(); const props = defineProps<{ - filter: string + filter: string, + showHidden: boolean }>(); const columnNames = computed(() => ['Name', t('costs.table.earlier'), ...getColumnNames(locale.value), t('costs.table.total'), t('costs.table.actions')]); +const filterRegex = computed(() => { + const filterStrings = props.filter.split(/[\s,.]+/).map(filterStr => filterStr.toLowerCase()); + return createRegexForFilter(filterStrings); +}); + +const hiddenUsers = computed(() => Object.entries(CostsState.users).filter(user => { + const [key, value] = user; + return value.hidden === false || (value.hidden === true && props.showHidden === true); +})); + const filteredUsers = computed(() => { if (props.filter === '') { - return Object.entries(CostsState.users) + return hiddenUsers.value } - const filterStrings = props.filter.split(/[\s,.]+/).map(filterStr => filterStr.toLowerCase()); - const regex = createRegexForFilter(filterStrings); - - return Object.entries(CostsState.users).filter(user => { + return hiddenUsers.value.filter(user => { const [key, value] = user; const searchStrings = [value.firstName, value.name].join(' '); - return regex.test(searchStrings); + return filterRegex.value.test(searchStrings); }); }); diff --git a/src/Resources/src/components/costs/CostsTableActions.vue b/src/Resources/src/components/costs/CostsTableActions.vue new file mode 100644 index 000000000..fa93e9389 --- /dev/null +++ b/src/Resources/src/components/costs/CostsTableActions.vue @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/components/misc/ActionButton.vue b/src/Resources/src/components/misc/ActionButton.vue index 72b43a8df..f840a0c0d 100644 --- a/src/Resources/src/components/misc/ActionButton.vue +++ b/src/Resources/src/components/misc/ActionButton.vue @@ -5,17 +5,31 @@ > + +

@@ -27,6 +41,7 @@