Last Week at Tong Hin

For this week, I was able to implement the logic of regenerating original quantities of previous ItemHistory that were currently not computed and stored 0 as an original quantity.

Started off by using DbContext in ViewModel to get all list of histories then proceeded to use a foreach loop, where each row of history was subjected to a function that computed its original quantities, eventually saved the updated history to database using SaveAsync().

Once the logic was coded, it was time to test it. Added a test-case for previous histories original values calculation, as it was 0 previously. Faced issue with DateTime, as I was using DateTime.now(), so using OrderBy() didn’t actually ordered the rows. As this feature is considered a service of ItemHistory, it became clear that there needed to be a separate file to test it, so a HistoryServiceTest was formed.

Next, Mr.Peter decided to put the code to the test, and we discovered a bug in the algorithm that caused a source history to go unnoticed. Mr.Peter made me fix the code and showed me a better way to test. Moreover, another bug was discovered that allowed previous non-computed rows of history to take their value in current history, so the condition was changed to skip non-computed rows. Once all bugs were fixed the logic looked promising.

Finally, began Code review with Mr.Peter. Discussed on one more condition to use item status while calculating original values of ItemHistory. Added Status to History and added a test-case to check if the correct StatusId was being assigned on creation of ItemHistory.

This marked the end of my 3-month internship with Tong Hin.

Previous Histories Original Quantities Calculations

For this week, I was able to implement the logic of calculating the original quantities for history and proceeded to implement logic for previous histories quantities calculation.

Started off by running an SQL script to include additional columns. Updated the overridden AddAsync method to populate the additional fields in a history according to business rule. Made use of edge cases to test the logic in the repository, some bugs were discovered that prevented the detection of previous locations for both the source and the destination, and fixed it.

Moreover, I was struggling to understand how to test the repository’s create logic because I was currently using the UI to test the logic, which is not a good method. Mr. Peter was able to clarify this for me. Created HistoryRespositoryTests and added testcases to test the repository logic through various conditions and edge cases. Furthermore, discussed the importance of populating existing history data quantities.

Lastly, I realized I had hardcoded the disable property in barcode, so I converted it to a boolean property and binded it to the IsEnabled property. Moved onto a new task to populate previous history quantities. Added a button to the UI which on interaction will retrieve all histories and populate their original quantities. I was able to successfully retrieve all histories from the database and display them in the UI.

Development on Original Quantities of History

For this week, I was working on the feature to compute the existing and final quantities of history.

Started off by coding an algorithm to compute these values, the aim was to design an algorithm with minimal computational complexity. Since in my last meeting with Mr. Peter, I was informed that any changes in database would only be made when all other ways of performing this task return unsuccessful. Therefore, I was left with no other option than to store the data locally. The idea was to store the final quantity of a history quantity which would be the existing quantity of the following history for the same item.

Created a static class to hold global variables, stored final and initial quantity in a global variable to prevent data being lost on a new API call. Eventually, I was able to design an algorithm which correctly computes each quantity; However, storing data locally meant that the data will be lost when the App restarts. After considering these facts and also the computational cost Mr. Peter instructed me to change my approach and use a database for storing quantities.

To store the values in the database, I added four new fields to the entity. I override the create method for history entity so that it now populates the new fields based on the logic. Finally, I ran a stock adjustment test to see if the new fields were being filled in.

Further development on History View

For this week, I was able to implement some new features and fix bugs in the History View. Started by separating the View and ViewModel from ItemView and ItemViewModel respectively. Successfully displaying it as a separate tab in ItemView.

Next, I made the barcode disabled, along with its checkbox, to prevent any changes from being made. Discovered that the application was making pointless calls to the API even when it was not being used, this issue was fixed. Moreover, I implemented another feature that gives users an option to view the item’s history in ascending or descending date format. To achieve this I had to make changes to both the API and UI, the UI now contains a checkbox which on checking/unchecking will make separate API calls to display data in different date order. Furthermore, I was able to provide users with the ability to alter the number of rows displayed per page.

Finally, I started brainstorming on a new task which involves comparing and computing old and new data for warehouses. I discovered that I needed to make a separate API call to get the final item quantity. I was able to make the API call in such a way that the entire data set loaded at the same time. Adding logic to determine existing item quantity still remains.

Creating General History View

For this week, I managed to complete the History View which now queries the API, based on the input, and presents the user with item’s history details.

Begun by defining properties for history tab then updated the data binding in the view, to establish a connection between the UI and the data it displays. Defined Wrapper, to map the queried result according to the relevant properties.

Next, started implementing Commands which are used to handle a user interaction or action. Finally, establishing  connection between UI and the API , through Refit, to make the application work. 

Lastly, made the View more robust by making the API result and item’s barcode appear (automatically), when the View loads. Furthermore, implemented logic to accept different Type in any case, basically making it case insensitive. 

Learning WPF fundamentals and Prism framework

