forked from FBakkensen/github_copilot_instructions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodeunit-template.al
More file actions
351 lines (293 loc) · 12.2 KB
/
Copy pathcodeunit-template.al
File metadata and controls
351 lines (293 loc) · 12.2 KB
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
// Codeunit Template for Business Central AL Development
// Copy this template and replace placeholders with your specific values
// Following SharedGuidelines standards for business logic and event patterns
codeunit [ObjectID] "[Prefix] [EntityName] Mgt"
{
// Management codeunit for [EntityName] operations
// Use this template for small to medium functionality
procedure Create[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; [KeyParameters]: Text): Boolean
var
Handled: Boolean;
begin
OnBeforeCreate[EntityName]([EntityName], [KeyParameters], Handled);
DoCreate[EntityName]([EntityName], [KeyParameters], Handled);
OnAfterCreate[EntityName]([EntityName]);
exit(Handled);
end;
local procedure DoCreate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; [KeyParameters]: Text; var Handled: Boolean)
begin
if Handled then
exit;
[EntityName].Init();
[EntityName]."No." := GetNextNumber();
[EntityName].Description := [KeyParameters];
[EntityName].Insert(true);
Handled := true;
end;
procedure Validate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"): Boolean
var
ErrorMessages: Text;
begin
// Comprehensive validation
if [EntityName]."No." = '' then
ErrorMessages += 'No. is required.\';
if [EntityName].Description = '' then
ErrorMessages += 'Description is required.\';
// Add specific business validations
if not IsValid[EntityName]([EntityName]) then
ErrorMessages += 'Business validation failed.\';
if ErrorMessages <> '' then begin
Error(ErrorMessages);
exit(false);
end;
exit(true);
end;
procedure Update[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; UpdateData: Record "[Prefix] [EntityName]"): Boolean
var
Handled: Boolean;
begin
OnBeforeUpdate[EntityName]([EntityName], UpdateData, Handled);
DoUpdate[EntityName]([EntityName], UpdateData, Handled);
OnAfterUpdate[EntityName]([EntityName]);
exit(Handled);
end;
local procedure DoUpdate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; UpdateData: Record "[Prefix] [EntityName]"; var Handled: Boolean)
begin
if Handled then
exit;
if Validate[EntityName](UpdateData) then begin
[EntityName].Description := UpdateData.Description;
[EntityName].Status := UpdateData.Status;
[EntityName].Modify(true);
Handled := true;
end;
end;
procedure Delete[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"): Boolean
var
Handled: Boolean;
begin
OnBeforeDelete[EntityName]([EntityName], Handled);
DoDelete[EntityName]([EntityName], Handled);
OnAfterDelete[EntityName]([EntityName]);
exit(Handled);
end;
local procedure DoDelete[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; var Handled: Boolean)
begin
if Handled then
exit;
if CanDelete[EntityName]([EntityName]) then begin
[EntityName].Delete(true);
Handled := true;
end else
Error('Cannot delete %1 due to related records.', [EntityName]."No.");
end;
procedure Get[EntityName]Statistics([EntityName]No: Code[20]; var Statistics: Record "[Prefix] [EntityName] Statistics" temporary)
begin
// Calculate and populate statistics
Statistics.Init();
Statistics."Entity No." := [EntityName]No;
Statistics."Total Records" := Count[EntityName]Records([EntityName]No);
Statistics."Last Modified Date" := GetLast[EntityName]ModificationDate([EntityName]No);
Statistics.Insert();
end;
procedure Process[EntityName]Batch(var [EntityName]: Record "[Prefix] [EntityName]")
var
ProcessedCount: Integer;
ProgressDialog: Dialog;
begin
ProgressDialog.Open('Processing [EntityName] records...\Progress: #1######');
if [EntityName].FindSet() then
repeat
Process[EntityName]Record([EntityName]);
ProcessedCount += 1;
ProgressDialog.Update(1, Round(ProcessedCount / [EntityName].Count * 10000, 1));
until [EntityName].Next() = 0;
ProgressDialog.Close();
Message('Processed %1 records.', ProcessedCount);
end;
local procedure Process[EntityName]Record(var [EntityName]: Record "[Prefix] [EntityName]")
begin
// Individual record processing logic
[EntityName].CalcFields("[FlowField]");
// Add specific processing logic here
[EntityName].Modify();
end;
local procedure GetNextNumber(): Code[20]
var
NoSeriesMgt: Codeunit NoSeriesManagement;
[EntityName]Setup: Record "[Prefix] [EntityName] Setup";
begin
[EntityName]Setup.Get();
[EntityName]Setup.TestField("No. Series");
exit(NoSeriesMgt.GetNextNo([EntityName]Setup."No. Series", 0D, true));
end;
local procedure IsValid[EntityName]([EntityName]: Record "[Prefix] [EntityName]"): Boolean
begin
// Add business-specific validation logic
if [EntityName].Status = [EntityName].Status::" " then
exit(false);
// Add more validation rules as needed
exit(true);
end;
local procedure CanDelete[EntityName]([EntityName]: Record "[Prefix] [EntityName]"): Boolean
var
RelatedRecord: Record "[Related Table]";
begin
RelatedRecord.SetRange("[Key Field]", [EntityName]."No.");
exit(RelatedRecord.IsEmpty);
end;
local procedure Count[EntityName]Records([EntityName]No: Code[20]): Integer
var
RelatedRecord: Record "[Related Table]";
begin
RelatedRecord.SetRange("[Key Field]", [EntityName]No);
exit(RelatedRecord.Count);
end;
local procedure GetLast[EntityName]ModificationDate([EntityName]No: Code[20]): DateTime
var
[EntityName]: Record "[Prefix] [EntityName]";
begin
if [EntityName].Get([EntityName]No) then
exit([EntityName].SystemModifiedAt);
exit(0DT);
end;
// Event publishers for extensibility
[BusinessEvent(false)]
local procedure OnBeforeCreate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; [KeyParameters]: Text; var Handled: Boolean)
begin
end;
[BusinessEvent(false)]
local procedure OnAfterCreate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]")
begin
end;
[BusinessEvent(false)]
local procedure OnBeforeUpdate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; UpdateData: Record "[Prefix] [EntityName]"; var Handled: Boolean)
begin
end;
[BusinessEvent(false)]
local procedure OnAfterUpdate[EntityName](var [EntityName]: Record "[Prefix] [EntityName]")
begin
end;
[BusinessEvent(false)]
local procedure OnBeforeDelete[EntityName](var [EntityName]: Record "[Prefix] [EntityName]"; var Handled: Boolean)
begin
end;
[BusinessEvent(false)]
local procedure OnAfterDelete[EntityName](var [EntityName]: Record "[Prefix] [EntityName]")
begin
end;
// Event subscribers for standard table events
[EventSubscriber(ObjectType::Table, Database::"[Prefix] [EntityName]", 'OnAfterInsertEvent', '', false, false)]
local procedure OnAfterInsert[EntityName](var Rec: Record "[Prefix] [EntityName]")
begin
// Handle post-insert operations
if IsGuiAllowed() then
Message('[EntityName] %1 has been created successfully.', Rec."No.");
end;
[EventSubscriber(ObjectType::Table, Database::"[Prefix] [EntityName]", 'OnAfterModifyEvent', '', false, false)]
local procedure OnAfterModify[EntityName](var Rec: Record "[Prefix] [EntityName]")
begin
// Handle post-modify operations
UpdateRelatedRecords(Rec);
end;
local procedure UpdateRelatedRecords([EntityName]: Record "[Prefix] [EntityName]")
var
RelatedRecord: Record "[Related Table]";
begin
RelatedRecord.SetRange("[Key Field]", [EntityName]."No.");
if RelatedRecord.FindSet() then
repeat
// Update related records as needed
RelatedRecord."[Update Field]" := [EntityName]."[Source Field]";
RelatedRecord.Modify();
until RelatedRecord.Next() = 0;
end;
}
// Major Functionality Codeunit Template
codeunit [ObjectID] "[Prefix] [EntityName] Workflow"
{
// Major functionality codeunit with comprehensive workflow patterns
// Use this template for complex business processes
procedure Execute[EntityName]Workflow(var [EntityName]: Record "[Prefix] [EntityName]")
var
Handled: Boolean;
begin
OnBeforeExecute[EntityName]Workflow([EntityName], Handled);
DoExecute[EntityName]Workflow([EntityName], Handled);
OnAfterExecute[EntityName]Workflow([EntityName]);
end;
local procedure DoExecute[EntityName]Workflow(var [EntityName]: Record "[Prefix] [EntityName]"; var Handled: Boolean)
var
[EntityName]Mgt: Codeunit "[Prefix] [EntityName] Mgt";
WorkflowStage: Integer;
begin
if Handled then
exit;
// Multi-stage workflow processing
WorkflowStage := 1;
ValidateWorkflowPreconditions([EntityName], WorkflowStage);
WorkflowStage := 2;
ProcessBusinessLogic([EntityName], WorkflowStage);
WorkflowStage := 3;
FinalizeWorkflow([EntityName], WorkflowStage);
Handled := true;
end;
local procedure ValidateWorkflowPreconditions(var [EntityName]: Record "[Prefix] [EntityName]"; WorkflowStage: Integer)
var
[EntityName]Mgt: Codeunit "[Prefix] [EntityName] Mgt";
begin
UpdateWorkflowProgress([EntityName], WorkflowStage, 'Validating preconditions...');
if not [EntityName]Mgt.Validate[EntityName]([EntityName]) then
Error('Workflow validation failed at stage %1.', WorkflowStage);
end;
local procedure ProcessBusinessLogic(var [EntityName]: Record "[Prefix] [EntityName]"; WorkflowStage: Integer)
begin
UpdateWorkflowProgress([EntityName], WorkflowStage, 'Processing business logic...');
// Add complex business logic here
case [EntityName].Status of
[EntityName].Status::Active:
ProcessActiveEntity([EntityName]);
[EntityName].Status::Inactive:
ProcessInactiveEntity([EntityName]);
end;
end;
local procedure FinalizeWorkflow(var [EntityName]: Record "[Prefix] [EntityName]"; WorkflowStage: Integer)
begin
UpdateWorkflowProgress([EntityName], WorkflowStage, 'Finalizing workflow...');
[EntityName]."Last Processed Date" := Today;
[EntityName].Modify(true);
SendWorkflowNotification([EntityName]);
end;
local procedure ProcessActiveEntity(var [EntityName]: Record "[Prefix] [EntityName]")
begin
// Processing logic for active entities
end;
local procedure ProcessInactiveEntity(var [EntityName]: Record "[Prefix] [EntityName]")
begin
// Processing logic for inactive entities
end;
local procedure UpdateWorkflowProgress([EntityName]: Record "[Prefix] [EntityName]"; Stage: Integer; Message: Text)
begin
if IsGuiAllowed() then
Window.Update(1, StrSubstNo('Stage %1: %2', Stage, Message));
end;
local procedure SendWorkflowNotification([EntityName]: Record "[Prefix] [EntityName]")
begin
if IsGuiAllowed() then
Message('Workflow completed successfully for %1.', [EntityName]."No.");
end;
var
Window: Dialog;
[BusinessEvent(false)]
local procedure OnBeforeExecute[EntityName]Workflow(var [EntityName]: Record "[Prefix] [EntityName]"; var Handled: Boolean)
begin
end;
[BusinessEvent(false)]
local procedure OnAfterExecute[EntityName]Workflow(var [EntityName]: Record "[Prefix] [EntityName]")
begin
end;
[IntegrationEvent(false, false)]
procedure OnAfterWorkflowCompleted([EntityName]: Record "[Prefix] [EntityName]")
begin
end;
}