1. Home
  2. গার্মেন্টস ইন্ডাস্ট্রির জ...
  3. ০ ২। Sampling & Merc...
  4. ডেটাবেজ ডিজাইন

ডেটাবেজ ডিজাইন

ঠিক আছে! আমি আপনার বর্ণিত Sampling & Merchandising মডিউলের জন্য sampling_merchandising Django অ্যাপ তৈরি করব, এবং এইবার সব মডেল, অ্যাডমিন ফাইল, এবং Unfold সাইডবার কোডে ইংরেজি ব্যবহার করব। তবে, বাংলায় ব্যাখ্যা এবং কমেন্ট দেব যেন আপনার বোঝা সহজ হয়। মডেলগুলো আপনার দেওয়া টেবিল (SampleRequest, SampleTracking, FabricDevelopment, TrimDevelopment, CostingSheet) এর উপর ভিত্তি করে তৈরি হবে এবং order_management অ্যাপের Order মডেলের সাথে সম্পর্কযুক্ত হবে। Unfold অ্যাডমিন সাইডবারে এই মডেলগুলো যুক্ত করা হবে, যা আপনার আগের সেটআপের সাথে সামঞ্জস্যপূর্ণ।


ধাপে ধাপে বাস্তবায়ন

১. নতুন Django অ্যাপ তৈরি

আপনার Django প্রোজেক্ট ডিরেক্টরিতে নিচের কমান্ড রান করে sampling_merchandising অ্যাপ তৈরি করুন:

python manage.py startapp sampling_merchandising

এটি sampling_merchandising নামে একটি ডিরেক্টরি তৈরি করবে।

২. Django মডেল তৈরি (ইংরেজিতে)

sampling_merchandising/models.py ফাইলে টেবিলগুলোর উপর ভিত্তি করে মডেল তৈরি করা হবে। মডেলের নাম, ফিল্ড, এবং মেটাডেটা ইংরেজিতে হবে।

from django.db import models
from order_management.models import Order  # Order মডেল ইম্পোর্ট

# SampleRequest মডেল
class SampleRequest(models.Model):
    SAMPLE_TYPE_CHOICES = (
        ('fit', 'Fit Sample'),
        ('size_set', 'Size Set Sample'),
        ('pre_production', 'Pre-Production Sample'),
    )
    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    )

    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    sample_type = models.CharField(max_length=50, choices=SAMPLE_TYPE_CHOICES)
    request_date = models.DateField()
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    approved_date = models.DateField(null=True, blank=True)
    remarks = models.TextField(blank=True)

    class Meta:
        verbose_name = "Sample Request"
        verbose_name_plural = "Sample Requests"

    def __str__(self):
        return f"{self.sample_type} ({self.order.style_number})"

# SampleTracking মডেল
class SampleTracking(models.Model):
    sample_request = models.ForeignKey(SampleRequest, on_delete=models.CASCADE)
    sent_date = models.DateField()
    courier_name = models.CharField(max_length=100)
    tracking_number = models.CharField(max_length=100)
    received_date = models.DateField(null=True, blank=True)

    class Meta:
        verbose_name = "Sample Tracking"
        verbose_name_plural = "Sample Trackings"

    def __str__(self):
        return f"{self.sample_request.sample_type} - {self.tracking_number}"

# FabricDevelopment মডেল
class FabricDevelopment(models.Model):
    STATUS_CHOICES = (
        ('in_process', 'In Process'),
        ('developed', 'Developed'),
        ('rejected', 'Rejected'),
    )

    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    fabric_type = models.CharField(max_length=100)
    gsm = models.PositiveIntegerField()
    color = models.CharField(max_length=50)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='in_process')
    supplier = models.CharField(max_length=100)
    remarks = models.TextField(blank=True)

    class Meta:
        verbose_name = "Fabric Development"
        verbose_name_plural = "Fabric Developments"

    def __str__(self):
        return f"{self.fabric_type} ({self.order.style_number})"

