microsoft / microsoft/BCApps

[Bug]: [E-Document] PDF preview factbox writes to Tenant Media on every OnAfterGetCurrRecord of purchase invoice pages

Open
#11,077 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Team: Integrations
Dominant language
AL
Stars
683
Forks
459
Avg merge
3d 26m
Merged PRs (30d)
633

Description

Describe the issue

PR #9145 hosts page 6111 "Inbound E-Doc. Picture" as a factbox on Purchase Invoice (51), Purchase Invoices (9308), Posted Purchase Invoice (138) and Posted Purchase Invoices (146). Its OnAfterGetCurrRecordLoadPdfImage() ends with:

TempMediaRepository.Image.ImportStream(ImageStream, EDocDataStorageImageDescriptionLbl, 'image/png');

TempMediaRepository is temporary, but Media.ImportStream always inserts the media object into system table 2000000184 "Tenant Media" – the temporary record only holds the GUID reference (docs). Displaying a purchase invoice is now a database write, with three consequences:

  1. A write transaction is opened. Code that is not allowed inside a write transaction fails until the next commit. Our test opens the Posted Purchase Invoice card and invokes CancelInvoice; it now fails in codeunit "Correct Posted Purch. Invoice", CreateCreditMemo():
   if not CODEUNIT.Run(CODEUNIT::"Correct Posted Purch. Invoice", PurchInvHeader) then begin

The following C/AL functions are limited during write transactions because one or more tables will be locked. [...] Codeunit.Run is allowed in write transactions only if the return value is not used.

The test passed before this PR. Any partner test that runs Cancel/Correct (or anything else using Codeunit.Run with a return value / RunModal) through the Posted Purchase Invoice test page is affected.

  1. Orphaned Tenant Media rows. Every render inserts a "Tenant Media" record that nothing references and nothing deletes. PdfLoaded is never set to true, so the "already loaded" guard is dead code: the PDF blob is re-read, re-rendered to PNG and re-imported on every OnAfterGetCurrRecord / CurrPage.Update – on the list pages, on every row change.

  2. Not limited to linked invoices. The part has no SubPageLink and the host calls SetRecFilterByEDocDataStorageEntryNo() unconditionally, so without a filter the part is positioned on the first "E-Doc. Data Storage" record in the table and renders that one. Our test invoice has no E-Document at all and still fails.

Expected behavior

Opening a purchase invoice (posted or not) does not write to the database. Render the preview once and persist it (e.g. a Media field on "E-Doc. Data Storage" populated when the E-Document is received), so the factbox only reads. Cancel/Correct from the Posted Purchase Invoice card works without an intermediate Commit(), as before.

Steps to reproduce

Precondition: at least one "E-Doc. Data Storage" record with File Format = PDF exists in the database.

PurchInvHeader.Get(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true));
Commit();

PostedPurchaseInvoiceCard.OpenEdit();
PostedPurchaseInvoiceCard.GoToRecord(PurchInvHeader);
LibraryDialogHandler.SetExpectedConfirm(CancelPostedInvoiceQst, true);
LibraryDialogHandler.SetExpectedConfirm(OpenPostedCreditMemoQst, false);
PostedPurchaseInvoiceCard.CancelInvoice.Invoke(); // <- write-transaction error

Or simply: count "Tenant Media" records, open a posted purchase invoice card / scroll the list, count again.

Additional context
  • PR #9145 states "No table schema change; no new stored data" – the Tenant Media inserts contradict that.
  • In the web client the transaction is committed at the end of every server call, so interactive users only see the data growth, not the error; tests and transactional code hit the error.
  • Files: InboundEDocPicture.Page.al, pageextension 6146 "E-Doc. Posted Purch. Inv."
  • Version: 29.0 (main)
I will provide a fix for a bug
  • I will provide a fix for a bug

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with InboundEDocPicture.Page.al and pageextension 6146 "E-Doc. Posted Purch. Inv.", then trace OnAfterGetCurrRecord, LoadPdfImage(), and TempMediaRepository.Image.ImportStream. Run the Posted Purchase Invoice reproduction and inspect Tenant Media before and after opening or scrolling pages; done means preview access causes no database write and CancelInvoice no longer hits the write-transaction error.

Written by the indexing model from the issue text.

Assessment

Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.