Second week in Tong Hin!

I was given my first task in Tong Hin and assigned to convert a WPF project to prism MVVM View Model and do some unit tests . As usual , I will note down the things I’ve done my second week .

For my second week , I started to work on the UI of my given task . I have completed most of the UI but without data bindings . I also fixed some minor problem such as connecting the config path to the database, created different checkbox buttons in my project .

Also , I finally did my first unit test (with the help of my supervisor) and learned some things about wrappers . I also managed to complete most of the “Prism MVVM View Model” tutorial and EF core tutorial .

Next , I learned a new delegate such as Func in c# , Func is a delegate that points to a method that accepts one or more arguments and returns a value .

That is all for this week . Will be ready for more challenges , so for next week , my goal is to will try to load the data from database to the data-grid in my UI in the project and tryout more unit testing .

Integration and checking of errors

For the past week I have worked on integration tests as well as checking the creation of modules for errors.

The checking involved checking whether a Tax, Supplier, PurchaseOrder, GoodsReceived and PurchaseInvoice can be created successfully without any errors, as well as checking the content inserted into the views.

When using tab navigation, the tests created will not be able to mock the NavigationContext, which will always lead the test being run to use the default value instead of navigating to the wanted and requested view of PurchaseInvoice, either from PurchaseOrder or GoodsReceived. Hence, to solve this problem another method is creating which includes parameters that carry the designated values, which will then be called from the method which includes the NavigationContext.

Next, when adding LineItems using the Add button in PurchaseInvoice from GoodsReceived, only 1 line item is updated and the errors lied because I did not map the LineItemId.

Lastly, I started working on displaying a dialogue box when a PurchaseInvoice already exists. The test has been created with the help of my supervisor.

See you all on my last blog Next week 🙂

Navigation Concept and More of Errors Solving

Since I have completed the PurchaseInvoice module, I needed to fix errors that are present and check the codes again.

Firstly, I started by checking the property isAllPurchaseInvoiceReceived, by checking from the UI to see if the property gets flagged when all invoices are received, and hence after checking, I had to change the logical property of quantity to ensure that if a quantity more than ordered is received the property, then it will not be flagged or be true in its boolean expression.

Next, another error which was found is that when a user creates a GoodsReceive and PurchaseInvoice from PurchaseOrder, the GoodsReceive can afterwards be used when creating a PurchaseInvoice from GoodsReceive, which will result in having an Invoice with the same quantity number received but different cost which is a conflict. To solve the error, the relationship between GoodsReceive and PurchaseInvoice was adjusted by using the EF Core concept of relationships One-to-One by defining the relationship in the config file.

I have also pulled codes from Git and adjusted few parts, that resulted in the project to be using tabs navigation concept instead of dialogues. Such that a user, can have multiple tabs opened at the same time and each is independent on the other. At the same time, this current navigation is more user friendly.

WPF allows the concept of using a ViewModel without getting access to its View. In other words, it loads the codes and knowledge from a ViewModel without taking the view into consideration.

Another information I learnt from GitHub was when pulling if we are not present in the designated branch then we won’t be able to see the changes that have been to the codes. As pulling without being in the branch does not grant us access to the changes made.

See you all next week 🙂

Fixing errors and bugs in the project module

Since I have completed the purchase invoice from both purchase order and goods received, I spent the week checking the codes, and finding bugs to be solved to ensure that the module runs as intended without any problems.

I also had problems with the quantity mapping, as the total quantity being mapped in purchase invoice from purchase order is not the same as the total quantity from purchase invoice from goods received line item. The error was because I was initially reading the quantity from purchase invoice line item and goods receive line item instead of reading from the same entity which is goods receive line item. Due to this, different total quantity was being displayed in the UI.

Next, I wrote integration tests for purchase invoice from purchase order and goods received. The tests included creating new purchase invoices, and loading the list of purchase invoices, as well as viewing the individual purchase invoices.

When writing tests, mocks are being used. Mock uses the concept of testing a unit of code which depends on a group of other codes, such that the code will be tested even though its dependent codes are not written or contain bugs. In this case, mocks act as a platform which provides the test with its all needed requirements and environment to ensure that it works and pass as intended.

I also learnt how to resolve issues in Git. Meaning that once an issue is assigned to a person, and it is solved, to resolve the issue on Git, comments such as Fix, Close and Resolve are written alongside to the issue number created, as well as the codes need to be pushed so the changes can be viewed and tracked.

