Week 12 Internship : Enhance POS system workflow

During this week, I was assigned the task of improving the POS system workflow. The main objective was to reduce the number of clicks users need to perform while using the system. To achieve this, I spent time brainstorming and analyzing different scenarios to determine the best solution. Finally, I devised an optimized approach for the entire system. I added three buttons that appear dynamically based on specific situations. When creating an order for the first time, the system displays two buttons: “Checkout” and “Payment.” The “Checkout” button allows users to create an order without generating an invoice or making a payment, catering to users who do not wish to complete these actions immediately. The “Payment” button, however, performs different functions depending on the situation. If the order has not been created yet, clicking the “Payment” button will automatically create the order, generate an invoice, and navigate the user directly to the payment page. If the order has already been created, the “Payment” button generates the invoice and navigates to the payment page, providing a quick and seamless checkout process.

After an order has been created, the system accommodates two possible scenarios. If the order has been created but the invoice has not yet been generated, the system displays the “Payment” button along with a “Create Invoice” button. When the user clicks the “Create Invoice” button, they are taken to the invoice preview page, where they can review the invoice, generate a PDF, and complete the invoice creation process. If the invoice has already been created, a “View Invoice” button is displayed instead. Clicking this button automatically generates a temporary PDF for the user to preview the invoice. The “Payment” button remains visible at all times, whether the order has been paid or not, to allow users to review payments at any time in the future. After a payment is completed, I configured the system to reset to the new order page and clear all parameter data. This ensures a smoother, more efficient workflow for the POS system.

Week 11 Internship : Find solutions for listen to print button and Create Default page

Solution for listen button in print preview

This week, my main task was finding a solution to listen for the print preview button. I was working on calling the print count async function when the user clicks the print button. However, this button appears in the print preview, which is a default browser feature. Due to privacy and security restrictions, we cannot access or listen to the button in the print preview. Before arriving at this conclusion, I explored numerous components and libraries to meet the requirements. However, after several days of research, I found that this approach is not feasible with JavaScript.

Create Default page

In addition to that, I worked on creating a retail default page. This page includes default data such as customer, tax, delivery method, etc., which are required for form completion. However, since some customers prefer not to provide their information, these default values can be automatically filled in when the required fields are null or left blank. I also implemented functionality to save this data into local storage. This task took me two days, as I was unfamiliar with saving data to local storage and had to conduct some research. Eventually, I succeeded in saving data to local storage, retrieving it on another page, and using it seamlessly.

Fix Bugs

During the remaining time, I focused on fixing bugs listed on the progress tracker. First, I adjusted the size of the select box in the order create/edit view to make it larger and more user-friendly. Additionally, I worked on adding a confirmation dialog to the return reason line item selection. This feature prevents users from accidentally unchecking a box by displaying a confirmation prompt. Implementing this task took considerable time as I had to figure out how to listen for the event and trigger the dialog when the user attempts to unselect a checkbox. After multiple attempts, I finally managed to make it work smoothly.

Week 10 Internship : Solve Signal R Function & Synchronization Pages

Solve Signal R function

In the first three days, I worked on connecting SignalR to receive the progress count from the item API. Since connecting to SignalR was new to me, I initially faced several challenges. First, I struggled with determining the correct URL to send to SignalR for establishing the connection. Despite trying various URLs, I couldn’t connect successfully. Finally, I sought help from Mr. Peter, who provided me with the correct URL. However, even after using the correct URL, SignalR still showed an unsuccessful connection.

After debugging, researching, and consulting ChatGPT, I discovered the second issue: the HTTP transport type needed to be explicitly initialized. By default, SignalR uses WebSocket as the transport type, which didn’t work for this connection. Switching to long polling as the transport type resolved this issue, and the connection was established. However, a third problem soon arose.

While fetching the sync progress, I noticed it always got stuck at 120/240 and stopped. After reviewing the log reports, Mr. Peter explained that the syncing process needed to be completed before fetching all item data. Some items were stored and appeared in the database, while others located in stores did not appear in the MongoDB database. This mismatch caused errors. By creating a sync function, I was able to synchronize the items successfully and fetch progress without issues.