# TrimDevelopment মডেল
class TrimDevelopment(models.Model):
    STATUS_CHOICES = (
        ('in_process', 'In Process'),
        ('developed', 'Developed'),
        ('rejected', 'Rejected'),
    )

    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    trim_type = models.CharField(max_length=100)
    color = models.CharField(max_length=50)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='in_process')
    supplier = models.CharField(max_length=100)
    remarks = models.TextField(blank=True)

    class Meta:
        verbose_name = "Trim Development"
        verbose_name_plural = "Trim Developments"

    def __str__(self):
        return f"{self.trim_type} ({self.order.style_number})"

# CostingSheet মডেল
class CostingSheet(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    fabric_cost = models.DecimalField(max_digits=10, decimal_places=2)
    trim_cost = models.DecimalField(max_digits=10, decimal_places=2)
    wash_cost = models.DecimalField(max_digits=10, decimal_places=2)
    labor_cost = models.DecimalField(max_digits=10, decimal_places=2)
    overhead_cost = models.DecimalField(max_digits=10, decimal_places=2)
    total_cost = models.DecimalField(max_digits=10, decimal_places=2)
    approved = models.BooleanField(default=False)

    class Meta:
        verbose_name = "Costing Sheet"
        verbose_name_plural = "Costing Sheets"

    def __str__(self):
        return f"Costing Sheet ({self.order.style_number})"

ব্যাখ্যা:

  • মডেলের নাম এবং ফিল্ডগুলো ইংরেজিতে রাখা হয়েছে, যেমন SampleRequest, sample_type, status ইত্যাদি।
  • Order মডেলের সাথে ForeignKey সম্পর্ক তৈরি করা হয়েছে।
  • gettext_lazy ব্যবহার না করে সরাসরি ইংরেজি লেবেল ব্যবহার করা হয়েছে।

৩. অ্যাডমিনে মডেল রেজিস্টার (ইংরেজিতে)

sampling_merchandising/admin.py ফাইলে মডেলগুলো Unfold অ্যাডমিনে রেজিস্টার করা হবে। অ্যাডমিন কনফিগারেশনও ইংরেজিতে হবে।

from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import SampleRequest, SampleTracking, FabricDevelopment, TrimDevelopment, CostingSheet

# SampleRequest মডেল রেজিস্টার
@admin.register(SampleRequest)
class SampleRequestAdmin(ModelAdmin):
    list_display = ('sample_type', 'order', 'request_date', 'status', 'approved_date')
    search_fields = ('sample_type', 'order__style_number', 'remarks')
    list_filter = ('sample_type', 'status', 'request_date')
    ordering = ('-request_date',)

# SampleTracking মডেল রেজিস্টার
@admin.register(SampleTracking)
class SampleTrackingAdmin(ModelAdmin):
    list_display = ('sample_request', 'sent_date', 'courier_name', 'tracking_number', 'received_date')
    search_fields = ('sample_request__sample_type', 'tracking_number', 'courier_name')
    list_filter = ('sent_date', 'received_date')
    ordering = ('-sent_date',)

# FabricDevelopment মডেল রেজিস্টার
@admin.register(FabricDevelopment)
class FabricDevelopmentAdmin(ModelAdmin):
    list_display = ('fabric_type', 'order', 'gsm', 'color', 'status', 'supplier')
    search_fields = ('fabric_type', 'order__style_number', 'color', 'supplier')
    list_filter = ('status', 'color')
    ordering = ('order',)

# TrimDevelopment মডেল রেজিস্টার
@admin.register(TrimDevelopment)
class TrimDevelopmentAdmin(ModelAdmin):
    list_display = ('trim_type', 'order', 'color', 'status', 'supplier')
    search_fields = ('trim_type', 'order__style_number', 'color', 'supplier')
    list_filter = ('status', 'color')
    ordering = ('order',)

# CostingSheet মডেল রেজিস্টার
@admin.register(CostingSheet)
class CostingSheetAdmin(ModelAdmin):
    list_display = ('order', 'fabric_cost', 'trim_cost', 'wash_cost', 'labor_cost', 'total_cost', 'approved')
    search_fields = ('order__style_number',)
    list_filter = ('approved',)
    ordering = ('-id',)

ব্যাখ্যা:

  • অ্যাডমিন ক্লাসের নাম এবং কনফিগারেশন (যেমন list_display, search_fields) ইংরেজিতে রাখা হয়েছে।
  • Unfold অ্যাডমিন ব্যবহার করা হয়েছে যেন আপনার আগের সেটআপের সাথে সামঞ্জস্য থাকে।

৪. settings.py আপডেট (ইংরেজি সাইডবার)

settings.py ফাইলে sampling_merchandising অ্যাপ যুক্ত করব এবং Unfold সাইডবারে নতুন মডেলগুলোর লিঙ্ক ইংরেজিতে যোগ করব।

from django.templatetags.static import static
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _

INSTALLED_APPS = [
    'unfold',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'order_management',
    'sampling_merchandising',
]

MEDIA_URL = '/media/'
MEDIA_ROOT = 'media'

STATIC_URL = '/static/'
STATICFILES_DIRS = ['static']

UNFOLD = {
    "SITE_TITLE": "Kreatech ERP",
    "SITE_HEADER": "Kreatech ERP",
    "SITE_LOGO": static("path/to/your/custom-logo.svg"),
    "SITE_URL": "/",
    "SHOW_HISTORY": False,
    "SIDEBAR": {
        "show_search": True,
        "show_all_applications": False,
        "navigation": [
            {
                "title": "Data and Analytics",
                "separator": True,
                "collapsible": True,
                "items": [
                    {
                        "title": "Dashboard",
                        "icon": "dashboard",
                        "link": reverse_lazy("admin:index"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                ],
            },
            {
                "title": "Authentication",
                "separator": True,
                "collapsible": True,
                "items": [
                    {
                        "title": "Users",
                        "icon": "people",
                        "link": reverse_lazy("admin:auth_user_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Groups",
                        "icon": "group",
                        "link": reverse_lazy("admin:auth_group_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Permissions",
                        "icon": "lock",
                        "link": reverse_lazy("admin:auth_permission_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                ],
            },
            {
                "title": "Order Management",
                "separator": True,
                "collapsible": True,
                "items": [
                    {
                        "title": "Buyers",
                        "icon": "business",
                        "link": reverse_lazy("admin:order_management_buyer_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Orders",
                        "icon": "shopping_cart",
                        "link": reverse_lazy("admin:order_management_order_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Order Breakdowns",
                        "icon": "list_alt",
                        "link": reverse_lazy("admin:order_management_orderbreakdown_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Tech Packs",
                        "icon": "description",
                        "link": reverse_lazy("admin:order_management_techpack_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Delivery Schedules",
                        "icon": "local_shipping",
                        "link": reverse_lazy("admin:order_management_deliveryschedule_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                ],
            },
            {
                "title": "Sampling and Merchandising",
                "separator": True,
                "collapsible": True,
                "items": [
                    {
                        "title": "Sample Requests",
                        "icon": "request_quote",
                        "link": reverse_lazy("admin:sampling_merchandising_samplerequest_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Sample Trackings",
                        "icon": "local_shipping",
                        "link": reverse_lazy("admin:sampling_merchandising_sampletracking_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Fabric Developments",
                        "icon": "texture",
                        "link": reverse_lazy("admin:sampling_merchandising_fabricdevelopment_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Trim Developments",
                        "icon": "category",
                        "link": reverse_lazy("admin:sampling_merchandising_trimdevelopment_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                    {
                        "title": "Costing Sheets",
                        "icon": "calculate",
                        "link": reverse_lazy("admin:sampling_merchandising_costingsheet_changelist"),
                        "permission": lambda request: request.user.is_superuser,
                    },
                ],
            },
        ],
    },
}

ব্যাখ্যা:

  • INSTALLED_APPS-এ sampling_merchandising যুক্ত করা হয়েছে।
  • Unfold সাইডবারে নতুন সেকশন “Sampling and Merchandising” ইংরেজিতে যুক্ত করা হয়েছে।
  • আইকনগুলো Google Material Icons থেকে নেওয়া হয়েছে।

৫. URLs কনফিগারেশন

আপনার প্রোজেক্টের urls.py ইতিমধ্যে সঠিকভাবে কনফিগার করা আছে। তবুও, নিশ্চিত করার জন্য এটি আবার দেওয়া হলো:

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from django.shortcuts import redirect

def redirect_to_admin(request):
    return redirect('admin:index')

urlpatterns = [
    path('', redirect_to_admin, name='home'),
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

৬. মিডিয়া ডিরেক্টরি নিশ্চিত করা

order_management.TechPack মডেল ফাইল আপলোডের জন্য media/techpacks/ ডিরেক্টরি ব্যবহার করে। নিশ্চিত করুন এটি আছে:

mkdir -p media/techpacks

৭. মাইগ্রেশন রান করা

নতুন মডেলগুলোর জন্য ডাটাবেস টেবিল তৈরি করতে নিচের কমান্ড রান করুন:

python manage.py makemigrations
python manage.py migrate

৮. স্যাম্পল ডেটা পপুলেট করা

আপনার গল্পের ডেমো ডেটা (TWL-HM-2025) ডাটাবেসে যুক্ত করার জন্য একটি ম্যানেজমেন্ট কমান্ড তৈরি করছি। কমেন্ট এবং স্ট্রিং ইংরেজিতে হবে।

from django.core.management.base import BaseCommand
from order_management.models import Order
from sampling_merchandising.models import SampleRequest, SampleTracking, FabricDevelopment, TrimDevelopment, CostingSheet
from django.utils import timezone

class Command(BaseCommand):
    help = 'Populates sample data for the Sampling and Merchandising module'

    def handle(self, *args, **kwargs):
        # Get the order
        order = Order.objects.get(style_number="TWL-HM-2025")

        # Create SampleRequest
        sample1 = SampleRequest.objects.create(
            order=order,
            sample_type="fit",
            request_date="2025-08-02",
            status="approved",
            approved_date="2025-08-05",
            remarks="Nice fitting"
        )
        SampleRequest.objects.create(
            order=order,
            sample_type="size_set",
            request_date="2025-08-06",
            status="pending",
            remarks="Awaiting approval"
        )

        # Create SampleTracking
        SampleTracking.objects.create(
            sample_request=sample1,
            sent_date="2025-08-03",
            courier_name="DHL",
            tracking_number="DHL123456",
            received_date="2025-08-04"
        )

        # Create FabricDevelopment
        FabricDevelopment.objects.create(
            order=order,
            fabric_type="Cotton",
            gsm=160,
            color="Navy",
            status="developed",
            supplier="ABC Textiles",
            remarks="Approved by buyer"
        )
        FabricDevelopment.objects.create(
            order=order,
            fabric_type="Rib (Collar)",
            gsm=200,
            color="Navy Mix",
            status="in_process",
            supplier="KnitZ Corp",
            remarks="Awaiting lab dip"
        )

        # Create TrimDevelopment
        TrimDevelopment.objects.create(
            order=order,
            trim_type="Main Label",
            color="White",
            status="developed",
            supplier="TagTech Ltd",
            remarks="Sample Approved"
        )
        TrimDevelopment.objects.create(
            order=order,
            trim_type="Hang Tag",
            color="Blue",
            status="in_process",
            supplier="Creative Tags",
            remarks="Awaiting design"
        )

        # Create CostingSheet
        CostingSheet.objects.create(
            order=order,
            fabric_cost=2.00,
            trim_cost=0.50,
            wash_cost=0.30,
            labor_cost=0.80,
            overhead_cost=0.20,
            total_cost=3.80,
            approved=True
        )

        self.stdout.write(self.style.SUCCESS('Sample data populated successfully!'))

এই কমান্ড রান করতে:

python manage.py populate_sample_data

নোট: এই কমান্ড রান করার আগে নিশ্চিত করুন যে order_management অ্যাপে TWL-HM-2025 স্টাইল নম্বরের একটি অর্ডার আছে। আগের populate_sample_data কমান্ড দিয়ে এটি যুক্ত করা যেতে পারে।

৯. টেস্ট করা

  1. ডেভেলপমেন্ট সার্ভার চালু করুন:
   python manage.py runserver
  1. http://127.0.0.1:8000/admin/ এ লগইন করুন।
  2. Unfold সাইডবারে “Sampling and Merchandising” সেকশন দেখুন, যেখানে নতুন মডেলগুলোর লিঙ্ক থাকবে (Sample Requests, Sample Trackings, ইত্যাদি)।
  3. স্যাম্পল ডেটা পপুলেট করে ডাটা যুক্ত হয়েছে কিনা চেক করুন।

মন্তব্য

  • মডেল সম্পর্ক: SampleRequest, FabricDevelopment, TrimDevelopment, এবং CostingSheet মডেলগুলো order_management.Order এর সাথে ForeignKey দিয়ে সংযুক্ত। SampleTracking মডেলটি SampleRequest এর সাথে সংযুক্ত।
  • ইংরেজি ব্যবহার: সব মডেল, ফিল্ড, এবং অ্যাডমিন কনফিগারেশন ইংরেজিতে করা হয়েছে, যেমন আপনি চেয়েছেন।
  • Unfold সাইডবার: নতুন সেকশন “Sampling and Merchandising” ইংরেজিতে যুক্ত করা হয়েছে। আইকনগুলো Google Material Icons থেকে নেওয়া।
  • মিডিয়া হ্যান্ডলিং: order_management.TechPack এর জন্য মিডিয়া সেটিং ইতিমধ্যে কনফিগার করা আছে। এই অ্যাপে ফাইল আপলোডের প্রয়োজন নেই।
  • স্যাম্পল ডেটা: আপনার গল্পের ডেমো ডেটা (TWL-HM-2025) ইংরেজি ফিল্ড নামের সাথে পপুলেট করা হয়েছে।

পরবর্তী ধাপ

আপনার কাছে এখন order_management এবং sampling_merchandising অ্যাপ রয়েছে। আপনি যদি চান, আমি নিচের কাজগুলো করতে পারি:

  1. প্রোডাকশন প্ল্যানিং মডিউল: লাইন অ্যালোকেশন, মেশিন সেটআপ, এবং সেলাই প্ল্যানিং নিয়ে নতুন অ্যাপ তৈরি করা। এটি গল্প, টেবিল, এবং মডেল সহ ইংরেজিতে বা বাংলায় করা যেতে পারে।
  2. ড্যাশবোর্ড উন্নত করা: রুট URL (/) এর জন্য একটি ড্যাশবোর্ড তৈরি করা, যেখানে অর্ডার, স্যাম্পল স্ট্যাটাস, এবং কস্টিং সারাংশ দেখানো যাবে।
  3. কাস্টম ফিচার: যেমন রিপোর্ট জেনারেশন, ফিল্টার, বা অ্যাডমিন অ্যাকশন যুক্ত করা।

অনুগ্রহ করে জানান:

  • আপনি কি প্রোডাকশন প্ল্যানিং মডিউল নিয়ে এগোতে চান? যদি হ্যাঁ, তাহলে ইংরেজি বা বাংলায় করব?
  • নাকি অন্য কোনো ফিচার বা কাস্টমাইজেশন যুক্ত করতে চান?

আপনার উত্তরের অপেক্ষায়!

How can we help?