/
report.dm
174 lines (155 loc) · 6.37 KB
/
report.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/datum/computer_file/report
filename = "report"
filetype = "RPT"
/// The name of this report type.
var/title = "Generic Report"
/// Form code, for maximum bureaucracy.
var/form_name = "AB1"
/// The name of the mob that made the report.
var/creator
/// Time submitted.
var/file_time
/// The access required to submit the report. See documentation below.
var/list/access_edit = list(list())
/// The access required to view the report.
var/list/access = list(list())
/// A list of fields the report comes with, in order that they should be displayed.
var/list/datum/report_field/fields = list()
/// Whether this report type should show up on NTNet.
var/available_on_ntnet = FALSE
/// Can be set to a pencode logo for use with some display methods.
var/logo
/datum/computer_file/report/New()
..()
generate_fields()
/datum/computer_file/report/Destroy()
QDEL_NULL_LIST(fields)
. = ..()
/**
* Access stuff. The report's access/access_edit should control whether it can be opened/submitted.
* For field editing or viewing, use the field's access/access_edit permission instead.
* The access system is based on "access patterns", lists of access values.
* A user needs all access values in a pattern to be granted access.
* A user needs to only match one of the potentially several stored access patterns to be granted access.
* You must have access to have edit access.
*
* This proc resets the access to the report, resulting in just one access pattern for access/edit.
* Arguments can be access values (numbers) or lists of access values.
* If null is passed to one of the arguments, that access type is left alone. Pass list() to reset to no access needed instead.
* The recursive option resets access to all fields in the report as well.
* If the override option is set to FALSE, the access supplied will instead be added as another access pattern, rather than resetting the access.
*/
/datum/computer_file/report/proc/set_access(access, access_edit, recursive = 1, override = 1)
if(access)
if(!islist(access))
access = list(access)
override ? (src.access = list(access)) : (src.access += list(access)) //Note that this is a list of lists.
if(access_edit)
if(!islist(access_edit))
access_edit = list(access_edit)
override ? (src.access_edit = list(access_edit)) : (src.access_edit += list(access_edit))
if(recursive)
for(var/datum/report_field/field in fields)
field.set_access(access, access_edit, override)
/// Strongly recommended to use these procs to check for access. They can take access values (numbers) or lists of values.
/datum/computer_file/report/proc/verify_access(given_access)
return has_access_pattern(access, given_access)
/datum/computer_file/report/proc/verify_access_edit(given_access)
if(!verify_access(given_access))
return //Need access for access_edit
return has_access_pattern(access_edit, given_access)
/// Looking up fields. Names might not be unique unless you ensure otherwise.
/datum/computer_file/report/proc/field_from_ID(ID)
for(var/datum/report_field/field in fields)
if(field.ID == ID)
return field
/datum/computer_file/report/proc/field_from_name(name)
for(var/datum/report_field/field in fields)
if(field.display_name() == name)
return field
/// The place to enter fields for report subtypes, via add_field.
/datum/computer_file/report/proc/generate_fields()
return
/datum/computer_file/report/proc/submit(mob/user)
if(!istype(user))
return 0
for(var/datum/report_field/field in fields)
if(field.required && !field.get_value())
to_chat(user, SPAN_NOTICE("You are missing a required field!"))
return 0
creator = user.name
file_time = time_stamp()
rename_file(file_time)
return 1
/datum/computer_file/report/proc/rename_file(append)
append = append || time_stamp()
append = replacetext(append, ":", "_")
if(istype(holder, /obj/item/stock_parts/computer/hard_drive))
holder.rename_file(src, "[form_name]_[append]")
else
filename = "[form_name]_[append]"
/// Don't add fields except through this proc.
/datum/computer_file/report/proc/add_field(field_type, name, value = null, required = 0)
var/datum/report_field/field = new field_type(src)
field.name = name
if(value)
field.value = value
if(required)
field.required = 1
field.ID = sequential_id(type)
fields += field
return field
/datum/computer_file/report/clone()
var/datum/computer_file/report/temp = ..()
temp.title = title
temp.form_name = form_name
temp.creator = creator
temp.file_time = file_time
temp.access_edit = access_edit
temp.access = access
for(var/i = 1, i <= length(fields), i++)
var/datum/report_field/new_field = temp.fields[i]
new_field.copy_value(fields[i])
return temp
/datum/computer_file/report/proc/display_name()
return "Form [form_name]: [title]"
/// If access is given, will include access information by performing checks against it.
/datum/computer_file/report/proc/generate_nano_data(list/given_access)
. = list()
.["name"] = display_name()
.["uid"] = uid
.["creator"] = creator
.["file_time"] = file_time
.["fields"] = list()
if(given_access)
.["access"] = verify_access(given_access)
.["access_edit"] = verify_access_edit(given_access)
for(var/datum/report_field/field in fields)
.["fields"] += list(field.generate_nano_data(given_access))
/**
* This formats the report into pencode for use with paper and printing. Setting access to null will bypass access checks.
* with_fields will include a field link after the field value (useful to print fillable forms).
* no_html will strip any html, possibly killing useful formatting in the process.
*/
/datum/computer_file/report/proc/generate_pencode(access, with_fields, no_html)
. = list()
. += "\[center\][logo]\[/center\]"
. += "\[center\]\[h2\][display_name()]\[/h2\]\[/center\]"
. += "\[grid\]"
for(var/datum/report_field/F in fields)
. += F.generate_row_pencode(access, with_fields)
. += "\[/grid\]"
. = JOINTEXT(.)
if(no_html)
. = html2pencode(.)
/// Recipient reports have a designated recipients field, for receiving submitted reports.
/datum/computer_file/report/recipient
var/datum/report_field/people/list_from_manifest/recipients
/datum/computer_file/report/recipient/Destroy()
recipients = null
return ..()
/datum/computer_file/report/recipient/generate_fields()
recipients = add_field(/datum/report_field/people/list_from_manifest, "Send Copies To")
/datum/computer_file/report/recipient/submit(mob/user)
if((. = ..()))
recipients.send_email(user)