Compare commits

..
Author SHA1 Message Date
bence 882b326aca Merge pull request 'merge new and edit methods in CommunityController' (!33) from feature/unify-saves-in-communitycontroller into master
rvr-nextgen/pipeline/head This commit looks good
Reviewed-on: #33
2023-04-26 09:46:09 +02:00
bence 49fe85dcde merge new and edit methods in CommunityController
rvr-nextgen/pipeline/pr-master This commit looks good
2023-04-26 09:43:57 +02:00
bence a021aff92c Merge pull request 'feature/RVRNEXT-5-handling-currency-exchange-rates' (!32) from feature/RVRNEXT-5-handling-currency-exchange-rates into master
rvr-nextgen/pipeline/head This commit looks good
Reviewed-on: #32
2023-04-25 19:32:11 +02:00
bence 6abe93e3b5 RVRNEXT-5 fine-tune styles
rvr-nextgen/pipeline/pr-master This commit looks good
2023-04-25 19:28:42 +02:00
bence 7e84e6b4ba RVRNEXT-5 add/update layout for currency exchange rates 2023-04-25 19:28:42 +02:00
bence 76ed977375 RVRNEXT-5 add logic for handling currency exchange rates 2023-04-25 19:28:42 +02:00
bence fea403fe5a RVRNEXT-5 add new routes for currency exchange rates 2023-04-25 19:28:42 +02:00
bence 1d96fd0cb9 RVRNEXT-5 add model and repository for currency exchange rate 2023-04-25 19:28:42 +02:00
bence 7437e19de5 RVRNEXT-5 add migration for currency exchange rates 2023-04-23 20:50:45 +02:00
bence 47567c9b75 RVRNEXT-5 add links to community main page 2023-04-23 20:46:11 +02:00
bence ef16e70235 Merge pull request 'feature/RVRNEXT-5-handling-currencies' (!31) from feature/RVRNEXT-5-handling-currencies into master
rvr-nextgen/pipeline/head This commit looks good
Reviewed-on: #31
2023-04-23 20:21:31 +02:00
bence 91d064947e RVRNEXT-5 formError should be searched in the whole document
rvr-nextgen/pipeline/pr-master This commit looks good
2023-04-23 20:20:10 +02:00
bence 9a6e95673e RVRNEXT-5 add formError for multi for layouts 2023-04-23 20:20:10 +02:00
bence d24c3bb1cb RVRNEXT-5 move private methods to the end of CommunityController 2023-04-23 20:20:10 +02:00
bence 2ad637e55f RVRNEXT-5 make prepare-commit-msg accept fixup commits 2023-04-23 20:20:10 +02:00
bence ac09342c9d RVRNEXT-5 fix layouts for communities 2023-04-23 20:20:10 +02:00
bence 3a1054e1df RVRNEXT-5 adjust table style 2023-04-23 20:20:10 +02:00
bence 0f02c4b5be RVRNEXT-5 update CommunityController with currency operations 2023-04-23 20:20:10 +02:00
bence be0a15d02d RVRNEXT-5 extend views with currency edit 2023-04-23 20:09:49 +02:00
bence 12065b0525 RVRNEXT-5 add model and repository for currencies 2023-04-23 20:09:44 +02:00
bence 0fc21cc461 RVRNEXT-5 add migration for currencies 2023-04-23 20:09:44 +02:00
bence 7d63de4403 RVRNEXT-5 add new endpoints for currency handling 2023-04-23 17:36:03 +02:00
bence c520c256ee Merge pull request 'solve community member edit with forms' (!30) from feature/solve-community-member-edit-with-forms into master
rvr-nextgen/pipeline/head This commit looks good
Reviewed-on: #30
2023-04-23 15:59:32 +02:00
bence 2f9b97d1a4 solve community member edit with forms
rvr-nextgen/pipeline/pr-master This commit looks good
2023-04-23 15:55:31 +02:00
17 changed files with 574 additions and 114 deletions

No files matched your search

