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" 
Parents
  • 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.

Reply
  • 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.

    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

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

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

    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 , 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 , 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. 

Related
Recommended