-
Notifications
You must be signed in to change notification settings - Fork 696
Expand file tree
/
Copy pathAltCustVATRegDocImpl.Codeunit.al
More file actions
347 lines (317 loc) · 16.8 KB
/
AltCustVATRegDocImpl.Codeunit.al
File metadata and controls
347 lines (317 loc) · 16.8 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
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Finance.VAT.Registration;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Sales.Customer;
using Microsoft.Sales.Document;
using System.Diagnostics;
using System.Environment.Configuration;
using System.Telemetry;
codeunit 205 "Alt. Cust. VAT Reg. Doc. Impl." implements "Alt. Cust. VAT Reg. Doc."
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
EventSubscriberInstance = Manual;
var
AltCustVATRegFacade: Codeunit "Alt. Cust. VAT. Reg. Facade";
FeatureTelemetry: Codeunit "Feature Telemetry";
SalesLinesRecreated: Boolean;
InstructionTxt: Label 'The following data is taken from the Alternative VAT Registration setup. It will override values in the document and affect the posting. Do you want to continue?';
DocumentValueTxt: Label 'Document value';
AlternativeValueTxt: Label 'Alternative value';
CannotChangeVATDataWhenPrepmtErr: Label 'You cannot make this change because it leads to a different VAT Registration No., Gen. Bus. Posting Group or VAT Bus. Posting Group than in the sales document. Since you have posted a prepayment invoice, such a change will cause an inconsistency in the ledger entries.';
CannotChangeVATDataWhenPartiallyPostedErr: Label 'You cannot make this change because it leads to a different VAT Registration No., Gen. Bus. Posting Group or VAT Bus. Posting Group than in the sales document. Since you have posted a partial shipment, such a change will cause an inconsistency in the ledger entries.';
VATDataTakenFromCustomerMsg: Label 'The VAT Country/Region code has been changed to the value that does not have an alternative VAT registration.\\The following fields have been updated from the customer card: %1', Comment = '%1 = list of the fields';
FeatureNameTxt: Label 'Alternative Customer VAT Registration', Locked = true;
ConfirmAltCustVATRegNotificationNameTok: Label 'Confirm an alternative customer VAT registration.';
ConfirmAltCustVATRegNotificationDescTok: Label 'Show the user the page to confirm an alternative customer VAT registration when choosing either ship-to address or the VAT country different from the customer''s';
AddAlternativeCustVATRegQst: Label 'The VAT country is different than the customer''s. Do you want to add an alternative VAT registration for this VAT country?';
AddAlternativeCustVATRegMsg: Label 'Add';
DontShowMsg: Label 'Don''t show';
AddAltCustVATRegNotificationNameTok: Label 'Suggest an alternative customer VAT registration from sales document';
AddAltCustVATRegNotificationDescTok: Label 'Suggest the user to add an alternative customer VAT registration when choosing a VAT country different from the customer''s';
procedure Init(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header")
begin
if xSalesHeader."Bill-to Customer No." = '' then
exit;
SalesHeader.Validate("Alt. VAT Registration No.", false);
SalesHeader.Validate("Alt. Gen. Bus Posting Group", false);
SalesHeader.Validate("Alt. VAT Bus Posting Group", false);
end;
procedure CopyFromCustomer(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header")
var
Customer: Record Customer;
begin
if not IsAltVATRegUsed(SalesHeader) then
exit;
RunChecks(SalesHeader);
Customer.SetLoadFields("Country/Region Code", "VAT Registration No.", "Gen. Bus. Posting Group", "VAT Bus. Posting Group");
if not GetCustVATCalc(Customer, SalesHeader) then
exit;
CopyFromCustomer(SalesHeader, xSalesHeader, Customer);
end;
local procedure CopyFromCustomer(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header"; Customer: Record Customer)
var
ChangedFieldsList: Text;
begin
if (SalesHeader."Alt. VAT Registration No." or SalesHeader."Alt. VAT Bus Posting Group") and
(SalesHeader."VAT Country/Region Code" <> Customer."Country/Region Code") and
(xSalesHeader."VAT Country/Region Code" = SalesHeader."VAT Country/Region Code")
then begin
SalesHeader."VAT Country/Region Code" := Customer."Country/Region Code";
AddStringToCommaSeparatedList(ChangedFieldsList, SalesHeader.FieldCaption("VAT Country/Region Code"));
end;
if SalesHeader."Alt. VAT Registration No." then begin
SalesHeader.Validate("Alt. VAT Registration No.", false);
SalesHeader.Validate("VAT Registration No.", Customer."VAT Registration No.");
AddStringToCommaSeparatedList(ChangedFieldsList, SalesHeader.FieldCaption("VAT Registration No."));
end;
if SalesHeader."Alt. Gen. Bus Posting Group" then begin
SalesHeader.Validate("Alt. Gen. Bus Posting Group", false);
SalesHeader.Validate("Gen. Bus. Posting Group", Customer."Gen. Bus. Posting Group");
AddStringToCommaSeparatedList(ChangedFieldsList, SalesHeader.FieldCaption("Gen. Bus. Posting Group"));
end;
if SalesHeader."Alt. VAT Bus Posting Group" then begin
SalesHeader.Validate("Alt. VAT Bus Posting Group", false);
SalesHeader.Validate("VAT Bus. Posting Group", Customer."VAT Bus. Posting Group");
AddStringToCommaSeparatedList(ChangedFieldsList, SalesHeader.FieldCaption("VAT Bus. Posting Group"));
end;
if GuiAllowed() then
Message(VATDataTakenFromCustomerMsg, ChangedFieldsList);
end;
procedure UpdateSetupOnShipToCountryChangeInSalesHeader(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header")
var
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
VATCustomer: Record Customer;
begin
GetCustVATCalc(VATCustomer, SalesHeader);
if AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, VATCustomer."No.", SalesHeader."Ship-to Country/Region Code") then
SalesHeader.Validate("VAT Country/Region Code", AltCustVATReg."VAT Country/Region Code")
else
CopyFromCustomer(SalesHeader, xSalesHeader);
end;
procedure UpdateSetupOnVATCountryChangeInSalesHeader(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header")
var
Customer: Record Customer;
begin
if AlternativeCustVATRegIsBlank(SalesHeader) then begin
CopyFromCustomer(SalesHeader, xSalesHeader);
if not GetCustVATCalc(Customer, SalesHeader) then
exit;
if Customer."Country/Region Code" = SalesHeader."VAT Country/Region Code" then
exit;
ThrowAddAltCustVATRegNotification(Customer."No.", SalesHeader."VAT Country/Region Code");
exit;
end;
RunChecks(SalesHeader);
if SalesHeader.SystemCreatedAt <> 0DT then
if not ConfirmChanges(SalesHeader) then
error('');
UpdateAltCustVATRegInSalesHeader(SalesHeader);
end;
procedure UpdateSetupOnBillToCustomerChangeInSalesHeader(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header"; BillToCustomer: Record Customer)
var
GLSetup: Record "General Ledger Setup";
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
begin
GLSetup.Get();
if GLSetup."Bill-to/Sell-to VAT Calc." <> GLSetup."Bill-to/Sell-to VAT Calc."::"Bill-to/Pay-to No." then
exit;
if IsAltVATRegUsed(SalesHeader) then begin
if SalesHeader."Bill-to Customer No." = SalesHeader."Sell-to Customer No." then
exit;
CopyFromCustomer(SalesHeader, xSalesHeader, BillToCustomer);
exit;
end;
if AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, BillToCustomer."No.", SalesHeader."Ship-to Country/Region Code") then begin
SalesHeader.Validate("VAT Country/Region Code", AltCustVATReg."VAT Country/Region Code");
exit;
end;
AltCustVATRegFacade.CopyBillToCustomerToSalesHeader(SalesHeader, BillToCustomer);
end;
local procedure IsAltVATRegUsed(SalesHeader: Record "Sales Header"): Boolean
begin
exit(SalesHeader."Alt. VAT Registration No." or SalesHeader."Alt. Gen. Bus Posting Group" or SalesHeader."Alt. VAT Bus Posting Group");
end;
local procedure AlternativeCustVATRegIsBlank(SalesHeader: Record "Sales Header"): Boolean
var
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
begin
exit(not GetAlternativeCustVATReg(AltCustVATReg, SalesHeader));
end;
local procedure GetAlternativeCustVATReg(var AltCustVATReg: Record "Alt. Cust. VAT Reg."; SalesHeader: Record "Sales Header"): Boolean
var
Customer: Record Customer;
begin
Customer.SetLoadFields("No.");
GetCustVATCalc(Customer, SalesHeader);
exit(AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, Customer."No.", SalesHeader."VAT Country/Region Code"));
end;
local procedure ConfirmChanges(var SalesHeader: Record "Sales Header") Confirmed: Boolean
var
TempChangeLogEntry: Record "Change Log Entry" temporary;
ConfirmAltCustVATRegPage: Page "Confirm Alt. Cust. VAT Reg.";
begin
FeatureTelemetry.LogUsage('0000NHM', FeatureNameTxt, 'Confirm changes');
if not BuildFieldChangeBuffer(TempChangeLogEntry, SalesHeader) then
exit(true);
if not GuiAllowed() then
exit(true);
if SalesHeader.GetHideValidationDialog() then
exit(true);
if not ShowConfirmation() then
exit(true);
ConfirmAltCustVATRegPage.SetUIControls(InstructionTxt, DocumentValueTxt, AlternativeValueTxt);
ConfirmAltCustVATRegPage.SetSource(TempChangeLogEntry);
Confirmed := ConfirmAltCustVATRegPage.RunModal() = Action::Ok;
if ConfirmAltCustVATRegPage.DontShowAgainOptionSelected() then
DisableConfirmation();
exit(Confirmed);
end;
local procedure ShowConfirmation(): Boolean
var
MyNotifications: Record "My Notifications";
begin
if Database.IsInWriteTransaction() then
exit(false);
exit(MyNotifications.IsEnabled(GetConfirmChangesNotificationId()));
end;
local procedure DisableConfirmation()
var
MyNotifications: Record "My Notifications";
begin
if not MyNotifications.Disable(GetConfirmChangesNotificationId()) then
MyNotifications.InsertDefault(GetConfirmChangesNotificationId(), ConfirmAltCustVATRegNotificationNameTok, ConfirmAltCustVATRegNotificationDescTok, false);
end;
local procedure UpdateAltCustVATRegInSalesHeader(var SalesHeader: Record "Sales Header")
var
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
begin
GetAlternativeCustVATReg(AltCustVATReg, SalesHeader);
BindSubscription(this);
AltCustVATRegFacade.CopyAltCustVATRegToSalesHeader(SalesHeader, AltCustVATReg);
UnbindSubscription(this);
FeatureTelemetry.LogUptake('0000NHG', FeatureNameTxt, Enum::"Feature Uptake Status"::Used);
end;
local procedure BuildFieldChangeBuffer(var TempChangeLogEntry: Record "Change Log Entry" temporary; SalesHeader: Record "Sales Header"): Boolean
var
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
begin
GetAlternativeCustVATReg(AltCustVATReg, SalesHeader);
AltCustVATRegFacade.AddTempChangeLogEntryForAltCustVATRegChanges(TempChangeLogEntry, SalesHeader, AltCustVATReg);
exit(not TempChangeLogEntry.IsEmpty());
end;
local procedure RunChecks(SalesHeader: Record "Sales Header")
begin
CheckPrepayment(SalesHeader);
CheckPartialPosting(SalesHeader);
end;
local procedure CheckPrepayment(SalesHeader: Record "Sales Header")
var
SalesLine: Record "Sales Line";
begin
SalesLine.SetRange("Document Type", SalesHeader."Document Type");
SalesLine.SetRange("Document No.", SalesHeader."No.");
SalesLine.SetFilter("Prepmt. Amt. Inv.", '<>%1', 0);
if not SalesLine.IsEmpty() then
error(CannotChangeVATDataWhenPrepmtErr);
end;
local procedure CheckPartialPosting(SalesHeader: Record "Sales Header")
var
SalesLine: Record "Sales Line";
begin
SalesLine.SetRange("Document Type", SalesHeader."Document Type");
SalesLine.SetRange("Document No.", SalesHeader."No.");
SalesLine.SetFilter("Quantity Shipped", '<>%1', 0);
if not SalesLine.IsEmpty() then
error(CannotChangeVATDataWhenPartiallyPostedErr);
end;
local procedure GetCustVATCalc(var VATCustomer: Record Customer; SalesHeader: Record "Sales Header"): Boolean
var
GLSetup: Record "General Ledger Setup";
begin
GLSetup.GetRecordOnce();
case GLSetup."Bill-to/Sell-to VAT Calc." of
GLSetup."Bill-to/Sell-to VAT Calc."::"Bill-to/Pay-to No.":
begin
if not VATCustomer.Get(SalesHeader."Bill-to Customer No.") then
exit(VATCustomer.Get(SalesHeader."Sell-to Customer No."));
exit(true);
end;
GLSetup."Bill-to/Sell-to VAT Calc."::"Sell-to/Buy-from No.":
exit(VATCustomer.Get(SalesHeader."Sell-to Customer No."));
end;
end;
local procedure GetConfirmChangesNotificationId(): Guid
begin
exit('5a911b76-547b-49f4-ba6f-ffc64d75077d');
end;
local procedure AddStringToCommaSeparatedList(var List: Text; Value: Text)
begin
if List <> '' then
List += ', ';
List += Value;
end;
local procedure ThrowAddAltCustVATRegNotification(CustNo: Code[20]; VATCountryRegionCode: Code[10])
var
MyNotifications: Record "My Notifications";
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
Notification: Notification;
begin
if not MyNotifications.IsEnabled(AddAltCustVATRegNotificationId()) then
exit;
Notification.Id(AddAltCustVATRegNotificationId());
Notification.Message(AddAlternativeCustVATRegQst);
Notification.SetData(AltCustVATReg.FieldName("Customer No."), CustNo);
Notification.SetData(AltCustVATReg.FieldName("VAT Country/Region Code"), VATCountryRegionCode);
Notification.AddAction(AddAlternativeCustVATRegMsg, Codeunit::"Alt. Cust. VAT Reg. Doc. Impl.", 'AddAltCustVATRegFromNotification');
Notification.AddAction(DontShowMsg, Codeunit::"Alt. Cust. VAT Reg. Doc. Impl.", 'DisableAddAltCustVATRegNotification');
Notification.Send();
end;
procedure AddAltCustVATRegFromNotification(Notification: Notification)
var
AltCustVATReg: Record "Alt. Cust. VAT Reg.";
NewId: Integer;
begin
if AltCustVATReg.FindLast() then
NewId := AltCustVATReg.Id;
NewId += 1;
AltCustVATReg.Init();
AltCustVATReg.Validate(Id, NewId);
AltCustVATReg.Validate("Customer No.",
CopyStr(Notification.GetData(AltCustVATReg.FieldName("Customer No.")), 1, MaxStrLen(AltCustVATReg."Customer No.")));
AltCustVATReg.Validate("VAT Country/Region Code",
CopyStr(Notification.GetData(AltCustVATReg.FieldName("VAT Country/Region Code")), 1, MaxStrLen(AltCustVATReg."VAT Country/Region Code")));
AltCustVATReg.Insert(true);
Commit();
Page.RunModal(0, AltCustVATReg);
end;
procedure DisableAddAltCustVATRegNotification(Notification: Notification)
var
MyNotifications: Record "My Notifications";
begin
if not MyNotifications.Disable(Notification.Id()) then
MyNotifications.InsertDefault(Notification.Id(), AddAltCustVATRegNotificationNameTok, AddAltCustVATRegNotificationDescTok, false);
end;
local procedure AddAltCustVATRegNotificationId(): Text
begin
exit('44c9f482-ed1e-4882-9c96-3135915b566d')
end;
[EventSubscriber(ObjectType::Table, Database::"Sales Header", 'OnRecreateSalesLinesOnBeforeConfirm', '', false, false)]
local procedure AvoidDoubleConfirmationOnRecreateSalesLinesOnBeforeConfirm(var SalesHeader: Record "Sales Header"; xSalesHeader: Record "Sales Header"; var Confirmed: Boolean; var IsHandled: Boolean)
begin
if not SalesLinesRecreated then
exit;
Confirmed := true;
IsHandled := true;
SalesLinesRecreated := false;
end;
[EventSubscriber(ObjectType::Table, Database::"Sales Header", 'OnAfterRecreateSalesLines', '', false, false)]
local procedure SetSalesLineRecreatedOnAfterRecreateSalesLines()
begin
SalesLinesRecreated := true;
end;
}