Completed
Push — feature/link_expense_note ( 1fd4be )
by Laurent
01:47
created

CreateExpenseNoteCommandHandler::__invoke()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

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