Next, I developed a function to cancel the sync progress. This function stops the sync process for an item that hasn’t finished syncing by calling the stop API and passing the GUID, which halts the sync automatically. However, I encountered another issue: the cancel button didn’t work as expected. Initially, I suspected the API, but debugging revealed that the function was rendered twice, causing the cancel function to be invoked twice. As a result, pressing cancel stopped one progress instance, but the other continued syncing. This behavior was due to the Next.js configuration, which caused the useEffect hook to render twice. After adjusting the Next.js configuration, all SignalR-related functions and sync item processes were finalized successfully.

Week 9 Internship: Try on invoice PDF template and syncing users & items data

Generate 1 million data

On the first day, I tried to generate 1 million data records for each page on the system. Since this process would take several hours, I asked my colleagues to help by generating the data on their computers and accessing my IP address. After generating all the datasets, I performed some performance testing on API queries for item or user details and created new data after reaching 1,000,000 records. By the end of the tests, all functionalities worked smoothly, ensuring the system could remain operational for many years.

Generate invoice pdf template

While the data was being generated, I researched how to build a PDF template for invoices using HTML and JavaScript. I explored several components like html2pdf, react-pdf-html, and others, but none of them worked for my needs. Some required API calls to generate the PDFs, which would incur extra costs, and others weren’t compatible with Next.js. Eventually, I found a component called PDFMake that met all my requirements. It allowed me to customize the template, and once the PDF was generated, it provided a temporary URL. This feature is very useful when generating large numbers of PDFs, as it prevents storage overload by not saving them to local files. I also added an iframe component to preview the PDF and a print function, which allowed users to print the document without navigating to another tab. However, while coding according to Mr. Peter’s template, I ran into an issue: the component couldn’t import images or draw outlines for certain information. Mr. Peter then advised me to stop working on this task, as he had found a better solution for generating the PDFs.

Syncing users and items data

After completing the previous task, I was assigned a new one: syncing data from MongoDB. My first task was to sync the user data. I called the sync API, which synchronized the data from the retail system with the Mongo database, integrating data from different systems. I then tried to separate the data views: one for the retail system only and one for all users, including those from the other system. However, I discovered that I couldn’t view the details for the “All Users” page. I may need to create a separate API to search for specific data details. Afterward, I worked on syncing item data. Mr. Peter asked me to use the SignalR component to track the progress of the data syncing. This was because when calling the sync API function, there was no way to monitor its progress. By using SignalR, we could connect to the API and receive a progress count, which we could then display as a progress bar.

Week 8 Internship: Fixing Whole System Bugs and Create Voucher Page

Fixing Whole System Bugs

Since Mr. Peter has reviewed my entire system, he pointed out some small bugs that could be enhanced to make it smoother. There were over 20 tasks, and it took me two days to complete. These tasks included fixing some input bugs, such as ensuring the page auto-focuses when navigating or when selecting items, as well as allowing decimal inputs for stock management.

In addition, I improved the workflow for stock adjustments. Now, when a user enters a wrong barcode, the system resets all states and refocuses the textbox. I also added a confirmation dialog to the payment edit section to ensure users do not accidentally click the button. Furthermore, I implemented some hotkeys: the Escape key now closes open dialogs, and the Enter key skips the need to press the submit button.

Create Voucher Page

After fixing all the bugs, the system now runs more smoothly than before. I then continued working on the voucher page. The voucher page is easier to create because it only requires three data fields to be uploaded to the API. However, one important thing to watch out for is ensuring that the “last valid date” is not earlier than the creation date. If it is, the API will return an error. To prevent this, I added validation to the “last valid date” to ensure the voucher can be created successfully.

Research On How to Create 1,000,000 Records

After finished the voucher page, the whole system are almost done , but since others backend technologies are still haven’t done yet, so that Mr.Peter asked me to do some research on generating 1,000,000 records data and see how the system performance going on if data fully loaded. It modifies that if this system are being used for several years and look whether the system still can run smoothly. After two days of researching , I have founded a platform name cypress, it is a web testing tools, but it’s more on UI testing. After trying to create a test plan , it can create records smoothly. Unfortunately, Mr.Peter does not accept this type of solution, because it would not work when the UI position are being changed. After that I was trying to create another UI page to generate the data, how I do is just hardcode the data structure and run it in a loop according to the count what user want. But this would make several hours to generate 1,000,000 records.

