Page 7016 Sales Price List

App
Base Application
Namespace
Microsoft.Sales.Pricing
Versions
17-28
Source table
7000

Procedures, 2Events, 3

Versions171819202122232425262728

Source29

Source in 29

src/Layers/W1/BaseApp/Sales/Pricing/SalesPriceList.Page.al715 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.Pricing;

using Microsoft.Integration.Dataverse;
using Microsoft.Integration.SyncEngine;
using Microsoft.Pricing.Calculation;
using Microsoft.Pricing.PriceList;
using Microsoft.Pricing.Source;
using Microsoft.Projects.Project.Pricing;

/// <summary>
/// Displays and manages a single sales price list with its header details and line items.
/// </summary>
page 7016 "Sales Price List"
{
    Caption = 'Sales Price List';
    PageType = ListPlus;
    RefreshOnActivate = true;
    SourceTable = "Price List Header";
    SourceTableView = where("Price Type" = const(Sale));

    layout
    {
        area(content)
        {
            group(General)
            {
                Caption = 'General';
                group(LeftColumn)
                {
                    ShowCaption = false;
                    field(Code; Rec.Code)
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        ShowMandatory = true;
                        ToolTip = 'Specifies the unique identifier of the price list.';
                        Editable = CodeIsEditable;

                        trigger OnAssistEdit()
                        begin
                            if Rec.AssistEditCode(xRec) then
                                CurrPage.Update();
                        end;

                        trigger OnValidate()
                        begin
                            if Rec.Code <> '' then
                                CurrPage.Update();
                        end;
                    }
                    field(Description; Rec.Description)
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        ShowMandatory = true;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the description of the price list.';
                    }
                    field(SourceType; SourceType)
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Caption = 'Assign-to Type';
                        Editable = PriceListIsEditable;
                        Visible = not IsJobGroup;
                        ToolTip = 'Specifies the type of entity to which the price list is assigned. The options are relevant to the entity you are currently viewing.';

                        trigger OnValidate()
                        begin
                            ValidateSourceType(SourceType.AsInteger());
                            CurrPage.Update(true);
                        end;
                    }
                    field(JobSourceType; JobSourceType)
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Caption = 'Assign-to Type';
                        Editable = PriceListIsEditable;
                        Visible = IsJobGroup;
                        ToolTip = 'Specifies the type of entity to which the price list is assigned. The options are relevant to the entity you are currently viewing.';

                        trigger OnValidate()
                        begin
                            ValidateSourceType(JobSourceType.AsInteger());
                            CurrPage.Update(true);
                        end;
                    }
                    group(AssignToParentNoGroup)
                    {
                        ShowCaption = false;
                        Visible = ParentSourceNoVisible;
                        field(AssignToParentNo; Rec."Assign-to Parent No.")
                        {
                            ApplicationArea = All;
                            Importance = Promoted;
                            Editable = PriceListIsEditable;
                            ShowMandatory = true;
                            ToolTip = 'Specifies the entity to which the prices are assigned. The options depend on the selection in the Assign-to Type field. If you choose an entity, the price list will be used only for that entity.';
                            trigger OnValidate()
                            begin
                                CurrPage.Update(true);
                            end;
                        }
                    }
                    field(SourceNo; Rec."Source No.")
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Enabled = SourceNoEnabled;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the entity to which the prices are assigned. The options depend on the selection in the Assign-to Type field. If you choose an entity, the price list will be used only for that entity.';
                        Visible = UseCustomLookup;
                        ShowMandatory = SourceNoEnabled;

                        trigger OnValidate()
                        begin
                            CurrPage.Update(true);
                        end;

                        trigger OnLookup(var Text: Text): Boolean;
                        begin
                            if Rec.LookupSourceNo() then
                                CurrPage.Update(true);
                        end;
                    }
                    field(AssignToNo; Rec."Assign-to No.")
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Enabled = SourceNoEnabled;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the entity to which the prices are assigned. The options depend on the selection in the Assign-to Type field. If you choose an entity, the price list will be used only for that entity.';
                        Visible = not UseCustomLookup;
                        ShowMandatory = SourceNoEnabled;

                        trigger OnValidate()
                        begin
                            CurrPage.Update(true);
                        end;
                    }
                    group(Tax)
                    {
                        Caption = 'VAT';
                        field(VATBusPostingGrPrice; Rec."VAT Bus. Posting Gr. (Price)")
                        {
                            ApplicationArea = All;
                            Importance = Additional;
                            Editable = PriceListIsEditable;
                            ToolTip = 'Specifies the default VAT business posting group code.';

                            trigger OnValidate()
                            begin
                                CurrPage.Update(true);
                            end;
                        }
                        field(PriceIncludesVAT; Rec."Price Includes VAT")
                        {
                            ApplicationArea = All;
                            Importance = Additional;
                            Editable = PriceListIsEditable;

                            trigger OnValidate()
                            begin
                                CurrPage.Update(true);
                            end;
                        }
                    }
                    group(View)
                    {
                        Caption = 'View';
                        Visible = ViewGroupIsVisible;
                        field(AmountType; ViewAmountType)
                        {
                            ApplicationArea = All;
                            Caption = 'View Columns for';
                            ToolTip = 'Specifies the amount type filter that defines the columns shown in the price list lines.';
                            trigger OnValidate()
                            begin
                                Rec.Validate("Amount Type", ViewAmountType);
                                CurrPage.Lines.Page.SetSubFormLinkFilter(ViewAmountType);
                            end;
                        }
                    }
                }
                group(RightColumn)
                {
                    ShowCaption = false;
                    field(Status; Rec.Status)
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        ToolTip = 'Specifies whether the price list is in Draft status and can be edited, Inactive and cannot be edited or used, or Active and can be edited (when Allow Editing Active Price is enabled) and used for price calculations.';

                        trigger OnValidate()
                        begin
                            PriceListIsEditable := Rec.IsEditable();
                        end;
                    }
                    field(CurrencyCode; Rec."Currency Code")
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the currency code of the price list.';

                        trigger OnValidate()
                        begin
                            CurrPage.Update(true);
                        end;
                    }
                    field(StartingDate; Rec."Starting Date")
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the date from which the price is valid.';

                        trigger OnValidate()
                        begin
                            CurrPage.Update(true);
                        end;
                    }
                    field(EndingDate; Rec."Ending Date")
                    {
                        ApplicationArea = All;
                        Importance = Promoted;
                        Editable = PriceListIsEditable;
                        ToolTip = 'Specifies the last date that the price is valid.';

                        trigger OnValidate()
                        begin
                            CurrPage.Update(true);
                        end;
                    }
                    group(LineDefaults)
                    {
                        Caption = 'Line Defaults';
                        field(AllowUpdatingDefaults; Rec."Allow Updating Defaults")
                        {
                            ApplicationArea = All;
                            Importance = Additional;
                            Editable = PriceListIsEditable;
                            ToolTip = 'Specifies whether users can change the values in the fields on the price list lines that contain default values from the header. This does not affect the ability to allow line or invoice discounts.';
                            trigger OnValidate()
                            begin
                                CurrPage.Lines.Page.SetHeader(Rec);
                                CurrPage.Update(true);
                            end;
                        }
                        field(AllowInvoiceDisc; Rec."Allow Invoice Disc.")
                        {
                            ApplicationArea = All;
                            Importance = Additional;
                            Editable = PriceListIsEditable;
                            ToolTip = 'Specifies whether invoice discount is allowed. You can change this value on the lines.';

                            trigger OnValidate()
                            begin
                                CurrPage.Update(true);
                            end;
                        }
                        field(AllowLineDisc; Rec."Allow Line Disc.")
                        {
                            ApplicationArea = All;
                            Importance = Additional;
                            Editable = PriceListIsEditable;
                            ToolTip = 'Specifies whether line discounts are allowed. You can change this value on the lines.';

                            trigger OnValidate()
                            begin
                                CurrPage.Update(true);
                            end;
                        }
                    }
                }
            }
            part(Lines; "Price List Lines")
            {
                ApplicationArea = Basic, Suite;
                Editable = PriceListIsEditable;
                SubPageLink = "Price List Code" = field(Code);
            }
        }
        area(factboxes)
        {
            systempart(Control1900383207; Links)
            {
                ApplicationArea = RecordLinks;
                Visible = false;
            }
            systempart(Control1905767507; Notes)
            {
                ApplicationArea = Notes;
                Visible = false;
            }
        }
    }

    actions
    {
        area(Processing)
        {
            action(SuggestLines)
            {
                ApplicationArea = Basic, Suite;
                Enabled = PriceListIsEditable;
                Ellipsis = true;
                Image = SuggestItemPrice;
                Caption = 'Suggest Lines';
                ToolTip = 'Creates the sales price list lines based on the unit price in the product cards, like item or resource. Change the price list status to ''Draft'' to run this action.';

                trigger OnAction()
                var
                    PriceListManagement: Codeunit "Price List Management";
                begin
                    PriceListManagement.AddLines(Rec);
                end;
            }
            action(CopyLines)
            {
                ApplicationArea = Basic, Suite;
                Enabled = PriceListIsEditable and CopyLinesEnabled;
                Ellipsis = true;
                Image = CopyWorksheet;
                Caption = 'Copy Lines';
                ToolTip = 'Copies the lines from the existing price list. New prices can be adjusted by a factor and rounded differently. Change the price list status to ''Draft'' to run this action unless Allow Editing Active Price is enabled.';

                trigger OnAction()
                var
                    PriceListManagement: Codeunit "Price List Management";
                begin
                    PriceListManagement.CopyLines(Rec);
                end;
            }
            action(VerifyLines)
            {
                ApplicationArea = Basic, Suite;
                Visible = PriceListIsEditable and (Rec.Status = Rec.Status::Active);
                Ellipsis = true;
                Image = CheckDuplicates;
                Caption = 'Verify Lines';
                ToolTip = 'Checks data consistency in the new and modified price list lines. Finds the duplicate price lines and suggests the resolution of the line conflicts.';

                trigger OnAction()
                var
                    PriceListManagement: Codeunit "Price List Management";
                begin
                    PriceListManagement.ActivateDraftLines(Rec);
                end;
            }
        }
        area(navigation)
        {
            group(ActionGroupCRM)
            {
                Caption = 'Dynamics 365 Sales';
                Enabled = CRMIntegrationAllowed;
                Visible = CRMIntegrationEnabled;
                action(CRMGoToPricelevel)
                {
                    ApplicationArea = Suite;
                    Caption = 'Pricelevel';
                    Image = CoupledItem;
                    ToolTip = 'View price information introduced through synchronization with Dynamics 365 Sales.';

                    trigger OnAction()
                    var
                        CRMIntegrationManagement: Codeunit "CRM Integration Management";
                    begin
                        CRMIntegrationManagement.ShowCRMEntityFromRecordID(Rec.RecordId);
                    end;
                }
                action(CRMSynchronizeNow)
                {
                    AccessByPermission = TableData "CRM Integration Record" = IM;
                    ApplicationArea = Suite;
                    Caption = 'Synchronize';
                    Image = Refresh;
                    ToolTip = 'Send updated data to Dynamics 365 Sales.';

                    trigger OnAction()
                    var
                        CRMIntegrationManagement: Codeunit "CRM Integration Management";
                    begin
                        CRMIntegrationManagement.UpdateOneNow(Rec.RecordId);
                    end;
                }
                group(Coupling)
                {
                    Caption = 'Coupling', Comment = 'Coupling is a noun';
                    Image = LinkAccount;
                    ToolTip = 'Create, change, or delete a coupling between the Business Central record and a Dynamics 365 Sales record.';
                    action(ManageCRMCoupling)
                    {
                        AccessByPermission = TableData "CRM Integration Record" = IM;
                        ApplicationArea = Suite;
                        Caption = 'Set Up Coupling';
                        Image = LinkAccount;
                        ToolTip = 'Create or modify the coupling to a Dynamics 365 Sales product.';

                        trigger OnAction()
                        var
                            CRMIntegrationManagement: Codeunit "CRM Integration Management";
                        begin
                            CRMIntegrationManagement.DefineCoupling(Rec.RecordId);
                        end;
                    }
                    action(DeleteCRMCoupling)
                    {
                        AccessByPermission = TableData "CRM Integration Record" = D;
                        ApplicationArea = Suite;
                        Caption = 'Delete Coupling';
                        Enabled = CRMIsCoupledToRecord;
                        Image = UnLinkAccount;
                        ToolTip = 'Delete the coupling to a Dynamics 365 Sales product.';

                        trigger OnAction()
                        var
                            PriceListHeader: Record "Price List Header";
                            CRMCouplingManagement: Codeunit "CRM Coupling Management";
                            RecRef: RecordRef;
                        begin
                            CurrPage.SetSelectionFilter(PriceListHeader);
                            RecRef.GetTable(PriceListHeader);
                            CRMCouplingManagement.RemoveCoupling(RecRef);
                        end;
                    }
                }
                action(ShowLog)
                {
                    ApplicationArea = Suite;
                    Caption = 'Synchronization Log';
                    Image = Log;
                    ToolTip = 'View integration synchronization jobs for the price list header table.';

                    trigger OnAction()
                    var
                        CRMIntegrationManagement: Codeunit "CRM Integration Management";
                    begin
                        CRMIntegrationManagement.ShowLog(Rec.RecordId);
                    end;
                }
            }
        }
        area(Promoted)
        {
            group(Category_Process)
            {
                Caption = 'Process', Comment = 'Generated from the PromotedActionCategories property index 1.';

                actionref(VerifyLines_Promoted; VerifyLines)
                {
                }
                actionref(CopyLines_Promoted; CopyLines)
                {
                }
                actionref(SuggestLines_Promoted; SuggestLines)
                {
                }
            }
            group(Category_Category4)
            {
                Caption = 'Navigate', Comment = 'Generated from the PromotedActionCategories property index 3.';
            }
            group(Category_Report)
            {
                Caption = 'Report', Comment = 'Generated from the PromotedActionCategories property index 2.';
            }
            group(Category_Synchronize)
            {
                Caption = 'Synchronize';
                Visible = CRMIntegrationEnabled;

                group(Category_Coupling)
                {
                    Caption = 'Coupling';
                    ShowAs = SplitButton;

                    actionref(ManageCRMCoupling_Promoted; ManageCRMCoupling)
                    {
                    }
                    actionref(DeleteCRMCoupling_Promoted; DeleteCRMCoupling)
                    {
                    }
                }
                actionref(CRMSynchronizeNow_Promoted; CRMSynchronizeNow)
                {
                }
                actionref(ShowLog_Promoted; ShowLog)
                {
                }
                actionref(CRMGoToPricelevel_Promoted; CRMGoToPricelevel)
                {
                }
            }
        }
    }

    trigger OnInit()
    var
        FeaturePriceCalculation: Codeunit "Feature - Price Calculation";
    begin
        FeaturePriceCalculation.FailIfFeatureDisabled();
    end;

    trigger OnOpenPage()
    var
        IntegrationTableMapping: Record "Integration Table Mapping";
        PriceListLine: Record "Price List Line";
        PriceListManagement: Codeunit "Price List Management";
        DefaultSourceGroup: Enum "Price Source Group";
    begin
        UseCustomLookup := PriceListLine.UseCustomizedLookup();
        CopyLinesEnabled := PriceListManagement.VerifySourceGroupInLines();
        DefaultSourceGroup := GetSourceGroupFilter();
        UpdateSourceType(DefaultSourceGroup);
        PriceUXManagement.GetFirstSourceFromFilter(
            Rec, OriginalPriceSource, GetDefaultSourceType(DefaultSourceGroup));
        CRMIntegrationEnabled := CRMIntegrationManagement.IsCRMIntegrationEnabled();
        if CRMIntegrationEnabled then
            if IntegrationTableMapping.Get('PLHEADER-PRICE') then begin
                StatusActiveFilterApplied := true;
                AllowUpdatingDefaultsFilterApplied := IntegrationTableMapping.GetTableFilter().Contains('Field20=1(1)');
            end;
    end;

    local procedure GetSourceGroupFilter() SourceGroup: Enum "Price Source Group";
    var
        SourceGroupFilter: Text;
    begin
        Rec.FilterGroup(2);
        SourceGroupFilter := Rec.GetFilter("Source Group");
        Rec.FilterGroup(0);
        if SourceGroupFilter = '' then
            exit(SourceGroup::Customer);
        if not Evaluate(SourceGroup, SourceGroupFilter) then
            exit(SourceGroup::Customer);
    end;

    trigger OnAfterGetCurrRecord()
    var
        PriceListManagement: Codeunit "Price List Management";
    begin
        CRMIntegrationAllowed := Rec.IsCRMIntegrationAllowed(StatusActiveFilterApplied, AllowUpdatingDefaultsFilterApplied);
        CRMIsCoupledToRecord := CRMIntegrationEnabled;
        if CRMIsCoupledToRecord then
            CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId);
        Rec.SyncDropDownLookupFields();
        PriceListIsEditable := Rec.IsEditable();
        CodeIsEditable := PriceListIsEditable and (Rec.Code = '');
        UpdateSourceType(Rec."Source Group");
        SetSourceNoEnabled();
        ViewAmountType := Rec."Amount Type";
        ViewGroupIsVisible := true;
        if Rec.HasDraftLines() then
            PriceListManagement.SendVerifyLinesNotification(Rec);

        CurrPage.Lines.Page.SetHeader(Rec);
    end;

    trigger OnNewRecord(BelowxRec: Boolean)
    var
        DefaultAmountType: Enum "Price Amount Type";
    begin
        Rec.CopyFrom(OriginalPriceSource);
        UpdateSourceType(Rec."Source Group");
        if PriceUXManagement.IsAmountTypeFiltered(Rec, DefaultAmountType) then
            Rec."Amount Type" := DefaultAmountType
        else
            Rec."Amount Type" := OriginalPriceSource.GetDefaultAmountType();
        ViewAmountType := Rec."Amount Type";
    end;

    trigger OnQueryClosePage(CloseAction: Action): Boolean;
    var
        PriceListManagement: Codeunit "Price List Management";
        IsHandled: Boolean;
        Result: Boolean;
    begin
        IsHandled := false;
        OnQueryClosePageOnBeforeDraftLineCheck(Rec, Result, IsHandled);
        if IsHandled then
            exit(Result);

        if Rec.Find() then
            if Rec.HasDraftLines() then begin
                PriceListManagement.SendVerifyLinesNotification(Rec);
                exit(false);
            end;
        exit(true)
    end;

    trigger OnClosePage()
    begin
        if Rec.Find() then
            if Rec.Code <> '' then
                Rec.UpdateAmountType();
    end;

    local procedure UpdateSourceType(SourceGroup: Enum "Price Source Group")
    begin
        case SourceGroup of
            SourceGroup::Customer:
                begin
                    IsJobGroup := false;
                    SourceType := "Sales Price Source Type".FromInteger(Rec."Source Type".AsInteger());
                end;
            SourceGroup::Job:
                begin
                    IsJobGroup := true;
                    JobSourceType := "Job Price Source Type".FromInteger(Rec."Source Type".AsInteger());
                end;
            else
                OnUpdateSourceTypeOnCaseElse(Rec, SourceType, IsJobGroup);
        end;
    end;

    local procedure GetDefaultSourceType(SourceGroup: Enum "Price Source Group") DefaultSourceType: Enum "Price Source Type";
    begin
        case SourceGroup of
            SourceGroup::Customer:
                DefaultSourceType := Rec."Source Type"::"All Customers";
            SourceGroup::Job:
                DefaultSourceType := Rec."Source Type"::"All Jobs";
        end;
        OnAfterGetDefaultSourceType(SourceGroup, DefaultSourceType);
    end;

    var
        OriginalPriceSource: Record "Price Source";
        PriceUXManagement: Codeunit "Price UX Management";
        CRMCouplingManagement: Codeunit "CRM Coupling Management";
        CRMIntegrationManagement: Codeunit "CRM Integration Management";
        CRMIntegrationAllowed: Boolean;
        CRMIntegrationEnabled: Boolean;
        CRMIsCoupledToRecord: Boolean;
        StatusActiveFilterApplied: Boolean;
        AllowUpdatingDefaultsFilterApplied: Boolean;
        JobSourceType: Enum "Job Price Source Type";
        SourceType: Enum "Sales Price Source Type";
        ViewAmountType: Enum "Price Amount Type";

    protected var
        CodeIsEditable: Boolean;
        IsJobGroup: Boolean;
        ParentSourceNoEnabled: Boolean;
        ParentSourceNoVisible: Boolean;
        SourceNoEnabled: Boolean;
        PriceListIsEditable: Boolean;
        CopyLinesEnabled: Boolean;
        ViewGroupIsVisible: Boolean;
        UseCustomLookup: Boolean;

    /// <summary>
    /// Sets the enabled state of the source number field based on the source type configuration.
    /// </summary>
    protected procedure SetSourceNoEnabled()
    var
        PriceSource: Record "Price Source";
    begin
        Rec.CopyTo(PriceSource);
        ParentSourceNoEnabled := PriceSource.IsParentSourceAllowed();
        SourceNoEnabled := Rec.IsSourceNoAllowed();
        ParentSourceNoVisible := ParentSourceNoEnabled and not UseCustomLookup;
    end;

    /// <summary>
    /// Validates and applies the selected source type to the price list header.
    /// </summary>
    /// <param name="SourceType2">The source type integer value to validate.</param>
    protected procedure ValidateSourceType(SourceType2: Integer)
    begin
        Rec.Validate("Source Type", SourceType2);
        SetSourceNoEnabled();
        CurrPage.SaveRecord();
    end;

    /// <summary>
    /// Raises an event to handle custom source type updates when the source group is not Customer or Job.
    /// </summary>
    /// <param name="PriceListHeader">The price list header record.</param>
    /// <param name="SourceType">The sales price source type to set.</param>
    /// <param name="IsJobGroup">Indicates whether the source group is Job.</param>
    [IntegrationEvent(true, false)]
    local procedure OnUpdateSourceTypeOnCaseElse(PriceListHeader: Record "Price List Header"; var SourceType: Enum "Sales Price Source Type"; var IsJobGroup: Boolean)
    begin
    end;

    /// <summary>
    /// Raises an event after determining the default source type for the price source group.
    /// </summary>
    /// <param name="PriceSourceGroup">The price source group.</param>
    /// <param name="DefaultPriceSourceType">The default price source type to use.</param>
    [IntegrationEvent(true, false)]
    local procedure OnAfterGetDefaultSourceType(PriceSourceGroup: Enum "Price Source Group"; var DefaultPriceSourceType: Enum "Price Source Type")
    begin
    end;

    /// <summary>
    /// Raises an event before checking for draft lines when closing the page.
    /// </summary>
    /// <param name="PriceListHeader">The price list header record.</param>
    /// <param name="Result">The result to return from the query close page trigger.</param>
    /// <param name="IsHandled">Set to true to skip the default draft line check.</param>
    [IntegrationEvent(false, false)]
    local procedure OnQueryClosePageOnBeforeDraftLineCheck(PriceListHeader: Record "Price List Header"; var Result: Boolean; var IsHandled: Boolean)
    begin
    end;
}