See you all next week 🙂

Working more on the project structure

Continuing fixing errors from the pull and merging of codes, a lot of changes have been made to ensure that the codes compile and align with the new project structure.

The tests that have been written previously for Purchase Order and Goods Received were in need of changing and fixing, as the code structure have changed, the tests also got affected, as a result, the test bases were in need to be checked and fixed, because when debugging the tests to see where the error lies, the debugger does not run through the test, meaning it does not go into the test method environment indicating that the error lies in the test base.

Another thing is the save changes during initialization. Save changes is set to true without using the newly added save changes which is equipped with audit, because we are just initialization and setting the environment, thus, we do not need to audit or check and keep track to see who has made changes to the codes.
When writing tests, the Linq property Single() cannot be used for entities that are equipped with more than one element, as in this case we are trying to assume that entity has only one value which is not true. Thus First() is used when we want to retrieve one element only.

After the fixing and refactoring of codes, the views of the purchase invoice module were not being displayed, due to 2 main reasons which were that the Region Manager for purchase invoice was not added, as well as I mistakenly created a new view and removed the prism:ViewModelLocator.AutoWireViewModel="True" which resulted in the pages not being attached to each other and hence cannot be redirected once requested.

In the view models, often the properties are assigned with two access modifiers. Properties with private access modifiers when used do not make any changes to the User interface, on the other hand, properties with public as their access modifiers when changed or used will make changes on the user interface.

These are the major things that have been learnt the past week. See you all next week 🙂

New changes added to the project structure

The week started by completing the conversion of parameters files into events by using the enum class.

Next, I created multiple tests for the my transaction function, which creates a new purchase invoice based on different services.

Unfortunately, I had an error with the previously created tested for my transaction function, as the SupplierId could not get updated, it was null, but I couldn’t find the way to solve it, only to realize later on with the help of my supervisor, that I did not initialize the SupplierId in the tests, because I thought by just initializing and getting access to the whole entity, it will automatically assign the SupplierId, which was obviously wrong and made the tests created fail.

I then started analyzing the aggregates in the project, and found myself not understanding the concept behind the many-to-many relationship between some entities in the project. With further discussion, the relationship was converted from many-to-many to one-to-many relationship, and due to this many changes were needed to made.

Among the changes done to the files, were to change the complete function in the transaction for the purpose of auditing. As well as, EventName, Time and UserId has been added to the service functions, for auditing purposes as well, such that the when changes have been made, the person who made the change, along with the time and the change made can be tracked. Thus, by making these changes new parameters have been added to the methods.

Previously, the services and repositories interface used to implement the IDisposable interface, but now a new interface has been created that implements the complete, commit and rollback functions, not forgetting that this new interface implements the IDisposable interface as well.

Lastly, an important thing I learnt from Git, is that Pull merges two coding files together, in other words, it adds the changes that have been in both files and merges them into one. Push, on the other hand, add the branch into the project but does not merge it.

That’s all, see you all next week 🙂

Implementation of new functions and classes

This week is also about UI.

I created a new button to separate the purchaseInvoice different options. One which focuses on purchaseInvoice from purchaseOrder and another from GoodsReceived.

purchaseInvoice from purchaseOrder creation is created completely in other words creating a new purchaseInvoice and GoodsReceived. However, when updating the tests created previously, the tests failed due to the supplier entity and supplierId being 0.

At first, I couldn’t understand the reason why it is zero, but with the help of my supervisor, I found out that my mistake was that I did not include the supplierId and entity nor did I map it to the purchaseInvoice.

I also created an integration test for purchase invoice from purchase order. This test is more into testing the UI of the system. Checking whether when the intended button are clicked they perform and function as required.

I was also exposed to adding relationships in the database. I mean, when I set relationships in the entities file, some relationship will get ignored or confused by the entity framework if not fixed and identified properly in the Config files. Such that relationships such as one-to-many and many-to-many need to be written in the config files, along with their foreign keys, to ensure that the relationship is properly understood by the framework.

The main purpose behind using the Linq properties Include and ThenInclude is to ensure that the wanted properties to be retrieved are not null.

Lastly, I have refactored the codes in my module, such that all event functions are placed in the Events folder instead of Parameters folder.