@@ -0,0 +1,10 @@
CREATE TABLE `currencies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`community_id` int(10) unsigned NOT NULL,
`code` varchar(3) NOT NULL,
`round_digits` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_currency_for_community` (`community_id`, `code`),
KEY `community_id` (`community_id`),
CONSTRAINT `currencies_community_id` FOREIGN KEY (`community_id`) REFERENCES `communities` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
@@ -0,0 +1,10 @@
CREATE TABLE `currency_exchange_rates` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`currency_id` int(10) unsigned NOT NULL,
`exchange_rate` decimal(19,9) unsigned NOT NULL,
`valid_from` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `currency_id` (`currency_id`),
INDEX `valid_from` (`valid_from`),
CONSTRAINT `currency_exchange_rates_currency_id` FOREIGN KEY (`currency_id`) REFERENCES `currencies` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
+12 -3
View File
@@ -113,7 +113,7 @@ p.small, span.small {
}
.marginLeft {
margin-left: 10px;
margin-left: 5px;
}
.marginBottom {
@@ -121,7 +121,7 @@ p.small, span.small {
}
.marginRight {
margin-right: 10px;
margin-right: 5px;
}
.center {
@@ -455,10 +455,18 @@ table th {
}
table th, table td {
padding: 2px 0;
padding: 3px 0;
vertical-align: middle;
}
table th:not(:first-child), table td:not(:first-child) {
padding-left: 3px;
}
table th:not(:last-child), table td:not(:last-child) {
padding-right: 3px;
}
.choices__inner {
box-sizing: border-box;
}
@@ -477,6 +485,7 @@ table th, table td {
margin-top: 4px;
}
button, a.button {
margin: 3px 0;
padding: 0;
width: 100%;
}
@@ -1,5 +1,5 @@
(function () {
const element = document.getElementById('new_member_user_id');
const element = document.getElementById('newMember').elements['user_id'];
const choices = new Choices(element, {
noResultsText: 'No users found',
noChoicesText: 'Start typing to search users'
@@ -13,50 +13,5 @@
element.addEventListener('choice', function () {
choices.setChoices([], 'value', 'label', true);
document.getElementById('new_member_button').disabled = false;
});
document.getElementById('new_member_button').addEventListener('click', function () {
document.getElementById('loading').style.visibility = 'visible';
let data = new FormData();
data.append('user_id', document.getElementById('new_member_user_id').value);
RVR.httpRequest('POST', newMemberUrl, function () {
window.location.reload();
}, data);
});
const ownerCheckboxesButtons = document.getElementsByClassName('member_owner');
for (const ownerCheckboxesButton of ownerCheckboxesButtons) {
ownerCheckboxesButton.addEventListener('change', function () {
document.getElementById('loading').style.visibility = 'visible';
let data = new FormData();
data.append('community_member_id', this.dataset.id);
data.append('owner', this.checked ? 1 : 0);
RVR.httpRequest('POST', editMemberUrl, function () {
document.getElementById('loading').style.visibility = 'hidden';
if (!this.response.success) {
ownerCheckboxesButton.checked = !ownerCheckboxesButton.checked;
}
}, data);
});
};
const deleteButtons = document.getElementsByClassName('delete_member');
for (const deleteButton of deleteButtons) {
deleteButton.addEventListener('click', function () {
document.getElementById('loading').style.visibility = 'visible';
let data = new FormData();
data.append('community_member_id', this.dataset.id);
RVR.httpRequest('POST', deleteMemberUrl, function () {
window.location.reload();
}, data);
});
};
})();
+9 -3
View File
@@ -49,7 +49,7 @@ var RVR = {
document.getElementById('loading').style.visibility = 'visible';
var formData = new FormData(form);
var formError = form.getElementsByClassName('formError')[0];
var formError = document.getElementsByClassName('formError')[0];
var pageLeaveOnSuccess = form.dataset.redirectOnSuccess || form.dataset.reloadOnSuccess;
RVR.httpRequest('POST', form.action, function () {
@@ -163,8 +163,14 @@ var RVR = {
for (var i = 0; i < observedInputs.length; i++) {
var input = form.elements[observedInputs[i]];
if (input.defaultValue !== input.value) {
anyChanged = true;
if (input.type === 'checkbox') {
if (input.defaultChecked !== input.checked) {
anyChanged = true;
}
} else {
if (input.defaultValue !== input.value) {
anyChanged = true;
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ if [[ "${BRANCH_NAME}" =~ $BRANCH_PATTERN ]]; then
TICKET_ID=$(echo $BRANCH_NAME | sed -E "s@$BRANCH_PATTERN@\\2@")
COMMIT_MESSAGE=$(head -n 1 $1)
COMMIT_MESSAGE_REGEX="^$TICKET_ID .*"
COMMIT_MESSAGE_REGEX="^(fixup! )?$TICKET_ID .*"
if [[ ! "${COMMIT_MESSAGE}" =~ $COMMIT_MESSAGE_REGEX ]]; then
sed -i.bak -e "1s/^/$TICKET_ID /" $1
+185 -46
View File
@@ -3,9 +3,13 @@
use DateTime;
use RVR\PersistentData\Model\Community;
use RVR\PersistentData\Model\CommunityMember;
use RVR\PersistentData\Model\Currency;
use RVR\PersistentData\Model\CurrencyExchangeRate;
use RVR\PersistentData\Model\User;
use RVR\Repository\CommunityRepository;
use RVR\Repository\CommunityMemberRepository;
use RVR\Repository\CurrencyExchangeRateRepository;
use RVR\Repository\CurrencyRepository;
use RVR\Repository\UserRepository;
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
use SokoWeb\Interfaces\Response\IContent;
@@ -20,11 +24,17 @@ class CommunityController implements IAuthenticationRequired
private CommunityMemberRepository $communityMemberRepository;
private CurrencyRepository $currencyRepository;
private CurrencyExchangeRateRepository $currencyExchangeRatesRepository;
public function __construct()
{
$this->userRepository = new UserRepository();
$this->communityRepository = new CommunityRepository();
$this->communityMemberRepository = new CommunityMemberRepository();
$this->currencyRepository = new CurrencyRepository();
$this->currencyExchangeRatesRepository = new CurrencyExchangeRateRepository();
}
public function isAuthenticationRequired(): bool
@@ -41,7 +51,7 @@ class CommunityController implements IAuthenticationRequired
return new HtmlContent('communities/community', [
'community' => $community,
'members' => $this->getMembers($community),
'currencyNames' => [],
'currencies' => $this->getCurrencies($community),
'upcomingEvents' => [],
'editPermission' => $ownCommunityMember->getOwner()
]);
@@ -75,46 +85,28 @@ class CommunityController implements IAuthenticationRequired
]);
}
private function getMembers(Community $community): array
{
$members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true));
usort($members, function($a, $b) {
return strnatcmp($a->getUser()->getDisplayName(), $b->getUser()->getDisplayName());
});
return $members;
}
public function newMember(): ?IContent
public function saveMember(): ?IContent
{
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
return null;
}
$user = $this->userRepository->getById(\Container::$request->post('user_id'));
$communityMember = new CommunityMember();
$communityMember->setCommunity($community);
$communityMember->setUser($user);
\Container::$persistentDataManager->saveToDb($communityMember);
return new JsonContent(['success' => true]);
}
public function editMember(): ?IContent
{
if (!$this->checkPermission(\Container::$request->query('communityId'), 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 {
$user = $this->userRepository->getById(\Container::$request->post('user_id'));
$communityMember = new CommunityMember();
$communityMember->setCommunity($community);
$communityMember->setUser($user);
}
$communityMember = $this->communityMemberRepository->getById(\Container::$request->post('community_member_id'));
if ($communityMember->getUserId() === \Container::$request->user()->getUniqueId()) {
return new JsonContent([
'error' => ['errorText' => 'Own user cannot be edited.']
]);
}
$communityMember->setOwner(\Container::$request->post('owner'));
$communityMember->setOwner((bool)\Container::$request->post('owner'));
\Container::$persistentDataManager->saveToDb($communityMember);
return new JsonContent(['success' => true]);
@@ -126,7 +118,7 @@ class CommunityController implements IAuthenticationRequired
return null;
}
$communityMember = $this->communityMemberRepository->getById(\Container::$request->post('community_member_id'));
$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.']
@@ -138,17 +130,139 @@ class CommunityController implements IAuthenticationRequired
return new JsonContent(['success' => true]);
}
public function saveCommunity(): ?IContent
public function getCurrenciesEdit(): ?IContent
{
$communityId = \Container::$request->query('communityId');
if ($communityId){
if (!$this->checkPermission($communityId, true, $community, $ownCommunityMember)) {
return null;
}
} else {
$community = new Community();
if (!$this->checkPermission(\Container::$request->query('communityId'), 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('communityId'), 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('communityId'), true, $community, $ownCommunityMember)) {
return null;
}
$currency = $this->currencyRepository->getById(\Container::$request->query('currency_id'));
\Container::$persistentDataManager->deleteFromDb($currency);
return new JsonContent(['success' => true]);
}
public function getCurrencyExchangeRates(): ?IContent
{
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
return null;
}
$currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code'));
if ($currency === null) {
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('communityId'), 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('communityId'), 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]);
}
public function saveCommunity(): ?IContent
{
$name = \Container::$request->post('name');
$currency = \Container::$request->post('currency');
if (strlen($name) === 0 || strlen($currency) === 0 || strlen($currency) > 3) {
@@ -157,11 +271,18 @@ class CommunityController implements IAuthenticationRequired
]);
}
$community->setName($name);
$community->setCurrency($currency);
if (!$communityId) {
$communityId = \Container::$request->query('communityId');
if ($communityId){
if (!$this->checkPermission($communityId, true, $community, $ownCommunityMember)) {
return null;
}
} else {
$community = new Community();
$community->setCreatedDate(new DateTime());
}
$community->setName($name);
$community->setCurrency($currency);
\Container::$persistentDataManager->saveToDb($community);
if (!$communityId) {
@@ -182,6 +303,24 @@ class CommunityController implements IAuthenticationRequired
]);
}
private function getMembers(Community $community): array
{
$members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true));
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());
});
return $currencies;
}
private function checkPermission(
int $communityId,
bool $needToBeOwner,
+60
View File
@@ -0,0 +1,60 @@
<?php namespace RVR\PersistentData\Model;
use SokoWeb\PersistentData\Model\Model;
class Currency extends Model
{
protected static string $table = 'currencies';
protected static array $fields = ['community_id', 'code', 'round_digits'];
protected static array $relations = ['community' => Community::class];
private ?Community $community = null;
private ?int $communityId = null;
private string $code = '';
private int $roundDigits = 0;
public function setCommunity(Community $community): void
{
$this->community = $community;
}
public function setCommunityId(int $communityId): void
{
$this->communityId = $communityId;
}
public function setCode(string $code): void
{
$this->code = $code;
}
public function setRoundDigits(int $roundDigits): void
{
$this->roundDigits = $roundDigits;
}
public function getCommunity(): ?Community
{
return $this->community;
}
public function getCommunityId(): ?int
{
return $this->communityId;
}
public function getCode(): string
{
return $this->code;
}
public function getRoundDigits(): int
{
return $this->roundDigits;
}
}
@@ -0,0 +1,71 @@
<?php namespace RVR\PersistentData\Model;
use DateTime;
use SokoWeb\PersistentData\Model\Model;
class CurrencyExchangeRate extends Model
{
protected static string $table = 'currency_exchange_rates';
protected static array $fields = ['currency_id', 'exchange_rate', 'valid_from'];
protected static array $relations = ['currency' => Currency::class];
private ?Currency $currency = null;
private ?int $currencyId = null;
private float $exchangeRate = 0.0;
private DateTime $validFrom;
public function setCurrency(Currency $currency): void
{
$this->currency = $currency;
}
public function setCurrencyId(int $currencyId): void
{
$this->currencyId = $currencyId;
}
public function setExchangeRate(float $exchangeRate): void
{
$this->exchangeRate = $exchangeRate;
}
public function setValidFromDate(DateTime $validFrom): void
{
$this->validFrom = $validFrom;
}
public function setValidFrom(string $validFrom): void
{
$this->validFrom = new DateTime($validFrom);
}
public function getCurrency(): ?Currency
{
return $this->currency;
}
public function getCurrencyId(): ?int
{
return $this->currencyId;
}
public function getExchangeRate(): float
{
return $this->exchangeRate;
}
public function getValidFromDate(): DateTime
{
return $this->validFrom;
}
public function getValidFrom(): string
{
return $this->validFrom->format('Y-m-d H:i:s');
}
}
@@ -0,0 +1,24 @@
<?php namespace RVR\Repository;
use Generator;
use Container;
use RVR\PersistentData\Model\Currency;
use RVR\PersistentData\Model\CurrencyExchangeRate;
use SokoWeb\Database\Query\Select;
class CurrencyExchangeRateRepository
{
public function getById(int $id): ?CurrencyExchangeRate
{
return \Container::$persistentDataManager->selectFromDbById($id, CurrencyExchangeRate::class);
}
public function getAllByCurrency(Currency $currency): Generator
{
$select = new Select(Container::$dbConnection);
$select->where('currency_id', '=', $currency->getId());
$select->orderBy('valid_from');
yield from Container::$persistentDataManager->selectMultipleFromDb($select, CurrencyExchangeRate::class);
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php namespace RVR\Repository;
use Generator;
use Container;
use RVR\PersistentData\Model\Community;
use RVR\PersistentData\Model\Currency;
use SokoWeb\Database\Query\Select;
class CurrencyRepository
{
public function getById(int $id): ?Currency
{
return \Container::$persistentDataManager->selectFromDbById($id, Currency::class);
}
public function getAllByCommunity(Community $community, bool $useRelations = false): Generator
{
$select = new Select(Container::$dbConnection);
$select->where('community_id', '=', $community->getId());
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Currency::class, $useRelations);
}
public function getByCommunityAndCurrencyCode(Community $community, string $code): ?Currency
{
$select = new Select(Container::$dbConnection);
$select->where('community_id', '=', $community->getId());
$select->where('code', '=', $code);
return Container::$persistentDataManager->selectFromDb($select, Currency::class);
}
}
+11 -1
View File
@@ -17,7 +17,17 @@
<div>
<h3 class="marginBottom">Currencies</h3>
<p>Main currency: <b><?= $community->getCurrency() ?></b></p>
<p>Further currencies: <b><?= implode(', ', $currencyNames) ?></b></p>
<?php if (count($currencies) > 0): ?>
<p>Further currencies: <b>
<?php foreach ($currencies as $currency): ?>
<a href="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode()]) ?>"><?= $currency->getCode() ?></a>
<?php endforeach; ?>
</b></p>
<?php endif; ?>
<?php if ($editPermission): ?>
<hr>
<p><a href="<?= Container::$routeCollection->getRoute('community-currencies')->generateLink(['communityId' => $community->getId()]) ?>">Edit currencies</a></p>
<?php endif; ?>
</div>
<div>
<h3 class="marginBottom">Upcoming events</h3>
@@ -0,0 +1,45 @@
@extends(templates/layout_normal)
@section(main)
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit currencies</h2>
<div class="box">
<table class="fullWidth">
<thead>
<tr>
<th style="width: calc(100% / 3); text-align: left;">Currency</th>
<th style="width: calc(100% / 3); text-align: left;">Round digits</th>
<th style="width: calc(100% / 3);"></th>
</tr>
</thead>
<?php foreach ($currencies as $currency): ?>
<tr>
<td>
<form id="editCurrency_<?= $currency->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currencies-edit')->generateLink(['communityId' => $community->getId(), 'currency_id' => $currency->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="code,round_digits"></form>
<form id="deleteCurrency_<?= $currency->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currencies-delete')->generateLink(['communityId' => $community->getId(), 'currency_id' => $currency->getId()]) ?>" method="post" data-reload-on-success="true"></form>
<input type="text" form="editCurrency_<?= $currency->getId() ?>" class="text fullWidth" name="code" value="<?= $currency->getCode() ?>" maxlength="3" required>
</td>
<td>
<input type="number" form="editCurrency_<?= $currency->getId() ?>" class="text fullWidth" name="round_digits" value="<?= $currency->getRoundDigits() ?>" min="0" max="9" required>
</td>
<td style="text-align: right;">
<button type="submit" form="editCurrency_<?= $currency->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
--><button type="submit" form="deleteCurrency_<?= $currency->getId() ?>" class="small red">Delete</button>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td>
<form id="newCurrency" action="<?= Container::$routeCollection->getRoute('community-currencies-new')->generateLink(['communityId' => $community->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="code,round_digits"></form>
<input type="text" form="newCurrency" class="text fullWidth" name="code" placeholder="Currency" maxlength="3" required>
</td>
<td>
<input type="number" form="newCurrency" class="text fullWidth" name="round_digits" placeholder="Round digits" min="0" max="9" required>
</td>
<td style="text-align: right;">
<button type="submit" form="newCurrency" name="submit" class="small" disabled>Add</button>
</td>
</tr>
</table>
<p class="formError justify marginTop"></p>
</div>
@endsection
+8 -2
View File
@@ -1,7 +1,13 @@
@extends(templates/layout_normal)
@section(main)
<h2><?= isset($community) ? $community->getName() . ' - Edit' : 'New community' ?></h2>
<h2>
<?php if (isset($community)): ?>
<a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit
<?php else: ?>
New community
<?php endif; ?>
</h2>
<div class="box">
<?php
$formAction = isset($community) ?
@@ -11,7 +17,7 @@
<form id="communityForm" action="<?= $formAction ?>" method="post" data-redirect-on-success="true">
<input type="text" class="text big fullWidth" name="name" placeholder="Name" value="<?= isset($community) ? $community->getName() : '' ?>" required>
<input type="text" class="text big fullWidth marginTop" name="currency" value="<?= isset($community) ? $community->getCurrency() : '' ?>" placeholder="Default currency" maxlength="3" required>
<p id="accountFormError" class="formError justify marginTop"></p>
<p id="communityFormError" class="formError justify marginTop"></p>
<div class="right marginTop">
<button type="submit" name="submit"><?= isset($community) ? 'Save' : 'Create' ?></button>
</div>
+26 -10
View File
@@ -5,7 +5,7 @@
@extends(templates/layout_normal)
@section(main)
<h2><?= $community->getName() ?> - Edit members</h2>
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit members</h2>
<div class="box">
<table class="fullWidth">
<thead>
@@ -18,25 +18,41 @@
<?php foreach ($members as $member): ?>
<?php $editable = $member->getUserId() !== Container::$request->user()->getUniqueId(); ?>
<tr>
<td><?= $member->getUser()->getDisplayName() ?></td>
<td style="text-align: center;"><input type="checkbox" class="member_owner" data-id="<?= $member->getId() ?>" <?= $member->getOwner() ? 'checked' : '' ?> <?= !$editable ? 'disabled' : '' ?> /></td>
<td style="text-align: right;"><button type="button" class="small red delete_member" data-id="<?= $member->getId() ?>" <?= !$editable ? 'disabled' : '' ?>>Delete</button></td>
<td>
<form id="editMember_<?= $member->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-members-edit')->generateLink(['communityId' => $community->getId(), 'community_member_id' => $member->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="owner"></form>
<form id="deleteMember_<?= $member->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-members-delete')->generateLink(['communityId' => $community->getId(), 'community_member_id' => $member->getId()]) ?>" method="post" data-reload-on-success="true"></form>
<?= $member->getUser()->getDisplayName() ?>
</td>
<td style="text-align: center;">
<input type="checkbox" form="editMember_<?= $member->getId() ?>" name="owner" <?= $member->getOwner() ? 'checked' : '' ?> <?= !$editable ? 'disabled' : '' ?> />
</td>
<td style="text-align: right;">
<?php if ($editable): ?>
<button type="submit" form="editMember_<?= $member->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
--><button type="submit" form="deleteMember_<?= $member->getId() ?>" class="small red">Delete</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td><select type="text" id="new_member_user_id"></td>
<td></td>
<td style="text-align: right;"><button type="button" class="small" id="new_member_button" disabled>Add</button></td>
<td>
<form id="newMember" action="<?= Container::$routeCollection->getRoute('community-members-new')->generateLink(['communityId' => $community->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="user_id"></form>
<select type="text" form="newMember" name="user_id">
</td>
<td style="text-align: center;">
<input type="checkbox" form="newMember" name="owner" />
</td>
<td style="text-align: right;">
<button type="submit" form="newMember" name="submit" class="small" disabled>Add</button>
</td>
</tr>
</table>
<p class="formError justify marginTop"></p>
</div>
@endsection
@section(pageScript)
<script>
var searchUserUrl = '<?= Container::$routeCollection->getRoute('searchUser')->generateLink(['q' => 'QUERY']) ?>';
var newMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-new')->generateLink(['communityId' => $community->getId()]) ?>';
var editMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-edit')->generateLink(['communityId' => $community->getId()]) ?>';
var deleteMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-delete')->generateLink(['communityId' => $community->getId()]) ?>';
</script>
@endsection
@@ -0,0 +1,57 @@
@extends(templates/layout_normal)
@section(main)
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Exchange rates for <?= $currency->getCode() ?></h2>
<div class="box">
<table class="fullWidth">
<thead>
<tr>
<?php if ($editPermission): ?>
<th style="width: 25%; text-align: left;">Exchange rate</th>
<th style="width: 50%; text-align: left;">Valid from</th>
<th style="width: 25%;"></th>
<?php else: ?>
<th style="width: 35%; text-align: left;">Exchange rate</th>
<th style="width: 65%; text-align: left;">Valid from</th>
<?php endif; ?>
</tr>
</thead>
<?php foreach ($currencyExchangeRates as $currencyExchangeRate): ?>
<tr>
<?php if ($editPermission): ?>
<td>
<form id="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-edit')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode(), 'currency_exchange_rate_id' => $currencyExchangeRate->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="exchange_rate,valid_from"></form>
<form id="deleteCurrency_<?= $currencyExchangeRate->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-delete')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode(), 'currency_exchange_rate_id' => $currencyExchangeRate->getId()]) ?>" method="post" data-reload-on-success="true"></form>
<input type="number" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" class="text fullWidth" name="exchange_rate" value="<?= $currencyExchangeRate->getExchangeRate() ?>" min="0" step="0.000000001" required>
</td>
<td>
<input type="datetime-local" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" class="text fullWidth" name="valid_from" value="<?= $currencyExchangeRate->getValidFromDate()->format('Y-m-d\TH:i') ?>" required>
</td>
<td style="text-align: right;">
<button type="submit" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
--><button type="submit" form="deleteCurrency_<?= $currencyExchangeRate->getId() ?>" class="small red">Delete</button>
</td>
<?php else: ?>
<td><?= $currencyExchangeRate->getExchangeRate() ?></td>
<td><?= $currencyExchangeRate->getValidFromDate()->format('Y-m-d H:i') ?></td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
<?php if ($editPermission): ?>
<tr>
<td>
<form id="newExchangeRate" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-new')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="exchange_rate,valid_from"></form>
<input type="number" form="newExchangeRate" class="text fullWidth" name="exchange_rate" placeholder="Exchange rate" min="0" step="0.000000001" required>
</td>
<td>
<input type="datetime-local" form="newExchangeRate" class="text fullWidth" name="valid_from" placeholder="Valid from" required>
</td>
<td style="text-align: right;">
<button type="submit" form="newExchangeRate" name="submit" class="small" disabled>Add</button>
</td>
</tr>
<?php endif; ?>
</table>
<p class="formError justify marginTop"></p>
</div>
@endsection
+12 -2
View File
@@ -63,9 +63,19 @@ Container::$routeCollection->group('communities', function (RouteCollection $rou
$routeCollection->get('community-edit', 'edit', [CommunityController::class, 'getCommunityEdit']);
$routeCollection->post('community-edit-action', 'edit', [CommunityController::class, 'saveCommunity']);
$routeCollection->get('community-members', 'members', [CommunityController::class, 'getMembersEdit']);
$routeCollection->post('community-members-new', 'newMember', [CommunityController::class, 'newMember']);
$routeCollection->post('community-members-edit', 'editMember', [CommunityController::class, 'editMember']);
$routeCollection->post('community-members-new', 'newMember', [CommunityController::class, 'saveMember']);
$routeCollection->post('community-members-edit', 'editMember', [CommunityController::class, 'saveMember']);
$routeCollection->post('community-members-delete', 'deleteMember', [CommunityController::class, 'deleteMember']);
$routeCollection->get('community-currencies', 'currencies', [CommunityController::class, 'getCurrenciesEdit']);
$routeCollection->post('community-currencies-new', 'newCurrency', [CommunityController::class, 'saveCurrency']);
$routeCollection->post('community-currencies-edit', 'editCurrency', [CommunityController::class, 'saveCurrency']);
$routeCollection->post('community-currencies-delete', 'deleteCurrency', [CommunityController::class, 'deleteCurrency']);
$routeCollection->group('currencyExchangeRates', function (RouteCollection $routeCollection) {
$routeCollection->get('community-currency-exchange-rates', '{code}', [CommunityController::class, 'getCurrencyExchangeRates']);
$routeCollection->post('community-currency-exchange-rates-new', '{code}/new', [CommunityController::class, 'saveCurrencyExchangeRate']);
$routeCollection->post('community-currency-exchange-rates-edit', '{code}/edit', [CommunityController::class, 'saveCurrencyExchangeRate']);
$routeCollection->post('community-currency-exchange-rates-delete', '{code}/delete', [CommunityController::class, 'deleteCurrencyExchangeRate']);
});
});
});