Completed
Push — feature/multi_order ( eb7707 )
by Laurent
01:37
created

getAmountByMission()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 */
5
6
namespace flightlog\command;
7
8
use DoliDB;
9
use Exception;
10
use ExpenseReport;
11
use ExpenseReportLine;
12
use flightlog\exceptions\NoMissionException;
13
use flightlog\model\missions\FlightMission;
14
use flightlog\query\FlightForQuarterAndPilotQuery;
15
use flightlog\query\FlightForQuarterAndPilotQueryHandler;
16
use flightlog\query\GetPilotsWithMissionsQuery;
17
use flightlog\query\GetPilotsWithMissionsQueryHandler;
18
use PilotMissions;
19
use stdClass;
20
use Translate;
21
use User;
22
use Webmozart\Assert\Assert;
23
24
/**
25
 * Create the expense not for flights.
26
 *
27
 * @author Laurent De Coninck <[email protected]>
28
 */
29
class CreateExpenseNoteCommandHandler
30
{
31
    const FLIGHT_ELEMENT = 'flightlog_bbcvols';
32
33
    /**
34
     * @var stdClass
35
     */
36
    protected $conf;
37
38
    /**
39
     * @var Translate
40
     */
41
    protected $langs;
42
43
    /**
44
     * @var User
45
     */
46
    protected $user;
47
48
    /**
49
     * @var DoliDB
50
     */
51
    protected $db;
52
53
    /**
54
     * @var GetPilotsWithMissionsQueryHandler
55
     */
56
    private $getMissionsQueryHandler;
57
58
    /**
59
     * @var FlightForQuarterAndPilotQueryHandler
60
     */
61
    private $flightForQuarterAndPilotHandler;
62
63
64
    /**
65
     * @param DoliDB                               $db
66
     * @param stdClass                             $conf
67
     * @param User                                 $user
68
     * @param Translate                            $langs
69
     * @param GetPilotsWithMissionsQueryHandler    $missionsQueryHandler
70
     * @param FlightForQuarterAndPilotQueryHandler $flightForQuarterAndPilotQueryHandler
71
     */
72
    public function __construct(
73
        $db,
74
        $conf,
75
        $user,
76
        $langs,
77
        GetPilotsWithMissionsQueryHandler $missionsQueryHandler,
78
        FlightForQuarterAndPilotQueryHandler $flightForQuarterAndPilotQueryHandler
79
    ) {
80
        $this->db = $db;
81
        $this->conf = $conf;
82
        $this->user = $user;
83
        $this->langs = $langs;
84
        $this->getMissionsQueryHandler = $missionsQueryHandler;
85
        $this->flightForQuarterAndPilotHandler = $flightForQuarterAndPilotQueryHandler;
86
    }
87
88
    /**
89
     * @param CreateExpenseNoteCommand $command
90
     *
91
     * @throws Exception
92
     */
93
    public function __invoke(CreateExpenseNoteCommand $command)
94
    {
95
        $missions = $this->getMissionsQueryHandler->__invoke(new GetPilotsWithMissionsQuery($command->getYear(), $command->getQuartile()));
96
97
        if (!$missions->hasMission()) {
98
            throw new NoMissionException();
99
        }
100
101
        /** @var PilotMissions $currentMission */
102
        foreach ($missions as $currentMission) {
103
            $expenseNote = $this->createExpenseNote($command);
104
105
            $flightsForQuarter = $this->flightForQuarterAndPilotHandler->__invoke(new FlightForQuarterAndPilotQuery($currentMission->getPilotId(),
106
                $command->getQuartile(), $command->getYear()));
107
108
            /** @var FlightMission $currentFlightForQuarter */
109
            foreach ($flightsForQuarter as $currentFlightForQuarter) {
110
                $expenseNote = $this->addKilometersLine($currentFlightForQuarter, $expenseNote);
111
                $expenseNote = $this->addMissionLine($currentFlightForQuarter, $expenseNote);
112
            }
113
114
            $expenseNote = $this->saveExpenseNote($currentMission->getPilotId(), $expenseNote);
115
            if (null === $expenseNote) {
116
                dol_htmloutput_errors("Erreur lors de la création de la note de frais", $expenseNote->errors);
117
                continue;
118
            }
119
120
            /** @var FlightMission $currentFlightForQuarter */
121
            foreach ($flightsForQuarter as $currentFlightForQuarter) {
122
                $expenseNote->add_object_linked(self::FLIGHT_ELEMENT, $currentFlightForQuarter->getId());
123
            }
124
125
            $expenseNote->fetch($expenseNote->id);
126
            $expenseNote->setValidate($this->user);
127
            $expenseNote->setApproved($this->user);
128
            $expenseNote->setDocModel($this->user, "standard");
129
130
            $error = false;
131
            //$error = $expenseNote->generateDocument($expenseNote->modelpdf, $this->langs) <= 0;
132
133
            if (!$error) {
134
                dol_htmloutput_mesg(sprintf("Notes de frais crée pour %s", $currentMission->getPilotName()));
135
                continue;
136
            }
137
138
            dol_htmloutput_errors(sprintf("Notes de frais non crée pour %s", $currentMission->getPilotName()));
139
        }
140
    }
141
142
    /**
143
     * @param FlightMission $currentFlightForQuarter
144
     * @param ExpenseReport $expenseNote
145
     *
146
     * @return ExpenseReport
147
     */
148
    private function addKilometersLine(FlightMission $currentFlightForQuarter, $expenseNote)
149
    {
150
        $object_ligne = new ExpenseReportLine($this->db);
151
        $object_ligne->comments = $this->langs->trans(sprintf("Vol (id: %d) %s à %s  détail: %s",
152
            $currentFlightForQuarter->getId(), $currentFlightForQuarter->getStartPoint(),
153
            $currentFlightForQuarter->getEndPoint(), $currentFlightForQuarter->getKilometersComment()));
154
        $object_ligne->qty = $currentFlightForQuarter->getNumberOfKilometers();
155
        $object_ligne->value_unit = $this->getAmountByKilometer();
156
157
        $object_ligne->date = $currentFlightForQuarter->getDate()->format('Y-m-d');
158
159
        $object_ligne->fk_c_type_fees = 2;
160
        $object_ligne->fk_projet = '';
161
162
        $object_ligne->vatrate = price2num($this->getVatRate());
163
164
        $tmp = calcul_price_total($object_ligne->qty, $object_ligne->value_unit, 0, $this->getVatRate(), 0, 0, 0, 'TTC',
165
            0,
166
            0, '');
167
        $object_ligne->total_ttc = $tmp[2];
168
        $object_ligne->total_ht = $tmp[0];
169
        $object_ligne->total_tva = $tmp[1];
170
171
        $expenseNote->lines[] = $object_ligne;
172
173
        return $expenseNote;
174
    }
175
176
    /**
177
     * @param FlightMission $currentFlightForQuarter
178
     * @param ExpenseReport $expenseReport
179
     *
180
     * @return ExpenseReport
181
     */
182
    private function addMissionLine(FlightMission $currentFlightForQuarter, ExpenseReport $expenseReport)
183
    {
184
        $object_ligne = new ExpenseReportLine($this->db);
185
        $object_ligne->comments = sprintf("Vol (id: %d) %s à %s", $currentFlightForQuarter->getId(),
186
            $currentFlightForQuarter->getStartPoint(), $currentFlightForQuarter->getEndPoint());
187
        $object_ligne->qty = 1;
188
        $object_ligne->value_unit = $this->getAmountByMission();
189
190
        $object_ligne->date = $currentFlightForQuarter->getDate()->format('Y-m-d');
191
192
        $object_ligne->fk_c_type_fees = 8;
193
        $object_ligne->fk_projet = '';
194
195
        $object_ligne->vatrate = price2num($this->getVatRate());
196
197
        $tmp = calcul_price_total($object_ligne->qty, $object_ligne->value_unit, 0, $this->getVatRate(), 0, 0, 0, 'TTC',
198
            0,
199
            0, '');
200
        $object_ligne->total_ttc = $tmp[2];
201
        $object_ligne->total_ht = $tmp[0];
202
        $object_ligne->total_tva = $tmp[1];
203
204
        $expenseReport->lines[] = $object_ligne;
205
206
        return $expenseReport;
207
    }
208
209
    /**
210
     * Get the unit price pe KM.
211
     *
212
     * @return int
213
     */
214
    private function getAmountByKilometer()
215
    {
216
        return isset($this->conf->global->BBC_FLIGHT_LOG_TAUX_REMB_KM) ? $this->conf->global->BBC_FLIGHT_LOG_TAUX_REMB_KM : 0;
217
    }
218
219
    /**
220
     * @return mixed
221
     */
222
    private function getAmountByMission()
223
    {
224
        return $this->conf->global->BBC_FLIGHT_LOG_UNIT_PRICE_MISSION;
225
    }
226
227
    /**
228
     * @return string
229
     */
230
    private function getVatRate()
231
    {
232
        return '0.000';
233
    }
234
235
    /**
236
     * @param CreateExpenseNoteCommand $command
237
     *
238
     * @return ExpenseReport
239
     * @throws Exception
240
     */
241
    private function createExpenseNote(CreateExpenseNoteCommand $command)
242
    {
243
        $startDate = new \DateTime();
244
        $startDate->setDate($command->getYear(), (($command->getQuartile() - 1) * 3) + 1, 1);
245
246
        $endDate = new \DateTime();
247
        $endDate->setDate($command->getYear(), $command->getQuartile() * 3, 1);
248
        $endDate->add(new \DateInterval("P1M"))->sub(new \DateInterval("P1D"));
249
250
        $object = new ExpenseReport($this->db);
251
        $object->date_debut = $startDate->format("Y-m-d");
252
        $object->date_fin = $endDate->format("Y-m-d");
253
254
        $object->fk_statut = 1;
255
        $object->fk_user_validator = $command->getUserValidatorId();
256
        $object->note_public = $command->getPublicNote();
257
        $object->note_private = $command->getPrivateNote();
258
259
        return $object;
260
    }
261
262
    /**
263
     * @param int           $currentMissionUserId
264
     * @param ExpenseReport $expenseNote
265
     *
266
     * @return ExpenseReport
267
     */
268
    private function saveExpenseNote($currentMissionUserId, ExpenseReport $expenseNote)
269
    {
270
        Assert::integerish($currentMissionUserId);
271
272
        $expenseNoteUser = new User($this->db);
273
        $expenseNoteUser->id = $currentMissionUserId;
274
        $id = $expenseNote->create($expenseNoteUser);
275
        if($id < 0){
276
            return null;
277
        }
278
279
        return $expenseNote;
280
    }
281
282
}