Week 7: Create Return Order Page

Fix Line Item Problem

This Monday, I found an issue with the line item functionality while creating an order. Regardless of the item I ordered, it always showed item 1’s line item. After debugging, I discovered that the item ID was hardcoded to 1 while uploading the line items. I resolved this issue and implemented a new function to handle the selected line item and upload it to the API.

Return Order page

Next, I continued work on the return order page. Most of my time was spent on the “Edit Return Order Details” view. I was figuring out how to display the line items correctly, as the detail view included both selected and non-selected line items. I tried to combine these two elements, showing selected items with a ticked checkbox and non-selected items with an unticked checkbox. However, my attempts faced issues, such as duplicate entries or incorrectly unticked selected items. This problem took me 1-2 days to resolve. Eventually, I found a solution by printing all the line items from the invoice, comparing them with the return order DTO, and ticking the items that matched. This method helped me better understand how to handle line item data while updating an existing return order.

At the same time, I faced another challenge regarding the return order line item ID and the invoice line item ID. Initially, I didn’t understand the difference and used the return order line item ID as both IDs while updating the return order. This caused issues where incorrect items were displayed after uploading or the upload failed entirely. After completing the line item display functionality, I finally understood how the IDs work. Differentiating between the two IDs was difficult because the line item ID to upload depends on various scenarios. Users might select new line items, modify existing ones, or perform both actions simultaneously. Implementing this logic took me 2-3 days, but I eventually succeeded in fully updating all the required data.

After completing the main part of the return order, I enhanced the search bar in the list view. I noticed the “Get Query” function allowed three types of search data, so I added a dropdown menu to let users select their search type, such as by name, and IDs.

Conclusion

In conclusion . this week, I resolved significant issues with line item handling, improved my understanding of line item ID logic, and enhanced the return order page and search functionality.

Week 6 Internship : Enhancing Data Handling and Create Return Order Page

Optimizing user interface details

In the first three days, Mr. Peter assigned me tasks to optimize user interface details and enhance data handling processes. Firstly, I tried to add a function for validating data to ensure that the main data uploaded is not null. I also added a UI/UX feature that allows users to remove or add images in the payment edit view. After that, I worked on rebuilding the latest API to include a barcode for the store and integrating it into the code. Furthermore, I modified the subtotal printing logic to display 0 instead of NaN when the unit price is null. Additionally, I updated the payment statement to allow users to separate bills.

On the payment page, I enhanced the search bar functionality, enabling users to choose a search type, such as customer name, and various IDs. Besides that, I added hotkey and focus-handling features, allowing users to press the arrow key to select a customer in the POS page. Later on, I modified the network handling functionality to show an alert only when the user tries to call an API. For this, I added a function in the retail API service file to check whether the network is connected.

Thereafter, I redesigned the table alignment in the POS system to improve the layout for better clarity. However, I noticed that when zooming in on the page, the table header would stack with the table itself. I plan to find a better way to resolve this issue and enhance the design further.

Create Return Order Page

After completing these tasks, Mr. Peter assigned me to work on the return order page. This task was quite challenging because it involved multiple APIs. Firstly, I designed the UI page and drew a workflow for it. After that, I added an invoice search dialog as a component and imported it into the return order page. This dialog allows users to click the “Create” button to display a search interface listing all paid invoices that have not been canceled. Once an invoice is selected, all its line items are displayed. The most difficult part was enabling users to select specific items and input the quantity to return, which took me the entire Friday to solve and refine the workflow.

There are still more tasks to complete on this page, such as setting authorization for different user types. For instance, administrators can accept or reject return requests. Different users may have varying privileges to access this page based on their roles.

Conclusion

This week has been a productive and challenging experience, as I worked on enhancing various features and tackling complex tasks, particularly the return order workflow. These assignments helped me develop problem-solving skills and improve my technical abilities, especially in handling APIs and refining the UI/UX.

Internship Week 5: Enhance Order Page UI and Create Tax Dropdown

In this week, Mr. Peter gave me a task to work on enhancing the order page. Since this page is related to many files and functions, it took me four days to complete. Firstly, I created a tax dropdown to let the user choose different types of tax rates for each item. After that, I combined it with the order page line items and tried to fix the bug that did not show the tax dynamically after selecting the desired tax rate. Additionally, I redesigned the entire order page UI and set a user default store to ensure users have a great experience using it.

Secondly, I redesigned the payment UI by adjusting the spacing between payment types and other CSS styles. I also fixed the bug that allowed users to click on full payment an unlimited number of times. I set it so that users can only click once when the pop-up window is first shown or when the amount is cleared. Afterward, I worked on fixing bugs related to payment types. For non-cash payment types, I enhanced the conditional statements to validate data integrity and correctness, ensuring that a reference number and image are required. After these fixes, users can make payments and complete orders more smoothly.

Lastly, since Mr. Peter mentioned that my solution for fixing the cookie session was incomplete, I continued to work on this problem. I had only implemented checking whether the token was still valid, but not addressing expired cookie sessions or handling network disconnections. I set a timer for 30 minutes for the cookie session, so when it expires, users are forced to log out and log in again. Since the cookie session was not being triggered when users logged in, I added a reload function to the login page to ensure that the cookie session starts after the page refreshes. For network status detection, I referred to a blog that explained real-time network detection. I set up a general alert that displays “connection lost” with a retry button until the connection is restored, preventing users from losing unsaved data. Additionally, I added a network status indicator next to the username to show if the network is connected.

In conclusion, this week, I learned many new things, such as how to change all data dynamically when part of the data changes, and how to detect network status and handle cookie session timing.

Week 4 Internship : Fix Bugs and Create Stock Adjustment Page

This week, I worked on resolving bugs related to multiple alerts occurring at the same time and stacking together. I found a new component to replace the original SweetAlert2 which is the 1st generation of it , and after replacing it, the new component successfully handled errors when multiple alerts occurred simultaneously. I also solved the issue where users could still perform actions on a page after manually deleting cookies without refreshing the page. I added an interval to monitor the cookie status every 0.1 seconds. This way, if a user manually deletes cookies or if they expire, the cookie check function can detect it as quickly as possible, force the user to navigate to the login page, and prompt them to log in again.

On another day, Mr. Peter asked me to create a stock adjustment feature that would allow users to adjust the stock they want. The first UI design I presented was rejected, so I created a new UI that focused more on usability. The most complicated part was calling multiple APIs to collect data, which I then had to combine into a command that would call another API to upload the stock data. It was quite challenging for me, but after 2-3 days of effort, I successfully solved the logic and it now runs smoothly, uploading data without issues.

After that, Mr. Peter asked me to write unit tests for the stock adjustment page. If I’m still not familiar with it, I can try to enhance the order page instead. I found that the order page had many bugs, such as the last person calling the update function after clicking the create button, and issues with the delivery method that prevented orders from being created. So, next week, I will focus on fixing these issues to improve the smoothness of the POS system during order creation.

Week 3 Internship: Creating New Page on POS System and Fixing Alert Duplicate Bugs

In the third week of the internship, Mr. Peter gave me a task to create a new page, which is the Return page. It’s all about uploading the reasons that customers return the products. We also had to add some functions, including delete, make changes, and search filtering. In the beginning, all the workflows I was working on were still good, all the API fetching could refer to other pages until I faced the searching and filtering problem. This was because the APIs provided by other pages allowed developers to call and search by query, but the Return Reason API did not have the searching function. I tried to solve this problem by myself, attempting to fetch data without sending a query to the API and instead searching and filtering locally so that it would not be influenced by network lag or latency.

After finishing this page, Mr. Peter asked me to find bugs related to what would happen if users deleted cookies manually and if the network was disconnected. Through these behaviors, I found that while deleting cookies manually, users could still edit data without logging in until the page refreshed. Additionally, after the network was disconnected, the website would pop up with a message saying “reading data null” as usual. Then, Mr. Peter asked me to do unit testing on the page I had just finished, but it seemed like there was something wrong with the Jest configuration. I’m still trying to solve it to ensure the tests can run successfully. Externally, I found that every time a user wanted to delete some data on the page, the website would pop up a confirmation dialog box, but after clicking confirm, the second alert that shows “data deleted successfully” would not appear. So, Mr. Peter asked me to find another alert component to replace the original to fix this problem.

In conclusion, this week was quite busier than the previous week because of solving a lot of bugs and creating new pages. I learned a lot from the experience of fetching real data from the API and working with it.