BusinessCentral.LinterCop icon indicating copy to clipboard operation
BusinessCentral.LinterCop copied to clipboard

LC0044 - TransferFields issue when going from small to larger text or code field

Open CodeGenius-AU opened this issue 1 year ago • 5 comments

When using transferfields on different sized fields this warning will appear.

However, in my situation the transferfields is done from a Code[3] to a Code[10] and only in a DataUpgrade situation. Unfortunately, this causes warnings where there is no real issue. The transfer is done from small to larger field.

It would be great if the check would be smarter by either:

  • check if transferfields is from smaller to larger field
  • ignore check in DataUpgrade situations (replacing a table with new version where the field(s) are larger)

CodeGenius-AU avatar Feb 07 '24 09:02 CodeGenius-AU

I've looked into this, but unfortunately it's challenging to support this.

The rule currently only gathers set of tables without the direction between them. It will also be challenging to find all the possible directions in the BaseApp and keeping them up-to-date.

An (fictional) example "Sales Header" to "Sales Invoice Header" seems straight forward, but what if you create a Corrective Creditnota from a Posted Sales Invoice, then also to flow the other way around needs to work.

Next to the challenge of mapping the direction, I believe also other possible issues could occur. For example in the case of a PTE that want to do a TransferFields from "Sales Invoice Header" to "Sales Header" would then break if a field on the "Sales Invoice Header" would have a larger field then the "Sales Header".

So with this I'm unsure if loosing up this rule is the right approach.

Arthurvdv avatar Feb 09 '24 09:02 Arthurvdv

I understand your concern. However, in my example I've also said TransferFields was only used in a DataUpgrade codeunit.

If this was to be excluded, that would be great. The thing is I have to include quite a few locations with a pragma directive which makes the code less readable.

  • New table/field
  • Obsolete table/field (State=Removed)
  • TransferFields in DataUpgrade codeunit

CodeGenius-AU avatar Feb 09 '24 11:02 CodeGenius-AU

If there a specific scenario's where we can suppress the rule, that would be great. Can you share an example or a small project for me to better understand the circumstances of the different scenario's your referencing?

Arthurvdv avatar Feb 09 '24 19:02 Arthurvdv

Here's a small project I've put together which generates the warning.

LC0044-DataUpgrade.zip

CodeGenius-AU avatar Feb 20 '24 09:02 CodeGenius-AU

Thank you for providing an small project, this is very helpful.

Unfortunately there isn't a direct property 'DataUpgrade' available, but indeed we could determine whether this is the case with the status of the Source table with ObsoleteState = Removed; and the .TransferFields inside a codeunit with Subtype = Upgrade;.

Maybe I can try to see if we can exclude tables with the property ObsoleteState = Removed; when the .TransferFields inside a codeunit with Subtype = Upgrade;. There is a possible downside on this and could cause an error during the upgrade of an extension in the case we've overlooked an incompatible transfer (something like from Code[20] to Code[10]). So I'm between a Rock and a Hard Place on this. I understand the false positive, where disabling the rule completely is also not the best solution here I believe.

Just thinking out loud here; Is using the DataTransfer Data Type a viable solution for this? This provides more control and options for an Data Upgrade.

codeunit 50100 DataUpgrade
{
    Access = Internal;
    InherentPermissions = X;
    Subtype = Upgrade;

    var
        wgCduUpgradeTag: Codeunit "Upgrade Tag";

    trigger OnUpgradePerCompany()
    begin
        UpgradeFieldLength();
    end;

    local procedure UpgradeFieldLength()
    var
        ObsoletedTable: Record ObsoletedTable;
        NewTable: Record NewTable;
        TableDataTransfer: DataTransfer;
        UpgradeTagLbl: Label 'UPGRADETAG-LC0044-DATAUPGRADE', Locked = true;
    begin
        if wgCduUpgradeTag.HasUpgradeTag(UpgradeTagLbl) then
            exit;

        TableDataTransfer.SetTables(Database::ObsoletedTable, Database::NewTable);
        TableDataTransfer.AddFieldValue(ObsoletedTable.FieldNo(Code), NewTable.FieldNo(Code));
        TableDataTransfer.AddFieldValue(ObsoletedTable.FieldNo(Description), NewTable.FieldNo(Description));
        TableDataTransfer.AddJoin(ObsoletedTable.FieldNo(Code), NewTable.FieldNo(Code));
        TableDataTransfer.CopyRows();
        Clear(TableDataTransfer);

        ObsoletedTable.DeleteAll(false);

        wgCduUpgradeTag.SetUpgradeTag(UpgradeTagLbl);
    end;
}

Arthurvdv avatar Feb 27 '24 09:02 Arthurvdv