feat: [캘린더] 매입결제·수주납기·출고 예정일 일정 연동 추가

- expected_expense: 매입 결제 예정일 (미결제 건만)
- delivery: 수주 납기일 (활성 상태 수주만)
- shipment: 출고 예정일 (scheduled/ready 상태만)
- type 필터에 3개 타입 추가, null(전체)일 때 모두 포함

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-03-10 11:44:43 +09:00
parent 22f72f1bbc
commit 6d1925fcd1

View File

@@ -4,9 +4,12 @@
use App\Models\Construction\Contract;
use App\Models\Production\WorkOrder;
use App\Models\Orders\Order;
use App\Models\Tenants\Bill;
use App\Models\Tenants\ExpectedExpense;
use App\Models\Tenants\Leave;
use App\Models\Tenants\Schedule;
use App\Models\Tenants\Shipment;
use Illuminate\Support\Collection;
/**
@@ -26,7 +29,7 @@ class CalendarService extends Service
*
* @param string $startDate 조회 시작일 (Y-m-d)
* @param string $endDate 조회 종료일 (Y-m-d)
* @param string|null $type 일정 타입 필터 (schedule|order|construction|other|bill|null=전체)
* @param string|null $type 일정 타입 필터 (schedule|order|construction|other|bill|expected_expense|delivery|shipment|null=전체)
* @param string|null $departmentFilter 부서 필터 (all|department|personal)
*/
public function getSchedules(
@@ -73,6 +76,27 @@ public function getSchedules(
);
}
// 매입 결제 예정일
if ($type === null || $type === 'expected_expense') {
$schedules = $schedules->merge(
$this->getExpectedExpenseSchedules($tenantId, $startDate, $endDate)
);
}
// 수주 납기일
if ($type === null || $type === 'delivery') {
$schedules = $schedules->merge(
$this->getDeliverySchedules($tenantId, $startDate, $endDate)
);
}
// 출고 예정일
if ($type === null || $type === 'shipment') {
$schedules = $schedules->merge(
$this->getShipmentSchedules($tenantId, $startDate, $endDate)
);
}
// startDate 기준 정렬
$sortedSchedules = $schedules
->sortBy('startDate')
@@ -382,4 +406,128 @@ private function getBillSchedules(
];
});
}
/**
* 매입 결제 예정일 조회
*/
private function getExpectedExpenseSchedules(
int $tenantId,
string $startDate,
string $endDate
): Collection {
$expenses = ExpectedExpense::query()
->where('tenant_id', $tenantId)
->whereNotNull('expected_payment_date')
->where('expected_payment_date', '>=', $startDate)
->where('expected_payment_date', '<=', $endDate)
->where('payment_status', '!=', 'paid')
->with(['client:id,name'])
->orderBy('expected_payment_date')
->limit(100)
->get();
return $expenses->map(function ($expense) {
$clientName = $expense->client?->name ?? $expense->client_name ?? '';
return [
'id' => 'expense_'.$expense->id,
'title' => '[결제] '.$clientName.' '.number_format($expense->amount).'원',
'startDate' => $expense->expected_payment_date->format('Y-m-d'),
'endDate' => $expense->expected_payment_date->format('Y-m-d'),
'startTime' => null,
'endTime' => null,
'isAllDay' => true,
'type' => 'expected_expense',
'department' => null,
'personName' => null,
'color' => null,
];
});
}
/**
* 수주 납기일 조회
*/
private function getDeliverySchedules(
int $tenantId,
string $startDate,
string $endDate
): Collection {
$activeStatuses = [
'CONFIRMED',
'IN_PROGRESS',
'IN_PRODUCTION',
'PRODUCED',
'SHIPPING',
];
$orders = Order::query()
->where('tenant_id', $tenantId)
->whereNotNull('delivery_date')
->where('delivery_date', '>=', $startDate)
->where('delivery_date', '<=', $endDate)
->whereIn('status_code', $activeStatuses)
->with(['client:id,name'])
->orderBy('delivery_date')
->limit(100)
->get();
return $orders->map(function ($order) {
$clientName = $order->client?->name ?? $order->client_name ?? '';
$siteName = $order->site_name ?? $order->order_no;
return [
'id' => 'delivery_'.$order->id,
'title' => '[납기] '.$clientName.' '.$siteName,
'startDate' => $order->delivery_date->format('Y-m-d'),
'endDate' => $order->delivery_date->format('Y-m-d'),
'startTime' => null,
'endTime' => null,
'isAllDay' => true,
'type' => 'delivery',
'department' => null,
'personName' => null,
'color' => null,
];
});
}
/**
* 출고 예정일 조회
*/
private function getShipmentSchedules(
int $tenantId,
string $startDate,
string $endDate
): Collection {
$shipments = Shipment::query()
->where('tenant_id', $tenantId)
->whereNotNull('scheduled_date')
->where('scheduled_date', '>=', $startDate)
->where('scheduled_date', '<=', $endDate)
->whereIn('status', ['scheduled', 'ready'])
->with(['client:id,name', 'order:id,site_name'])
->orderBy('scheduled_date')
->limit(100)
->get();
return $shipments->map(function ($shipment) {
$clientName = $shipment->client?->name ?? $shipment->customer_name ?? '';
$siteName = $shipment->site_name ?? $shipment->order?->site_name ?? $shipment->shipment_no;
return [
'id' => 'shipment_'.$shipment->id,
'title' => '[출고] '.$clientName.' '.$siteName,
'startDate' => $shipment->scheduled_date->format('Y-m-d'),
'endDate' => $shipment->scheduled_date->format('Y-m-d'),
'startTime' => null,
'endTime' => null,
'isAllDay' => true,
'type' => 'shipment',
'department' => null,
'personName' => null,
'color' => null,
];
});
}
}