Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
93.75% covered (success)
93.75%
15 / 16
CRAP
95.70% covered (success)
95.70%
89 / 93
PurchaseOrderController
0.00% covered (danger)
0.00%
0 / 1
93.75% covered (success)
93.75%
15 / 16
24
95.70% covered (success)
95.70%
89 / 93
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 indexFiltered
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 index
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 store
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
8 / 8
 createPoNumber
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
7 / 7
 show
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 update
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 destroy
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 download
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
12 / 12
 preview
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
9 / 9
 dispatchEmail
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
17 / 17
 sendEmail
0.00% covered (danger)
0.00%
0 / 1
1.12
50.00% covered (warning)
50.00%
4 / 8
 getStrips
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getHtml
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 getFilePath
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 validateData
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
1<?php
2
3namespace Qmp\Laravel\PurchaseOrder\Controllers;
4
5use App\User;
6use Carbon\Carbon;
7use Illuminate\Database\Eloquent\Collection;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Response;
10use Illuminate\Http\Request;
11use Illuminate\Support\Facades\Log;
12use Illuminate\Support\Facades\Storage;
13use Qmp\Laravel\Mail\MailSender;
14use Qmp\Laravel\MicroService\Client\Client;
15use Qmp\Laravel\MicroService\Client\Tools\Request as ClientRequest;
16use Qmp\Laravel\MicroService\Controllers\AbstractMicroServiceController;
17use Illuminate\Validation\Rule;
18use Exception;
19use Error;
20use Illuminate\Support\Facades\Redis;
21use Illuminate\Support\Str;
22use Qmp\Laravel\ApiFilterRequest\Middleware\FilterRequest;
23use Qmp\Laravel\MongoJsExecutor\Executor;
24use Qmp\Laravel\PurchaseOrder\Mail\MailPurchaseOrder;
25use Qmp\Laravel\PurchaseOrder\Models\PurchaseOrder;
26
27class PurchaseOrderController extends AbstractMicroServiceController
28{
29    const STORAGE_DISK = 'temp';
30    const TEMP_STORAGE_FOLDER = 'purchase-order';
31
32    public function __construct(Request $request)
33    {
34        $this->middleware(FilterRequest::class)->only('indexFiltered');
35
36        parent::__construct($request);
37    }
38
39    /**
40     * @param \Illuminate\Http\Request $request
41     * @return \Illuminate\Http\JsonResponse
42     */
43    public function indexFiltered(Request $request): JsonResponse
44    {
45        $filters = $request->filter_request;
46        $purchaseOrder = PurchaseOrder::selectAll($filters);
47
48        return response()->json($purchaseOrder);
49    }
50
51    /**
52     * Display a listing of the resource.
53     *
54     * @return Collection
55     */
56    public function index(): Collection
57    {
58        return PurchaseOrder::all();
59    }
60
61    /**
62     * Store a newly created resource in storage.
63     *
64     * @param  \Illuminate\Http\Request $request
65     * @return \Illuminate\Http\JsonResponse
66     */
67    public function store(Request $request): JsonResponse
68    {
69
70        $validatedData = $this->validateData($request);
71
72        try {
73            $validatedData['poNumber'] = $this->createPoNumber($validatedData['commercial']);
74
75            $model = PurchaseOrder::create($validatedData);
76
77            Redis::publish('purchase-order', json_encode(['action' => 'create', 'id' => $model->_id]));
78            return response()->json(['status' => 'ok', 'datas' => $model->ToArray()], Response::HTTP_CREATED);
79        } catch (Exception | Error $e) {
80            Log::debug('Unable to store purchase order : ' . var_export(['message' => $e->getMessage(), 'line' => $e->getLine(), 'file' => $e->getFile()], true));
81            return response()->json(['status' => 'ko', 'message' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
82        }
83    }
84
85    /**
86     * @param $commercial
87     * @return string
88     * @throws \Qmp\Laravel\MongoJsExecutor\Exceptions\MissingValueArgument
89     */
90    protected function createPoNumber($commercial): string
91    {
92        $executor = Executor::fromJs(js('count-purchase-orders'))->withData([
93            'commercialId' => $commercial['id']
94        ]);
95        $counter = sprintf('%03d', $executor->execute() + 1);
96        $com = implode('', array_map(function($str) { 
97            return ucfirst(substr($str, 0, 1));
98        }, explode(' ', $commercial['name'])));
99
100        return sprintf('%s-%s-%s', Carbon::now()->format('Ymd'), $counter, $com);
101    }
102
103    /**
104     * Display the specified resource.
105     *
106     * @param $id
107     * @return \Illuminate\Http\JsonResponse
108     */
109    public function show($id): JsonResponse
110    {
111        $model = PurchaseOrder::findOrFail($id);
112        return response()->json($model);
113    }
114
115    /**
116     * Update the specified resource in storage.
117     *
118     * @param \Illuminate\Http\Request $request
119     * @param $id
120     * @return \Illuminate\Http\JsonResponse
121     */
122    public function update(Request $request, $id): JsonResponse
123    {
124        $validatedData = $this->validateData($request, $id);
125        $model = PurchaseOrder::findOrFail($id);
126
127        $result = $model->update($validatedData);
128
129        Redis::publish('purchase-order', json_encode(['action' => 'update', 'id' => $model->_id]));
130        return response()->json(['status' => $result ? 'ok' : 'ko']);
131    }
132
133    /**
134     * Remove the specified resource from storage.
135     *
136     * @param $id
137     * @return \Illuminate\Http\JsonResponse
138     */
139    public function destroy($id): JsonResponse
140    {
141        $model = PurchaseOrder::findOrFail($id);
142        $model->delete();
143        Redis::publish('purchase-order', json_encode(['action' => 'delete', 'id' => $id]));
144        return response()->json(["status" => "ok"]);
145    }
146
147    /**
148     * Download purchase order file
149     *
150     * @param Request $request
151     * @param $id
152     * @return \Illuminate\Http\JsonResponse
153     */
154    public function download(Request $request, $id): JsonResponse
155    {
156        $model = PurchaseOrder::findOrFail($id);
157
158        try {
159
160            $data = [
161                'type' => 'pdf',
162                'output_path' => $this->getFilePath($model),
163                'content' => $this->getHtml($model)
164            ];
165
166            $ClientRequest = ClientRequest::createObject('service_file_generator', 'generate', ['body' => $data]);
167            $response = Client::systemSend('post', $ClientRequest);
168
169            if (!Str::startsWith($response->code, 2)) {
170                throw new \Exception("unable generate pdf: service_file_generator $response->code $response->body");
171            }
172
173            return response()->json(['status' => 'ok', 'path' => $data['output_path']], Response::HTTP_OK);
174        } catch (\Exception $e) {
175            Log::debug('Unable to download purchase order file :' . var_export(['message' => $e->getMessage(), 'line' => $e->getLine(), 'file' => $e->getFile()], true));
176            return response()->json(['status' => 'ko', 'errors' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
177        }
178    }
179
180    public function preview(Request $request): JsonResponse
181    {
182
183        $validatedData = $this->validateData($request);
184
185        try {
186            $validatedData['poNumber'] = $this->createPoNumber($validatedData['commercial']);
187            $validatedData['created_at'] = (new \DateTime())->format('Y-m-d');
188
189            $validatedData['template']['strips'] = $this->getStrips($validatedData['entity']['color']);
190
191            $content = view('po::invoice', $validatedData)->render();
192           
193            
194            return response()->json(['status' => 'ok', 'preview' => $content], Response::HTTP_OK);
195        } catch (Exception | Error $e) {
196            Log::debug('Unable to create preview purchase order : ' . var_export(['message' => $e->getMessage(), 'line' => $e->getLine(), 'file' => $e->getFile()], true));
197            return response()->json(['status' => 'ko', 'message' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
198        }
199    }
200
201    public function dispatchEmail(Request $request, $id)
202    {
203        $model = PurchaseOrder::findOrFail($id);
204
205        try {
206            $data = [
207                'type' => 'pdf',
208                'output_path' => $this->getFilePath($model),
209                'content' => $this->getHtml($model),
210                'user_id' => $this->userId,
211                'service' => getEnv('SERVICE_NAME'),
212                'pubsub' => [
213                    'channel' => 'purchase-order',
214                    'message' => [
215                        'action' => 'send-email',
216                        'id' => $id
217                    ]
218                ]
219            ];
220
221            $ClientRequest = ClientRequest::createObject('service_file_generator', 'dispatch', ['body' => $data]);
222            $response = Client::systemSend('post', $ClientRequest);
223
224            if (!Str::startsWith($response->code, 2)) {
225                throw new \Exception("unable generate pdf: service_file_generator $response->code $response->body");
226            }
227
228            return response()->json(['status' => 'ok'], Response::HTTP_OK);
229
230        }  catch (\Exception $e) {
231            Log::debug('Unable to dispatch purchase order file :' . var_export(['message' => $e->getMessage(), 'line' => $e->getLine(), 'file' => $e->getFile()], true));
232            return response()->json(['status' => 'ko', 'errors' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
233        }
234    }
235
236    public function sendEmail(Request $request)
237    {
238        $request->validate([
239           'id' => 'required|string',
240           'path' => 'required|string'
241        ]);
242
243        $model = PurchaseOrder::findOrFail($request->get('id'));
244        $user = User::findOrFail($model->commercial['id']);
245
246        MailSender::model(new MailPurchaseOrder($model->toArray(), $request->get('path')))
247            ->to($user->email)
248            ->dispatch();
249
250        return response()->json(['status' => 'ok'], Response::HTTP_OK);
251    }
252
253    /**
254     * Undocumented function
255     *
256     * @param string $color
257     * @return string
258     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
259     */
260    protected function getStrips(string $color): string
261    {
262        $strips = str_replace('{{color}}', $color, Storage::disk('private_images')->get('purchase-order/stripe.svg'));
263        return 'data:image/svg+xml;base64,' . base64_encode($strips);
264    }
265
266    /**
267     * @param \Qmp\Laravel\PurchaseOrder\Models\PurchaseOrder $model
268     * @return string
269     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
270     */
271    protected function getHtml(PurchaseOrder $model): string
272    {
273        $model = $model->ToArray();
274        $model['template']['strips'] = $this->getStrips($model['entity']['color']);
275        return view('po::invoice', $model)->render();
276    }
277
278    /**
279     * @param \Qmp\Laravel\PurchaseOrder\Models\PurchaseOrder $model
280     * @return string
281     */
282    protected function getFilePath(PurchaseOrder $model): string
283    {
284        $model = $model->toArray();
285
286        $path = sprintf('%s/oi_%s_%s.pdf', self::TEMP_STORAGE_FOLDER, Str::snake(strtolower($model['advertiser'])), $model['poNumber']);
287        return Storage::disk(self::STORAGE_DISK)->path($path);
288
289    }
290
291    /**
292     * Undocumented function
293     *
294     * @param Request $request
295     * @param [type] $id
296     * @return array
297     */
298    protected function validateData(Request $request, $id = null): array
299    {
300        $rules = [
301            'company' => 'required|array',
302            'contacts' => 'present|array',
303            'commercial' => 'required|array',
304            'date' => 'present|array',
305            'benefits' => 'present|array',
306            'conditions' => 'present|array',
307            'entity' => 'required|array',
308            'tax' => 'present|numeric',
309            'offer' => 'present',
310            'poNumber' => 'present',
311            'advertiser' => 'required',
312            'tva' => 'present|numeric',
313            'totalHT' => 'present|numeric',
314            'total' => 'present|numeric'
315        ];
316
317        if ($id != null) {
318            $rules['_id'] = [
319                'required',
320                Rule::in([$id])
321            ];
322        }
323
324        return $request->validate($rules);
325    }
326}