When using the functions in the Events folder, I was introduced to using the enum, which is a special class that groups a group of related variables together. These, variables can be separated by a comma as follows:

public enum Level () { Low, Medium, High, }

The items in enum can be later on used or retrieved by using dot operation to get access to the enum class then the item.

More into coding

Last week was a merge of creating tests and starting UI codes.

After so long, I was done with writing tests. I had a better understanding of how tests work, and refactoring codes as well. Moreover, I was exposed to not writing hard coded codes.

After 7 weeks, I can say that I have learnt a lot about TDD and EF Core, which is something I was not exposed to during my studies and this is something that would definitely benefit me.

Collection and Lists might sound the same, but collections are preferred over lists due to their ability to group outputs. In other words, List does not provide the feature of grouping.

For the past 3 years, I had the idea that the difference between void and static functions was related to having returns.

Little did I know that the static functions and variables are like global variables that can be used across the files, and when a method is static all its members should occupy the word “static” as well.

I have also read about bindable base which is an implementation of INotifyPropertyChanged interface in C#.

Variables Value Change According to “Ready To Pick”

In my implementation, Ready To Pick works as a signaling mechanism to let other module know when they could access the sub data in current module. As I working with Ready To Pick function previously, there is new implementation to add on upon clicks on Ready To Pick button.

First of all, in order to press “Ready To Pick” or “Undo Ready To Pick”, we will select a data/item set for example. In this item set, there is multiple list of item will it’s own attributes. Given availableItem and standbyItem as item’s attributes, new implementation is to alter value of attributes by incrementing or decrementing the value upon status of isReadyToPick (bool). Implementation must alter all the value for each item available in item set adding/subtracting itemQuantity.

i) Clicking “Ready To Pick” button when isReadyToPick = false, would change it to true and alter attributes value such as below:
foreach (item in itemSet)
{
item.availableItem -= item.itemQuantity;
item.standbyItem += item.itemQuantity;
}


ii) Clicking “Ready To Pick” button when isReadyToPick = true, would change it to false and alter attributes value such as below:
foreach (item in itemSet)
{
item.availableItem += item.itemQuantity;
item.standbyItem -= item.itemQuantity;
}

To avoid infinite increment or decrement, implementation is done in a transaction, to make sure the logic rollback if there is error. By using transaction, all value changes for isReadyToPick(bool), availableItem(int), standbyItem(int), itemQuantity(int) will be reverted upon any update failure.

Few tests is done to assert value change of availableItem(int), standbyItem (int). Tests assertion pass after “Ready To Pick” button is triggered, the value of attributes add or subtract value of itemQuantity.

After the implementation done, I shall continue implementation logic for situation when item.availableItem -= item.itemQuantity appears to be negative value.

Disable Controls and Make Controls Read Only To Prevent Updating Altered Data in View Mode

To begin the week, I will be fixing bug in Service class by refactor small changes on implementation. My objective is changing Read() to Get() on certain variable in update method. As this variable only has existing Read function, I then added Collection<Variables> GetVariables in Repository class. Hence, I change ReadVariables() to GetVariables() for update/edit/delete and any function that will make changes on the value of this variable.

In the progress, we bump into an issue, where we still able to input despite in detail view mode. This is a serious bug, as any changes would be updated/saved when ReadyToPick is triggered. Thus, we came up with a idea after discussing the issue. I need to set all input/controls to IsReadOnly and disable them. In order to do that, I need to alter code in DetailView XAML class and add new properties in DetailViewModel class.

As an alternative, I add IsEnabled = "{Binding IsControlEnabled}" and IsReadOnly= "{Binding IsControlReadOnly}" for relevant controls. While in DetailViewModel, I introduced two properties which is IsControlEnabled with default value true and IsControlReadOnly with default value false. I then perform logic of IsControlEnabled = false and IsControlReadOnly = true under view mode, making user unable to make changes on all controls.

However, there is a grid data textbox, buttons and combo box that is not set to disable & read only simply by using above method. It happens that I need to link it to ancestor of data grid such as below:
i) IsEnabled="{Binding DataContext.IsControlEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
ii) IsReadOnly="{Binding DataContext.IsControlReadOnly, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"


After code is altered, system user could use ReadyToPick without able to edit them in view mode. (In edit mode, user able to make changes but ReadyToPick button is disable). Hence, the bug fixed.