Inventory System

A comprehensive inventory management system supporting dark/light modes and English/Chinese locales. Built with Vite and Vue3 on the frontend using Ant Design and Tabulator-table, and Python Django REST framework with MySQL and Django ORM on the backend. Ensures database transactions adhere to ACID properties.

Features

  • Dark / Light Mode: Users can toggle between dark and light themes for better user experience.
  • English / Chinese Locales: Supports multiple languages, including English and Traditional Chinese.
  • Inventory Summary Charts and Tables: Visual and tabular summaries of inventory data.
  • Stock In / Out / Transfer / Write-off Actions: Manage stock movements efficiently.
  • Stock Inventory Table with History Reading Support: Track inventory changes over time.
  • Excel Import with Django Bulk Import: Fast bulk data upload using Django's bulk import capabilities.
  • Product Table with Multi-Image Support: Manage products with multiple images.
  • Detailed Tables (Location, Category, Material, Color, etc.): Organize inventory with additional details.
  • Stock Take Page and Stock Adjustment: Perform stock counts and adjust inventory accordingly.
  • System Settings: Includes user account management, permission settings, and system logs.
  • Label Printing Support: Integrates with third-party tools like QZ-Tray to print labels directly from the web interface using ZPL.

Technology

  • Frontend: Vite, Vue3, Ant Design, Tabulator-table
  • Backend: Python Django REST Framework, MySQL, Django ORM
  • Database: MySQL with Django ORM ensuring ACID compliance
  • Label Printing: QZ-Tray for direct ZPL label printing

Development Insights

  • i18n Translation Linking on Database: Updating i18n translations in JSON files can be time-consuming. After making changes, you need to rebuild the project and upload the new output to the server. Without GitHub Actions, this process takes even more time. To improve efficiency, I modified the code to store the translation data in the database. The backend now handles and returns the translations in JSON format. This allows translations to be updated easily via APIs, and a simple webpage refresh retrieves the latest translated words. This approach is much easier for both developers and clients, as they can modify the translations themselves without complex steps.
class LocaleRegion(models.Model):
    name = models.CharField(max_length=255)
    # HK,ZH,EN
    code = models.CharField(max_length=255)
    value = models.IntegerField()

    class Meta:
        db_table = "system_locale_region"


class LocaleData(models.Model):
    key_word = models.CharField(max_length=254, unique=True)
    value1 = models.CharField(max_length=255)
    value2 = models.CharField(max_length=255)

    class Meta:
        db_table = "system_locale_data"
# /api/v1/locales/?lang=en
class LocalesProcessor(generics.GenericAPIView):
    def get(self, request):
        getLanguageCode = request.GET.get("lang", None)

        locales = {}
        languageModel = LocaleRegion.objects.get(code="en-US")
        # Check if request language code exist in Locales
        if LocaleRegion.objects.filter(code=getLanguageCode).exists():
            # Get the language code
            languageModel = LocaleRegion.objects.get(code=getLanguageCode)

        # Get all the LocalesWords
        for o in LocaleData.objects.all():
            # Get the language code
            keyName = "value" + str(languageModel.value)
            locales[o.key_word] = getattr(o, keyName)

        return Response(data={"details": locales})
  • Excel Import Optimization: Initially used pandas to loop through Excel data, which was slow due to serializer validations. Optimized by using Django ORM's bulk upload, processing all Excel data in one loop, extracting features into a set, updating them first, and matching by ID back to main data, significantly improving data processing speed.

    • Improved efficiency by minimizing serializer checks and leveraging bulk operations.
  • Stock Out Page Performance: Using Ant Design forms caused high RAM usage on low-spec mobile scanners, leading to page freezes. Learned that looped components should use simple elements instead of heavy UI framework components to reduce overhead. Implemented a TypeScript check to render simple HTML elements on mobile screens and Ant Design rich pages on larger screens. This experience led to exploring lighter UI frameworks like TailwindCSS.

    • Enhanced performance on mobile devices by reducing component complexity.