salihy
// Bitiş tarihi yani seçilen tarih
$endDate = $request->date('tarih');
// Başlangıç tarihi, bitiş tarihinden 10 gün öncesi
$startDate = $endDate
->copy()
->subDays(10);
// Burada başlangıç ve bitiş tarihi arasında, 1 gün arayla tarih dizisi oluşturuyoruz
// $dates artık 10 elemanlı bir dizi
$dates = Carbon\CarbonPeriod::create($startDate, $endDate);
// Önce istediğimiz kayıtları çekelim:
$records = Model::whereBetween('tarih', [$startDate, $endDate])
->select('urun_id', 'tedarikci_id', 'toplam', 'tarih')
->latest('tarih')
->get();
// Çekilen kayıtlarda kullanılan ürünlerin id lerini alıyoruz
// Aynı üründen birden fazla olabileceği için unique ile kopyaları kaldırıyoruz
$productIds = $records
->pluck('urun_id')
->unique()
->values()
->toArray();
// Çekilen kayıtlarda geçen tedarikçi id lerini alıyoruz. Aynı şekilde kopyaları kaldırıyoruz
$supplierIds = $records
->pluck('tedarikci_id')
->unique()
->values()
->toArray();
// Kullanılan ürünleri id => name olacak şekilde selectbox oluşturmak için çekiyoruz.
// Sadece id ve name yeterli
$productSelectbox = Product::whereIn('id', $productIds)
->select('id', 'name')
->pluck('name', 'id');
// Tablodaki ilk sütunda listelemek için tedarikçileri çekiyoruz. Sadece id ve name yeterli
$suppliers = Supplier::whereIn('id', $supplierIds)
->select('id', 'name')
->get();
// Her bir tarih sütununda göstermek üzere toplamları alıyoruz. Burada yaptığım işlem önce kayıtları
// tarihe göre gruplamak. Daha sonra bu grupları da kendi içinde tedarikci_id ye göre grupluyorum.
// Son olarak da en son elde ettiğim grupdaki toplamları da toplayıp genel toplam elde ediyorum.
$columns = collect($records)
->groupBy('tarih')
->map(function($items) {
return $items
->groupBy('tedarikci_id')
->map(fn($items) => $items->sum('toplam'));
})
->toArray();
// Şöyle bir dizi vermesi lazım:
/*
{
"2022-02-12": {
"1": 6250
},
"2022-02-11": {
"1": 3100,
"2": 6530,
"3": 345
},
...
}
*/
// yani
/*
{
tarih: {
tedarikci_id: toplam
},
}
*/
Toplam 3 veritabanı sorgusu ile hallettik. Şimdi tabloya geçelim:
<table>
<thead>
<tr>
<th>Tedarikçi</th>
{{--
Burada tarihlerden sütunları oluşturuyorum. Formatı siz beliryelebilirsiniz,
ben 12.02.2022 olacak şekilde yaptım
--}}
@foreach($dates as $date)
<th>{{ $date->format('d.m.Y') }}</th>
@endforeach
</tr>
</thead>
<tbody>
{{--
Tedarikçileri iterasyona sokup satırları oluşturuyorum ve ilk sütuna isimlerini yazıyorum
--}}
@foreach($suppliers as $supplier)
<tr>
<td>{{ $supplier->name }}</td>
{{--
Tarihleri iterasyona sokup $columns dizisinde eşleşen toplamları alıyorum
--}}
@foreach($dates as $date)
<td>{{ data_get($columns, "{$date->toDateString()}.{$supplier->id}") ?? '-' }}</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
Son olarak da ürünleri listelediğiniz selectbox. Sadece listelenen ürünlerden oluşuyor.
<select>
<option value="">---</option>
@foreach($productSelectbox as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
@endforeach
</select>
Bu kod hata verebilir, denemedim, mantığı anlatmaya çalıştım. Bazı yerlerde kontroller yapmanız gerekebilir. Ben direkt verilen tarihten 10 gün öncesine kadar aldım, arada olmayan kayıtlar olabilir. İçi dolu olan 10 tarih istiyorsanız başka işlemler yapmanız gerekiyor, o sizi daha da zorlayacaktır, bence gerek yok. Bu koda bakarak eksiklerinizi anlayabilirsiniz. İstediğiniz şeyi yapabilmeniz için birçok şeye hakim olmanız gerekiyor.