Skip to content

Commit

Permalink
Merge pull request #4 from koencaerels/development
Browse files Browse the repository at this point in the history
Merge development to master.
  • Loading branch information
koencaerels authored Jan 20, 2024
2 parents 97480c8 + 3b9fccf commit 697573d
Show file tree
Hide file tree
Showing 44 changed files with 2,687 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/php_build_and_qa_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ jobs:
npm run build-only
## —— Testing ————————————————————————————————————————————————————————————
# - name: Execute tests (Unit & Integration Tests) via PestPHP
# - name: Execute tests (Unit & Feature Tests) via PestPHP
# run: ./vendor/bin/pest
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Yoshi-Kan Website + Ledenbeheer

---

<p style="padding-top:9px;">
<p>
<img src="https://img.shields.io/github/license/koencaerels/yoshikan?style=flat" alt="GitHub license">
<img src="https://github.com/koencaerels/yoshikan/actions/workflows/php_build_and_qa_test.yml/badge.svg">
</p>
Expand All @@ -12,7 +12,21 @@ Yoshi-Kan Website + Ledenbeheer

## Requirements

...
* A webserver (Apache, NGINX, ...) with PHP 8.2 or higher.
* [Symfony](https://symfony.com/): PHP 8.2 or higher and these PHP extensions (which are installed and enabled by default in most PHP 8 installations):
Ctype, iconv, PCRE, Session, SimpleXML, and Tokenizer.
* [Composer](https://getcomposer.org/download/), which is used to install PHP packages.
* A database server (MySQL, PostgreSQL, SQLite, ... ) that is compatible with [Doctrine](https://www.doctrine-project.org/).
* Node.js,Yarn & NPM for the frontends build process.

### Third party services

* https://www.resend.com/ for sending emails concerning the two factor authentication
* https://www.brevo.com/ for sending the transactional emails
* https://www.mollie.com/ for the online payment services
* https://www.sentry.io/ for error logging and monitoring

You can configure these services in the `.env` file.

## Getting Started

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ public function __construct(
) {
}

public function resetItemsFromSubscription(Subscription $subscription): bool
{
$subscription = $this->subscriptionRepository->getById($subscription->getId());
$items = $this->subscriptionItemRepository->getBySubscription($subscription);
foreach ($items as $item) {
$this->subscriptionItemRepository->delete($item);
}
$subscription->clearItems();
$this->subscriptionRepository->save($subscription);

return true;
}

public function saveItemsFromSubscription(
Subscription $subscription,
Federation $federation,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/*
* This file is part of the Yoshi-Kan software.
*
* (c) Koen Caerels
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\YoshiKan\Application\Command\Member\ChangeLicense;

class ChangeLicense
{
// —————————————————————————————————————————————————————————————————————————
// Constructor
// —————————————————————————————————————————————————————————————————————————

private function __construct(
protected int $memberId,
protected int $federationId,
) {
}

// —————————————————————————————————————————————————————————————————————————
// Hydrate from a json command
// —————————————————————————————————————————————————————————————————————————

public static function hydrateFromJson(\stdClass $json): self
{
return new self(
$json->memberId,
$json->federationId,
);
}

// —————————————————————————————————————————————————————————————————————————
// Getters
// —————————————————————————————————————————————————————————————————————————

public function getMemberId(): int
{
return $this->memberId;
}

public function getFederationId(): int
{
return $this->federationId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

/*
* This file is part of the Yoshi-Kan software.
*
* (c) Koen Caerels
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\YoshiKan\Application\Command\Member\ChangeLicense;

use App\YoshiKan\Application\Command\Common\SubscriptionItemsFactory;
use App\YoshiKan\Application\Query\Member\Readmodel\SettingsReadModel;
use App\YoshiKan\Domain\Model\Member\MemberRepository;
use App\YoshiKan\Domain\Model\Member\SettingsCode;
use App\YoshiKan\Domain\Model\Member\Subscription;
use App\YoshiKan\Domain\Model\Member\SubscriptionItemRepository;
use App\YoshiKan\Domain\Model\Member\SubscriptionStatus;
use App\YoshiKan\Domain\Model\Member\SubscriptionType;
use App\YoshiKan\Infrastructure\Database\Member\FederationRepository;
use App\YoshiKan\Infrastructure\Database\Member\LocationRepository;
use App\YoshiKan\Infrastructure\Database\Member\SettingsRepository;
use App\YoshiKan\Infrastructure\Database\Member\SubscriptionRepository;
use Doctrine\ORM\EntityManagerInterface;

class ChangeLicenseHandler
{
// ———————————————————————————————————————————————————————————————
// Constructor
// ———————————————————————————————————————————————————————————————

public function __construct(
protected MemberRepository $memberRepository,
protected SubscriptionRepository $subscriptionRepository,
protected SubscriptionItemRepository $subscriptionItemRepository,
protected FederationRepository $federationRepository,
protected LocationRepository $locationRepository,
protected SettingsRepository $settingsRepository,
protected EntityManagerInterface $entityManager,
) {
}

// ———————————————————————————————————————————————————————————————
// Handle
// ———————————————————————————————————————————————————————————————

public function change(ChangeLicense $command): \stdClass
{
$member = $this->memberRepository->getById($command->getMemberId());
$federation = $this->federationRepository->getById($command->getFederationId());
$settings = $this->settingsRepository->findByCode(SettingsCode::ACTIVE->value);

$extraTraining = false;
if (3 === $member->getNumberOfTraining()) {
$extraTraining = true;
}

// -- calculate the new license dates -------------------------------

$now = new \DateTimeImmutable();
$licenseStart = $now->setDate((int) $now->format('Y'), (int) $now->format('m'), 1);
$licenseEnd = $licenseStart->modify('+1 year');

// -- create a new subscription -------------------------------------

$subscription = Subscription::make(
$this->subscriptionRepository->nextIdentity(),
$member->getContactFirstname(),
$member->getContactLastname(),
$member->getContactEmail(),
$member->getContactPhone(),
$member->getFirstname(),
$member->getLastname(),
$member->getDateOfBirth(),
$member->getGender(),
SubscriptionType::RENEWAL_LICENSE,
$member->getNumberOfTraining(),
$extraTraining,
false,
false,
false,
'Wijziging vergunning naar '.$federation->getName(),
$member->getLocation(),
json_decode(json_encode(SettingsReadModel::hydrateFromModel($settings)), true),
$federation,
$member->getMemberSubscriptionStart(),
$member->getMemberSubscriptionEnd(),
0,
false,
false,
true,
$licenseStart,
$licenseEnd,
$federation->getYearlySubscriptionFee(),
true,
false,
);

$subscription->setMember($member);
$subscription->changeStatus(SubscriptionStatus::AWAITING_PAYMENT);
$subscription->calculate();
$this->subscriptionRepository->save($subscription);
$this->entityManager->flush();

// -- make some subscription lines ----------------------------------

$subscriptionItemFactory = new SubscriptionItemsFactory(
$this->subscriptionRepository,
$this->subscriptionItemRepository
);
$resultItems = $subscriptionItemFactory->saveItemsFromSubscription(
$subscription,
$federation,
$settings
);

// -- flag new dates in the member ----------------------------------

$member->setLicenseDates(
$subscription->getLicenseStart(),
$subscription->getLicenseEnd()
);
$member->syncFromSubscription(
federation: $federation,
numberOfTraining: $subscription->getNumberOfTraining(),
isHalfYearSubscription: $subscription->isMemberSubscriptionIsHalfYear(),
);

$this->memberRepository->save($member);
$this->entityManager->flush();

// -- compile a result class ----------------------------------------

$subscriptionId = $this->subscriptionRepository->getMaxId();
$result = new \stdClass();
$result->id = $subscriptionId;
$result->reference = 'YKS-'.$subscriptionId.': '.$member->getFirstname().' '.$member->getLastName();

return $result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the Yoshi-Kan software.
*
* (c) Koen Caerels
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\YoshiKan\Application\Command\Member\ChangeLicense;

trait ChangeLicenseTrait
{
public function changeLicense(\stdClass $jsonCommand): \stdClass
{
$this->permission->CheckRole(['ROLE_DEVELOPER', 'ROLE_ADMIN', 'ROLE_CHIEF_EDITOR']);

$command = ChangeLicense::hydrateFromJson($jsonCommand);
$handler = new ChangeLicenseHandler(
memberRepository: $this->memberRepository,
subscriptionRepository: $this->subscriptionRepository,
subscriptionItemRepository: $this->subscriptionItemRepository,
federationRepository: $this->federationRepository,
locationRepository: $this->locationRepository,
settingsRepository: $this->settingsRepository,
entityManager: $this->entityManager,
);

$result = $handler->change($command);
$this->entityManager->flush();

return $result;
}
}
Loading

0 comments on commit 697573d

Please sign in to comment.