← Code-Übersicht

InvoiceState.php

Pfad: src/Domain/Rechnung/InvoiceState.php

Ext: php

Größe: 3498 Bytes

Geändert: 2026-07-16T14:10:33+02:00

Frühere Version vom 2026-07-16T14:10:33+02:00 · zur aktuellen Fassung

<?php
declare(strict_types=1);

namespace Demo\Domain\Rechnung;

/**
 * Gesamtzustand der verarbeiteten Rechnungen fuer ein Laufpaket.
 */
final class InvoiceState
{
    /**
     * @param string        $schemaVersion  Datenmodell-Version.
     * @param string        $generatedAt    Generierungszeit.
     * @param list<InvoiceRecord> $records  Rechnungseintraege.
     */
    public function __construct(
        public readonly string $schemaVersion,
        public readonly string $generatedAt,
        public readonly array $records
    ) {
    }

    /**
     * @return InvoiceState Leerer initialer Zustand.
     */
    public static function empty(): self
    {
        return new self('1.1', date('c'), []);
    }

    /**
     * @param array<string,mixed> $data Serialisierte Daten.
     * @return InvoiceState Hydrierter Zustand.
     */
    public static function fromArray(array $data): self
    {
        $records = [];
        foreach (is_array($data['records'] ?? null) ? $data['records'] : [] as $row) {
            if (!is_array($row)) {
                continue;
            }

            $records[] = InvoiceRecord::fromArray($row);
        }

        return new self(
            schemaVersion: (string) ($data['schemaVersion'] ?? '1.1'),
            generatedAt: (string) ($data['generatedAt'] ?? date('c')),
            records: $records
        );
    }

    /**
     * @param InvoiceRecord $record Neuer oder aktualisierter Datensatz.
     * @return self Zustand mit aktualisiertem Datensatz.
     */
    public function withRecord(InvoiceRecord $record): self
    {
        $updated = [];
        $found = false;

        foreach ($this->records as $current) {
            if ($current->quelleId === $record->quelleId) {
                $updated[] = $record;
                $found = true;
                continue;
            }

            $updated[] = $current;
        }

        if (!$found) {
            $updated[] = $record;
        }

        return new self(
            schemaVersion: $this->schemaVersion,
            generatedAt: date('c'),
            records: $updated
        );

    }

    /**
     * @return list<InvoiceRecord> Alle Datensaetze.
     */
    public function all(): array
    {
        return $this->records;
    }

    /**
     * @param string $quelleId Quellkennung.
     * @return InvoiceRecord|null Treffer oder null.
     */
    public function findBySourceId(string $quelleId): ?InvoiceRecord
    {
        foreach ($this->records as $record) {
            if ($record->quelleId === $quelleId) {
                return $record;
            }
        }

        return null;
    }

    /**
     * @param string $rechnungsschluessel Rechnerischer Schluessel.
     * @return InvoiceRecord|null Treffer oder null.
     */
    public function findByRechnungsschluessel(string $rechnungsschluessel): ?InvoiceRecord
    {
        foreach ($this->records as $record) {
            if ($record->rechnungsschluessel === $rechnungsschluessel) {
                return $record;
            }
        }

        return null;
    }

    /**
     * @return array<string,mixed> Serialisierte Form.
     */
    public function toArray(): array
    {
        $records = [];

        foreach ($this->records as $record) {
            $records[] = $record->toArray();
        }

        return [
            'schemaVersion' => $this->schemaVersion,
            'generatedAt' => $this->generatedAt,
            'records' => $records,
        ];
    }
}