Codeunit 363 PostSales-Delete, source in 29
Source29
src/Layers/W1/BaseApp/Sales/History/PostSalesDelete.Codeunit.al415 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.Sales.History;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.AuditCodes;
using Microsoft.Inventory.Tracking;
using Microsoft.Sales.Document;
using Microsoft.Sales.Setup;
using Microsoft.Utilities;
/// <summary>
/// Handles the deletion of posted sales documents and their related data according to retention policies.
/// </summary>
codeunit 363 "PostSales-Delete"
{
Permissions = TableData "Sales Shipment Header" = ri,
TableData "Sales Shipment Line" = rid,
TableData "Sales Invoice Header" = ri,
TableData "Sales Invoice Line" = rid,
TableData "Sales Cr.Memo Header" = ri,
TableData "Sales Cr.Memo Line" = rid,
TableData "Return Receipt Header" = ri,
TableData "Return Receipt Line" = rid;
trigger OnRun()
begin
end;
var
ItemTrackingMgt: Codeunit "Item Tracking Management";
MoveEntries: Codeunit MoveEntries;
DocumentDeletionErr: Label 'You cannot delete posted sales documents that are posted after %1. \\The date is defined by the Allow Document Deletion Before field in the Sales & Receivables Setup window.', Comment = '%1 - Posting Date';
AllowDocumentDeletionBeforeBlankErr: Label 'The date %1 must be set on the page %2 before deleting sales documents.', Comment = '%1 = Field name, %2 = Page name';
/// <summary>
/// Deletes a sales document header and creates placeholder records for the deleted posted documents.
/// </summary>
/// <param name="SalesHeader">Specifies the sales header to delete.</param>
/// <param name="SalesShptHeader">Returns the created sales shipment header placeholder.</param>
/// <param name="SalesInvHeader">Returns the created sales invoice header placeholder.</param>
/// <param name="SalesCrMemoHeader">Returns the created sales credit memo header placeholder.</param>
/// <param name="ReturnRcptHeader">Returns the created return receipt header placeholder.</param>
/// <param name="SalesInvHeaderPrePmt">Returns the created prepayment sales invoice header placeholder.</param>
/// <param name="SalesCrMemoHeaderPrePmt">Returns the created prepayment credit memo header placeholder.</param>
procedure DeleteHeader(SalesHeader: Record "Sales Header"; var SalesShptHeader: Record "Sales Shipment Header"; var SalesInvHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnRcptHeader: Record "Return Receipt Header"; var SalesInvHeaderPrePmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrePmt: Record "Sales Cr.Memo Header")
var
SalesInvLine: Record "Sales Invoice Line";
SalesCrMemoLine: Record "Sales Cr.Memo Line";
SalesShptLine: Record "Sales Shipment Line";
ReturnRcptLine: Record "Return Receipt Line";
SourceCode: Record "Source Code";
SourceCodeSetup: Record "Source Code Setup";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteHeader(SalesHeader, SalesShptHeader, SalesInvHeader, SalesCrMemoHeader, ReturnRcptHeader, SalesInvHeaderPrePmt, SalesCrMemoHeaderPrePmt, IsHandled);
if IsHandled then
exit;
SourceCodeSetup.Get();
SourceCodeSetup.TestField("Deleted Document");
SourceCode.Get(SourceCodeSetup."Deleted Document");
InitDeleteHeader(
SalesHeader, SalesShptHeader, SalesInvHeader, SalesCrMemoHeader,
ReturnRcptHeader, SalesInvHeaderPrePmt, SalesCrMemoHeaderPrePmt, SourceCode.Code);
if SalesShptHeader."No." <> '' then begin
SalesShptHeader.Insert();
SalesShptLine.Init();
SalesShptLine."Document No." := SalesShptHeader."No.";
SalesShptLine."Line No." := 10000;
SalesShptLine.Description := SourceCode.Description;
SalesShptLine.Insert();
end;
if ReturnRcptHeader."No." <> '' then begin
ReturnRcptHeader.Insert();
ReturnRcptLine.Init();
ReturnRcptLine."Document No." := ReturnRcptHeader."No.";
ReturnRcptLine."Line No." := 10000;
ReturnRcptLine.Description := SourceCode.Description;
ReturnRcptLine.Insert();
end;
if SalesInvHeader."No." <> '' then begin
SalesInvHeader.Insert();
SalesInvLine.Init();
SalesInvLine."Document No." := SalesInvHeader."No.";
SalesInvLine."Line No." := 10000;
SalesInvLine.Description := SourceCode.Description;
SalesInvLine.Insert();
end;
if SalesCrMemoHeader."No." <> '' then begin
SalesCrMemoHeader.Insert();
SalesCrMemoLine.Init();
SalesCrMemoLine."Document No." := SalesCrMemoHeader."No.";
SalesCrMemoLine."Line No." := 10000;
SalesCrMemoLine.Description := SourceCode.Description;
SalesCrMemoLine.Insert();
end;
if SalesInvHeaderPrePmt."No." <> '' then begin
SalesInvHeaderPrePmt.Insert();
SalesInvLine."Document No." := SalesInvHeaderPrePmt."No.";
SalesInvLine."Line No." := 10000;
SalesInvLine.Description := SourceCode.Description;
SalesInvLine.Insert();
end;
if SalesCrMemoHeaderPrePmt."No." <> '' then begin
SalesCrMemoHeaderPrePmt.Insert();
SalesCrMemoLine.Init();
SalesCrMemoLine."Document No." := SalesCrMemoHeaderPrePmt."No.";
SalesCrMemoLine."Line No." := 10000;
SalesCrMemoLine.Description := SourceCode.Description;
SalesCrMemoLine.Insert();
end;
OnAfterDeleteHeader(
SalesHeader, SalesShptHeader, SalesInvHeader, SalesCrMemoHeader, ReturnRcptHeader, SalesInvHeaderPrePmt, SalesCrMemoHeaderPrePmt);
end;
/// <summary>
/// Deletes all sales shipment lines and related item tracking entries for the specified shipment header.
/// </summary>
/// <param name="SalesShptHeader">Specifies the sales shipment header whose lines are to be deleted.</param>
procedure DeleteSalesShptLines(SalesShptHeader: Record "Sales Shipment Header")
var
SalesShptLine: Record "Sales Shipment Line";
ItemChargeAssignmentSales: Record "Item Charge Assignment (Sales)";
begin
SalesShptLine.SetRange("Document No.", SalesShptHeader."No.");
if SalesShptLine.Find('-') then
repeat
OnDeleteSalesShptLinesOnBeforeSalesShptLineDelete(SalesShptLine);
SalesShptLine.TestField("Quantity Invoiced", SalesShptLine.Quantity);
SalesShptLine.Delete(true);
until SalesShptLine.Next() = 0;
ItemChargeAssignmentSales.CheckAssignment(
Enum::"Sales Applies-to Document Type"::Shipment, SalesShptLine."Document No.", SalesShptLine."Line No.");
ItemTrackingMgt.DeleteItemEntryRelation(
DATABASE::"Sales Shipment Line", 0, SalesShptHeader."No.", '', 0, 0, true);
MoveEntries.MoveDocRelatedEntries(DATABASE::"Sales Shipment Header", SalesShptHeader."No.");
end;
/// <summary>
/// Deletes all sales invoice lines and related value entries for the specified invoice header.
/// </summary>
/// <param name="SalesInvHeader">Specifies the sales invoice header whose lines are to be deleted.</param>
procedure DeleteSalesInvLines(SalesInvHeader: Record "Sales Invoice Header")
var
SalesInvLine: Record "Sales Invoice Line";
begin
OnBeforeDeleteSalesInvLines(SalesInvHeader);
SalesInvLine.SetRange("Document No.", SalesInvHeader."No.");
if SalesInvLine.Find('-') then
repeat
OnDeleteSalesInvLinesOnBeforeSalesInvLineDelete(SalesInvLine);
SalesInvLine.Delete();
ItemTrackingMgt.DeleteValueEntryRelation(SalesInvLine.RowID1());
until SalesInvLine.Next() = 0;
MoveEntries.MoveDocRelatedEntries(DATABASE::"Sales Invoice Header", SalesInvHeader."No.");
end;
/// <summary>
/// Deletes all sales credit memo lines and related item tracking entries for the specified credit memo header.
/// </summary>
/// <param name="SalesCrMemoHeader">Specifies the sales credit memo header whose lines are to be deleted.</param>
procedure DeleteSalesCrMemoLines(SalesCrMemoHeader: Record "Sales Cr.Memo Header")
var
SalesCrMemoLine: Record "Sales Cr.Memo Line";
begin
SalesCrMemoLine.SetRange("Document No.", SalesCrMemoHeader."No.");
if SalesCrMemoLine.Find('-') then
repeat
OnDeleteSalesCrMemoLinesOnBeforeSalesCrMemoLineDelete(SalesCrMemoLine);
SalesCrMemoLine.Delete();
until SalesCrMemoLine.Next() = 0;
ItemTrackingMgt.DeleteItemEntryRelation(
DATABASE::"Sales Cr.Memo Line", 0, SalesCrMemoHeader."No.", '', 0, 0, true);
MoveEntries.MoveDocRelatedEntries(DATABASE::"Sales Cr.Memo Header", SalesCrMemoHeader."No.");
end;
/// <summary>
/// Deletes all return receipt lines and related item tracking entries for the specified return receipt header.
/// </summary>
/// <param name="ReturnRcptHeader">Specifies the return receipt header whose lines are to be deleted.</param>
procedure DeleteSalesRcptLines(ReturnRcptHeader: Record "Return Receipt Header")
var
ReturnRcptLine: Record "Return Receipt Line";
ItemChargeAssignmentSales: Record "Item Charge Assignment (Sales)";
begin
ReturnRcptLine.SetRange("Document No.", ReturnRcptHeader."No.");
if ReturnRcptLine.Find('-') then
repeat
OnDeleteSalesRcptLinesOnBeforeSalesRcptLineDelete(ReturnRcptLine);
ReturnRcptLine.TestField("Quantity Invoiced", ReturnRcptLine.Quantity);
ReturnRcptLine.Delete();
until ReturnRcptLine.Next() = 0;
ItemChargeAssignmentSales.CheckAssignment(
Enum::"Sales Applies-to Document Type"::"Return Receipt", ReturnRcptLine."Document No.", ReturnRcptLine."Line No.");
ItemTrackingMgt.DeleteItemEntryRelation(
DATABASE::"Return Receipt Line", 0, ReturnRcptHeader."No.", '', 0, 0, true);
MoveEntries.MoveDocRelatedEntries(DATABASE::"Return Receipt Header", ReturnRcptHeader."No.");
end;
/// <summary>
/// Initializes the posted document headers with data from the sales header for deletion tracking purposes.
/// </summary>
/// <param name="SalesHeader">Specifies the source sales header.</param>
/// <param name="SalesShptHeader">Returns the initialized sales shipment header.</param>
/// <param name="SalesInvHeader">Returns the initialized sales invoice header.</param>
/// <param name="SalesCrMemoHeader">Returns the initialized sales credit memo header.</param>
/// <param name="ReturnRcptHeader">Returns the initialized return receipt header.</param>
/// <param name="SalesInvHeaderPrePmt">Returns the initialized prepayment sales invoice header.</param>
/// <param name="SalesCrMemoHeaderPrePmt">Returns the initialized prepayment credit memo header.</param>
/// <param name="SourceCode">Specifies the source code for the deleted document.</param>
procedure InitDeleteHeader(SalesHeader: Record "Sales Header"; var SalesShptHeader: Record "Sales Shipment Header"; var SalesInvHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnRcptHeader: Record "Return Receipt Header"; var SalesInvHeaderPrePmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrePmt: Record "Sales Cr.Memo Header"; SourceCode: Code[10])
var
SalesSetup: Record "Sales & Receivables Setup";
begin
OnBeforeInitDeleteHeader(
SalesHeader, SalesShptHeader, SalesInvHeader, SalesCrMemoHeader, ReturnRcptHeader, SalesInvHeaderPrePmt, SalesCrMemoHeaderPrePmt,
SourceCode);
Clear(SalesShptHeader);
Clear(SalesInvHeader);
Clear(SalesCrMemoHeader);
Clear(ReturnRcptHeader);
SalesSetup.Get();
if (SalesHeader."Shipping No. Series" <> '') and (SalesHeader."Shipping No." <> '') then begin
SalesShptHeader.TransferFields(SalesHeader);
SalesShptHeader."No." := SalesHeader."Shipping No.";
SalesShptHeader."Posting Date" := Today;
SalesShptHeader."User ID" := CopyStr(UserId(), 1, MaxStrLen(SalesShptHeader."User ID"));
SalesShptHeader."Source Code" := SourceCode;
end;
if (SalesHeader."Return Receipt No. Series" <> '') and (SalesHeader."Return Receipt No." <> '') then begin
ReturnRcptHeader.TransferFields(SalesHeader);
ReturnRcptHeader."No." := SalesHeader."Return Receipt No.";
ReturnRcptHeader."Posting Date" := Today;
ReturnRcptHeader."User ID" := CopyStr(UserId(), 1, MaxStrLen(ReturnRcptHeader."User ID"));
ReturnRcptHeader."Source Code" := SourceCode;
end;
if (SalesHeader."Posting No. Series" <> '') and
((SalesHeader."Document Type" in [SalesHeader."Document Type"::Order, SalesHeader."Document Type"::Invoice]) and
(SalesHeader."Posting No." <> '') or
(SalesHeader."Document Type" = SalesHeader."Document Type"::Invoice) and
(SalesHeader."No. Series" = SalesHeader."Posting No. Series"))
then
InitSalesInvHeader(SalesInvHeader, SalesHeader, SourceCode);
if (SalesHeader."Posting No. Series" <> '') and
((SalesHeader."Document Type" in [SalesHeader."Document Type"::"Return Order", SalesHeader."Document Type"::"Credit Memo"]) and
(SalesHeader."Posting No." <> '') or
(SalesHeader."Document Type" = SalesHeader."Document Type"::"Credit Memo") and
(SalesHeader."No. Series" = SalesHeader."Posting No. Series"))
then begin
SalesCrMemoHeader.TransferFields(SalesHeader);
OnInitDeleteHeaderOnAfterSalesCrMemoHeaderTransferFields(SalesCrMemoHeader);
if SalesHeader."Posting No." <> '' then
SalesCrMemoHeader."No." := SalesHeader."Posting No.";
SalesCrMemoHeader."Pre-Assigned No. Series" := SalesHeader."No. Series";
SalesCrMemoHeader."Pre-Assigned No." := SalesHeader."No.";
SalesCrMemoHeader."Posting Date" := Today;
SalesCrMemoHeader."User ID" := CopyStr(UserId(), 1, MaxStrLen(SalesCrMemoHeader."User ID"));
SalesCrMemoHeader."Source Code" := SourceCode;
end;
if (SalesHeader."Prepayment No. Series" <> '') and (SalesHeader."Prepayment No." <> '') then begin
SalesHeader.TestField("Document Type", SalesHeader."Document Type"::Order);
SalesInvHeaderPrePmt.TransferFields(SalesHeader);
SalesInvHeaderPrePmt."No." := SalesHeader."Prepayment No.";
SalesInvHeaderPrePmt."Order No. Series" := SalesHeader."No. Series";
SalesInvHeaderPrePmt."Prepayment Order No." := SalesHeader."No.";
SalesInvHeaderPrePmt."Posting Date" := Today;
SalesInvHeaderPrePmt."Pre-Assigned No. Series" := '';
SalesInvHeaderPrePmt."Pre-Assigned No." := '';
SalesInvHeaderPrePmt."User ID" := CopyStr(UserId(), 1, MaxStrLen(SalesInvHeaderPrePmt."User ID"));
SalesInvHeaderPrePmt."Source Code" := SourceCode;
SalesInvHeaderPrePmt."Prepayment Invoice" := true;
end;
if (SalesHeader."Prepmt. Cr. Memo No. Series" <> '') and (SalesHeader."Prepmt. Cr. Memo No." <> '') then begin
SalesHeader.TestField("Document Type", SalesHeader."Document Type"::Order);
SalesCrMemoHeaderPrePmt.TransferFields(SalesHeader);
SalesCrMemoHeaderPrePmt."No." := SalesHeader."Prepmt. Cr. Memo No.";
SalesCrMemoHeaderPrePmt."Prepayment Order No." := SalesHeader."No.";
SalesCrMemoHeaderPrePmt."Posting Date" := Today;
SalesCrMemoHeaderPrePmt."Pre-Assigned No. Series" := '';
SalesCrMemoHeaderPrePmt."Pre-Assigned No." := '';
SalesCrMemoHeaderPrePmt."User ID" := CopyStr(UserId(), 1, MaxStrLen(SalesCrMemoHeaderPrePmt."User ID"));
SalesCrMemoHeaderPrePmt."Source Code" := SourceCode;
SalesCrMemoHeaderPrePmt."Prepayment Credit Memo" := true;
end;
OnAfterInitDeleteHeader(
SalesHeader, SalesShptHeader, SalesInvHeader, SalesCrMemoHeader, ReturnRcptHeader, SalesInvHeaderPrePmt, SalesCrMemoHeaderPrePmt);
end;
local procedure InitSalesInvHeader(var SalesInvHeader: Record "Sales Invoice Header"; SalesHeader: Record "Sales Header"; SourceCode: Code[10])
begin
SalesInvHeader.TransferFields(SalesHeader);
if SalesHeader."Posting No." <> '' then
SalesInvHeader."No." := SalesHeader."Posting No.";
if SalesHeader."Document Type" = SalesHeader."Document Type"::Invoice then begin
SalesInvHeader."Pre-Assigned No. Series" := SalesHeader."No. Series";
SalesInvHeader."Pre-Assigned No." := SalesHeader."No.";
end else begin
SalesInvHeader."Pre-Assigned No. Series" := '';
SalesInvHeader."Pre-Assigned No." := '';
SalesInvHeader."Order No. Series" := SalesHeader."No. Series";
SalesInvHeader."Order No." := SalesHeader."No.";
end;
SalesInvHeader."Posting Date" := Today;
SalesInvHeader."User ID" := CopyStr(UserId(), 1, MaxStrLen(SalesInvHeader."User ID"));
SalesInvHeader."Source Code" := SourceCode;
OnAfterInitSalesInvHeader(SalesInvHeader, SalesHeader);
end;
/// <summary>
/// Checks whether document deletion is allowed for the specified posting date based on retention policies.
/// </summary>
/// <param name="PostingDate">Specifies the posting date of the document to be deleted.</param>
procedure IsDocumentDeletionAllowed(PostingDate: Date)
var
SalesSetup: Record "Sales & Receivables Setup";
GeneralLedgerSetup: Record "General Ledger Setup";
DocumentsRetentionPeriod: Interface "Documents - Retention Period";
begin
GeneralLedgerSetup.Get();
DocumentsRetentionPeriod := GeneralLedgerSetup."Document Retention Period";
DocumentsRetentionPeriod.CheckDocumentDeletionAllowedByLaw(PostingDate);
SalesSetup.Get();
if SalesSetup."Allow Document Deletion Before" = 0D then
Error(AllowDocumentDeletionBeforeBlankErr, SalesSetup.FieldCaption("Allow Document Deletion Before"), SalesSetup.TableCaption);
if PostingDate >= SalesSetup."Allow Document Deletion Before" then
Error(DocumentDeletionErr, SalesSetup."Allow Document Deletion Before");
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitDeleteHeader(SalesHeader: Record "Sales Header"; var SalesShipmentHeader: Record "Sales Shipment Header"; var SalesInvoiceHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnReceiptHeader: Record "Return Receipt Header"; var SalesInvoiceHeaderPrepmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrepmt: Record "Sales Cr.Memo Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitSalesInvHeader(var SalesInvHeader: Record "Sales Invoice Header"; var SalesHeader: Record "Sales Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInitDeleteHeaderOnAfterSalesCrMemoHeaderTransferFields(var SalesCrMemoHeader: Record "Sales Cr.Memo Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteHeader(var SalesHeader: Record "Sales Header"; var SalesShipmentHeader: Record "Sales Shipment Header"; var SalesInvoiceHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnReceiptHeader: Record "Return Receipt Header"; var SalesInvoiceHeaderPrepmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrepmt: Record "Sales Cr.Memo Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterDeleteHeader(var SalesHeader: Record "Sales Header"; var SalesShipmentHeader: Record "Sales Shipment Header"; var SalesInvoiceHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnReceiptHeader: Record "Return Receipt Header"; var SalesInvoiceHeaderPrepmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrepmt: Record "Sales Cr.Memo Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInitDeleteHeader(var SalesHeader: Record "Sales Header"; var SalesShptHeader: Record "Sales Shipment Header"; var SalesInvHeader: Record "Sales Invoice Header"; var SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var ReturnRcptHeader: Record "Return Receipt Header"; var SalesInvHeaderPrePmt: Record "Sales Invoice Header"; var SalesCrMemoHeaderPrePmt: Record "Sales Cr.Memo Header"; var SourceCode: Code[10])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteSalesShptLinesOnBeforeSalesShptLineDelete(var SalesShptLine: Record "Sales Shipment Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteSalesInvLinesOnBeforeSalesInvLineDelete(var SalesInvoiceLine: Record "Sales Invoice Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteSalesCrMemoLinesOnBeforeSalesCrMemoLineDelete(var SalesCrMemoLine: Record "Sales Cr.Memo Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteSalesRcptLinesOnBeforeSalesRcptLineDelete(var SalesRcptLine: Record "Return Receipt Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteSalesInvLines(var SalesInvoiceHeader: Record "Sales Invoice Header");
begin
end;
}