diff --git a/app/Console/Commands/SendProcessOrderReport.php b/app/Console/Commands/SendProcessOrderReport.php new file mode 100644 index 00000000..9f7ccf80 --- /dev/null +++ b/app/Console/Commands/SendProcessOrderReport.php @@ -0,0 +1,219 @@ +argument('schedule_type'); + $plantId = (int) $this->argument('plant'); + + $mailRules = AlertMailRule::where('module', 'ProcessOrder') + ->where('rule_name', 'ProcessOrderMail') + ->where('schedule_type', $scheduleType) + ->where('plant', $plantId) + ->get(); + + $plants = ($plantId == 0) + ? Plant::all() + : Plant::where('id', $plantId)->get(); + + $plantCodes = $plants->pluck('name', 'id'); + + if ($plants->isEmpty()) { + $this->error('No valid plant(s) found.'); + return; + } + + if (strtolower($scheduleType) == 'daily') { + $startDate = now()->subDay()->setTime(8, 0, 0); + $endDate = now()->setTime(8, 0, 0); + } + + $query = ProcessOrder::whereBetween('created_at', [$startDate, $endDate]); + + if ($plantId != 0) { + $query->where('plant_id', $plantId); + } + + $tableData = []; + + $no = 1; + + foreach ($plants as $plant) { + + $receivedSummary = ProcessOrder::query() + ->where('plant_id', $plant->id) + ->whereBetween('created_at', [$startDate, $endDate]) + ->groupBy('process_order') + ->select('process_order', DB::raw('SUM(received_quantity) as total_received')) + ->pluck('total_received', 'process_order'); + + // $latestRecords = ProcessOrder::query() + // ->where('plant_id', $plant->id) + // ->whereBetween('created_at', [$startDate, $endDate]) + // ->orderBy('process_order') + // ->orderByDesc('created_at') + // ->distinct('process_order') + // ->selectRaw('MAX(coil_number) as max_coil_number') + // ->with(['line', 'item']) + // ->get(); + + $latestRecords = ProcessOrder::query() + ->where('plant_id', $plant->id) + ->whereBetween('created_at', [$startDate, $endDate]) + ->whereIn('id', function ($query) use ($plant, $startDate, $endDate) { + $query->selectRaw('MAX(id)') + ->from('process_orders') + ->where('plant_id', $plant->id) + ->whereBetween('created_at', [$startDate, $endDate]) + ->groupBy('process_order'); + }) + ->with(['line', 'item']) + ->orderBy('process_order') + ->get(); + + foreach ($latestRecords as $order) { + + $tableData[] = [ + 'no' => $no++, + 'plant' => $plant->name, + 'line' => $order->line?->name ?? '-', + 'machineName' => $order->machine_name, + 'item' => $order->item?->code ?? '-', + 'processOrder' => $order->process_order, + 'coilNo' => $order->coil_number, + 'orderQuan' => $order->order_quantity, + 'recQuan' => $receivedSummary[$order->process_order] ?? 0, + 'scrapQuan' => $order->scrap_quantity, + 'sfgNo' => $order->sfg_number, + ]; + } + } + + $noNotOk = 1; + + $NotOkData = []; + + foreach ($plants as $plant) { + + $processOrderTotals = DB::table('process_orders') + ->where('plant_id', $plant->id) + ->where('coil_number', '!=', 0) + ->selectRaw(' + process_order, + COUNT(*) AS total_count + ') + ->groupBy('process_order') + ->get() + ->keyBy('process_order'); + + $statusCounts = DB::table('characteristic_values') + ->where('plant_id', $plant->id) + ->whereBetween('created_at', [$startDate, $endDate]) + ->selectRaw(" + process_order, + SUM(CASE WHEN status = 'NotOk' THEN 1 ELSE 0 END) AS notok_count, + SUM(CASE WHEN status = 'Ok' THEN 1 ELSE 0 END) AS ok_count + ") + ->groupBy('process_order') + ->get() + ->keyBy('process_order'); + + $latestRecords = CharacteristicValue::query() + ->where('plant_id', $plant->id) + ->whereBetween('created_at', [$startDate, $endDate]) + ->orderBy('process_order') + ->orderByDesc('created_at') + ->distinct('process_order') + ->with(['line', 'item']) + ->get(); + + foreach ($latestRecords as $order) { + + $processOrder = $order->process_order; + + $total = $processOrderTotals[$processOrder]->total_count ?? 0; + $notOk = $statusCounts[$processOrder]->notok_count ?? 0; + $ok = $statusCounts[$processOrder]->ok_count ?? 0; + + $notOkPerc = $total > 0 + ? round(($notOk / $total) * 100, 2) + : 0; + + $okPerc = $total > 0 + ? round(($ok / $total) * 100, 2) + : 0; + + + $NotOkData[] = [ + 'no' => $noNotOk++, + 'plant' => $plant->name, + 'line' => $order->line?->name ?? '-', + 'machineName' => $order->machine_name, + 'item' => $order->item?->code ?? '-', + 'processOrder' => $order->process_order, + 'NotOkPerc' => $notOkPerc . '%', + 'OkPerc' => $okPerc . '%', + ]; + } + } + + $mail = new ProcessOrderMail($scheduleType, $tableData, $NotOkData); + $contentVars = $mail->content()->with; + + foreach ($mailRules as $rule) + { + $toEmails = collect(explode(',', $rule->email)) + ->map(fn ($e) => trim($e)) + ->filter() + ->unique() + ->values() + ->toArray(); + + $ccEmails = collect(explode(',', $rule->cc_emails)) + ->map(fn ($e) => trim($e)) + ->filter() + ->unique() + ->values() + ->toArray(); + + if (empty($toEmails)) { + $this->warn("Skipping rule ID {$rule->id} — no valid To emails found."); + + continue; + } + + \Mail::to($toEmails)->cc($ccEmails)->send($mail); + + $this->info("Mail sent for rule ID {$rule->id} → To: ".implode(', ', $toEmails).($ccEmails ? ' | CC: '.implode(', ', $ccEmails) : '')); + } + } +} diff --git a/app/Mail/ProcessOrderMail.php b/app/Mail/ProcessOrderMail.php new file mode 100644 index 00000000..4a401b9b --- /dev/null +++ b/app/Mail/ProcessOrderMail.php @@ -0,0 +1,80 @@ +scheduleType = $scheduleType; + $this->tableData = $tableData ?? []; + $this->NotOkData = $NotOkData ?? []; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Process Order Mail', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + $greeting = "Dear Sir/Madam,

Kindly find the attached process order report status details for the 'Order Quantity' and 'Received Quantity' count,"; + + + if ($this->scheduleType == 'Daily') { + $fromDate = (new DateTime('yesterday 08:00'))->format('d/m/Y H:i') . ':000'; + $toDate = (new DateTime('today 07:59'))->format('d/m/Y H:i') . ':999'; + $reportPeriod = "The following report presents results from: $fromDate to $toDate."; + $greeting .= $reportPeriod; + } + + + return new Content( + view: 'mail.process_order_report', + with: [ + 'company' => "CRI Digital Manufacturing Solutions", + 'greeting' => $greeting, + 'tableData' => $this->tableData, + 'NotOkData' => $this->NotOkData, + 'wishes' => "Thanks & Regards,
CRI Digital Manufacturing Solutions" + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/resources/views/mail/process_order_report.blade.php b/resources/views/mail/process_order_report.blade.php new file mode 100644 index 00000000..c93f34ae --- /dev/null +++ b/resources/views/mail/process_order_report.blade.php @@ -0,0 +1,92 @@ + + + + Process Order Report Table + + + +
+ {{ $company }} +
+
+

{!! $greeting !!}

+ + + + + + + + + + + + + + + + + + @foreach($tableData as $row) + + + + + + + + + + + + + @endforeach + +
NoPlantLineMachine nameItem CodeProcess OrderOrder QuantityTotal QuantityScrap QuantitySFG Number
{{ $row['no'] }}{{ $row['plant'] }}{{ $row['line'] }}{{ $row['machineName'] }}{{ $row['item'] }}{{ $row['processOrder'] }}{{ $row['orderQuan'] }}{{ $row['recQuan'] }}{{ $row['scrapQuan'] }}{{ $row['sfgNo'] }}
+
+

Process Order Not Ok Report

+ + + + + + + + + + + + + + + @foreach($NotOkData as $row) + + + + + + + + + + + @endforeach + +
NoPlantLineMachine nameItem CodeProcess OrderNot Ok Status (%)Ok Status (%)
{{ $row['no'] }}{{ $row['plant'] }}{{ $row['line'] }}{{ $row['machineName'] }}{{ $row['item'] }}{{ $row['processOrder'] }}{{ $row['NotOkPerc'] }}{{ $row['OkPerc'] }}
+ +

{!! $wishes !!}

+ +