microsoft / alappextensions Goto Github PK
View Code? Open in Web Editor NEWRepository for collaboration on Microsoft AL application add-on and localization extensions for Microsoft Dynamics 365 Business Central.
License: MIT License
Repository for collaboration on Microsoft AL application add-on and localization extensions for Microsoft Dynamics 365 Business Central.
License: MIT License
We created enhancements for a standard NAV BE localization functionality called CODA (processing of electronic bank statements) by modifying and supplementing the standard NAV code. This enhancement is necessary since the standard NAV functionality is too limited for our customers. Now we want to move our code into an extension.
Since there is no possibility to make use of events (because there aren’t any publishers), it’s impossible to move our enhancements to an extension.
These enhancements occur in Codeunit 2000042 Post Coded Bank Statement.
(There are also other enhancements related to the CODA processing, but these are possible to create in table- and pageextensions and via events.)
There we added changes like:
WITH CodBankStmtLine DO BEGIN
CASE "Type Standard Format Message" OF
...
//103: //TFS4292
103,111,114,121 : //TFS4292
BEGIN
DecodeNumber;
CodeFound := TRUE
END;
...
But specially more search options for the correct Customer Ledger Entry to equalize the payment with the CLE in NAV.
Other enhancements are like:
LOCAL PROCEDURE SearchCustomer@1010022() : Boolean;
VAR
CustBankAcc@1011000 : Record 287;
DomiciliationNo@1011001 : Text[12];
BankAccNo@1011002 : Text[30];
BEGIN
CLEAR(Cust);
WITH CodBankStmtLine DO BEGIN
IF "Type Standard Format Message" = 107 THEN BEGIN
IF Cust.SETCURRENTKEY("Domiciliation No.") THEN;
DomiciliationNo := COPYSTR("Statement Message",1,12);
Cust.SETRANGE("Domiciliation No.",DomiciliationNo);
EXIT(Cust.FINDFIRST);
END ELSE
IF "Bank Account No. Other Party" <> '' THEN BEGIN
CLEAR(CustBankAcc);
//TFS4292 Start Try to find customer based on IBAN No
IF COPYSTR("Bank Account No. Other Party",1,1) IN ['A'..'Z','a'..'z'] THEN BEGIN
IF CustBankAcc.SETCURRENTKEY(IBAN) THEN ;
CustBankAcc.SETRANGE(IBAN,"Bank Account No. Other Party");
IF NOT CustBankAcc.FINDFIRST THEN BEGIN
BankAccNo :=
COPYSTR("Bank Account No. Other Party",1,4) +
' ' + COPYSTR("Bank Account No. Other Party",5,4) +
' ' + COPYSTR("Bank Account No. Other Party",9,4) +
' ' + COPYSTR("Bank Account No. Other Party",13,4);
CustBankAcc.SETRANGE(IBAN,BankAccNo);
IF NOT CustBankAcc.FINDFIRST THEN
IF CodedTrans."Account Type" = CodedTrans."Account Type"::Customer THEN
CustBankAcc."Customer No." := CodedTrans."Account No.";
END;
END ELSE BEGIN
//TFS4292 Stop
// It would be nice to have an index, but we can search without
// The semicolon after THEN does matter
IF CustBankAcc.SETCURRENTKEY("Bank Account No.") THEN;
CustBankAcc.SETRANGE("Bank Account No.","Bank Account No. Other Party");
// Maybe the bank account no is formatted xxx-xxxxxxx-xx
IF NOT CustBankAcc.FINDFIRST THEN BEGIN
BankAccNo :=
COPYSTR("Bank Account No. Other Party",1,3) +
'-' + COPYSTR("Bank Account No. Other Party",4,7) +
'-' + COPYSTR("Bank Account No. Other Party",11,2);
CustBankAcc.SETRANGE("Bank Account No.",BankAccNo);
IF NOT CustBankAcc.FINDFIRST THEN
IF CodedTrans."Account Type" = CodedTrans."Account Type"::Customer THEN
CustBankAcc."Customer No." := CodedTrans."Account No.";
//TFS4292 Start
END;
//TFS4292 Stop
END;
EXIT(Cust.GET(CustBankAcc."Customer No."));
END;
END;
END;
Adding these enhancements on the normal insert/modify events of CodBankStmtLine, is near impossible. Much code would have to be copied from standard NAV BE in order to get the desired functionality.
So possible solutions are:
A) We rework these enhancements with normal insert/modify events and after the standard NAV BE code has run.
But this is a humongous work.
B) MS adds events to these functions and we rework these enhancements with events.
Which is still a large work.
C) We copy the standard NAV BE objects that work around this codeunit and modify them within our own application as new objects.
This leads to creation of code and object duplication and losing touch with standard NAV BE upgrades.
D) MS BE reworks this codeunit with our enhancements.
Any thoughts?
Currently, a lot of the stock objects have control and action names that are default (ControlXXX and ActionXXX). This is extremely difficult to extend those when you have to have the old dev environment open to find the name of the proper action or control that you want to define in "addafter()". I know, this is a big task, but it would be great, if those could be renamed with meaningful names.
Granted, those layout changes could be done via the InClient designer, but it is really easy to make "mass changes" by copying and pasting text blocks in the different files, but you don't know, if - for whatever reason - the Control ID is different in a particular object.
Question related to Issue #1452:
Report 206 in financialsUS does no longer use Table 10011 for sales tax calculations (this was modified over a year ago) but it is still used in Report 1306. Is there a reason for different tax calculation methods in those reports?
This would not be an issue for us if we could extend the Report's dataset and deploy additional layout
I have two accounts for invoicing transport:
Sales Freight
Purchase Transport
If I want to use the Purchase Transport account for invoicing freight and change the description to Freight:
Then it automatically changes the Account No to the Sales Freight account
It must be possible to change the description without changing the account number.
This happened after upgrading to NAV 2018 CU6.
Can this please be removed?
Every function that generates UI should check against HideValidationDialog.
ex.
TAB37 UpdateSalesLines
[External] UpdateSalesLines(ChangedFieldName : Text[100];AskQuestion : Boolean)
IF NOT SalesLinesExist THEN
EXIT;
NotRunningOnSaaS := TRUE;
CASE ChangedFieldName OF
FIELDCAPTION("Shipping Agent Code"),
FIELDCAPTION("Shipping Agent Service Code"):
NotRunningOnSaaS := NOT PermissionManager.SoftwareAsAService;
END;
CheckAskQuestion(ChangedFieldName, AskQuestion); /////TFS//////
IF AskQuestion THEN BEGIN
Question := STRSUBSTNO(
Text031 +
Text032,ChangedFieldName);
IF GUIALLOWED THEN
IF NotRunningOnSaaS THEN
IF DIALOG.CONFIRM(Question,TRUE) THEN
...
We don't want to see the dialog, but we can't change AskQuestion in the functioncall.
An event with Rec, ChangedFieldName, VAR AskQuestion and CurrFieldNo as parameters is also possible to avoid this dialog.
It would be better however when every function that generates UI checks against HideValidationDialog.
...
Question := STRSUBSTNO(
Text031 +
Text032,ChangedFieldName);
IF AskQuestion THEN BEGIN
IF GUIALLOWED THEN
IF NotRunningOnSaaS THEN
if not HideValidationDialog then //////MS/////
IF DIALOG.CONFIRM(Question,TRUE) THEN
...
If it doens't exist yet, a GetHideValidationDialog
and SetHideValidationDialog
should be provided too.
In CU1380, Batch Processing Mgt. MS has created a great new event called OnCustomProcessing with a handled parameter.
My issue is that MS has used this event themselves in CU1371, Sales Batch Post Mgt. Rendering the event nearly completely useless since we cannot predict which subscription will be executed first and all events might set or reset the handled parameter in a different way.
I would like to propose MS either moves their code in function HandleOnCustomProcessing to a hook instead of an event subscriber or create a new event before the OnCustomProcessing event in CU1380.
Similar issues exist with the events OnVerifyRecord and OnBeforeBatchProcessing in CU1380.
I.e.
P&P-Q/O/I/R/C, POST "Post purchase orders, etc."
Perhaps this has been replaced with one of the new "D365xxx" Sets?
W1 13.0 (23896)
Docker image: microsoft/bcsandbox:base
I have a Posted sales invoice that is being used to create a Credit Memo.
I have other tables where I wish to record the fact that the Credit memo has been created.
These tables may have several records for each sales invoice line and I need to relate these lines to the corresponding line or lines in the Credit memo.
For the trivial case the Sales line line numbers may match the credit memo but not generally.
Currently I have several inserts in the codeunit that record the line numbers used when the sales invoice lines are copied to the temp table. For other locations in the codeunit I forbid (TESTFIELD) copying of sales invoice lines that are related to my additional tables. When the credit memo lines are actually created I use the temp table line numbers to link the created credit memo lines to the posted sales invoice lines that they came from.
The standard code seems to overload the "Shipment No." and "Return Receipt Line No." fields to store this information "sometimes" eg: FromSalesInvLine.GET("Shipment No.","Return Receipt Line No.");
, but the fields appear to be cleared by the time the "OnBeforeInsertToSalesLine" and "OnAfterInsertToSalesLine" (v13.0.22490) triggers are called.
My preference would be for a temp "Line Number Buffer" with all the relationships to be provided on the InsertToSalesLine triggers so I can make simple (eg: is it one-to-one) or complex (eg: pick a line if they're "compatible") decisions on how to handle the various possibilities. NB: Without all the detail I probably won't be able to trap all the error states to give reasonable errors.
As suggested in issue #1057 switching from html tables to csv tables would take away the problem with the limitation of the number of fields (limitation of excel with html tables).
This solution is described here: https://blogs.msdn.microsoft.com/freddyk/2009/09/20/word-management/
please implement this, because it is now possible to add fields with an extension because of the new codeevents in codeunit 5054.
Hello,
In our localization "Close Income Statement" in made monthly not yearly.
To resolve this problem a solution could be, a new function in codeunit 11
[External] SetCheckFiscalYear(NewFiscalYear : Boolean)
IsFiscalYear := NewFiscalYear;
IsFiscalYear is Boolean and is a global variable in codeunit 11.
This function will be used in local function Checkdates.
Thank you!
Hi,
We need to have some checks of GUIALLOWED before window ist called, else NAS will run on an Error.
Objects we discovered need a change:
Thanks in advance
In OnValidate of No on Sales Line we used to change something on the entered Item No and reread the global variable Item.
If we didn't do this Item.GET("No.")
, we would get the error 'Another use has modified the record ...'.
So in events:
LOCAL [EventSubscriber] OnBeforeValidate_Quantity_SalesLine(VAR Rec : Record "Sales Line";VAR xRec : Record "Sales Line";CurrFieldNo : Integer)
WITH Rec DO BEGIN
lrecItem.GET("No.");
DoSomething()
lrecItem.MODIFY;
Item.GET("No."); // reread global var
However Item.GET("No.");
isn't possible cause we have no access to the global var Item.
There is however the local function GetItem, but this only performs the actual get when the No has changed.
LOCAL GetItem()
TESTFIELD("No.");
IF "No." <> Item."No." THEN
Item.GET("No.");
We want to always reread the global var Item.
Any ideas on how to solve this?
For now we have solved it by putting the IF "No." <> Item."No." THEN
in comment in GetItem.
Using NAV2018CU3
I have already requested this on Yammer, but I now have a very specific case where I need this: Regarding my issue #2699, I would like to become the primary key for Table 49 to be a 40 character hash string that is generated out of a number of fields, instead of concatenating the various fields together (and probably blows the 250 character limit). But we do not have any access to hash functions, be it MD5, SHA-1 or anything.
I've recently noticed the Codeunits in range 3000 .. 3026 that neatly wrap .NET features in C/AL Codeunits and thus allowing us to use them. Please add another Codeunit here that provides us with simplified access to hashing functions that take 1 string and return 1 string. Something like this:
CalculateSHA256(Value : Text) : Text
enc := enc.UTF8;
SHA256 := SHA256.SHA256Managed();
ba := enc.GetBytes(Value);
ba := SHA256.ComputeHash(ba);
EXIT(GetHexString(ba));
If you create a new order using the "Create Order" function and there was no customer in the original quotation, the system asks whether a new customer is created. If you confirm this with Yes, a new customer number is created from existing templates and then the new customer number is entered for all existing quotations. This works via Table 5050 in the "UpdateQuotes" function. However, several problems can arise here. The "Sell-To Customer No." and "Bill-To Customer No." are inserted but not validated. As a result, some fields in the sales header are not updated, such as the "Invoice Disc. Code". This exists in the newly created customer, but not in the original quote, and then not in the newly created sales order. This can have fatal consequences in postprocessing if some fields are not validated and information is simply missing. The error affects not only the current Business Central version, but also all NAV versions that are still supported. Here, too, a correction should be made.
In order to "play nicely" with the posting engine in codeunit 12, we'd like to have access to its global variables when it raises an integration event.
In other words, we'd like the GlobalVarAccess property set to "Yes" for each of the four integration events. Is that possible?
Hi @esbenk,
last week we have discussed - how to avoid a commit, if I try to run a "Post-Something-Operation" including a Commit
as a Batch-Operation.
In my opinion it could be help, to include e.g. a OnBeforeCommitEvent(…)
Event in the COMMIT command e.g.:
[BusinessEvent(true)]
procedure OnBeforeCommit(var suspendCommit:Boolean)
begin
end;
When I use a codeunit with dynamics
subscriber than I could set suspendCommit = true
and avoid the Commit until the end of my Batch-Operation.
And now the tricky part :) how can I secure, that I only suspend the Commit of my Current Session which invoked the Batch-Operation? Would this be possible? If yes than pleas include the Event!
BR / Michael
Codeunit 5005351 OnRun()
For using own fields in function GetSamePhysInvtOrderLine
we need to change the parameter.
Instead of calling with explicit fields of record PhysInvtRecordingLine, we need the whole record.
PhsyInvtOrderHeader.GetSamePhysInvtOrderLine(PhysInvtRecordingLine, ErrorText, PhysInvtOrderLine)
I understand that the UI simplification is ongoing, but here are some problems that it's causing for us (and probably other extension developers). When Microsoft recaptions a page field (e.g., Ship-to Code on the Sales Invoice page is now just Code, as it is located in the Ship-to section of the page), it breaks our extensions. Our addafter was set to "Ship-to Code", as that's what the field has always been named (and it's named that in 2016, 2017, and earlier builds of 2018). Presumably, Microsoft is going to continue this trend, which is great, but it's wreaking havoc on pageextensions. If you are recaptioning a field on a page, could you please set the control Name to the field name? It's a problem for new extension developers, too. To take that same example, when you are adding a control to the Sales Invoice page, how would someone know that addafter(Code) is referring to the Ship-to Code? "Code" works fine in the UI, but it's not a good control name. We publish our extensions for NAV 2016 and 2017 too, so it would be ideal if the control names could be consistent across NAV versions (even though you might change the captions for simplification).
This is impacting our extensions on the following pages (so if you could revert the control Names on these pages at a minimum, I would appreciate it):
Customer Card
Sales Invoice
Sales Order
Sales Quote
Sales Return Order
I am using the Header records to store state between events so the VAR parameter on the events must refer to the same instance of the Header record from CU80/90.
Please add the VAR property to the SalesHeader
parameter in Codeunit 80 functions PostSalesLine
, PostGLAndCustomer
and PostCustomerEntry
Please add the VAR property to the PurchHeader
parameter in Codeunit 90 functions PostPurchLine
and PostVendorEntry
Note the function PostGLAndVendor
already has the flag.
Also do the same for the header record in OnAfterPostSalesLine
and OnAfterPostPurchLine
in codeunits 80 and 90 respectively.
[Integration]
LOCAL PROCEDURE OnAfterPostSalesLine@224(VAR SalesHeader@1000 : Record 36;VAR SalesLine@1001 : Record 37;CommitIsSuppressed@1002 : Boolean);
BEGIN
END;
[Integration]
LOCAL PROCEDURE OnAfterPostPurchLine@226(VAR PurchaseHeader@1000 : Record 38;VAR PurchaseLine@1001 : Record 39;CommitIsSupressed@1002 : Boolean);
BEGIN
END;
--- at2018-base/Codeunit_80.txt 2018-08-09 06:14:17.431429982 +0100
+++ AT2018-CU5/Codeunit_80.txt 2018-08-09 06:14:22.743429748 +0100
@@ -465,7 +465,7 @@ OBJECT Codeunit 80 Sales-Post
END;
END;
- LOCAL PROCEDURE PostSalesLine@161(SalesHeader@1000 : Record 36;VAR SalesLine@1001 : Record 37;VAR EverythingInvoiced@1004 : Boolean;VAR TempInvoicePostBuffer@1017 : TEMPORARY Record 49;VAR TempVATAmountLine@1005 : TEMPORARY Record 290;VAR TempVATAmountLineRemainder@1006 : TEMPORARY Record 290;VAR TempItemLedgEntryNotInvoiced@1007 : TEMPORARY Record 32;HasATOShippedNotInvoiced@1008 : Boolean;VAR TempDropShptPostBuffer@1009 : TEMPORARY Record 223;VAR ICGenJnlLineNo@1010 : Integer;VAR TempServiceItem2@1012 : TEMPORARY Record 5940;VAR TempServiceItemComp2@1013 : TEMPORARY Record 5941);
+ LOCAL PROCEDURE PostSalesLine@161(VAR SalesHeader@1000 : Record 36;VAR SalesLine@1001 : Record 37;VAR EverythingInvoiced@1004 : Boolean;VAR TempInvoicePostBuffer@1017 : TEMPORARY Record 49;VAR TempVATAmountLine@1005 : TEMPORARY Record 290;VAR TempVATAmountLineRemainder@1006 : TEMPORARY Record 290;VAR TempItemLedgEntryNotInvoiced@1007 : TEMPORARY Record 32;HasATOShippedNotInvoiced@1008 : Boolean;VAR TempDropShptPostBuffer@1009 : TEMPORARY Record 223;VAR ICGenJnlLineNo@1010 : Integer;VAR TempServiceItem2@1012 : TEMPORARY Record 5940;VAR TempServiceItemComp2@1013 : TEMPORARY Record 5941);
VAR
SalesInvLine@1014 : Record 113;
SalesCrMemoLine@1015 : Record 115;
@@ -568,7 +568,7 @@ OBJECT Codeunit 80 Sales-Post
END;
END;
- LOCAL PROCEDURE PostGLAndCustomer@164(SalesHeader@1000 : Record 36;VAR TempInvoicePostBuffer@1001 : TEMPORARY Record 49;VAR CustLedgEntry@1002 : Record 21);
+ LOCAL PROCEDURE PostGLAndCustomer@164(VAR SalesHeader@1000 : Record 36;VAR TempInvoicePostBuffer@1001 : TEMPORARY Record 49;VAR CustLedgEntry@1002 : Record 21);
BEGIN
OnBeforePostGLAndCustomer(SalesHeader,TempInvoicePostBuffer,CustLedgEntry);
@@ -4172,7 +4172,7 @@ OBJECT Codeunit 80 Sales-Post
END;
END;
- LOCAL PROCEDURE PostCustomerEntry@101(SalesHeader@1000 : Record 36;TotalSalesLine2@1005 : Record 37;TotalSalesLineLCY2@1006 : Record 37;DocType@1002 : Option;DocNo@1003 : Code[20];ExtDocNo@1004 : Code[35];SourceCode@1007 : Code[10]);
+ LOCAL PROCEDURE PostCustomerEntry@101(VAR SalesHeader@1000 : Record 36;TotalSalesLine2@1005 : Record 37;TotalSalesLineLCY2@1006 : Record 37;DocType@1002 : Option;DocNo@1003 : Code[20];ExtDocNo@1004 : Code[35];SourceCode@1007 : Code[10]);
VAR
GenJnlLine@1001 : Record 81;
BEGIN
--- at2018-base/Codeunit_90.txt 2018-08-09 06:14:17.439429981 +0100
+++ AT2018-CU5/Codeunit_90.txt 2018-08-09 06:14:22.751429748 +0100
@@ -485,7 +485,7 @@ OBJECT Codeunit 90 Purch.-Post
END;
END;
- LOCAL PROCEDURE PostPurchLine@152(PurchHeader@1001 : Record 38;VAR PurchLine@1000 : Record 39;VAR TempInvoicePostBuffer@1006 : TEMPORARY Record 49;VAR TempVATAmountLine@1005 : TEMPORARY Record 290;VAR TempVATAmountLineRemainder@1004 : TEMPORARY Record 290;VAR TempDropShptPostBuffer@1009 : TEMPORARY Record 223;VAR EverythingInvoiced@1003 : Boolean;VAR ICGenJnlLineNo@1008 : Integer);
+ LOCAL PROCEDURE PostPurchLine@152(VAR PurchHeader@1001 : Record 38;VAR PurchLine@1000 : Record 39;VAR TempInvoicePostBuffer@1006 : TEMPORARY Record 49;VAR TempVATAmountLine@1005 : TEMPORARY Record 290;VAR TempVATAmountLineRemainder@1004 : TEMPORARY Record 290;VAR TempDropShptPostBuffer@1009 : TEMPORARY Record 223;VAR EverythingInvoiced@1003 : Boolean;VAR ICGenJnlLineNo@1008 : Integer);
VAR
PurchInvLine@1010 : Record 123;
PurchCrMemoLine@1011 : Record 125;
@@ -2660,7 +2660,7 @@ OBJECT Codeunit 90 Purch.-Post
END;
END;
- LOCAL PROCEDURE PostVendorEntry@68(PurchHeader@1006 : Record 38;TotalPurchLine2@1005 : Record 39;TotalPurchLineLCY2@1004 : Record 39;DocType@1003 : Option;DocNo@1002 : Code[20];ExtDocNo@1001 : Code[35];SourceCode@1000 : Code[10]);
+ LOCAL PROCEDURE PostVendorEntry@68(VAR PurchHeader@1006 : Record 38;TotalPurchLine2@1005 : Record 39;TotalPurchLineLCY2@1004 : Record 39;DocType@1003 : Option;DocNo@1002 : Code[20];ExtDocNo@1001 : Code[35];SourceCode@1000 : Code[10]);
VAR
GenJnlLine@1007 : Record 81;
BEGIN
Hello,
Is it possible to add the field Vendor Invoice No. (ID 68) from table Purchase Header (T38) to table Purch. Rcpt. Header (T120)? As i need the value of Vendor Invoice No. through transferfields from table 38 to table 120.
Thank you.
Kind regards.
This issue actually goes hand-in-hand with my other event-requests (#2526, #2473). Maybe it's time I elaborate:
What I am trying to achieve is allowing certain Gen. Journal Lines to be posted with custom routines. There are scenarios (hooray for Italy) where we need special treatment for certain lines and don't want them to finish in the general ledger (statiscs, trial balance, reports, accruals, you name it). So while I'd like to keep the posting (Journals, Chart of Accounts) infrastructure intact, I just need my entries to finish elsewhere.
I have already requested a few events to allow me to implement my posting routine (see above), but there is a fundamental flaw in that design:
I think some parts (mostly the global-variable-thingy) in CU12 / CU13 could do with a little workover to allow us to efficiently implement custom posting routines through events / extensions.
Happy to elaborate, should you need more info.
Hello,
Could you please create new publishers in the CU7600 (Calendar Management) / refactor the function?
Reason: We need to propagate new fields from the calendar changes to the base calendar
CU7600 The functions CheckDateStatus AND CheckCustomizedDateStatus (current state, both functions contains the same code except the first line in the CheckCustomizedDateStatus, I attach only one of them, but we need to refactor both of them)
[External] CheckDateStatus(CalendarCode : Code[10];TargetDate : Date;VAR Description : Text[50]) : Boolean
BaseCalChange.RESET;
BaseCalChange.SETRANGE("Base Calendar Code",CalendarCode);
IF BaseCalChange.FINDSET THEN
REPEAT
CASE BaseCalChange."Recurring System" OF
BaseCalChange."Recurring System"::" ":
IF TargetDate = BaseCalChange.Date THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
BaseCalChange."Recurring System"::"Weekly Recurring":
IF DATE2DWY(TargetDate,1) = BaseCalChange.Day THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
BaseCalChange."Recurring System"::"Annual Recurring":
IF (DATE2DMY(TargetDate,2) = DATE2DMY(BaseCalChange.Date,2)) AND
(DATE2DMY(TargetDate,1) = DATE2DMY(BaseCalChange.Date,1))
THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
END;
UNTIL BaseCalChange.NEXT = 0;
Description := '';
Future state (new var parameter)
[External] CheckDateStatus(CalendarCode : Code[10];TargetDate : Date;VAR Description : Text[50]; VAR BaseCalChange) : Boolean
BaseCalChange.RESET;
BaseCalChange.SETRANGE("Base Calendar Code",CalendarCode);
IF BaseCalChange.FINDSET THEN
REPEAT
CASE BaseCalChange."Recurring System" OF
BaseCalChange."Recurring System"::" ":
IF TargetDate = BaseCalChange.Date THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
BaseCalChange."Recurring System"::"Weekly Recurring":
IF DATE2DWY(TargetDate,1) = BaseCalChange.Day THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
BaseCalChange."Recurring System"::"Annual Recurring":
IF (DATE2DMY(TargetDate,2) = DATE2DMY(BaseCalChange.Date,2)) AND
(DATE2DMY(TargetDate,1) = DATE2DMY(BaseCalChange.Date,1))
THEN BEGIN
Description := BaseCalChange.Description;
EXIT(BaseCalChange.Nonworking);
END;
END;
UNTIL BaseCalChange.NEXT = 0;
Description := '';
CU7600 The function CombineChanges (current state)
...
TempCustChange."Recurring System" := CustCalChange."Recurring System";
TempCustChange."Entry No." := TempCounter;
TempCustChange.INSERT;
UNTIL CustCalChange.NEXT = 0;
...
TempCustChange.Nonworking := BaseCalChange.Nonworking;
TempCustChange."Recurring System" := BaseCalChange."Recurring System";
TempCustChange.INSERT;
UNTIL BaseCalChange.NEXT = 0;
...
Future state
...
TempCustChange."Recurring System" := CustCalChange."Recurring System";
TempCustChange."Entry No." := TempCounter;
OnCombineChangesCustCalendar(var TempCustChange, CustCalChange, TempCounter);
TempCustChange.INSERT;
UNTIL CustCalChange.NEXT = 0;
...
TempCustChange.Nonworking := BaseCalChange.Nonworking;
TempCustChange."Recurring System" := BaseCalChange."Recurring System";
OnCombineChangesBaseCalendar(var TempCustChange, BaseCalChange, TempCounter);
TempCustChange.INSERT;
UNTIL BaseCalChange.NEXT = 0;
...
CU7600 The function CreateWhereUsedEntries(current state)
...
WhereUsedBaseCalendar.INSERT;
END;
COMMIT;
Future state
...
WhereUsedBaseCalendar.INSERT;
END;
OnCreateWhereUsedEntries(var WhereUsedBaseCalendar, BaseCalendarCode );
COMMIT;
P7605 The function UpdateBaseCalendarChanges(current state)
...
CustomizedCalendarChange.Nonworking := Nonworking;
CustomizedCalendarChange.INSERT;
END;
Future state
...
CustomizedCalendarChange.Nonworking := Nonworking;
CustomizedCalendarChange.INSERT;
OnUpdateBaseCalendarChanges(var CustomizedCalendarChange, Rec, Nonworking);
END;
P7604/P7605 Please create a new functions. This is the most important thing, without this function, it is impossible to do any change on this page...
[External] GetCalendarCode(VAR CalendarCode : Code[10];VAR LocNonworking : Boolean;VAR LocDescription : Text[30])
[External] GetCalendarCode(VAR SourceType : 'Company,Customer,Vendor,Location,Shipping Agent';VAR SourceCode : Code[20];VAR AdditionalSourceCode : Code[20];VAR CalendarCode : Code[10];VAR LocNonworking : Boolean;VAR LocDescription : Text[30])
Business scenario: maintaining customer/vendor/item information in a master management database (w1 localisation) and send update to operational database (NL localisation).
In several places dialogs and confirm messages are added without the function GUIALLOWED.
As I no longer can change standard code, can you please add logic that in case code is hit via job queue functionality dialog and confirm messages are automatically suppressed?
Examples:
Table 1220 Data Exch.
ImportToDataExch(DataExchDef : Record "Data Exch. Def") : Boolean
IF NOT "File Content".HASVALUE THEN
IF NOT ImportFileContent(DataExchDef) THEN
EXIT(FALSE);
ProgressWindow.OPEN(ProgressWindowMsg);
Table 18 Customer
Partner Type - OnValidate()
IF NOT TransactionMode.CheckTransModePartnerType(AccountType::Customer,"Transaction Mode Code","Partner Type") THEN
IF NOT CONFIRM(PartnerTypeMismatchMsg,FALSE) THEN
ERROR('')
could you change reference-type of parameters TableId and No
now:
LOCAL [IntegrationEvent] OnAfterCreateDimTableIDs(VAR SalesHeader : Record "Sales Header";FieldNo : Integer;TableID : ARRAY [10] OF Integer;No : ARRAY [10] OF Code[20])
ask for:
LOCAL [IntegrationEvent] OnAfterCreateDimTableIDs(VAR SalesHeader : Record "Sales Header";FieldNo : Integer;# VAR TableID : ARRAY [10] OF Integer;# VAR No : ARRAY [10] OF Code[20])
In Codeunit 7307 Whse.-Activity-Register the functions LocationGet
and GetItemUnitOfMeasure2
(why 2? where's the original?) would have to be global and external and return via VAR the getted Location/ItemUnitOfMeasure (so you can get rid of the global variables).
LOCAL LocationGet(LocationCode : Code[10])
IF LocationCode = '' THEN
CLEAR(Location)
ELSE
IF Location.Code <> LocationCode THEN
Location.GET(LocationCode);
LOCAL GetItemUnitOfMeasure2(ItemNo : Code[20];UOMCode : Code[10])
IF (ItemUnitOfMeasure."Item No." <> ItemNo) OR
(ItemUnitOfMeasure.Code <> UOMCode)
THEN
IF NOT ItemUnitOfMeasure.GET(ItemNo,UOMCode) THEN
ItemUnitOfMeasure.INIT;
The function UpdateWhseShptLine
should be global + external and the variable WhseShptLine should be a local (instead of a global).
TY
The system already have workflow template for general journal (MS-GJBAPW and MS-GJLAPW).
So, please also do:
IF JobDiffBuffer[1].FIND('-') THEN
….
REPEAT
// begin
//IF JobDiffBuffer[1].Quantity > 0 THEN BEGIN
IF JobDiffBuffer[1].Quantity <> 0 THEN BEGIN
// end
With filesystem access off-limits for AL 2.0 for now, this poses a big problem upgrading clients who have legacy customizations that transfer files to/from NAV and third party customers/vendors/banks/etc. as well as transfer files to/from third party software (e.g. Barcode label automation, Shipping Software, etc).
Many of these third party solutions are not able to integrate via http rest and rely on file transfers, making them nearly impossible to use from an extension.
Proposal:
Can Microsoft create an "SFTP Client" Codeunit in NAV? Sample functionality includes (but not limited to) login/logout, list remote files, download a file, upload a file, delete a remote file, etc (if local client/server file system access is a security concern then use instream/outstream/memorystream when possible).
This would really open up NAV's integration capability.
The reports that are used in warehouse module are hard coded (REPORT.RUN(REPORT::xxx). Therefore it is not possible to replace these reports by own reports shipped with an ISV solution.
All warehouse documents should be added to Report Selections table. A new page Report Selection - Warehouse New field Show Request Window (Boolean) should be additionally added to this table. This field should be used as parameter for REPORT.RUN statement.
I would like to use this issue to address the subject of the Codunit 12 in particular. In the "PostApply" function, there are various subfunctions that perform important posting functions. This includes, among other things, the discount calculation as well as the cash discount calculation. Some of these functions are also reused in other posting functions such as "PostCust" or "PostVend".
With the previously provided events it is unfortunately not possible to implement your own logic here. You would have to be able to "overwrite" functionalities in these routines. In this way, you could then also integrate your own discount calculation logic or cash discount logic (multi-level).
Is it possible to switch these functions to the handle pattern? concretely, this concerns the following functions:
Information about the pattern can be found here
This would allow you to implement your own logic for these functions. This presupposes, of course, that you have to have access to all the internal functions from outside, so that you can take over a large part of the original in case of need.
I would like to know whether there is a general possibility that there will be a remedy here soon. Under these circumstances, user-defined adjustments to the booking processes are unfortunately not easily possible.
Hi Team,
In a lot of databases we have a unit of measure description that is larger than 10 characters.
Is it possible to extend this field to 30 or 50 like other standard Dynamics NAV tables? Or is there a reason why this is still 10?
Hi,
I was trying to add Default Dimensions to a Master Data Table from my Extension.
So I added the "Dimension - Single" action to my Page according to the pattern used in e.g. Customer List.
No problem to depoy it, but unfortunately the "Default Dimension" table has a Table Relation, which is also validated.
IF (Table ID=CONST(13)) Salesperson/Purchaser ELSE IF (Table ID=CONST(15)) "G/L Account" ELSE IF (Table ID=CONST(18)) Customer ELSE IF (Table ID=CONST(23)) Vendor ELSE IF (Table ID=CONST(27)) Item ELSE IF (Table ID=CONST(152)) "Resource Group" ELSE IF (Table ID=CONST(156)) Resource ELSE IF (Table ID=CONST(167)) Job ELSE IF (Table ID=CONST(270)) "Bank Account" ELSE IF (Table ID=CONST(413)) "IC Partner" ELSE IF (Table ID=CONST(5071)) Campaign ELSE IF (Table ID=CONST(5200)) Employee ELSE IF (Table ID=CONST(5600)) "Fixed Asset" ELSE IF (Table ID=CONST(5628)) Insurance ELSE IF (Table ID=CONST(5903)) "Service Order Type" ELSE IF (Table ID=CONST(5904)) "Service Item Group" ELSE IF (Table ID=CONST(5940)) "Service Item" ELSE IF (Table ID=CONST(5714)) "Responsibility Center" ELSE IF (Table ID=CONST(5800)) "Item Charge" ELSE IF (Table ID=CONST(99000754)) "Work Center" ELSE IF (Table ID=CONST(5105)) "Customer Template" ELSE IF (Table ID=CONST(849)) "Cash Flow Manual Revenue" ELSE IF (Table ID=CONST(850)) "Cash Flow Manual Expense"
Any idea, how I can solve that? Does it actually make sense to have the Table Relation here?
due to some limitations, we are using our own POST action in all sale and purchase documents pages
example : page 42
code under standard post action is
We cant access DocumentIsPosted variable in event subscribed to NEW Post action and we are getting document not posted confirmation event after posting documents.
Please provide a way to handle DocumentIsPosted .. may be by adding this to table etc.
Hi,
we are trying to transfer ower solution into an extension.
We uses the item variant to differ between master data. The master data Table use the No,.Series and as we know the No. Series Lines are Code20.
So we extend the variant code field from Code10 to Code20. As far as I know In an extension this is not possible.
Is it possible that the base application will extend the variant code from code10 to code20?
Kind regards,
Reiner Ovelgoenne
I put an idea onto the ideas page (https://experience.dynamics.com/ideas/idea/?ideaid=89d21a1e-bc9a-e811-b96f-0003ff68935d) but I was suggested to put it here instead/as well.
The Payment Reconciliation Journal has a severe limitation in that it does not recognise when a Bank Ledger has already been posted - the most common example is Vendor Payments. We should be able to match against these unreconciled Bank Ledger entries, and ideally it should try to auto-match as well.
In comparison the Bank Acc. Reconciliation does do this - including the auto-match. Behind the scenes it uses the same Table and Posting Codeunit as the other Bank Rec so this should be possible?
Actually this codeunit contains only a GetPeriod function (useful for checking if you're on a trial tenant or not), see here:
https://demiliani.com/2018/08/02/dynamics-365-business-central-how-to-check-in-your-extension-is-running-on-a-trial-tenant/
This function checks the Tenant License State table (2000000189) that contains details of your tenant license such as Start Date and End Date and the State of your license (that is an option field with the following values: Evaluation,Trial,Paid,Warning,Suspended,Deleted,,,,LockedOut ).
It could be useful to have in codeunit 2300 some functions to return the Start Date and the End Date of a tenant license and maybe directly the State, without querying the table.
Hi
due to lack of possibility to change behaviour of standard flowfield and keys, I'm doing some stress test with standard code.
In a medium-complex database with:
it's easy to have thousands of dimension set IDs till to maxium of 400 x 80 x 20 = 640.000 combinations.
With a simple stress-test codeunit I have generated only 10.000 randomic G/L entries but sufficients to crash dimension set filter due to maximum number of parameters (2100) supported by SQL Server:
In the past we could extend "G/L Entry" table with ""Global Dimension Code 3", 4 and so on; create the missing keys and alter the "Amount" flowfield of "G/L Account". But now?
I think this issue is partially related to #730 but anyway, in this scenario, Dimension Set Filter will never work. Maybe a new type of field such as "Filter on Related Table" can resolve the issue applying the WHERE clause in "Dimension Set Entry" table instead of passing thousand of parameters for "Dimension Set ID" in "G/L Entry".
S.
There are scenario's where you want to print a report from code directly to a printer, without user interaction. However, with Business Central that's not possible because the server doesn't have access to local printers from code.
I have a working solution using PrintNode. That is based on Report.Save method, get the PDF output in a stream and then send it via a web service to the local printer. But then you need to hard code it for every single report and it doesn't really integrate with report selections.
It would be of great help if it would be possible to get the output of a print job before it actually prints. The current event OnAfterFindPrinter in Codeunit 1 doesn't work for that.
So I was thinking of a generic event OnReportPrintOutput in Codeunit 1 which passes the output as a PDF in a stream. It should also pass the ShowRequestPage parameter (so the code knows that the report was displayed on the screen and then could choose to behave differently). And it should accept a return parameter that indicates that the output is handled so Business Central knows that it doesn't need to print the output.
There is an issue with Codeunit 8 AccSchedManagement
. It provides us the two methods SetGLAccRowFilters
and SetGLAccColumnFilters
. They are both public and marked as external, so my guess is that they are to be used "from outside". The problem is, that the latter (SetGLAccColumnFilters
) uses two global variables FromDate
and ToDate
to apply the Date Filter
on the acc. schedule line. Having this Codeunit in my event-handlers (I subscribe to OnBeforeCalcCellExit
of the same Codeunit) obviously creates a new instance and therefore I lose the contents of these two variables and therefore an empty date filter gets applied to my acc. schedule line.
Please add a
if guiallowed then
before
IF CONFIRM(AnotherItemWithSameDescrQst,FALSE,Item."No.",Item.Description) THEN
and
IF CONFIRM(AnotherChargeItemWithSameDescQst,FALSE,ItemCharge."No.",ItemCharge.Description) THEN
is called.
This is currently causing problems when trying to insert new purchase lines via webservice.
Hello,
It would be very useful if you could extend current option filed Type for item attributes with new value - Date.
Current choices are:
We have that on 2 places: "Item Attributes".Type and "Item Attribute Value Selection"."Attribute Type".
Date option is particularly important and useful for all HR related master tables.
Also, is it possible to remove word Item from text constants, or replace it with placeholder?
We have it in 4 tables:
Item Attribute Value Selection:
Filter Item Attributes Buffer:
These changes would make Item Attributes extendable for all other master tables.
Thanks,
Radovan
With upcoming serialisation in Pharma, 2019, these field lengths could/will be to short in the future.
Suggestion:
Please allow several SMTP setups to be used per company.
This can be achieved by assigning a SMTP Setup record to SMTPMailSetup variable in CU 400 with an external procedure.
Reason:
Several different smtp servers might be required to allow for handling mails "in the name of" another company (warehouse handling).
Hi,
we want to transfer our solution into an extension. The field City (for example in Table 5050) is to short. German city names can be longer than 30 digit. We extend this field from Text30 to Text50.
As far as I know a length change of a base application field is not possible.
Is it possible to change the field length vom text30 to text50 in the base application?
Kind regards,
Reiner Ovelgoenne
Page 953, Manager Time Sheet List, is now sorted by "Resource No.","Starting Date"
Please change this to only sort by "Starting Date"
Reason:
When working with this page as a manager, the number of records per resource increases over time.
When you are an approver for more than one resource you need to navigate between the latest weeks time sheets for each resource. This get's more and more hard to get an overview of what you've worked with or not.
After a while it's getting quite annoying to navigate between different resources last time sheet. (Yes, filters helps, but a lot of users are not that good on filters as you all know...)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.