diff options
Diffstat (limited to 'db/migrations/0139_real_warlock.sql')
| -rw-r--r-- | db/migrations/0139_real_warlock.sql | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/db/migrations/0139_real_warlock.sql b/db/migrations/0139_real_warlock.sql new file mode 100644 index 00000000..7e8e7877 --- /dev/null +++ b/db/migrations/0139_real_warlock.sql @@ -0,0 +1,326 @@ +CREATE VIEW "public"."attachment_revision_history" AS ( + SELECT + br.id as rfq_id, + br.rfq_code, + ba.id as attachment_id, + ba.attachment_type, + ba.serial_no, + + -- 발주처 리비전 정보 + rev.id as client_revision_id, + rev.revision_no as client_revision_no, + rev.original_file_name as client_file_name, + rev.file_size as client_file_size, + rev.revision_comment as client_revision_comment, + rev.created_at as client_revision_created_at, + rev.is_latest as is_latest_client_revision, + + -- 벤더 응답 통계 + COALESCE(response_stats.total_responses, 0) as total_vendor_responses, + COALESCE(response_stats.responded_count, 0) as responded_vendors, + COALESCE(response_stats.pending_count, 0) as pending_vendors, + COALESCE(response_stats.total_files, 0) as total_response_files + + FROM b_rfqs br + JOIN b_rfq_attachments ba ON br.id = ba.rfq_id + JOIN b_rfq_attachment_revisions rev ON ba.id = rev.attachment_id + LEFT JOIN ( + SELECT + var.attachment_id, + COUNT(*) as total_responses, + COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END) as responded_count, + COUNT(CASE WHEN var.response_status = 'NOT_RESPONDED' THEN 1 END) as pending_count, + COUNT(vra.id) as total_files + FROM vendor_attachment_responses var + LEFT JOIN vendor_response_attachments_b vra ON var.id = vra.vendor_response_id + GROUP BY var.attachment_id + ) response_stats ON ba.id = response_stats.attachment_id + + ORDER BY ba.id, rev.created_at DESC +);--> statement-breakpoint +CREATE VIEW "public"."rfq_progress_summary" AS ( + SELECT + br.id as rfq_id, + br.rfq_code, + br.status as rfq_status, + br.due_date, + (br.due_date - CURRENT_DATE) as days_to_deadline, + + -- 첨부파일 통계 + attachment_stats.total_attachments, + attachment_stats.attachments_with_multiple_revisions, + attachment_stats.total_client_revisions, + + -- Initial RFQ 통계 + COALESCE(initial_stats.vendor_count, 0) as initial_vendor_count, + COALESCE(initial_stats.total_responses, 0) as initial_total_responses, + COALESCE(initial_stats.responded_count, 0) as initial_responded_count, + COALESCE(initial_stats.up_to_date_count, 0) as initial_up_to_date_count, + COALESCE(initial_stats.version_mismatch_count, 0) as initial_version_mismatch_count, + COALESCE(initial_stats.response_rate, 0) as initial_response_rate, + COALESCE(initial_stats.version_match_rate, 0) as initial_version_match_rate, + + -- Final RFQ 통계 + COALESCE(final_stats.vendor_count, 0) as final_vendor_count, + COALESCE(final_stats.total_responses, 0) as final_total_responses, + COALESCE(final_stats.responded_count, 0) as final_responded_count, + COALESCE(final_stats.up_to_date_count, 0) as final_up_to_date_count, + COALESCE(final_stats.version_mismatch_count, 0) as final_version_mismatch_count, + COALESCE(final_stats.response_rate, 0) as final_response_rate, + COALESCE(final_stats.version_match_rate, 0) as final_version_match_rate, + + COALESCE(file_stats.total_files, 0) as total_response_files + + FROM b_rfqs br + LEFT JOIN ( + SELECT + ba.rfq_id, + COUNT(*) as total_attachments, + COUNT(CASE WHEN rev_count.total_revisions > 1 THEN 1 END) as attachments_with_multiple_revisions, + SUM(rev_count.total_revisions) as total_client_revisions + FROM b_rfq_attachments ba + LEFT JOIN ( + SELECT + attachment_id, + COUNT(*) as total_revisions + FROM b_rfq_attachment_revisions + GROUP BY attachment_id + ) rev_count ON ba.id = rev_count.attachment_id + GROUP BY ba.rfq_id + ) attachment_stats ON br.id = attachment_stats.rfq_id + + LEFT JOIN ( + SELECT + br.id as rfq_id, + COUNT(DISTINCT var.vendor_id) as vendor_count, + COUNT(*) as total_responses, + COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END) as responded_count, + COUNT(CASE WHEN vrd.effective_status = 'UP_TO_DATE' THEN 1 END) as up_to_date_count, + COUNT(CASE WHEN vrd.effective_status = 'VERSION_MISMATCH' THEN 1 END) as version_mismatch_count, + ROUND( + COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END) * 100.0 / + NULLIF(COUNT(*), 0), 2 + ) as response_rate, + ROUND( + COUNT(CASE WHEN vrd.effective_status = 'UP_TO_DATE' THEN 1 END) * 100.0 / + NULLIF(COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END), 0), 2 + ) as version_match_rate + FROM b_rfqs br + JOIN vendor_response_detail vrd ON br.id = vrd.rfq_id + JOIN vendor_attachment_responses var ON vrd.response_id = var.id + WHERE var.rfq_type = 'INITIAL' + GROUP BY br.id + ) initial_stats ON br.id = initial_stats.rfq_id + + LEFT JOIN ( + SELECT + br.id as rfq_id, + COUNT(DISTINCT var.vendor_id) as vendor_count, + COUNT(*) as total_responses, + COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END) as responded_count, + COUNT(CASE WHEN vrd.effective_status = 'UP_TO_DATE' THEN 1 END) as up_to_date_count, + COUNT(CASE WHEN vrd.effective_status = 'VERSION_MISMATCH' THEN 1 END) as version_mismatch_count, + ROUND( + COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END) * 100.0 / + NULLIF(COUNT(*), 0), 2 + ) as response_rate, + ROUND( + COUNT(CASE WHEN vrd.effective_status = 'UP_TO_DATE' THEN 1 END) * 100.0 / + NULLIF(COUNT(CASE WHEN var.response_status = 'RESPONDED' THEN 1 END), 0), 2 + ) as version_match_rate + FROM b_rfqs br + JOIN vendor_response_detail vrd ON br.id = vrd.rfq_id + JOIN vendor_attachment_responses var ON vrd.response_id = var.id + WHERE var.rfq_type = 'FINAL' + GROUP BY br.id + ) final_stats ON br.id = final_stats.rfq_id + + LEFT JOIN ( + SELECT + br.id as rfq_id, + COUNT(vra.id) as total_files + FROM b_rfqs br + JOIN b_rfq_attachments ba ON br.id = ba.rfq_id + JOIN vendor_attachment_responses var ON ba.id = var.attachment_id + LEFT JOIN vendor_response_attachments_b vra ON var.id = vra.vendor_response_id + GROUP BY br.id + ) file_stats ON br.id = file_stats.rfq_id +);--> statement-breakpoint +CREATE VIEW "public"."vendor_response_attachments_enhanced" AS ( + SELECT + vra.id as response_attachment_id, + vra.vendor_response_id, + vra.file_name, + vra.original_file_name, + vra.file_path, + vra.file_size, + vra.file_type, + vra.description, + vra.uploaded_at, + + -- 응답 기본 정보 + var.attachment_id, + var.vendor_id, + var.rfq_type, + var.rfq_record_id, + var.response_status, + var.current_revision, + var.responded_revision, + var.response_comment, + var.vendor_comment, + var.requested_at, + var.responded_at, + + -- 첨부파일 정보 + ba.attachment_type, + ba.serial_no, + ba.rfq_id, + + -- 벤더 정보 + v.vendor_code, + v.vendor_name, + v.country as vendor_country, + + -- 발주처 현재 리비전 정보 + latest_rev.id as latest_client_revision_id, + latest_rev.revision_no as latest_client_revision_no, + latest_rev.original_file_name as latest_client_file_name, + + -- 리비전 비교 + CASE + WHEN var.responded_revision = ba.current_revision THEN true + ELSE false + END as is_version_matched, + + -- 버전 차이 계산 (Rev.0, Rev.1 형태 가정) + CASE + WHEN var.responded_revision IS NULL THEN NULL + WHEN ba.current_revision IS NULL THEN NULL + ELSE CAST(SUBSTRING(ba.current_revision FROM '[0-9]+') AS INTEGER) - + CAST(SUBSTRING(var.responded_revision FROM '[0-9]+') AS INTEGER) + END as version_lag, + + CASE + WHEN var.response_status = 'RESPONDED' + AND var.responded_revision != ba.current_revision THEN true + ELSE false + END as needs_update, + + -- 파일 순서 + ROW_NUMBER() OVER ( + PARTITION BY var.id + ORDER BY vra.uploaded_at DESC + ) as file_sequence, + + -- 최신 응답 파일 여부 + CASE + WHEN ROW_NUMBER() OVER ( + PARTITION BY var.id + ORDER BY vra.uploaded_at DESC + ) = 1 THEN true + ELSE false + END as is_latest_response_file + + FROM vendor_response_attachments_b vra + JOIN vendor_attachment_responses var ON vra.vendor_response_id = var.id + JOIN b_rfq_attachments ba ON var.attachment_id = ba.id + LEFT JOIN vendors v ON var.vendor_id = v.id + LEFT JOIN b_rfq_attachment_revisions latest_rev ON ba.latest_revision_id = latest_rev.id +);--> statement-breakpoint +CREATE VIEW "public"."vendor_response_detail" AS ( + SELECT + var.id as response_id, + ba.rfq_id, + br.rfq_code, + var.rfq_type, + var.rfq_record_id, + + -- 첨부파일 정보 + ba.id as attachment_id, + ba.attachment_type, + ba.serial_no, + ba.description as attachment_description, + + -- 벤더 정보 + v.id as vendor_id, + v.vendor_code, + v.vendor_name, + v.country as vendor_country, + + -- 응답 상태 + var.response_status, + var.current_revision, + var.responded_revision, + var.response_comment, + var.vendor_comment, + var.requested_at, + var.responded_at, + + -- 발주처 최신 리비전 + latest_rev.revision_no as latest_client_revision_no, + latest_rev.original_file_name as latest_client_file_name, + latest_rev.file_size as latest_client_file_size, + latest_rev.revision_comment as latest_client_revision_comment, + + -- 리비전 분석 + CASE + WHEN var.responded_revision = ba.current_revision THEN true + ELSE false + END as is_version_matched, + + CASE + WHEN var.responded_revision IS NULL OR ba.current_revision IS NULL THEN NULL + ELSE CAST(SUBSTRING(ba.current_revision FROM '[0-9]+') AS INTEGER) - + CAST(SUBSTRING(var.responded_revision FROM '[0-9]+') AS INTEGER) + END as version_lag, + + CASE + WHEN var.response_status = 'RESPONDED' + AND var.responded_revision != ba.current_revision THEN true + ELSE false + END as needs_update, + + CASE + WHEN revision_count.total_revisions > 1 THEN true + ELSE false + END as has_multiple_revisions, + + -- 응답 파일 정보 + COALESCE(file_stats.total_files, 0) as total_response_files, + file_stats.latest_file_name as latest_response_file_name, + file_stats.latest_file_size as latest_response_file_size, + file_stats.latest_uploaded_at as latest_response_uploaded_at, + + -- 효과적인 상태 + CASE + WHEN var.response_status = 'NOT_RESPONDED' THEN 'NOT_RESPONDED' + WHEN var.response_status = 'WAIVED' THEN 'WAIVED' + WHEN var.response_status = 'REVISION_REQUESTED' THEN 'REVISION_REQUESTED' + WHEN var.response_status = 'RESPONDED' AND var.responded_revision = ba.current_revision THEN 'UP_TO_DATE' + WHEN var.response_status = 'RESPONDED' AND var.responded_revision != ba.current_revision THEN 'VERSION_MISMATCH' + ELSE var.response_status + END as effective_status + + FROM vendor_attachment_responses var + JOIN b_rfq_attachments ba ON var.attachment_id = ba.id + JOIN b_rfqs br ON ba.rfq_id = br.id + LEFT JOIN vendors v ON var.vendor_id = v.id + LEFT JOIN b_rfq_attachment_revisions latest_rev ON ba.latest_revision_id = latest_rev.id + LEFT JOIN ( + SELECT + attachment_id, + COUNT(*) as total_revisions + FROM b_rfq_attachment_revisions + GROUP BY attachment_id + ) revision_count ON ba.id = revision_count.attachment_id + LEFT JOIN ( + SELECT + vendor_response_id, + COUNT(*) as total_files, + MAX(original_file_name) as latest_file_name, + MAX(file_size) as latest_file_size, + MAX(uploaded_at) as latest_uploaded_at + FROM vendor_response_attachments_b + GROUP BY vendor_response_id + ) file_stats ON var.id = file_stats.vendor_response_id +);
\ No newline at end of file |
