Table 5964 Service Contract Line, source in 29
Source29
src/Layers/W1/BaseApp/Service/Contract/ServiceContractLine.Table.al1299 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Service.Contract;
using Microsoft.Finance.Currency;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Item;
using Microsoft.Sales.Customer;
using Microsoft.Service.Comment;
using Microsoft.Service.Document;
using Microsoft.Service.Item;
using Microsoft.Service.Ledger;
using Microsoft.Service.Setup;
using System.Utilities;
table 5964 "Service Contract Line"
{
Caption = 'Service Contract Line';
DrillDownPageID = "Serv. Contr. List (Serv. Item)";
LookupPageID = "Serv. Contr. List (Serv. Item)";
DataClassification = CustomerContent;
fields
{
field(1; "Contract Type"; Enum "Service Contract Type")
{
Caption = 'Contract Type';
ToolTip = 'Specifies the type of the contract.';
}
field(2; "Contract No."; Code[20])
{
Caption = 'Contract No.';
ToolTip = 'Specifies the number of the service contract or service contract quote associated with the service contract line.';
TableRelation = "Service Contract Header"."Contract No." where("Contract Type" = field("Contract Type"));
}
field(3; "Line No."; Integer)
{
Caption = 'Line No.';
}
field(4; "Contract Status"; Enum "Service Contract Status")
{
Caption = 'Contract Status';
ToolTip = 'Specifies the status of the contract.';
}
field(5; "Service Item No."; Code[20])
{
Caption = 'Service Item No.';
ToolTip = 'Specifies the number of the service item that is subject to the service contract.';
TableRelation = "Service Item" where(Blocked = filter(" "));
trigger OnValidate()
var
ServiceItemLine: Record "Service Item Line";
ServContractMgt: Codeunit ServContractManagement;
ConfirmManagement: Codeunit "Confirm Management";
InvoicePeriod: DateFormula;
LastInvoiceDate: Date;
NewLastInvoiceDate: Date;
ServiceItemNoIsNotEmpty: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnValidateServiceItemNoOnBeforeOnValidate(Rec, xRec, IsHandled);
if IsHandled then
exit;
TestStatusOpen();
GetServContractHeader();
if ServContractHeader."Last Invoice Date" <> 0D then begin
LastInvoiceDate := ServContractHeader."Last Invoice Date";
Evaluate(InvoicePeriod, ServContractMgt.GetInvoicePeriodText(ServContractHeader."Invoice Period"));
NewLastInvoiceDate := CalcDate(InvoicePeriod, LastInvoiceDate);
if (ServContractHeader."Expiration Date" <> 0D) and
(NewLastInvoiceDate > ServContractHeader."Expiration Date")
then
Error(Text025, ServiceItemLine.TableCaption(), ServContractHeader.FieldCaption("Expiration Date"));
end;
IsHandled := false;
OnValidateServiceItemNoOnBeforeCheckServContractHeaderStatus(Rec, xRec, IsHandled);
if not IsHandled then
if (ServContractHeader.Status = ServContractHeader.Status::Signed) and (not "New Line") then
Error(Text013, FieldCaption("Service Item No."));
ServiceItemNoIsNotEmpty := "Service Item No." <> '';
OnValidateServiceItemNoOnAfterCalcServiceItemNoIsNotEmpty(Rec, ServiceItemNoIsNotEmpty, xRec, HideDialog);
if ServiceItemNoIsNotEmpty then begin
GetServItem();
TestField("Customer No.");
IsHandled := false;
OnValidateServiceItemNoOnBeforeCheckSameCustomer(ServItem, ServContractHeader, IsHandled);
if not IsHandled then
if ServItem."Customer No." <> ServContractHeader."Customer No." then
Error(Text000, "Customer No.");
IsHandled := false;
OnValidateServiceItemNoOnBeforeCheckSameItemExist(Rec, IsHandled);
if not IsHandled then begin
ServContractLine.Reset();
ServContractLine.SetRange("Contract No.", "Contract No.");
ServContractLine.SetRange("Contract Type", "Contract Type");
ServContractLine.SetRange("Service Item No.", "Service Item No.");
ServContractLine.SetFilter("Line No.", '<>%1', "Line No.");
if not ServContractLine.IsEmpty() then
Error(Text003);
end;
if not HideDialog then begin
ServContractLine.Reset();
ServContractLine.SetCurrentKey("Service Item No.", "Contract Status");
ServContractLine.SetRange("Service Item No.", "Service Item No.");
ServContractLine.SetFilter("Contract Status", '<>%1', ServContractLine."Contract Status"::Cancelled);
ServContractLine.SetRange("Contract Type", ServContractLine."Contract Type"::Contract);
ServContractLine.SetFilter("Contract No.", '<>%1', "Contract No.");
OnValidateServiceItemNoOnAfterServContractLineSetFiltersWithContractStatus(Rec, ServContractLine);
if not ServContractLine.IsEmpty() then begin
if not ConfirmManagement.GetResponseOrDefault(
StrSubstNo(Text019, "Service Item No."), true)
then begin
"Service Item No." := xRec."Service Item No.";
exit;
end;
end else begin
ServContractLine.Reset();
ServContractLine.SetCurrentKey("Service Item No.");
ServContractLine.SetRange("Service Item No.", "Service Item No.");
ServContractLine.SetRange("Contract Type", ServContractLine."Contract Type"::Quote);
ServContractLine.SetFilter("Contract No.", '<>%1', "Contract No.");
if not ServContractLine.IsEmpty() then
if not ConfirmManagement.GetResponseOrDefault(
StrSubstNo(Text019, "Service Item No."), true)
then begin
"Service Item No." := xRec."Service Item No.";
exit;
end;
end;
end;
if (ServItem."Ship-to Code" <> ServContractHeader."Ship-to Code") and
not HideDialog
then
if not ConfirmManagement.GetResponseOrDefault(
StrSubstNo(Text001, "Service Item No."), true)
then begin
"Service Item No." := xRec."Service Item No.";
exit;
end;
"Ship-to Code" := ServItem."Ship-to Code";
end;
ServContractLine := Rec;
Init();
OnValidateServiceItemNoOnAfterInit(Rec, ServContractLine);
"Starting Date" := ServContractLine."Starting Date";
"Contract Expiration Date" := ServContractLine."Contract Expiration Date";
"Credit Memo Date" := ServContractLine."Credit Memo Date";
"Next Planned Service Date" := ServContractLine."Next Planned Service Date";
"Service Period" := ServContractLine."Service Period";
"Customer No." := ServContractLine."Customer No.";
if ServContractLine."Service Item No." <> '' then
"Ship-to Code" := ServContractLine."Ship-to Code"
else
"Ship-to Code" := ServContractHeader."Ship-to Code";
"Contract Status" := ServContractLine."Contract Status";
"Service Item No." := ServContractLine."Service Item No.";
if "Service Item No." = '' then
exit;
Description := ServItem.Description;
"Serial No." := ServItem."Serial No.";
"Service Item Group Code" := ServItem."Service Item Group Code";
"Item No." := ServItem."Item No.";
"Variant Code" := ServItem."Variant Code";
"Unit of Measure Code" := ServItem."Unit of Measure Code";
ServContractMgt.CheckItemServiceBlocked(Rec);
if (ServContractHeader."Response Time (Hours)" < ServItem."Response Time (Hours)") and
(ServContractHeader."Response Time (Hours)" <> 0)
then
"Response Time (Hours)" := ServContractHeader."Response Time (Hours)"
else
if ServItem."Response Time (Hours)" <> 0 then
"Response Time (Hours)" := ServItem."Response Time (Hours)"
else
"Response Time (Hours)" := ServContractHeader."Response Time (Hours)";
ServMgtSetup.Get();
Validate("Line Cost", ServItem."Default Contract Cost");
Validate("Line Value", ServItem."Default Contract Value");
Validate("Line Discount %", ServItem."Default Contract Discount %");
OnValidateServiceItemNoOnBeforeModify(ServItem, ServContractHeader);
if ServContractLine.Get("Contract Type", "Contract No.", "Line No.") then begin
UseServContractLineAsxRec := true;
Modify(true);
end;
end;
}
field(6; Description; Text[100])
{
Caption = 'Description';
ToolTip = 'Specifies the description of the service item that is subject to the contract.';
trigger OnValidate()
begin
TestStatusOpen();
end;
}
field(7; "Serial No."; Code[50])
{
Caption = 'Serial No.';
ToolTip = 'Specifies the serial number of the service item that is subject to the contract.';
trigger OnValidate()
begin
TestStatusOpen();
TestField("Item No.");
end;
}
field(8; "Service Item Group Code"; Code[10])
{
Caption = 'Service Item Group Code';
TableRelation = "Service Item Group";
trigger OnValidate()
begin
TestStatusOpen();
TestField("Service Item No.");
end;
}
field(9; "Customer No."; Code[20])
{
Caption = 'Customer No.';
ToolTip = 'Specifies the number of the customer associated with the service contract.';
TableRelation = Customer;
}
field(10; "Ship-to Code"; Code[10])
{
Caption = 'Ship-to Code';
ToolTip = 'Specifies a code for an alternate shipment address if you want to ship to another address than the one that has been entered automatically. This field is also used in case of drop shipment.';
Editable = false;
TableRelation = "Ship-to Address".Code where("Customer No." = field("Customer No."));
}
field(11; "Item No."; Code[20])
{
Caption = 'Item No.';
ToolTip = 'Specifies the number of the item linked to the service item in the service contract.';
TableRelation = Item where(Type = const(Inventory), Blocked = const(false), "Service Blocked" = const(false));
trigger OnValidate()
begin
TestStatusOpen();
if "Item No." <> xRec."Item No." then
TestField("Service Item No.", '');
if "Item No." <> '' then begin
Item.Get("Item No.");
Currency.InitRoundingPrecision();
Description := Item.Description;
"Unit of Measure Code" := Item."Sales Unit of Measure";
GetServContractHeader();
"Response Time (Hours)" := ServContractHeader."Response Time (Hours)";
ServMgtSetup.Get();
"Line Cost" :=
Round(Item."Unit Cost" * ServMgtSetup."Contract Value %" / 100,
Currency."Amount Rounding Precision");
"Line Discount %" := 0;
case ServMgtSetup."Contract Value Calc. Method" of
ServMgtSetup."Contract Value Calc. Method"::"Based on Unit Price":
"Line Value" :=
Round(Item."Unit Price" * ServMgtSetup."Contract Value %" / 100,
Currency."Amount Rounding Precision");
ServMgtSetup."Contract Value Calc. Method"::"Based on Unit Cost":
"Line Value" :=
Round(Item."Unit Cost" * ServMgtSetup."Contract Value %" / 100,
Currency."Amount Rounding Precision");
end;
Validate("Line Value", "Line Value");
end else begin
"Unit of Measure Code" := '';
"Variant Code" := '';
"Serial No." := '';
end;
end;
}
field(12; "Unit of Measure Code"; Code[10])
{
Caption = 'Unit of Measure Code';
ToolTip = 'Specifies how each unit of the item or resource is measured, such as in pieces or hours. By default, the value in the Base Unit of Measure field on the item or resource card is inserted.';
TableRelation = if ("Item No." = filter(<> '')) "Item Unit of Measure".Code where("Item No." = field("Item No."))
else
"Unit of Measure";
trigger OnValidate()
begin
TestStatusOpen();
if "Unit of Measure Code" <> xRec."Unit of Measure Code" then begin
TestField("Service Item No.", '');
TestField("Item No.");
end;
end;
}
field(13; "Response Time (Hours)"; Decimal)
{
AutoFormatType = 0;
BlankZero = true;
Caption = 'Response Time (Hours)';
DecimalPlaces = 0 : 5;
MinValue = 0;
trigger OnValidate()
begin
TestStatusOpen();
end;
}
field(14; "Last Planned Service Date"; Date)
{
Caption = 'Last Planned Service Date';
ToolTip = 'Specifies the date of the last planned service on this item.';
Editable = false;
}
field(15; "Next Planned Service Date"; Date)
{
Caption = 'Next Planned Service Date';
ToolTip = 'Specifies the date of the next planned service on the item included in the contract.';
trigger OnValidate()
begin
TestStatusOpen();
if ("Next Planned Service Date" <> 0D) and
("Next Planned Service Date" < "Starting Date")
then
Error(Text009, FieldCaption("Next Planned Service Date"), FieldCaption("Starting Date"));
end;
}
field(16; "Last Service Date"; Date)
{
Caption = 'Last Service Date';
ToolTip = 'Specifies the date when the service item on the line was last serviced.';
}
field(17; "Last Preventive Maint. Date"; Date)
{
Caption = 'Last Preventive Maint. Date';
ToolTip = 'Specifies the date when the last time preventative service was performed on this item.';
Editable = false;
}
field(18; "Invoiced to Date"; Date)
{
Caption = 'Invoiced to Date';
Editable = false;
}
field(19; "Credit Memo Date"; Date)
{
Caption = 'Credit Memo Date';
ToolTip = 'Specifies the date when you can create a credit memo for the service item that needs to be removed from the service contract.';
trigger OnValidate()
begin
TestStatusOpen();
TestField(Credited, false);
CheckCreditMemoDate();
end;
}
field(20; "Contract Expiration Date"; Date)
{
Caption = 'Contract Expiration Date';
ToolTip = 'Specifies the date when an item should be removed from the contract.';
trigger OnValidate()
var
IsHandled: Boolean;
begin
TestStatusOpen();
IsHandled := false;
OnBeforeValidateContractExpirationDate(Rec, xRec, CurrFieldNo, IsHandled);
if IsHandled then
exit;
TestField(Credited, false);
ServContractHeader.Get("Contract Type", "Contract No.");
if (not ServContractHeader.Prepaid) and
(xRec."Contract Expiration Date" <= "Invoiced to Date") and
(xRec."Contract Expiration Date" <> 0D)
then
if ("Contract Expiration Date" > "Invoiced to Date") or
("Contract Expiration Date" = 0D)
then
Error(
Text024,
FieldCaption("Contract Expiration Date"));
if "Contract Expiration Date" = 0D then begin
"Credit Memo Date" := 0D;
exit;
end;
if "Contract Expiration Date" < "Starting Date" then
Error(
Text009,
FieldCaption("Contract Expiration Date"),
FieldCaption("Starting Date"));
if ServContractHeader."Expiration Date" <> 0D then
if "Contract Expiration Date" > ServContractHeader."Expiration Date" then
Error(
Text017,
FieldCaption("Contract Expiration Date"),
ServContractHeader.FieldCaption("Expiration Date"));
if "Contract Expiration Date" < "Credit Memo Date" then
Error(
Text009,
FieldCaption("Contract Expiration Date"),
FieldCaption("Credit Memo Date"));
if "Credit Memo Date" = 0D then
"Credit Memo Date" := "Contract Expiration Date";
if not ServContractHeader."Automatic Credit Memos" then begin
ServLedgEntry.Reset();
ServLedgEntry.SetCurrentKey(Type, "No.", "Entry Type", "Moved from Prepaid Acc.", "Posting Date", Open);
ServLedgEntry.SetRange(Type, ServLedgEntry.Type::"Service Contract");
ServLedgEntry.SetRange("No.", "Contract No.");
ServLedgEntry.SetRange("Moved from Prepaid Acc.", false);
ServLedgEntry.SetRange(Open, false);
ServLedgEntry.CalcSums("Amount (LCY)");
if ServLedgEntry."Amount (LCY)" <> 0 then
Message(Text011, "Contract No.");
end;
end;
}
field(21; "Service Period"; DateFormula)
{
Caption = 'Service Period';
ToolTip = 'Specifies the period of time that must pass between each servicing of an item.';
trigger OnValidate()
begin
TestStatusOpen();
end;
}
field(22; "Line Value"; Decimal)
{
AutoFormatExpression = '';
AutoFormatType = 1;
BlankZero = true;
Caption = 'Line Value';
ToolTip = 'Specifies the value of the service item line in the contract or contract quote.';
trigger OnValidate()
begin
if "Line Value" < 0 then
FieldError("Line Value");
Validate("Line Discount %");
end;
}
field(23; "Line Discount %"; Decimal)
{
AutoFormatType = 0;
BlankZero = true;
Caption = 'Line Discount %';
ToolTip = 'Specifies the discount percentage that is granted for the item on the line.';
DecimalPlaces = 0 : 5;
MaxValue = 100;
MinValue = 0;
trigger OnValidate()
var
IsHandled: Boolean;
begin
TestStatusOpen();
IsHandled := false;
OnBeforeValidateLineDiscountPercent(Rec, xRec, CurrFieldNo, IsHandled);
if IsHandled then
exit;
Currency.InitRoundingPrecision();
"Line Value" := Round("Line Value", Currency."Amount Rounding Precision");
"Line Amount" :=
Round("Line Value" - "Line Value" * "Line Discount %" / 100,
Currency."Amount Rounding Precision");
"Line Discount Amount" :=
Round("Line Value" - "Line Amount", Currency."Amount Rounding Precision");
Profit := Round("Line Amount" - "Line Cost", Currency."Amount Rounding Precision");
end;
}
field(24; "Line Amount"; Decimal)
{
AutoFormatExpression = '';
AutoFormatType = 1;
BlankZero = true;
Caption = 'Line Amount';
ToolTip = 'Specifies the net amount, excluding any invoice discount amount, that must be paid for products on the line.';
trigger OnValidate()
var
IsHandled: Boolean;
begin
TestStatusOpen();
IsHandled := false;
OnBeforeValidateLineAmount(Rec, xRec, CurrFieldNo, IsHandled);
if IsHandled then
exit;
TestField("Line Value");
Currency.InitRoundingPrecision();
"Line Discount Amount" := Round("Line Value" - "Line Amount", Currency."Amount Rounding Precision");
"Line Discount %" := "Line Discount Amount" / "Line Value" * 100;
Profit := Round("Line Amount" - "Line Cost", Currency."Amount Rounding Precision");
end;
}
field(28; "Variant Code"; Code[10])
{
Caption = 'Variant Code';
ToolTip = 'Specifies the variant of the item on the line.';
TableRelation = "Item Variant".Code where("Item No." = field("Item No."), Blocked = const(false), "Service Blocked" = const(false));
trigger OnValidate()
begin
TestStatusOpen();
end;
}
field(29; "Starting Date"; Date)
{
Caption = 'Starting Date';
ToolTip = 'Specifies the starting date of the service contract.';
Editable = false;
}
field(30; "New Line"; Boolean)
{
Caption = 'New Line';
ToolTip = 'Specifies whether the service contract line is new or existing.';
Editable = false;
InitValue = true;
}
field(31; Credited; Boolean)
{
Caption = 'Credited';
ToolTip = 'Specifies if the service contract line has been credited.';
trigger OnValidate()
begin
TestStatusOpen();
TestField("Contract Expiration Date");
end;
}
field(32; "Line Cost"; Decimal)
{
AutoFormatExpression = '';
AutoFormatType = 1;
BlankZero = true;
Caption = 'Line Cost';
ToolTip = 'Specifies the calculated cost of the service item line in the service contract or contract quote.';
trigger OnValidate()
begin
TestStatusOpen();
Currency.InitRoundingPrecision();
Profit := Round("Line Amount" - "Line Cost", Currency."Amount Rounding Precision");
end;
}
field(33; "Line Discount Amount"; Decimal)
{
AutoFormatExpression = '';
AutoFormatType = 1;
BlankZero = true;
Caption = 'Line Discount Amount';
ToolTip = 'Specifies the discount amount that is granted for the item on the line.';
trigger OnValidate()
begin
TestStatusOpen();
Currency.InitRoundingPrecision();
if "Line Value" <> 0 then
"Line Discount %" := "Line Discount Amount" / "Line Value" * 100
else
"Line Discount %" := 0;
"Line Amount" :=
Round("Line Value" - "Line Value" * "Line Discount %" / 100, Currency."Amount Rounding Precision");
Profit := Round("Line Amount" - "Line Cost", Currency."Amount Rounding Precision");
end;
}
field(34; Profit; Decimal)
{
AutoFormatExpression = '';
AutoFormatType = 1;
BlankZero = true;
Caption = 'Profit';
ToolTip = 'Specifies the profit, expressed as the difference between the Line Amount and Line Cost fields on the service contract line.';
trigger OnValidate()
begin
TestStatusOpen();
Currency.InitRoundingPrecision();
"Line Amount" := Round(Profit + "Line Cost", Currency."Amount Rounding Precision");
"Line Discount Amount" := Round("Line Value" - "Line Amount", Currency."Amount Rounding Precision");
if "Line Value" <> 0 then
"Line Discount %" := "Line Discount Amount" / "Line Value" * 100;
end;
}
}
keys
{
key(Key1; "Contract Type", "Contract No.", "Line No.")
{
Clustered = true;
}
key(Key2; "Contract No.", "Line No.", "Contract Type")
{
}
key(Key3; "Service Item No.", "Contract Status")
{
}
key(Key4; "Contract Type", "Contract No.", Credited, "New Line")
{
MaintainSIFTIndex = false;
MaintainSQLIndex = false;
SumIndexFields = "Line Amount", Profit;
}
key(Key5; "Customer No.", "Ship-to Code")
{
}
}
fieldgroups
{
}
trigger OnDelete()
var
ConfirmManagement: Codeunit "Confirm Management";
begin
TestStatusOpen();
if "Contract Type" = "Contract Type"::Contract then begin
GetServContractHeader();
if ServContractHeader.Status = ServContractHeader.Status::Cancelled then
Error(Text015, ServContractHeader.Status);
if (ServContractHeader.Status = ServContractHeader.Status::Signed) and
(not "New Line") and
ServContractHeader."Automatic Credit Memos"
then begin
TestField("Contract Expiration Date");
CODEUNIT.Run(CODEUNIT::CreateCreditfromContractLines, Rec);
end;
if (ServContractHeader.Status = ServContractHeader.Status::Signed) and
(not "New Line") and
(not ServContractHeader."Automatic Credit Memos")
then
if CreditMemoBaseExists() and
(not StatusCheckSuspended)
then
if not ConfirmManagement.GetResponseOrDefault(Text022, true) then
Error(Text023);
ServMgtSetup.Get();
if "Service Item No." <> '' then begin
if ServMgtSetup."Register Contract Changes" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Service Item No."), 2,
Format("Service Item No."), '', "Service Item No.", "Line No.");
ServLogMgt.ServItemRemovedFromContract(Rec);
end else
if ServMgtSetup."Register Contract Changes" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption(Description), 2, Description, '', '', "Line No.");
GetServContractHeader();
if (not ServContractHeader."Allow Unbalanced Amounts") and
(ServContractHeader.Status = ServContractHeader.Status::Signed)
then
ContractGainLossEntry.CreateEntry(
"Service Contract Change Type"::"Line Deleted", "Contract Type", "Contract No.", -"Line Amount", '');
end;
ServCommentLine.SetRange("Table Name", ServCommentLine."Table Name"::"Service Contract");
ServCommentLine.SetRange("Table Subtype", "Contract Type");
ServCommentLine.SetRange("No.", "Contract No.");
ServCommentLine.SetRange(Type, ServCommentLine.Type::General);
ServCommentLine.SetRange("Table Line No.", "Line No.");
ServCommentLine.DeleteAll();
UpdateContractAnnualAmount(true);
end;
trigger OnInsert()
begin
TestField(Description);
GetServContractHeader();
CheckServContractHeader();
ServMgtSetup.Get();
UpdateContractAnnualAmount(false);
if ("Service Item No." = '') and ("Response Time (Hours)" = 0) then
"Response Time (Hours)" := ServContractHeader."Response Time (Hours)";
if "Contract Type" = "Contract Type"::Contract then
if "Service Item No." <> '' then begin
if ServMgtSetup."Register Contract Changes" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Service Item No."), 1, '',
Format("Service Item No."), "Service Item No.", "Line No.");
ServLogMgt.ServItemAddToContract(Rec);
end else
if ServMgtSetup."Register Contract Changes" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption(Description), 1, '', Description, '', "Line No.");
end;
trigger OnModify()
begin
if UseServContractLineAsxRec then begin
xRec := ServContractLine;
UseServContractLineAsxRec := false;
end;
if ("Service Item No." = '') and
("Item No." = '') and
(Description = '')
then
Error(Text016, FieldCaption(Description));
ServMgtSetup.Get();
if ServMgtSetup."Register Contract Changes" then
if "Contract Type" = "Contract Type"::Contract then
LogContractLineChanges(xRec);
if Rec."Line Amount" <> xRec."Line Amount" then
UpdateContractAnnualAmount(false);
if "Service Item No." <> xRec."Service Item No." then begin
ServLogMgt.ServItemAddToContract(Rec);
ServLogMgt.ServItemRemovedFromContract(xRec);
end;
end;
var
Currency: Record Currency;
Item: Record Item;
ServMgtSetup: Record "Service Mgt. Setup";
ServLedgEntry: Record "Service Ledger Entry";
ServContractHeader: Record "Service Contract Header";
ServContractLine: Record "Service Contract Line";
ServItem: Record "Service Item";
ContractChangeLog: Record "Contract Change Log";
ContractGainLossEntry: Record "Contract Gain/Loss Entry";
ServCommentLine: Record "Service Comment Line";
ServLogMgt: Codeunit ServLogManagement;
HideDialog: Boolean;
StatusCheckSuspended: Boolean;
UseServContractLineAsxRec: Boolean;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text000: Label 'This service item does not belong to customer no. %1.';
Text001: Label 'Service item %1 has a different ship-to code for this customer.\\Do you want to continue?';
#pragma warning restore AA0470
Text003: Label 'This service item already exists in this service contract.';
#pragma warning disable AA0470
Text008: Label '%1 field value cannot be later than the %2 field value on the contract line.';
Text009: Label 'The %1 cannot be less than the %2.';
Text011: Label 'Service ledger entry exists for service contract line %1.\\You may need to create a credit memo.';
Text013: Label 'You cannot change the %1 field on signed service contracts.';
Text015: Label 'You cannot delete service contract lines on %1 service contracts.';
Text016: Label 'Service contract lines must have at least a %1 filled in.';
Text017: Label 'The %1 cannot be later than the %2.';
Text018: Label 'You cannot reset %1 manually.';
Text019: Label 'Service item %1 already belongs to one or more service contracts/quotes.\\Do you want to continue?';
Text020: Label 'The service period for service item %1 under contract %2 has not yet started.';
Text021: Label 'The service period for service item %1 under contract %2 has expired.';
#pragma warning restore AA0470
Text022: Label 'If you delete this contract line while the Automatic Credit Memos check box is not selected, a credit memo will not be created.\Do you want to continue?';
Text023: Label 'The update has been interrupted to respect the warning.';
#pragma warning disable AA0470
Text024: Label 'You cannot enter a later date in or clear the %1 field on the contract line that has been invoiced for the period containing that date.';
Text025: Label 'You cannot add a new %1 because the service contract has expired. Renew the %2 on the service contract.', Comment = 'You cannot add a new Service Item Line because the service contract has expired. Renew the Expiration Date on the service contract.';
#pragma warning restore AA0470
#pragma warning restore AA0074
procedure SetupNewLine()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeSetupNewLine(Rec, IsHandled);
if IsHandled then
exit;
if not ServContractHeader.Get("Contract Type", "Contract No.") then
exit;
"Customer No." := ServContractHeader."Customer No.";
"Ship-to Code" := ServContractHeader."Ship-to Code";
"Contract Status" := ServContractHeader.Status;
"Contract Expiration Date" := ServContractHeader."Expiration Date";
"Credit Memo Date" := "Contract Expiration Date";
"Service Period" := ServContractHeader."Service Period";
if ("Contract Type" = "Contract Type"::Contract) and
("Contract Status" = "Contract Status"::Signed)
then
"Starting Date" := WorkDate()
else
"Starting Date" := ServContractHeader."Starting Date";
if "Starting Date" > ServContractHeader."First Service Date" then
"Next Planned Service Date" := "Starting Date"
else
"Next Planned Service Date" := ServContractHeader."First Service Date";
OnAfterSetupNewLine(Rec, ServContractHeader);
end;
local procedure GetServItem()
var
ServContractManagement: Codeunit ServContractManagement;
begin
TestField("Service Item No.");
if "Service Item No." <> ServItem."No." then begin
ServItem.Get("Service Item No.");
ServContractManagement.CheckServiceItemBlockedForServiceContract(Rec);
end;
OnAfterGetServiceItem(Rec, ServItem);
end;
procedure CalculateNextServiceVisit()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCalculateNextServiceVisit(Rec, IsHandled);
if IsHandled then
exit;
ServMgtSetup.Get();
if (Format("Service Period") <> '') and
("Next Planned Service Date" <> 0D)
then begin
GetServContractHeader();
case ServMgtSetup."Next Service Calc. Method" of
ServMgtSetup."Next Service Calc. Method"::Planned:
"Next Planned Service Date" := CalcDate("Service Period", "Last Planned Service Date");
ServMgtSetup."Next Service Calc. Method"::Actual:
"Next Planned Service Date" := CalcDate("Service Period", "Last Service Date");
end;
end else
"Next Planned Service Date" := 0D;
OnAfterCalculateNextServiceVisit(ServContractHeader, ServMgtSetup);
end;
procedure UpdateContractAnnualAmount(Deleting: Boolean)
var
OldServContractHeader: Record "Service Contract Header";
ServContractLine2: Record "Service Contract Line";
LineAmount: Decimal;
IsHandled: Boolean;
begin
GetServContractHeader();
IsHandled := false;
OnUpdateContractAnnualAmountOnAfterGetServContractHeader(Rec, ServContractHeader, IsHandled);
if IsHandled then
exit;
if not ServContractHeader."Allow Unbalanced Amounts" then begin
LineAmount := CalculateOtherLineAmounts();
OldServContractHeader := ServContractHeader;
if Deleting then
ServContractHeader."Annual Amount" := LineAmount
else begin
ServContractHeader."Annual Amount" := LineAmount + "Line Amount";
if not "New Line" then
ContractGainLossEntry.CreateEntry(
"Service Contract Change Type"::"Manual Update", "Contract Type", "Contract No.",
"Line Amount" - xRec."Line Amount", '')
else
if ServContractHeader.Status = ServContractHeader.Status::Signed then
if ServContractLine2.Get("Contract Type", "Contract No.", "Line No.") then
ContractGainLossEntry.CreateEntry(
"Service Contract Change Type"::"Manual Update", "Contract Type", "Contract No.",
"Line Amount" - ServContractLine2."Line Amount", '')
else
ContractGainLossEntry.CreateEntry(
"Service Contract Change Type"::"Line Added", "Contract Type", "Contract No.",
"Line Amount", '');
end;
ServContractHeader.ValidateNextInvoicePeriod();
ServContractHeader.SuspendStatusCheck(StatusCheckSuspended);
ServContractHeader.Modify(true);
if ServContractHeader."Contract Type" = ServContractHeader."Contract Type"::Contract then
if ServMgtSetup."Register Contract Changes" then
ServContractHeader.UpdContractChangeLog(OldServContractHeader);
end;
end;
local procedure CalculateOtherLineAmounts(): Decimal
var
ServContractLine2: Record "Service Contract Line";
begin
ServContractLine2.Reset();
ServContractLine2.SetRange("Contract Type", "Contract Type");
ServContractLine2.SetRange("Contract No.", "Contract No.");
ServContractLine2.SetFilter("Line No.", '<>%1', "Line No.");
OnCalculateOtherLineAmountsOnAfterSetFilters(ServContractLine2);
ServContractLine2.CalcSums("Line Amount");
exit(ServContractLine2."Line Amount");
end;
procedure HideDialogBox(Hide: Boolean)
begin
HideDialog := Hide;
end;
procedure TestStatusOpen()
begin
if StatusCheckSuspended then
exit;
GetServContractHeader();
ServContractHeader.TestField("Change Status", ServContractHeader."Change Status"::Open);
OnAfterTestStatusOpen(Rec, CurrFieldNo);
end;
local procedure CheckServContractHeader()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckServContractHeader(ServContractHeader, IsHandled);
if IsHandled then
exit;
ServContractHeader.TestField("Customer No.");
ServContractHeader.TestField("Contract No.");
ServContractHeader.TestField("Starting Date");
if "Service Item No." <> '' then begin
ServContractHeader.TestField("Service Period");
ServContractHeader.TestField("First Service Date");
end;
end;
local procedure CheckCreditMemoDate()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckCreditMemoDate(Rec, xRec, IsHandled);
if IsHandled then
exit;
if "Credit Memo Date" <> 0D then
if "Credit Memo Date" > "Contract Expiration Date" then
Error(
Text008,
FieldCaption("Credit Memo Date"), FieldCaption("Contract Expiration Date"));
if "Credit Memo Date" <> xRec."Credit Memo Date" then
if "Credit Memo Date" = 0D then
Error(Text018, FieldCaption("Credit Memo Date"));
end;
procedure GetStatusCheckSuspended(): Boolean
begin
exit(StatusCheckSuspended);
end;
procedure SuspendStatusCheck(Suspend: Boolean)
begin
StatusCheckSuspended := Suspend;
end;
local procedure GetServContractHeader()
begin
TestField("Contract No.");
if ("Contract Type" <> ServContractHeader."Contract Type") or
("Contract No." <> ServContractHeader."Contract No.")
then
ServContractHeader.Get("Contract Type", "Contract No.");
end;
procedure ShowComments()
begin
ServContractHeader.Get("Contract Type", "Contract No.");
ServContractHeader.TestField("Customer No.");
TestField("Line No.");
ServCommentLine.Reset();
ServCommentLine.SetRange("Table Name", ServCommentLine."Table Name"::"Service Contract");
ServCommentLine.SetRange("Table Subtype", "Contract Type");
ServCommentLine.SetRange("No.", "Contract No.");
ServCommentLine.SetRange(Type, ServCommentLine.Type::General);
ServCommentLine.SetRange("Table Line No.", "Line No.");
PAGE.RunModal(PAGE::"Service Comment Sheet", ServCommentLine);
end;
procedure ValidateServicePeriod(CurrentDate: Date)
begin
if "Starting Date" > CurrentDate then
Error(Text020, "Service Item No.", "Contract No.");
if "Contract Expiration Date" = 0D then begin
ServContractHeader.Get(ServContractHeader."Contract Type"::Contract, "Contract No.");
if (ServContractHeader."Expiration Date" <> 0D) and
(ServContractHeader."Expiration Date" <= CurrentDate)
then
Error(Text021, "Service Item No.", "Contract No.");
end else
if "Contract Expiration Date" < CurrentDate then
Error(Text021, "Service Item No.", "Contract No.");
end;
procedure CreditMemoBaseExists() Result: Boolean
var
ServContractMgt: Codeunit ServContractManagement;
CreditAmount: Decimal;
FirstPrepaidPostingDate: Date;
LastIncomePostingDate: Date;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCreditMemoBaseExists(Rec, Result, IsHandled);
if IsHandled then
exit(Result);
if "Line Amount" > 0 then begin
TestField("Contract Expiration Date");
if "Invoiced to Date" >= "Contract Expiration Date" then begin
Currency.InitRoundingPrecision();
if ServContractHeader.Prepaid then
FirstPrepaidPostingDate := ServContractMgt.FindFirstPrepaidTransaction("Contract No.")
else
FirstPrepaidPostingDate := 0D;
LastIncomePostingDate := "Invoiced to Date";
if FirstPrepaidPostingDate <> 0D then
LastIncomePostingDate := FirstPrepaidPostingDate - 1;
CreditAmount :=
Round(
ServContractMgt.CalcContractLineAmount("Line Amount",
"Contract Expiration Date", LastIncomePostingDate),
Currency."Amount Rounding Precision");
if FirstPrepaidPostingDate <> 0D then
if "Contract Expiration Date" < FirstPrepaidPostingDate then
CreditAmount :=
Round(
ServContractMgt.CalcContractLineAmount("Line Amount",
FirstPrepaidPostingDate, "Invoiced to Date"),
Currency."Amount Rounding Precision")
else
CreditAmount :=
Round(
ServContractMgt.CalcContractLineAmount("Line Amount",
"Contract Expiration Date", "Invoiced to Date"),
Currency."Amount Rounding Precision");
end;
exit((CreditAmount > 0) and (not Credited));
end;
exit(false);
end;
procedure LogContractLineChanges(ServContractLine2: Record "Service Contract Line")
begin
if "Item No." <> ServContractLine2."Item No." then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Item No."), 0,
Format(ServContractLine2."Item No."), Format("Item No."),
ServContractLine2."Service Item No.", "Line No.");
if "Line Value" <> ServContractLine2."Line Value" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Line Value"), 0,
Format(ServContractLine2."Line Value"), Format("Line Value"),
ServContractLine2."Service Item No.", "Line No.");
if "Line Discount %" <> ServContractLine2."Line Discount %" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Line Discount %"), 0,
Format(ServContractLine2."Line Discount %"), Format("Line Discount %"),
ServContractLine2."Service Item No.", "Line No.");
if "Line Amount" <> ServContractLine2."Line Amount" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Line Amount"), 0,
Format(ServContractLine2."Line Amount"), Format("Line Amount"),
ServContractLine2."Service Item No.", "Line No.");
if "Contract Expiration Date" <> ServContractLine2."Contract Expiration Date" then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Contract Expiration Date"), 0,
Format(ServContractLine2."Contract Expiration Date"), Format("Contract Expiration Date"),
ServContractLine2."Service Item No.", "Line No.");
if "Service Item No." <> ServContractLine2."Service Item No." then
ContractChangeLog.LogContractChange(
"Contract No.", 1, FieldCaption("Service Item No."), 0,
Format(ServContractLine2."Service Item No."), Format("Service Item No."),
ServContractLine2."Service Item No.", "Line No.");
OnAfterLogContractLineChanges(Rec, ServContractLine2);
end;
procedure SelectMultipleServiceItems()
var
ServiceContractHeader: Record "Service Contract Header";
ServiceItemListPage: Page "Service Item List";
SelectionFilter: Text;
begin
OnBeforeSelectMultipleServiceItems(Rec);
GetServContractHeader();
SelectionFilter := ServiceItemListPage.SelectServiceItemsForServiceContract(ServiceContractHeader, Rec);
if SelectionFilter <> '' then
AddServiceItems(SelectionFilter);
OnAfterSelectMultipleServiceItems(Rec);
end;
local procedure AddServiceItems(SelectionFilter: Text)
var
ServiceItem: Record "Service Item";
ServiceContractLine: Record "Service Contract Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAddServiceItems(Rec, SelectionFilter, IsHandled);
if IsHandled then
exit;
InitNewLine(ServiceContractLine);
ServiceContractLine.HideDialogBox(true);
ServiceItem.SetLoadFields("No.");
ServiceItem.SetFilter("No.", SelectionFilter);
if ServiceItem.FindSet() then
repeat
AddServiceItem(ServiceContractLine, ServiceItem."No.");
until ServiceItem.Next() = 0;
end;
local procedure AddServiceItem(var ServiceContractLine: Record "Service Contract Line"; ServiceItemNo: Code[20])
begin
ServiceContractLine."Line No." += 10000;
ServiceContractLine.Validate("Service Item No.", ServiceItemNo);
ServiceContractLine.Insert(true);
end;
local procedure InitNewLine(var NewServiceContractLine: Record "Service Contract Line")
var
ServiceContractLine: Record "Service Contract Line";
begin
NewServiceContractLine.Copy(Rec);
ServiceContractLine.SetRange("Contract Type", NewServiceContractLine."Contract Type");
ServiceContractLine.SetRange("Contract No.", NewServiceContractLine."Contract No.");
if ServiceContractLine.FindLast() then
NewServiceContractLine."Line No." := ServiceContractLine."Line No."
else
NewServiceContractLine."Line No." := 0;
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCalculateNextServiceVisit(ServContractHeader: Record "Service Contract Header"; ServMgtSetup: Record "Service Mgt. Setup")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetServiceItem(ServiceContractLine: Record "Service Contract Line"; var ServiceItem: Record "Service Item")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterLogContractLineChanges(var ServiceContractLine: Record "Service Contract Line"; xServiceContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetupNewLine(var ServiceContractLine: Record "Service Contract Line"; ServiceContractHeader: Record "Service Contract Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTestStatusOpen(ServiceContractLine: Record "Service Contract Line"; CurrentFieldNo: Integer)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeCheckServContractHeader(ServContractHeader: Record "Service Contract Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeCheckCreditMemoDate(var ServiceContractLine: Record "Service Contract Line"; xServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCreditMemoBaseExists(ServiceContractLine: Record "Service Contract Line"; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateContractExpirationDate(var ServiceContractLine: Record "Service Contract Line"; var xServiceContractLine: Record "Service Contract Line"; CurrentFieldNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateLineAmount(var ServiceContractLine: Record "Service Contract Line"; var xServiceContractLine: Record "Service Contract Line"; CurrentFieldNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateLineDiscountPercent(var ServiceContractLine: Record "Service Contract Line"; var xServiceContractLine: Record "Service Contract Line"; CurrentFieldNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOtherLineAmountsOnAfterSetFilters(var ServiceContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateContractAnnualAmountOnAfterGetServContractHeader(var ServiceContractLine: Record "Service Contract Line"; ServContractHeader: Record "Service Contract Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateServiceItemNoOnAfterCalcServiceItemNoIsNotEmpty(var ServiceContractLine: Record "Service Contract Line"; var ServiceItemNoIsNotEmpty: Boolean; xServiceContractLine: Record "Service Contract Line"; var HideDialog: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateServiceItemNoOnBeforeCheckSameItemExist(var ServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateServiceItemNoOnAfterServContractLineSetFiltersWithContractStatus(var ServiceContractLine: Record "Service Contract Line"; var ServContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateServiceItemNoOnBeforeCheckSameCustomer(ServItem: Record "Service Item"; var ServContractHeader: Record "Service Contract Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnValidateServiceItemNoOnBeforeModify(ServItem: Record "Service Item"; ServContractHeader: Record "Service Contract Header")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnValidateServiceItemNoOnAfterInit(var ServContractLineRec: Record "Service Contract Line"; ServContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnValidateServiceItemNoOnBeforeOnValidate(var ServiceContractLine: Record "Service Contract Line"; xServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnValidateServiceItemNoOnBeforeCheckServContractHeaderStatus(var ServiceContractLine: Record "Service Contract Line"; xServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSetupNewLine(var ServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalculateNextServiceVisit(var ServiceContractLine: Record "Service Contract Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSelectMultipleServiceItems(var ServiceContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSelectMultipleServiceItems(var ServiceContractLine: Record "Service Contract Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAddServiceItems(var ServiceContractLine: Record "Service Contract Line"; SelectionFilter: Text; var IsHandled: Boolean)
begin
end;
}