userRepository = new UserRepository(); $this->communityRepository = new CommunityRepository(); $this->communityMemberRepository = new CommunityMemberRepository(); $this->currencyRepository = new CurrencyRepository(); $this->currencyExchangeRatesRepository = new CurrencyExchangeRateRepository(); $this->transactionRepository = new TransactionRepository(); } public function isAuthenticationRequired(): bool { return true; } public function getCommunityHome(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), false, $community, $ownCommunityMember)) { return null; } \Container::$persistentDataManager->loadRelationsFromDb($community, false, ['main_currency']); $balanceCalculator = new BalanceCalculator($community); $debts = $balanceCalculator->calculate(); $debtItems = []; $debtBalance = 0.0; $outstandingItems = []; $outstandingBalance = 0.0; foreach ($debts as $debt) { if ($debt['payer']->getId() === \Container::$request->user()->getUniqueId()) { $debtBalance += $debt['amount']; $debtItems[] = $debt; } if ($debt['payee']->getId() === \Container::$request->user()->getUniqueId()) { $outstandingBalance += $debt['amount']; $outstandingItems[] = $debt; } } $balance = $outstandingBalance - $debtBalance; return new HtmlContent('communities/community', [ 'community' => $community, 'upcomingEvents' => [], 'debtItems' => $debtItems, 'debtBalance' => $debtBalance, 'outstandingItems' => $outstandingItems, 'outstandingBalance' => $outstandingBalance, 'balance' => $balance, 'editPermission' => $ownCommunityMember->getOwner() ]); } public function getCommunitySettings(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), false, $community, $ownCommunityMember)) { return null; } return new HtmlContent('communities/community_settings', [ 'community' => $community, 'members' => $this->getMembers($community), 'currencies' => $this->getCurrencies($community), 'editPermission' => $ownCommunityMember->getOwner() ]); } public function getCommunityNew(): IContent { return new HtmlContent('communities/community_edit'); } public function getCommunityEdit(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } return new HtmlContent('communities/community_edit', [ 'community' => $community ]); } public function saveCommunity(): ?IContent { $name = \Container::$request->post('name'); if (strlen($name) === 0) { return new JsonContent([ 'error' => ['errorText' => 'Please fill all required fields!'] ]); } $communitySlug = \Container::$request->query('communitySlug'); if ($communitySlug){ if (!$this->checkPermission($communitySlug, true, $community, $ownCommunityMember)) { return null; } } else { $mainCurrencyCode = \Container::$request->post('main_currency_code'); $mainCurrencyRoundDigits = \Container::$request->post('main_currency_round_digits'); if (strlen($mainCurrencyCode) === 0 || strlen($mainCurrencyCode) > 3 || $mainCurrencyRoundDigits < 0 || $mainCurrencyRoundDigits > 9) { return new JsonContent([ 'error' => ['errorText' => 'Please fill all required fields!'] ]); } $community = new Community(); $community->setCreatedDate(new DateTime()); } $community->setName($name); \Container::$persistentDataManager->saveToDb($community); if (!$communitySlug) { /** * @var User $user */ $user = \Container::$request->user(); $communityMember = new CommunityMember(); $communityMember->setCommunity($community); $communityMember->setUser($user); $communityMember->setOwner(true); \Container::$persistentDataManager->saveToDb($communityMember); $mainCurrency = new Currency(); $mainCurrency->setCommunity($community); $mainCurrency->setCode($mainCurrencyCode); $mainCurrency->setRoundDigits($mainCurrencyRoundDigits); \Container::$persistentDataManager->saveToDb($mainCurrency); $community->setMainCurrency($mainCurrency); \Container::$persistentDataManager->saveToDb($community); } return new JsonContent([ 'redirect' => ['target' => \Container::$routeCollection->getRoute('community')->generateLink(['communitySlug' => $community->getSlug()])] ]); } public function getMembersEdit(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } return new HtmlContent('communities/community_members', [ 'community' => $community, 'members' => $this->getMembers($community) ]); } public function saveMember(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $communityMemberId = \Container::$request->query('community_member_id'); if ($communityMemberId) { $communityMember = $this->communityMemberRepository->getById($communityMemberId); if ($communityMember->getUserId() === $ownCommunityMember->getUserId()) { return new JsonContent([ 'error' => ['errorText' => 'Own user cannot be edited.'] ]); } } else { if ($this->transactionRepository->isAnyCommon()) { return new JsonContent([ 'error' => ['errorText' => 'There are transactions with common payee!'] ]); } $user = $this->userRepository->getById(\Container::$request->post('user_id')); if ($this->communityMemberRepository->getByCommunityAndUser($community, $user) !== null) { return new JsonContent([ 'error' => ['errorText' => 'This user is already a member of this community.'] ]); } $communityMember = new CommunityMember(); $communityMember->setCommunity($community); $communityMember->setUser($user); } $communityMember->setOwner((bool)\Container::$request->post('owner')); \Container::$persistentDataManager->saveToDb($communityMember); return new JsonContent(['success' => true]); } public function deleteMember(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $communityMember = $this->communityMemberRepository->getById(\Container::$request->query('community_member_id')); if ($communityMember->getUserId() === \Container::$request->user()->getUniqueId()) { return new JsonContent([ 'error' => ['errorText' => 'Own user cannot be deleted.'] ]); } \Container::$persistentDataManager->loadRelationsFromDb($communityMember, false, ['user']); if ($this->transactionRepository->isAnyForUser($communityMember->getUser())) { return new JsonContent([ 'error' => ['errorText' => 'There are transactions where the member is payer or payee!'] ]); } \Container::$persistentDataManager->deleteFromDb($communityMember); return new JsonContent(['success' => true]); } public function getCurrenciesEdit(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } return new HtmlContent('communities/community_currencies', [ 'community' => $community, 'currencies' => $this->getCurrencies($community) ]); } public function saveCurrency(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $code = \Container::$request->post('code'); $roundDigits = (int)\Container::$request->post('round_digits'); if (strlen($code) === 0 || strlen($code) > 3 || $roundDigits < 0 || $roundDigits > 9) { return new JsonContent([ 'error' => ['errorText' => 'Please fill all required fields!'] ]); } $currencyId = \Container::$request->query('currency_id'); if ($currencyId){ $currency = $this->currencyRepository->getById($currencyId); } else { $currency = new Currency(); $currency->setCommunity($community); } $existingCurrency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, $code); if ($existingCurrency !== null && $currency->getId() !== $existingCurrency->getId()) { return new JsonContent([ 'error' => ['errorText' => 'A currency with the same code exists for this community.'] ]); } $currency->setCode($code); $currency->setRoundDigits($roundDigits); \Container::$persistentDataManager->saveToDb($currency); return new JsonContent(['success' => true]); } public function deleteCurrency(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $currency = $this->currencyRepository->getById(\Container::$request->query('currency_id')); if ($currency->getId() === $community->getMainCurrencyId()) { return null; } if ($this->transactionRepository->isAnyForCurrency($currency)) { return new JsonContent([ 'error' => ['errorText' => 'There are transactions with this currency!'] ]); } foreach ($this->currencyExchangeRatesRepository->getAllByCurrency($currency) as $currencyExchangeRate) { \Container::$persistentDataManager->deleteFromDb($currencyExchangeRate); } \Container::$persistentDataManager->deleteFromDb($currency); return new JsonContent(['success' => true]); } public function getCurrencyExchangeRates(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code')); if ($currency === null || $currency->getId() === $community->getMainCurrencyId()) { return null; } $currencyExchangeRates = $this->currencyExchangeRatesRepository->getAllByCurrency($currency); return new HtmlContent('communities/currency_exchange_rates', [ 'community' => $community, 'currency' => $currency, 'currencyExchangeRates' => $currencyExchangeRates, 'editPermission' => $ownCommunityMember->getOwner() ]); } public function saveCurrencyExchangeRate(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code')); if ($currency === null) { return null; } $exchangeRate = (float)\Container::$request->post('exchange_rate'); if ($exchangeRate < 0) { return new JsonContent([ 'error' => ['errorText' => 'Please fill all required fields!'] ]); } $currencyExchangeRateId = \Container::$request->query('currency_exchange_rate_id'); if ($currencyExchangeRateId){ $currencyExchangeRate = $this->currencyExchangeRatesRepository->getById($currencyExchangeRateId); } else { $currencyExchangeRate = new CurrencyExchangeRate(); $currencyExchangeRate->setCurrency($currency); } $currencyExchangeRate->setExchangeRate($exchangeRate); $currencyExchangeRate->setValidFromDate(new DateTime(\Container::$request->post('valid_from'))); \Container::$persistentDataManager->saveToDb($currencyExchangeRate); return new JsonContent(['success' => true]); } public function deleteCurrencyExchangeRate(): ?IContent { if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) { return null; } $currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code')); if ($currency === null) { return null; } $currencyExchangeRate = $this->currencyExchangeRatesRepository->getById(\Container::$request->query('currency_exchange_rate_id')); \Container::$persistentDataManager->deleteFromDb($currencyExchangeRate); return new JsonContent(['success' => true]); } private function getMembers(Community $community): array { $members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true, ['user'])); usort($members, function($a, $b) { return strnatcmp($a->getUser()->getDisplayName(), $b->getUser()->getDisplayName()); }); return $members; } private function getCurrencies(Community $community): array { $currencies = iterator_to_array($this->currencyRepository->getAllByCommunity($community)); usort($currencies, function($a, $b) { return strnatcmp($a->getCode(), $b->getCode()); }); usort($currencies, function($a, $b) use ($community) { return (int)($b->getId() === $community->getMainCurrencyId()) - (int)($a->getId() === $community->getMainCurrencyId()); }); return $currencies; } private function checkPermission( string $communitySlug, bool $needToBeOwner, ?Community &$community, ?CommunityMember &$ownCommunityMember): bool { $community = $this->communityRepository->getBySlug($communitySlug); if ($community === null) { return false; } /** * @var User $user */ $user = \Container::$request->user(); $ownCommunityMember = $this->communityMemberRepository->getByCommunityAndUser($community, $user); if ($ownCommunityMember === null || ($needToBeOwner && !$ownCommunityMember->getOwner())) { return false; } return true; } }