Refactoring

If we read the code that we have just written, we can immediately start cleaning the code, and then start refactoring it.

Let's browse through the functions one by one, see how we can refactor, and see what the result looks like.

The new class members

Quite a number of functions can be the members of a class or the table. We can add the function called OccupiedOrHasNotBeenCleanedForAWeek, CreateCleaningEntryForRoom, FindLastCleaningDate, and CreateCleaningEntryForRoom as members of the Room table.

If we do this, our Codeunit will look like the following:

The new class members

The Codeunit is very clean and refactored.

The new function library

One of the functions cannot be moved as a member of the Room table. The LastWeek function is a generic function.

Let's create a new function library and call it the Bed and Breakfast function, as shown here:

The new function library

Room members

The Room table now has three members that can be generically reused whenever appropriate.

We can probably make these functions more generic. For example, by adding the Cleaning Entry Status as a parameter to the function.

We can also refactor the functions into their own Codeunit. This will make sense if our development team has different programmers working on application areas that will overlap. If this is not likely, then the extra overhead might not be worth the hassle.

Room members

The room price calculation

We need the calculation of a room price in a number of places. At least the Journal and the Stay have this requirement. We can also foresee a future enhancement of a Web Service returning a price, based on an inquiry or a wizard for manual inquiries.

Although the price is based on three elements—Room Code, Season Code, and Guest No., the Room is the only process that is mandatory and can be assigned as the owner of the process. Rather than implementing the price calculation as a member of the price table, we will implement this as a member of the Room. From a functional perspective, the reason is that we know the room and want to know the price, and not the other way around.

The following code is the function on the Room table. It can be called with the optional members—Season Code and Customer No.-and calls into a method Codeunit with these parameters:

GetPrice(SeasonCode : Code[10];CustomerNo : Code[20]) : Decimal
EXIT(RoomCalculatePrice.GetRoomPrice(Rec, SeasonCode, CustomerNo));

Each table that requires the calculation of a Room price has its own function that attempts to read the room from the database, and then calls into the GetPrice function:

GetRoomPrice()
WITH Room DO BEGIN
  IF NOT GET("Room Code") THEN
    EXIT;
  Price := GetPrice("Season Code", "Customer No.");
END;

The Codeunit first does the calculation, based on the most detailed price. The following code is the implementation of the Rules table. Alternatively, we can also find the best or lowest price, as it is implemented in Sales pricing in Microsoft Dynamics NAV:

GetRoomPrice(Room : Record "Bed and Breakfast Room";SeasonCode : Code[10];CustomerNo : Code[20]) : Decimal
WITH BedandBreakfastPrice DO BEGIN
  IF GET(Room.Code, SeasonCode, CustomerNo) THEN
    EXIT(Price);

  IF GET(Room.Code, '', CustomerNo) THEN
    EXIT(Price);

  IF GET(Room.Code, SeasonCode) THEN
    EXIT(Price);

  IF GET(Room.Code) THEN
    EXIT(Price);
END;

Tip

When using compound keys in rules tables, the last values in the GET statement can be left blank. This allows flexibility for the key fields without breaking the code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset