Coverage for middle_layer/allocate/domain_layer/services/serialize_proposal_summary_to_csv_service.py: 100.00%
14 statements
« prev ^ index » next coverage.py v7.10.5, created at 2026-03-09 06:13 +0000
« prev ^ index » next coverage.py v7.10.5, created at 2026-03-09 06:13 +0000
1# Copyright 2024 Associated Universities, Inc.
2#
3# This file is part of Telescope Time Allocation Tools (TTAT).
4#
5# TTAT is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# any later version.
9#
10# TTAT is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with TTAT. If not, see <https://www.gnu.org/licenses/>.
17"""Serialize Proposal Summaries as CSV to be exported"""
19import csv
20import json
21from io import StringIO
23from common.domain_layer import JSON_OBJECT
26def serialize_proposal_summary_row(summ) -> dict[str, str]:
27 """Serialize a Proposal Summary for export in a CSV file
29 :param summ: proposal summary to serialize
30 :return: Dict, where keys are CSV column names
31 """
32 proposal_summary_dict = {
33 "proposalId": summ["proposal_id"],
34 "scientificMeritMetric": summ["scientific_merit_metric"],
35 "piName": summ["pi_name"],
36 "coiNames": summ["coi_names"],
37 "title": summ["title"],
38 "abstract": summ["abstract"],
39 "reviewProcessTag": summ["review_process_tag"],
40 "externalJointFacilities": summ["external_joint_facilities"],
41 "internalJointFacilities": summ["internal_joint_facilities"] if summ["internal_joint_facilities"] else "",
42 "proposalClass": summ["proposal_class"],
43 "isTriggered": summ["is_triggered"],
44 "isThesis": summ["is_thesis"],
45 "totalRequestedHours": str(summ["total_requested_hours"]),
46 "priorities": summ["priorities"],
47 "facilityConfigurations": summ["facility_configurations"],
48 "hardwareBands": summ["hardware_bands"],
49 "priorityA": str(summ["priority_a"]),
50 "priorityB": str(summ["priority_b"]),
51 "priorityC": str(summ["priority_c"]),
52 "priorityN": str(summ["priority_n"]),
53 "schedulerComments": summ["scheduler_comments"],
54 "externalScienceReviewComments": summ["external_science_review_comments"],
55 "externalTechnicalReviewComments": summ["external_technical_review_comments"],
56 "externalDataManagementReviewComments": summ["external_data_management_review_comments"],
57 "internalScienceReviewComments": summ["internal_science_review_comments"],
58 "internalTechnicalReviewComments": summ["internal_technical_review_comments"],
59 "internalDataManagementReviewComments": summ["internal_data_management_review_comments"],
60 "externalAllocationDispositionComments": summ["external_allocation_disposition_comments"],
61 "internalAllocationDispositionComments": summ["internal_allocation_disposition_comments"],
62 }
63 return proposal_summary_dict
66def serialize_proposal_summaries_to_csv(summaries: list) -> str:
67 """Serialize a list of proposal summaries into a string of CSV rows with a header at the top,
68 for export as a CSV file
70 :param summaries: List of summaries to serialize
71 :return: String with all of the summaries, in order, represented as CSV
72 """
74 headers = [
75 "proposalId",
76 "scientificMeritMetric",
77 "piName",
78 "coiNames",
79 "title",
80 "abstract",
81 "reviewProcessTag",
82 "externalJointFacilities",
83 "internalJointFacilities",
84 "proposalClass",
85 "isTriggered",
86 "isThesis",
87 "totalRequestedHours",
88 "priorities",
89 "facilityConfigurations",
90 "hardwareBands",
91 "priorityA",
92 "priorityB",
93 "priorityC",
94 "priorityN",
95 "schedulerComments",
96 "externalScienceReviewComments",
97 "externalTechnicalReviewComments",
98 "externalDataManagementReviewComments",
99 "internalScienceReviewComments",
100 "internalTechnicalReviewComments",
101 "internalDataManagementReviewComments",
102 "externalAllocationDispositionComments",
103 "internalAllocationDispositionComments",
104 ]
106 csv_file = StringIO()
107 csvwriter = csv.DictWriter(csv_file, headers)
108 csvwriter.writeheader()
109 csvwriter.writerows([serialize_proposal_summary_row(summary) for summary in summaries])
110 return csv_file.getvalue()