Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IncludeSender in Format Address subscriber and add a GetLanguageCode() procedure. #26293

Open
deerware opened this issue Apr 16, 2024 · 6 comments
Labels
event-request Request for adding an event Integration GitHub request for Integration area

Comments

@deerware
Copy link
Contributor

deerware commented Apr 16, 2024

Describe the request

The codeunit 365 "Format Address" has publishers in all of its functions like Company, Customer, etc, which allow global customization of how the addresses are structured.

Unfortunately, these events do not contain the Language Code property, which is a problem, because the codeunit is not using the global language, but the language usually set on the record (when calling from a report).
So when the function is bypassed (using IsHandled = true), there is no way how to translate the country or other information correctly using the currently set LanguageCode.

I suggest either:

  1. Add LanguageCode to the publishers, or
  2. Change publishers to IncludeSender = true and add a GetLanguageCode global procedure
    • This way, in subscribers we could just use sender.FormatAddr(), since that is already global, and not worry about the Language Code, in cases where we only change the information that is sent, not its order.

Additional context

In our customizations, we sometimes change the language code on factors other then the Language Code of the printed document, like manually changing the language from the request page. So we can't rely on the Language Code of the document that is sent to the function.

In some cases (like Company), there even is no Language Code. Adding the country to the company address is a frequent request of our customers and we currently can't simply add it using a single subscriber, because of the language code.
Internal work item: AB#525470

@Jose-agg Jose-agg added event-request Request for adding an event Integration GitHub request for Integration area labels Apr 16, 2024
@Groenbech96
Copy link
Contributor

Can you be more specific with example of events you are referring to? And how they should be changed?

@deerware
Copy link
Contributor Author

Hi, @Groenbech96

For example in the report 208 "Sales - Shipment" there is the following code:

// dataitem("Sales Shipment Header"; "Sales Shipment Header") 
trigger OnAfterGetRecord()
begin
    CurrReport.Language := LanguageMgt.GetLanguageIdOrDefault("Language Code");
    CurrReport.FormatRegion := LanguageMgt.GetFormatRegionOrDefault("Format Region");
    FormatAddr.SetLanguageCode("Language Code"); // Language Code is passed into the Format Address Codeunit

    FormatAddressFields("Sales Shipment Header");
    FormatDocumentFields("Sales Shipment Header");

    if not CompanyBankAccount.Get("Sales Shipment Header"."Company Bank Account Code") then
        CompanyBankAccount.CopyBankFieldsFromCompanyInfo(CompanyInfo);

    DimSetEntry1.SetRange("Dimension Set ID", "Dimension Set ID");
end;

local procedure FormatAddressFields(SalesShipmentHeader: Record "Sales Shipment Header")
begin
    FormatAddr.GetCompanyAddr(SalesShipmentHeader."Responsibility Center", RespCenter, CompanyInfo, CompanyAddr);
    FormatAddr.SalesShptShipTo(ShipToAddr, SalesShipmentHeader);
    ShowCustAddr := FormatAddr.SalesShptBillTo(CustAddr, ShipToAddr, SalesShipmentHeader);
end;

The procedure FormatAddr.SalesShiptShipTo in codeunit 365 "Format Address" procedure contains a publisher with IsHandled, which we wanted to use to generate our own address array, using our custom fields, unfortunately, the global LanguageCode is not included in the publisher arguments, so we didn't know in which Language we should show for example the Country translations.

The procedure and publisher look like this:

procedure SalesShptShipTo(var AddrArray: array[8] of Text[100]; var SalesShptHeader: Record "Sales Shipment Header")
var
    Handled: Boolean;
begin
    OnBeforeSalesShptShipTo(AddrArray, SalesShptHeader, Handled); // Missing LanguageCode
    if Handled then
        exit;

    FormatAddr(
        AddrArray, SalesShptHeader."Ship-to Name", SalesShptHeader."Ship-to Name 2", SalesShptHeader."Ship-to Contact", SalesShptHeader."Ship-to Address", SalesShptHeader."Ship-to Address 2",
        SalesShptHeader."Ship-to City", SalesShptHeader."Ship-to Post Code", SalesShptHeader."Ship-to County", SalesShptHeader."Ship-to Country/Region Code");
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeSalesShptShipTo(var AddrArray: array[8] of Text[100]; var SalesShipmentHeader: Record "Sales Shipment Header"; var Handled: Boolean)
begin
end;

This could be, in my opinion, fixed by either adding the global LanguageCode to individual publishers, or by adding a global GetLanguageCode() and enableing IncludeSender for the publishers. With the IncludeSender we could also just call the sender.FormatAddr() procedure with our custom fields in the subscriber and not worry about LanguageCode, since it is already correctly set in the sender.

Let me know if you need any more details.

Milan

@deerware
Copy link
Contributor Author

PS: As for why we can't just use the Language Code from the document - please refer to Additional Context of my original submission.

@Groenbech96
Copy link
Contributor

Is there a way for you to use existing OnAfterFormatAddress?

@deerware
Copy link
Contributor Author

The OnAfterFormatAddress does not contain any information about the record that we are formatting. In out case, when formatting Company, we needed to replace some baseapp fields with custom ones, plus add the baseapp Country, which we cannot do in the OnAfterFormatAddress, where the record is already deconstructed. We need to work with the record.

It's also called after the code so to avoid duplicitous calling of all the formatting functions, OnFormatAddrOnAfterGetCountry would be better, but it still doesn't work for us, since is too deep. We only want to alter some specific documents, not all formatting, and need to substitute the fields sent into the functions, not their order or something.

For example (this is not our case) if we had custom fields in the Company Information just for printing alternative company address for foreign customers, because the normal local address normally contains some weird characters with accents or whatever, and wanted to hijack the Company(CompanyInformation: Record ...) procedure and replace the Name, Address, City, .... with our own fields, we can't do that in the OnAfterFormatAddress subscriber (or any other subscriber in the FormatAddr procedure), because we don't have the original record anymore, and we also don't know from where the FormatAddr was called, and don't want to replace the City in all addresses (customers, ship to, sell to, ...), just in the Company one.

The only way to do it correctly is to hijack the Company and then ideally call the FormatAddr() with our own deconstruction of the record, but now we can't retain the LanguageCode with that approach.

@Groenbech96
Copy link
Contributor

Do you have the list of events that you would need the LanguageCode added to?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
event-request Request for adding an event Integration GitHub request for Integration area
Projects
None yet
Development

No branches or pull requests

3 participants