calculating price of a book

hello everyone

i am using dynamics 365 business central

i have created a table named “book” and page named “bookcard” i have two fields in it price and page count. and i have created a code unit

codeunit 50143 BookCodeUnit
{
trigger OnRun()
begin

end;

local procedure CalculatePrice()
var
book: Record Book;
begin
book.Price := book.PageCount * 2.5;

end;

}

now i want to know that how can i make that as soon as i fill the field pagecount , then the price appears for that book in the field “price”

also if i am calling the function in the trigger OnRun()

then its not working

  1. you have 2 fields (“price” and “page count”) and if you want to update value you need to use OnValidate trigger for this purpose.

  2. if you want to use CU but not Validate-trigger for is you need to catch update action for page and use your function (NOT local) with MODIFY;

field(PageCount; PageCount)
{
ApplicationArea = All;
trigger OnValidate();
begin
if (PageCount <= 0) then
Message(‘Enter Correct Number Of PageCount’)
else
Price := PageCount * 2.5;

end;

sir i have applied this code on pagecard but its not working

not page, but table

yes sir it worked… thanks

local procedure CalculatePrice()
var
book: Record Book;
begin

Message(‘the price of book is %1’, book.Price);

end;

It is giving message that price of book is 0

i know its taking whole field. but how can i filter it so that it shows me only particular book price which i open

yes, you receive 0 because record Book is emtry

To show correct price you need to define way (usage horizont) which you want to use:

  • if you have procedure “inside” table Book when you need to request like Book.Calculateprice;

  • if you have this procedure outside table Book then you need to receive inside procedure CalculatePrice(xxx) either conditions (and select record) or record Book as parameter (and don’t use “book: Record Book;” )

Well the idea of having a codeunit do “the job” is brilliant. Right after “the book” of clean structured AL coding. Moving everything to the table object (as suggested) is how you would do it in Navision C/AL, where we often had the bad habit of considering objects, when doing our development. Resulting in source code which is hard to “read”, difficult to maintain and challenging to extend. In Navision you often see tables and pages with tons of code and large “My Solution Management” codeunits which are a mixture of all kinds of functions.

In Business Central you need not to worry about object costs (except on-premise) and its a must that you code is extendable, just as you need the standard code to be extendable.

If you were to solve you example (I expected that is is a thought example - nobody would calculate the price of a book by using the number of pages…) in Business Central VSCode/AL, then I would think the codeunit as method. In your case method CalculatePrice. In it’s simples fashion, then it only contains of public function:

procedure CalculatePrice(var Book: Record Book)
var
    PageNoNotCorrectMsg: Label 'Enter correct number of %1';
begin
    with bo do begin
        if (PageCount <= 0) then
            Message(PageNoNotCorrectMsg,FieldCaption(PageCount))
        else
            Price := PageCount * 2.5;
    end;
end;

This way, whenever you need to change something regarding how your price is calculated, then all you need to do is to change this codeunit. You don’t need to “jeopardize” other parts of your code. You would also need to implement the method by creating it in the book table object:

procedure CalculatePrice();
var 
    CalculatePrice: Codeunit CalculatePrice;
begin
    CalculatePrice.CalculatePrice();
end;

Then all you need is to add the call to the PageCount field’s OnValidate trigger:

trigger OnValidate();
begin
    if PageCount = xRec.PageCount then exit;
    CalculatePrice();
end;

I know it requires more code and more objects, but it’s really the way to go if you want to develop for Dynamics 365 Business Central. You don’t want to repeat mistakes we have done in Navision. I can really recommend you to want this video by by MVP friend Gary Winter.

[embed:b99cc4af-f990-4d68-b98f-dd11f41cb350:717196e1-4b3f-4b7f-ac88-553648d8dc19:service=youtube&embedCode=%3Ciframe%20width%3D%22560%22%20height%3D%22315%22%20src%3D%22https%3A%2F%2Fwww.youtube.com%2Fembed%2FJCMx2BwKtrc%22%20frameborder%3D%220%22%20allow%3D%22autoplay%3B%20encrypted-media%22%20allowfullscreen%3E%3C%2Fiframe%3E&scriptProperty=]

Erik, I think each person has own opinion for it (e.g. many people prefer to have handling of 1 “Entity” in the “1 place”). and I think it is bad idea to have separate codeunit for Validation (value calculation) of field.

The another issue - developers use 1 table to write a tones of code which does not linked with Entity-table. Like if we have separate CU with some code we need to have procedure CalculatePrice(var Book: Record Book). But if it is value update (and we no need to do MODIFY) it is better to use VALIDATE trigger inside table.

And third - if we plan to update (and support Code in future) - we can use Event model for some update.

FYI - when you create solution you pay nothing for it, but go to the Cusotmer place [emoticon:c4563cd7d5574777a71c318021cbbcc8]

P.S. I don’t want argue, but just share my opinion.

This question is about Business Central, not NAV (C/AL). So it is not really a question of supporting (VS?) Code in the future. The “future” is here now.

Generally I do not recommend to create a separate codeunit for all my OnValidate triggers, of course not. But generally then my eyes start to hurt [emoticon:4191f5ee34e248a29fa0dbe8d975f74a], if there are more then 10 to 15 lines of code there. Then it typically means that it can be done in a more structured way - not always of course.

In this case (the Book app/add-on is an old NAV training example) we talk about learning how to become a better developer. Please correct me [mention:498e039e20994b7b8b5c46c62fde2ecb:e9ed411860ed4f2ba0265705b8793d05], if I’m wrong?

Also right now the example of how to calculate the book price is very simplified. And very likely then it could/would also be run from other validations. So from a architectural/structural point, then it would be smart to have it in separate codeunit, as you then only need to change the codeunit.

When actually doing this in VSCode, then I always use the snippets from the CRS VSCode extension to create a method type of codeunit. This way it comes “pre-configured” with handler and events. I just need to implement it in the table.

What I’m really saying is, when training/learning try always to create as clean and structured code as possible. Get some good habits of how to do it. Then you will also learn when not to do it this way. The transition from developers who for years primary have developed customization’s, to be developing customization’s may initially not look as bad.

It’s quite easy to create the a customization as an extension, but unless you want to end in a hell of either “one-big-extension” or a mess of inter-dependent sub-apps, then it is important to think in the whole architecture of the extension from the beginning. And here it is typically not enough just to depend on system events.

PS: Relax, I love to hear and learn from yours (and everybody else’s) opinion on this. If anything it is a discussion, not an argument. [emoticon:c4563cd7d5574777a71c318021cbbcc8]