For this week, I managed to finish up learning the fundamentals of WPF application and Prism framework which is a UI (user interface) framework used to create desktop applications. Furthermore, I designed the View of ItemMovement tab which now accepts the barcode, reference #, movement type and dates to filter item movement search.

One of the most important WPF application concepts is the MVVM model. This is a powerful concept as it allows to separate the program logic to the user interface. Moreover, data binding in WPF allows data to flow between UI elements and data objects on the user interface. Furthermore, the Prism framework implements a set of design patterns that aid in the creation of well-structured and maintainable XAML applications, this makes the WPF application easier to manage.

Lastly, I need to implement the logic for History so the query is successfully carried. I have updated the View to include more fields to enable advanced search options. Currently, I’m still trying to implement the ViewModel and Wrapper.

Further Development of Order API and Adding Feature to History

Begun by adding test cases for the new feature Status. Considered on the Entity Relation Diagram (ERD) for the Payment model of the system, sat with my supervisor to finalize the ERD of payment.

Next, I began with the coding aspect of the Payment model, defined entities Payment (which contains the details of that transaction) and PaymentType (having the various means of payment). Moreover, I defined their relation and researched upon many-to-many relation in Entity Framework as one order can have multiple payments and one payment can comprise multiple orders.

Lastly, I got a new task to create a History Query API and display History details on the UI for users to check on any general history. Completed the Query with successful testing and shifted my focus on the UI part. Went through some courses to understand Windows Presentation Foundation (WPF) which is a UI framework used at Tong Hin.

Making Order API Robust

Begun development on the new features including the barcode, ids, remark, and name fields. Upgraded the test cases to ensure that these fields are valid. Moreover, I began work on a new feature, which will include the addition of a selling price, discount, and with tax computation and test cases. introduced logic for calculating the subtotal amount after taxes, then moved on to creating the test case. Encountered a difficulty with relation due to the fact that one tax can have numerous line items.

Next. I fixed The issue in the relationship which was that the code misinterpreted it as a one to one relation. Once fixed, I tested out Create Command (since now, when a Order is created, the total amount is computed. Similarly, calculating logic was added to the Update Command and tested.

Lastly, built Status entity which has a one to many relation with Order and provided relevant fields. The aim of status is to inform the cashier about the progress of the order. Started considering the structure of Payment.

Further Improvement in Create and Update Commands Test Cases

I started off the week by adding more test cases for the Update command, observing the update logic in different scenarios. Found out there was a bug in the Update logic which was allowing the code to update the line items with Ids that were already taken before and also which did not yet exist. 

After some brainstorming I was finally able to fix the bug. I added a piece of code which acted as validation for Ids. It would throw an error if the LineItem Id that was provided was not present in that retail order.

Next, I got a new task to add a new field of Order No which was to be generated by a sequence generator. Purpose of adding this field was to give each order a distinguished identity, as we won’t be using their Ids as identification in actual business. Following this change I made changes to my Create command Handler so that now it creates a new sequence whenever an Order was created.

Now it was time to test my Create command which was modified with a new feature. I was able to successfully run 3 test cases, for the test cases I had to create a new Sequence Generator Id then pass it into the Create function which was then handled, by Create logic handler, and a OrderNo would be created. To test if my transaction which I added last week, I created a test case that would fail and observed if the transaction rolled back to the last savepoint.

Had a problem with validating the Sequence Generator Id as it was optional to input when there is no Id created, after discussing with my supervisor we came to the conclusion to not include a validation for the Sequence Generator.

Furthermore, I wrote test cases for Update command testing the Order No update and altered the DTO of Get query to output the Order No to the user.

Since a basic model of API was done, I was introduced to new tasks and features to make the API more robust.

Third Week of Internship at Tong Hin

I spend my third week mostly working on a complex command Update and fixing bugs in my code.

I started off the week by adding more test cases in the Repository test file, the purpose behind this was to test if my repository is correctly performing the CRUD operations. After this, I realized that I’m yet to write test cases for data which should have been done once the entities were created as these test cases help ensure the data type of each field is consistent.

Next, I shifted my focus to correctly format my API test cases, of Create and Delete, according to the norms of 3 A’s which are Arrange, Act and Assert. Moreover, I improved my test cases by adding more assertions. 

Finally, I started on coding the logic of the Update command which was challenging because Updating every field can have multiple possibilities.

After coding the logic I realized there was a bug which was occurring when an existing line item was removed and a completely new one was added. Once the bug in the UpdateHandler was fixed, I added the controller which handles the whole PUT request.

Lastly, I moved my focus on testing the Update Command. On running the test case gave me an error report ‘database operation expected to affect 1 row(s) but actually affected 0 row(s)’ error. After a lot of unsuccessful debugging I finally sought help from my supervisor who helped me find the bug and explain to me the root cause of it. This error was due to the primary key which I was hardcoding inside my update logic. We are not supposed to set the primary key as the database does it for us automatically.