summaryrefslogtreecommitdiff
path: root/src/Model/Event/SendUnits.php
blob: ed4d5b61f10234ce84a202d11601526f26cdb5d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php

namespace App\Model\Event;

use App\DB;

class SendUnits extends BaseEvent
{
  public string $type;

  public int $amount;
  public string $unit;

  public int $source;
  public int $destination;

  public ?int $home = null;
  public ?int $residence = null;

  public bool $isCanceled = false;

  /**
   * @return void
   */
  public function __invoke(): void
  {
    if ($this->isCanceled) {
      if ($this->type === 'SendBack' || $this->type === 'Recall') {
        $this->source = $this->home;
        $this->destination = $this->residence;

        $this->borrow();
      }
    }

    else {
      if ($this->type === 'Recall' || $this->type === 'SendBack') {
        $this->return();
      }

      else if ($this->type === 'Borrow') {
        $this->borrow();
      }

      else if ($this->type === 'Gift') {
        $this->gift();
      }
    }
  }

  private function return(): void
  {
    DB::query(
      <<<SQL
      insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id)
      values (:amount, :type, false, :id, :id)
        on conflict (type, home_village_id, residence_village_id, is_traveling)
        do update set amount = village_units.amount+:amount
      SQL,
      ['amount' => $this->amount, 'type' => $this->unit, 'id' => $this->destination]
    );

    DB::query(
      'delete from village_units where type=:type and home_village_id=:home and residence_village_id=:residence and is_traveling=true',
      ['type' => $this->unit, 'home' => $this->destination, 'residence' => $this->source]
    );
  }

  private function borrow(): void
  {
    DB::query(
      <<<SQL
      insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id)
      values (:amount, :type, false, :home, :residence)
        on conflict (type, home_village_id, residence_village_id, is_traveling)
        do update set amount = village_units.amount+:amount
      SQL,
      ['amount' => $this->amount, 'type' => $this->unit, 'home' => $this->source, 'residence' => $this->destination]
    );

    DB::query(
      'delete from village_units where type=:type and home_village_id=:home and residence_village_id=:residence and is_traveling=true',
      ['type' => $this->unit, 'home' => $this->source, 'residence' => $this->source]
    );
  }

  private function gift(): void
  {
    DB::query(
      <<<SQL
      insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id)
      values (:amount, :type, false, :home, :residence)
        on conflict (type, home_village_id, residence_village_id, is_traveling)
        do update set amount = village_units.amount+:amount
      SQL,
      ['amount' => $this->amount, 'type' => $this->unit, 'home' => $this->destination, 'residence' => $this->residence]
    );

    DB::query(
      'delete from village_units where type=:type and home_village_id=:home and residence_village_id=:residence and is_traveling=true',
      ['type' => $this->unit, 'home' => $this->source, 'residence' => $this->source]
    );
  }

  public function dbInsert(): void
  {
    DB::query(
      'insert into events (time, village_id) VALUES (:time, :village_id)',
      ['time' => $this->event->time->format('c'), 'village_id' => $this->event->villageId]
    );

    DB::query(
      <<<SQL
      insert into events_send_units (event_id, type, amount, unit, source, destination, home, residence, is_canceled)
      VALUES (:event_id, :type, :amount, :unit, :source, :destination, :home, :residence, :is_canceled)
      SQL,
      [
        'event_id' => DB::$connection->lastInsertId(),
        'type' => $this->type,
        'amount' => $this->amount,
        'unit' => $this->unit,
        'source' => $this->source, 'destination' => $this->destination,
        'home' => $this->home, 'residence' => $this->residence,
        'is_canceled' => $this->isCanceled ?: 0, // @see https://www.php.net/manual/de/pdostatement.execute.php#126013
      ]
    );
  }

  public function dbDelete(): void
  {
    DB::query('delete from events where id=:id', ['id' => $this->eventId]);
    DB::query('delete from events_send_units where id=:id', ['id' => $this->id]);
  }
}