Skip to content

Commit

Permalink
Add route to patch dive data from divecomputer
Browse files Browse the repository at this point in the history
  • Loading branch information
blackshadev committed Sep 16, 2023
1 parent ae7f169 commit 0470515
Show file tree
Hide file tree
Showing 14 changed files with 415 additions and 174 deletions.
180 changes: 37 additions & 143 deletions app/Application/Dives/DataTransferObjects/DiveData.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,155 +9,49 @@
use App\Application\Places\DataTransferObjects\PlaceData;
use App\Application\Tags\DataTransferObjects\TagData;
use Carbon\Carbon;
use Carbon\CarbonInterface;

final class DiveData
{
private ?Carbon $date = null;

private ?int $divetime = null;

private ?float $maxDepth = null;

private ?int $computerId = null;

private ?string $fingerprint = null;

private PlaceData $place;

private ?array $tanks = null;

private ?array $tags = null;

private ?array $buddies = null;

private ?array $samples = null;

public function __construct()
{
$this->place = new PlaceData();
/**
* @param CarbonInterface|null $date
* @param int|null $divetime
* @param float|null $maxDepth
* @param int|null $computerId
* @param string|null $fingerprint
* @param PlaceData $placeData
* @param array<TankData>|null $tanks
* @param array<TagData>|null $tags
* @param array<BuddyData>|null $buddies
* @param array|null $samples
*/
public function __construct(
public readonly ?CarbonInterface $date,
public readonly ?int $divetime,
public readonly ?float $maxDepth,
public readonly ?int $computerId,
public readonly ?string $fingerprint,
public readonly PlaceData $placeData,
public readonly ?array $tanks,
public readonly ?array $tags,
public readonly ?array $buddies,
public readonly ?array $samples,
) {
}

public static function fromArray(array $data): self
{
$diveData = new static();
$diveData->setData($data);
return $diveData;
}

public function getDate(): ?Carbon
{
return $this->date;
}

public function getDivetime(): ?int
{
return $this->divetime;
}

public function getMaxDepth(): ?float
{
return $this->maxDepth;
}

public function getComputerId(): ?int
{
return $this->computerId;
}

public function getFingerprint(): ?string
{
return $this->fingerprint;
}

public function getPlace(): PlaceData
{
return $this->place;
}

/** @return null|TagData[] */
public function getTags(): ?array
{
return $this->tags;
}

/** @return null|BuddyData[] */
public function getBuddies(): ?array
{
return $this->buddies;
}

/** @return null|TankData[] */
public function getTanks(): ?array
{
return $this->tanks;
}

public function setDate(?Carbon $date): void
{
$this->date = $date;
}

public function setDivetime(?int $divetime): void
{
$this->divetime = $divetime;
}

public function setMaxDepth(?float $maxDepth): void
{
$this->maxDepth = $maxDepth;
}

public function setComputerId(?int $computerId): void
{
$this->computerId = $computerId;
}

public function setFingerprint(?string $fingerprint): void
{
$this->fingerprint = $fingerprint;
}

public function setPlace(PlaceData $place): void
{
$this->place = $place;
}

public function setTanks(?array $tanks): void
{
$this->tanks = $tanks;
}

public function getSamples(): ?array
{
return $this->samples;
}

public function setSamples(?array $samples): void
{
$this->samples = $samples;
}

public function setTags(?array $tags): void
{
$this->tags = $tags;
}

public function setBuddies(?array $buddies): void
{
$this->buddies = $buddies;
}

private function setData(array $data): void
{
$this->date = Carbon::parse($data['date']) ?? null;
$this->divetime = $data['divetime'] ?? null;
$this->maxDepth = $data['max_depth'] ?? null;
$this->computerId = $data['computer_id'] ?? null;
$this->fingerprint = $data['fingerprint'] ?? null;
$this->samples = $data['samples'] ?? null;
$this->place = PlaceData::fromArray($data['place'] ?? []);
$this->tags = array_map(fn ($tagData) => TagData::fromArray($tagData), $data['tags'] ?? []);
$this->buddies = array_map(fn ($buddyData) => BuddyData::fromArray($buddyData), $data['buddies'] ?? []);
$this->tanks = array_map(fn ($tank) => TankData::fromArray($tank), $data['tanks'] ?? []);
return new static(
date: Carbon::parse($data['date']) ?? null,
divetime: $data['divetime'] ?? null,
maxDepth: $data['max_depth'] ?? null,
computerId: $data['computer_id'] ?? null,
fingerprint: $data['fingerprint'] ?? null,
placeData: PlaceData::fromArray($data['place'] ?? []),
tanks: array_map(fn ($tank) => TankData::fromArray($tank), $data['tanks'] ?? []),
tags: array_map(fn ($tagData) => TagData::fromArray($tagData), $data['tags'] ?? []),
buddies: array_map(fn ($buddyData) => BuddyData::fromArray($buddyData), $data['buddies'] ?? []),
samples: $data['samples'] ?? null
);
}
}
94 changes: 94 additions & 0 deletions app/Application/Dives/Services/DiveComputerDataPatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace App\Application\Dives\Services;

use App\Application\Dives\DataTransferObjects\DiveData;
use App\Application\Equipment\DataTransferObjects\TankData;
use App\Domain\Computers\Repositories\ComputerRepository;
use App\Domain\Dives\Entities\Dive;
use App\Domain\Dives\Entities\DiveTank;
use App\Domain\Dives\Repositories\DiveRepository;
use App\Domain\Dives\ValueObjects\DiveId;
use App\Domain\Dives\ValueObjects\GasMixture;
use App\Domain\Dives\ValueObjects\TankPressures;
use App\Domain\Support\Arrg;
use App\Domain\Users\Entities\User;
use Webmozart\Assert\Assert;

final class DiveComputerDataPatcher
{
public function __construct(
private DiveRepository $diveRepository,
private ComputerRepository $computerRepository,
private DiveCreatorInterface $creator,
) {
}

public function patchOrCreate(User $user, DiveData $diveData): DiveId
{
$dive = $this->diveRepository->findByFingerprint(
$user->getId(),
$diveData->computerId,
$diveData->fingerprint
);

if ($dive === null) {
return $this->creator->create($user, $diveData);
}

return $this->patch($dive, $diveData);
}

/**
* Patches all given dive attributes except the data unavailable from dive computers:
* - buddies
* - tags
* - places
*/
public function patch(Dive $dive, DiveData $diveData): DiveId
{
Assert::notNull($diveData->date);
Assert::notNull($diveData->maxDepth);
Assert::notNull($diveData->divetime);
Assert::notNull($diveData->computerId);
Assert::notNull($diveData->fingerprint);

$computer = $this->computerRepository->findById($diveData->computerId);

$dive->setDate($diveData->date);
$dive->setDivetime($diveData->divetime);
$dive->setMaxDepth($diveData->maxDepth);
$dive->setFingerprint($diveData->fingerprint);
$dive->setComputer($computer);

$computer->updateLastRead($dive->getDate(), $dive->getFingerprint());

if ($diveData->samples !== null) {
$dive->setSamples($diveData->samples);
}

if ($diveData->tanks !== null) {
$tanks = Arrg::map(
$diveData->tanks,
static fn (TankData $tank) => DiveTank::new(
diveId: null,
volume: $tank->getVolume(),
gasMixture: new GasMixture(
oxygen: $tank->getOxygen(),
),
pressures: new TankPressures(
type: $tank->getPressures()->getType(),
begin: $tank->getPressures()->getBegin(),
end: $tank->getPressures()->getEnd(),
),
)
);

$dive->setTanks($tanks);
}

return $this->diveRepository->save($dive);
}
}
18 changes: 9 additions & 9 deletions app/Application/Dives/Services/DiveCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use App\Domain\Dives\ValueObjects\DiveId;
use App\Domain\Users\Entities\User;

final class DiveCreator
final class DiveCreator implements DiveCreatorInterface
{
public function __construct(
private DiveUpdater $diveUpdater,
Expand All @@ -22,22 +22,22 @@ public function create(User $user, DiveData $diveData): DiveId
{
$dive = Dive::new(
userId: $user->getId(),
date: $diveData->getDate(),
divetime: $diveData->getDivetime(),
maxDepth: $diveData->getMaxDepth(),
fingerprint: $diveData->getFingerprint(),
date: $diveData->date,
divetime: $diveData->divetime,
maxDepth: $diveData->maxDepth,
fingerprint: $diveData->fingerprint,
);

$computer = $diveData->getComputerId() !== null ?
$this->computerRepository->findById($diveData->getComputerId()) : null;
$computer = $diveData->computerId !== null ?
$this->computerRepository->findById($diveData->computerId) : null;
$dive->setComputer($computer);

if (!is_null($computer) && !is_null($dive->getFingerprint())) {
$computer->updateLastRead($dive->getDate(), $dive->getFingerprint());
}

if ($diveData->getSamples() !== null) {
$dive->setSamples($diveData->getSamples());
if ($diveData->samples !== null) {
$dive->setSamples($diveData->samples);
}

$diveId = $this->diveUpdater->update($dive, $diveData);
Expand Down
14 changes: 14 additions & 0 deletions app/Application/Dives/Services/DiveCreatorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace App\Application\Dives\Services;

use App\Application\Dives\DataTransferObjects\DiveData;
use App\Domain\Dives\ValueObjects\DiveId;
use App\Domain\Users\Entities\User;

interface DiveCreatorInterface
{
public function create(User $user, DiveData $diveData): DiveId;
}
4 changes: 2 additions & 2 deletions app/Application/Dives/Services/DiveTankCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public function __construct(
public function create(Dive $dive, TankData $data): DiveTank
{
$diveTank = DiveTank::new(
diveId: $dive->getDiveId(),
diveId: $dive->getDiveId()->value(),
volume: $data->getVolume(),
gasMixture: new GasMixture(
oxygen: $data->getOxygen()
),
pressures: new TankPressures(
type: $data->getPressures()->getType(),
begin: $data->getPressures()->getBegin(),
end: $data->getPressures()->getEnd(),
type: $data->getPressures()->getType(),
)
);
$this->diveTankRepository->save($diveTank);
Expand Down
2 changes: 1 addition & 1 deletion app/Application/Dives/Services/DiveTankUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public function update(DiveTank $diveTank, TankData $data): void
$diveTank->setGasMixture(new GasMixture($data->getOxygen()));
$diveTank->setPressures(
new TankPressures(
type: $data->getPressures()->getType(),
begin: $data->getPressures()->getBegin(),
end: $data->getPressures()->getEnd(),
type: $data->getPressures()->getType(),
)
);
$diveTank->setVolume($data->getVolume());
Expand Down
Loading

0 comments on commit 0470515

Please sign in to comment.