🎬 গল্প: “The Production Floor Symphony”
মডিউল: Production Floor Control
উদ্দেশ্য: প্রোডাকশন ফ্লোরে কার্যক্রম পরিচালনা, যেমন লাইন প্ল্যানিং, মেশিন বরাদ্দ, অপারেটর নিয়োগ, এবং টার্গেট বনাম অর্জন ট্র্যাকিং। এই মডিউলটি Inventory Management এবং Order Management এর সাথে সংযুক্ত, যেখানে GoodsIssue থেকে ফ্যাব্রিক এবং অন্যান্য মালামাল প্রোডাকশনের জন্য ইস্যু হয় এবং OrderStyle থেকে অর্ডারের তথ্য নেওয়া হয়।
🎭 চরিত্র পরিচিতি
| নাম | পদের নাম | দায়িত্ব |
|---|---|---|
| Nahid | Merchandiser | অর্ডার এবং স্টাইল তথ্য প্রদান |
| Asif | Inventory Controller | ফ্যাব্রিক ইস্যু এবং স্টক ম্যানেজমেন্ট |
| Shahid | Warehouse Manager | ইস্যু এবং ট্রান্সফার অনুমোদন |
| Rubel | Production Planner | লাইন প্ল্যানিং এবং টার্গেট সেটিং |
| Mizan | Floor Supervisor | মেশিন বরাদ্দ এবং অপারেটর নিয়োগ |
| Tania | Production Manager | প্রোডাকশন মনিটরিং এবং টার্গেট অর্জন রিপোর্ট |
| Factory B | Production Warehouse | প্রোডাকশন গুদাম (ফ্যাব্রিক স্টোরেজ) |
| ABC Buyer | Buyer | অর্ডার দাতা (ABC-NAVY-TSHIRT-2025) |
🧩 গল্পের ধাপগুলো
🧾 ধাপ ১: অর্ডার এবং ইনভেন্টরি প্রস্তুতি
গল্প: Nahid, মার্চেন্ডাইজার, ABC Buyer-এর অর্ডার ABC-NAVY-TSHIRT-2025 এর জন্য OrderStyle তৈরি করেন। এই অর্ডারের জন্য 20000 টি টি-শার্ট প্রয়োজন (S, M, L, XL সাইজে)। আগের গল্প থেকে, Asif ইতিমধ্যে Factory B-তে 2000 মিটার Cotton Navy Fabric ট্রান্সফার করেছেন, এবং 1000 মিটার ইস্যু করেছেন প্রোডাকশনের জন্য। Rubel, Production Planner, এই অর্ডারের উপর ভিত্তি করে প্রোডাকশন প্ল্যান তৈরি করতে শুরু করেন।
📦 Table: order_management_orderstyle
| id | order_id | style_name |
|---|---|---|
| 1 | 1 | ABC-NAVY-TSHIRT-2025 |
📦 Table: inventory_goodsissue
| id | issue_id | item_id | warehouse_id | quantity | unit | issue_date | status | approved_by | style_id | remarks |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | IS-2025-0001 | 1 | 2 (Factory B) | 1000.00 | meter | 2025-08-17 | approved | Shahid | 1 | Issued for ABC-NAVY-TSHIRT-2025 |
ব্যাখ্যা:
style_idরেফার করে ABC-NAVY-TSHIRT-2025।GoodsIssueথেকে 1000 মিটার ফ্যাব্রিক Factory B থেকে ইস্যু হয়েছে।
🧾 ধাপ ২: লাইন প্ল্যানিং
গল্প: Rubel, Production Planner, ABC-NAVY-TSHIRT-2025 এর জন্য প্রোডাকশন লাইন প্ল্যান করেন। তিনি দেখেন যে Factory B-তে ২টি প্রোডাকশন লাইন (Line 1 এবং Line 2) আছে। তিনি সিদ্ধান্ত নেন Line 1-এ 10000 টি-শার্ট এবং Line 2-এ 10000 টি-শার্ট উৎপাদন হবে। প্রতিটি লাইনের জন্য দৈনিক টার্গেট 1000 টি-শার্ট, এবং ডেলিভারি ডেডলাইন 2025-09-30।
📦 Table: production_planning_lineplanning
| id | style_id | line_name | target_quantity | daily_target | start_date | end_date | status |
|---|---|---|---|---|---|---|---|
| 1 | 1 | Line 1 | 10000 | 1000 | 2025-08-18 | 2025-08-28 | active |
| 2 | 1 | Line 2 | 10000 | 1000 | 2025-08-18 | 2025-08-28 | active |
ব্যাখ্যা:
style_idরেফার করে ABC-NAVY-TSHIRT-2025।target_quantityহলো মোট উৎপাদন টার্গেট।daily_targetহলো প্রতিদিনের উৎপাদন লক্ষ্য।start_dateএবংend_dateডেলিভারি ডেডলাইনের মধ্যে।
🧾 ধাপ ৩: মেশিন বরাদ্দ
গল্প: Mizan, Floor Supervisor, Line 1 এবং Line 2-এর জন্য মেশিন বরাদ্দ করেন। Line 1-এ ১০টি সেলাই মেশিন এবং ২টি কাটিং মেশিন, এবং Line 2-এ ৮টি সেলাই মেশিন এবং ২টি কাটিং মেশিন বরাদ্দ করা হয়। তিনি নিশ্চিত করেন যে মেশিনগুলো ABC-NAVY-TSHIRT-2025 এর স্পেসিফিকেশনের জন্য উপযুক্ত।
📦 Table: production_planning_machineallocation
| id | line_planning_id | machine_type | quantity | allocation_date | remarks |
|---|---|---|---|---|---|
| 1 | 1 | Sewing | 10 | 2025-08-18 | For Line 1, ABC-NAVY-TSHIRT-2025 |
| 2 | 1 | Cutting | 2 | 2025-08-18 | For Line 1, ABC-NAVY-TSHIRT-2025 |
| 3 | 2 | Sewing | 8 | 2025-08-18 | For Line 2, ABC-NAVY-TSHIRT-2025 |
| 4 | 2 | Cutting | 2 | 2025-08-18 | For Line 2, ABC-NAVY-TSHIRT-2025 |
ব্যাখ্যা:
line_planning_idরেফার করেLinePlanning(Line 1 বা Line 2)।machine_typeহলো মেশিনের ধরন (Sewing, Cutting)।quantityহলো বরাদ্দকৃত মেশিনের সংখ্যা।
🧾 ধাপ ৪: অপারেটর নিয়োগ
গল্প: Mizan প্রতিটি লাইনে অপারেটর নিয়োগ করেন। Line 1-এ ১৫ জন অপারেটর (১০ জন সেলাই, ৫ জন কাটিং) এবং Line 2-এ ১২ জন অপারেটর (৮ জন সেলাই, ৪ জন কাটিং) নিয়োগ করা হয়। তিনি নিশ্চিত করেন যে অপারেটররা প্রশিক্ষিত এবং ABC-NAVY-TSHIRT-2025 এর জন্য উপযুক্ত।
📦 Table: production_planning_operatorassignment
| id | line_planning_id | operator_name | role | assignment_date | remarks |
|---|---|---|---|---|---|
| 1 | 1 | Rahim | Sewing | 2025-08-18 | Assigned to Line 1 |
| 2 | 1 | Karim | Cutting | 2025-08-18 | Assigned to Line 1 |
| 3 | 2 | Sumi | Sewing | 2025-08-18 | Assigned to Line 2 |
| 4 | 2 | Rashed | Cutting | 2025-08-18 | Assigned to Line 2 |
ব্যাখ্যা:
line_planning_idরেফার করেLinePlanning।operator_nameহলো অপারেটরের নাম।roleহলো অপারেটরের কাজ (Sewing, Cutting)।- বাস্তবে আরও অপারেটর থাকবে; এখানে স্যাম্পল হিসেবে ৪ জন দেখানো হয়েছে।
🧾 ধাপ ৫: প্রোডাকশন মনিটরিং এবং টার্গেট বনাম অর্জন
গল্প: Tania, Production Manager, প্রতিদিন প্রোডাকশন মনিটর করেন। 2025-08-18 তারিখে, Line 1 দৈনিক টার্গেট 1000 টি-শার্টের বিপরীতে 950 টি উৎপাদন করে, এবং Line 2 টার্গেট 1000-এর বিপরীতে 900 টি উৎপাদন করে। Tania TargetVsAchievement টেবিলে এন্ট্রি করে এবং দেখেন যে উৎপাদন টার্গেটের কাছাকাছি। তিনি Mizan-কে নির্দেশ দেন অপারেটরদের দক্ষতা বাড়াতে।
📦 Table: production_planning_targetvsachievement
| id | line_planning_id | date | target_quantity | achieved_quantity | remarks |
|---|---|---|---|---|---|
| 1 | 1 | 2025-08-18 | 1000 | 950 | Line 1, slightly below target |
| 2 | 2 | 2025-08-18 | 1000 | 900 | Line 2, needs improvement |
ব্যাখ্যা:
line_planning_idরেফার করেLinePlanning।target_quantityহলো দৈনিক টার্গেট।achieved_quantityহলো প্রকৃত উৎপাদন।remarksদিয়ে সমস্যা বা পরামর্শ লিপিবদ্ধ করা হয়।
🧾 ধাপ ৬: প্রোডাকশন রিপোর্ট
গল্প: Tania একটি Production Summary Report তৈরি করেন। তিনি দেখেন:
- Line 1: 950/10000 টি-শার্ট উৎপাদিত (9.5% সম্পন্ন)।
- Line 2: 900/10000 টি-শার্ট উৎপাদিত (9% সম্পন্ন)।
- মোট ফ্যাব্রিক ব্যবহৃত: 1000 মিটার (GoodsIssue থেকে)।
- বাকি ফ্যাব্রিক: Factory B-তে 1000 মিটার (ItemWarehouseStock থেকে)।
Tania, Rubel-এর সাথে পরামর্শ করে, পরবর্তী দিনে আরও 1000 মিটার ফ্যাব্রিক ইস্যু করার পরিকল্পনা করেন।
📦 Table: inventory_goodsissue (আপডেটেড)
| id | issue_id | item_id | warehouse_id | quantity | unit | issue_date | status | approved_by | style_id | remarks |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | IS-2025-0001 | 1 | 2 (Factory B) | 1000.00 | meter | 2025-08-17 | approved | Shahid | 1 | Issued for ABC-NAVY-TSHIRT-2025 |
| 2 | IS-2025-0002 | 1 | 2 (Factory B) | 1000.00 | meter | 2025-08-19 | pending | Shahid | 1 | For next production batch |
ব্যাখ্যা:
- নতুন
GoodsIssueএন্ট্রি (IS-2025-0002) যুক্ত হয়েছে। statusপ্রাথমিকভাবেpending, Shahid অনুমোদন করবেন।
📊 ইন্টিগ্রেশন ফ্লো
[ABC Buyer: Order] → [Nahid: OrderStyle ABC-NAVY-TSHIRT-2025] → [Asif: GoodsIssue IS-2025-0001 from Factory B] → [Rubel: LinePlanning Line 1 & Line 2] → [Mizan: MachineAllocation & OperatorAssignment] → [Tania: TargetVsAchievement & Production Report] → [Asif: New GoodsIssue IS-2025-0002]🧰 Django মডেল
নিচে production_planning/models.py দেওয়া হলো, যা Production Floor Control মডিউলের জন্য।
from django.db import models
from django.contrib.auth.models import User
from order_management.models import OrderStyle
class LinePlanning(models.Model):
STATUS_CHOICES = (
('planned', 'Planned'),
('active', 'Active'),
('completed', 'Completed'),
)
style = models.ForeignKey(OrderStyle, on_delete=models.CASCADE, verbose_name="Style")
line_name = models.CharField(max_length=100, verbose_name="Line Name")
target_quantity = models.IntegerField(verbose_name="Target Quantity")
daily_target = models.IntegerField(verbose_name="Daily Target")
start_date = models.DateField(verbose_name="Start Date")
end_date = models.DateField(verbose_name="End Date")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='planned', verbose_name="Status")
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="Created By")
class Meta:
verbose_name = "Line Planning"
verbose_name_plural = "Line Plannings"
def __str__(self):
return f"{self.line_name} - {self.style.style_name}"
class MachineAllocation(models.Model):
MACHINE_TYPE_CHOICES = (
('sewing', 'Sewing'),
('cutting', 'Cutting'),
('finishing', 'Finishing'),
)
line_planning = models.ForeignKey(LinePlanning, on_delete=models.CASCADE, verbose_name="Line Planning")
machine_type = models.CharField(max_length=20, choices=MACHINE_TYPE_CHOICES, verbose_name="Machine Type")
quantity = models.IntegerField(verbose_name="Quantity")
allocation_date = models.DateField(verbose_name="Allocation Date")
remarks = models.TextField(blank=True, verbose_name="Remarks")
class Meta:
verbose_name = "Machine Allocation"
verbose_name_plural = "Machine Allocations"
def __str__(self):
return f"{self.machine_type} - {self.line_planning.line_name}"
class OperatorAssignment(models.Model):
ROLE_CHOICES = (
('sewing', 'Sewing'),
('cutting', 'Cutting'),
('finishing', 'Finishing'),
)
line_planning = models.ForeignKey(LinePlanning, on_delete=models.CASCADE, verbose_name="Line Planning")
operator_name = models.CharField(max_length=100, verbose_name="Operator Name")
role = models.CharField(max_length=20, choices=ROLE_CHOICES, verbose_name="Role")
assignment_date = models.DateField(verbose_name="Assignment Date")
remarks = models.TextField(blank=True, verbose_name="Remarks")
class Meta:
verbose_name = "Operator Assignment"
verbose_name_plural = "Operator Assignments"
def __str__(self):
return f"{self.operator_name} - {self.line_planning.line_name}"
class TargetVsAchievement(models.Model):
line_planning = models.ForeignKey(LinePlanning, on_delete=models.CASCADE, verbose_name="Line Planning")
date = models.DateField(verbose_name="Date")
target_quantity = models.IntegerField(verbose_name="Target Quantity")
achieved_quantity = models.IntegerField(verbose_name="Achieved Quantity")
remarks = models.TextField(blank=True, verbose_name="Remarks")
reported_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="Reported By")
class Meta:
verbose_name = "Target vs Achievement"
verbose_name_plural = "Target vs Achievements"
def __str__(self):
return f"{self.line_planning.line_name} - {self.date}"ব্যাখ্যা:
- LinePlanning: প্রোডাকশন লাইনের পরিকল্পনা,
styleফিল্ড দিয়ে OrderStyle এর সাথে লিঙ্ক। - MachineAllocation: মেশিন বরাদ্দ,
line_planningফিল্ড দিয়ে লাইনের সাথে লিঙ্ক। - OperatorAssignment: অপারেটর নিয়োগ,
line_planningফিল্ড দিয়ে লাইনের সাথে লিঙ্ক। - TargetVsAchievement: দৈনিক টার্গেট বনাম অর্জন ট্র্যাকিং।
ধাপ: অ্যাডমিন কনফিগারেশন
নিচে production_planning/admin.py দেওয়া হলো।
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import LinePlanning, MachineAllocation, OperatorAssignment, TargetVsAchievement
@admin.register(LinePlanning)
class LinePlanningAdmin(ModelAdmin):
list_display = ('line_name', 'style', 'target_quantity', 'daily_target', 'start_date', 'end_date', 'status', 'created_by')
search_fields = ('line_name', 'style__style_name')
list_filter = ('status', 'start_date', 'end_date')
ordering = ('-start_date',)
@admin.register(MachineAllocation)
class MachineAllocationAdmin(ModelAdmin):
list_display = ('line_planning', 'machine_type', 'quantity', 'allocation_date', 'remarks')
search_fields = ('line_planning__line_name', 'machine_type')
list_filter = ('machine_type', 'allocation_date')
ordering = ('-allocation_date',)
@admin.register(OperatorAssignment)
class OperatorAssignmentAdmin(ModelAdmin):
list_display = ('line_planning', 'operator_name', 'role', 'assignment_date', 'remarks')
search_fields = ('operator_name', 'line_planning__line_name')
list_filter = ('role', 'assignment_date')
ordering = ('-assignment_date',)
@admin.register(TargetVsAchievement)
class TargetVsAchievementAdmin(ModelAdmin):
list_display = ('line_planning', 'date', 'target_quantity', 'achieved_quantity', 'reported_by', 'remarks')
search_fields = ('line_planning__line_name', 'reported_by__username')
list_filter = ('date', 'line_planning')
ordering = ('-date',)ব্যাখ্যা:
- প্রতিটি মডেলের জন্য
list_display,search_fields,list_filter, এবংorderingকাস্টমাইজ করা হয়েছে। - Unfold Admin ব্যবহার করা হয়েছে।
ধাপ: settings.py
settings.py ইতিমধ্যে Production Planning সেকশন ধারণ করে। তবে নিশ্চিত করতে পুনরায় শেয়ার করছি।
"""
Django settings for config project.
Generated by 'django-admin startproject' using Django 5.2.4.
For more information on this file, see
https://docs.djangoproject.com/en/5.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.2/ref/settings/
"""
from pathlib import Path
from django.templatetags.static import static
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-d&5pro-b^j#$qo7amy26x$%5$+@-zim%mg9nl@px68(apvg@c7'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"unfold",
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'custom_auth',
'order_management',
'sampling_merchandising',
'production_planning',
'procurement',
'inventory',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
UNFOLD = {
"SITE_TITLE": "GarmrntsErp",
"SITE_HEADER": "GarmrntsErp Dashboard",
"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 Styles"),
"icon": "style",
"link": reverse_lazy("admin:order_management_orderstyle_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,
},
{
"title": _("Consumption Calculations"),
"icon": "scale",
"link": reverse_lazy("admin:sampling_merchandising_consumptioncalculation_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Follow Up Notes"),
"icon": "notes",
"link": reverse_lazy("admin:sampling_merchandising_followupnote_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
{
"title": _("Procurement & Purchase"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Suppliers"),
"icon": "business",
"link": reverse_lazy("admin:procurement_supplier_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Purchase Requisitions"),
"icon": "request_page",
"link": reverse_lazy("admin:procurement_purchaserequisition_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Purchase Orders"),
"icon": "shopping_bag",
"link": reverse_lazy("admin:procurement_purchaseorder_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Goods Receive Notes"),
"icon": "inventory",
"link": reverse_lazy("admin:procurement_goodsreceivenote_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("PO Tracking"),
"icon": "track_changes",
"link": reverse_lazy("admin:procurement_potracking_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
{
"title": _("Inventory Management"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Warehouses"),
"icon": "warehouse",
"link": reverse_lazy("admin:inventory_warehouse_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Items"),
"icon": "inventory_2",
"link": reverse_lazy("admin:inventory_item_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Warehouse Stocks"),
"icon": "store",
"link": reverse_lazy("admin:inventory_itemwarehousestock_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Transactions"),
"icon": "swap_horiz",
"link": reverse_lazy("admin:inventory_transaction_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Inventory Transfers"),
"icon": "local_shipping",
"link": reverse_lazy("admin:inventory_inventorytransfer_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Goods Receipts"),
"icon": "archive",
"link": reverse_lazy("admin:inventory_goodsreceipt_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Goods Issues"),
"icon": "assignment_turned_in",
"link": reverse_lazy("admin:inventory_goodsissue_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
{
"title": _("Production Planning"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Line Planning"),
"icon": "view_timeline",
"link": reverse_lazy("admin:production_planning_lineplanning_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Machine Allocation"),
"icon": "build",
"link": reverse_lazy("admin:production_planning_machineallocation_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Operator Assignment"),
"icon": "engineering",
"link": reverse_lazy("admin:production_planning_operatorassignment_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Target vs Achievement"),
"icon": "trending_up",
"link": reverse_lazy("admin:production_planning_targetvsachievement_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
],
},
}ধাপ: স্যাম্পল ডেটা
নিচে production_planning_sample_data.json দেওয়া হলো, যা Production Floor Control মডিউলের সাথে সামঞ্জস্যপূর্ণ। ফাইলটি C:\Users\Olee-Ahmmed\Desktop\GarmrntsErp\config\fixtures\production_planning_sample_data.json পাথে সেভ করুন।
[
{
"model": "auth.user",
"pk": 8,
"fields": {
"username": "rubel",
"first_name": "Rubel",
"last_name": "",
"email": "rubel@example.com",
"password": "pbkdf2_sha256$260000$randomsalt$hashedpassword",
"is_staff": true,
"is_active": true
}
},
{
"model": "auth.user",
"pk": 9,
"fields": {
"username": "mizan",
"first_name": "Mizan",
"last_name": "",
"email": "mizan@example.com",
"password": "pbkdf2_sha256$260000$randomsalt$hashedpassword",
"is_staff": true,
"is_active": true
}
},
{
"model": "auth.user",
"pk": 10,
"fields": {
"username": "tania",
"first_name": "Tania",
"last_name": "",
"email": "tania@example.com",
"password": "pbkdf2_sha256$260000$randomsalt$hashedpassword",
"is_staff": true,
"is_active": true
}
},
{
"model": "production_planning.lineplanning",
"pk": 1,
"fields": {
"style": 1,
"line_name": "Line 1",
"target_quantity": 10000,
"daily_target": 1000,
"start_date": "2025-08-18",
"end_date": "2025-08-28",
"status": "active",
"created_by": 8
}
},
{
"model": "production_planning.lineplanning",
"pk": 2,
"fields": {
"style": 1,
"line_name": "Line 2",
"target_quantity": 10000,
"daily_target": 1000,
"start_date": "2025-08-18",
"end_date": "2025-08-28",
"status": "active",
"created_by": 8
}
},
{
"model": "production_planning.machineallocation",
"pk": 1,
"fields": {
"line_planning": 1,
"machine_type": "sewing",
"quantity": 10,
"allocation_date": "2025-08-18",
"remarks": "For Line 1, ABC-NAVY-TSHIRT-2025"
}
},
{
"model": "production_planning.machineallocation",
"pk": 2,
"fields": {
"line_planning": 1,
"machine_type": "cutting",
"quantity": 2,
"allocation_date": "2025-08-18",
"remarks": "For Line 1, ABC-NAVY-TSHIRT-2025"
}
},
{
"model": "production_planning.machineallocation",
"pk": 3,
"fields": {
"line_planning": 2,
"machine_type": "sewing",
"quantity": 8,
"allocation_date": "2025-08-18",
"remarks": "For Line 2, ABC-NAVY-TSHIRT-2025"
}
},
{
"model": "production_planning.machineallocation",
"pk": 4,
"fields": {
"line_planning": 2,
"machine_type": "cutting",
"quantity": 2,
"allocation_date": "2025-08-18",
"remarks": "For Line 2, ABC-NAVY-TSHIRT-2025"
}
},
{
"model": "production_planning.operatorassignment",
"pk": 1,
"fields": {
"line_planning": 1,
"operator_name": "Rahim",
"role": "sewing",
"assignment_date": "2025-08-18",
"remarks": "Assigned to Line 1"
}
},
{
"model": "production_planning.operatorassignment",
"pk": 2,
"fields": {
"line_planning": 1,
"operator_name": "Karim",
"role": "cutting",
"assignment_date": "2025-08-18",
"remarks": "Assigned to Line 1"
}
},
{
"model": "production_planning.operatorassignment",
"pk": 3,
"fields": {
"line_planning": 2,
"operator_name": "Sumi",
"role": "sewing",
"assignment_date": "2025-08-18",
"remarks": "Assigned to Line 2"
}
},
{
"model": "production_planning.operatorassignment",
"pk": 4,
"fields": {
"line_planning": 2,
"operator_name": "Rashed",
"role": "cutting",
"assignment_date": "2025-08-18",
"remarks": "Assigned to Line 2"
}
},
{
"model": "production_planning.targetvsachievement",
"pk": 1,
"fields": {
"line_planning": 1,
"date": "2025-08-18",
"target_quantity": 1000,
"achieved_quantity": 950,
"remarks": "Line 1, slightly below target",
"reported_by": 10
}
},
{
"model": "production_planning.targetvsachievement",
"pk": 2,
"fields": {
"line_planning": 2,
"date": "2025-08-18",
"target_quantity": 1000,
"achieved_quantity": 900,
"remarks": "Line 2, needs improvement",
"reported_by": 10
}
},
{
"model": "inventory.goodsissue",
"pk": 2,
"fields": {
"issue_id": "IS-2025-0002",
"item": 1,
"warehouse": 2,
"quantity": 1000.00,
"unit": "meter",
"issue_date": "2025-08-19",
"status": "pending",
"approved_by": 6,
"style": 1,
"remarks": "For next production batch"
}
}
]ব্যাখ্যা:
- User: Rubel, Mizan, Tania।
- LinePlanning: Line 1 এবং Line 2।
- MachineAllocation: Sewing এবং Cutting মেশিন।
- OperatorAssignment: Rahim, Karim, Sumi, Rashed।
- TargetVsAchievement: দৈনিক টার্গেট এবং অর্জন।
- GoodsIssue: নতুন ইস্যু (IS-2025-0002)।
ধাপ: ডাটাবেস প্রস্তুতি এবং টেস্ট
- মডেল আপডেট:
production_planning/models.pyএবংproduction_planning/admin.pyসেভ করুন।
- মাইগ্রেশন প্রয়োগ:
python manage.py makemigrations
python manage.py migrate- ডেটা লোড:
python manage.py loaddata fixtures/production_planning_sample_data- সার্ভার চালু:
python manage.py runserver- অ্যাডমিন প্যানেল চেক:
http://127.0.0.1:8000/admin/এ লগইন করুন।- Production Planning সেকশন চেক করুন:
- Line Planning: Line 1, Line 2
- Machine Allocation: Sewing, Cutting
- Operator Assignment: Rahim, Karim, Sumi, Rashed
- Target vs Achievement: Line 1 (950/1000), Line 2 (900/1000)
🎯 মডিউলের উদ্দেশ্য
| মডেল | উদ্দেশ্য |
|---|---|
LinePlanning | প্রোডাকশন লাইনের পরিকল্পনা এবং টার্গেট সেটিং |
MachineAllocation | মেশিন বরাদ্দ ট্র্যাকিং |
OperatorAssignment | অপারেটর নিয়োগ এবং রোল ট্র্যাকিং |
TargetVsAchievement | দৈনিক টার্গেট বনাম অর্জন মনিটরিং |
🔄 পরবর্তী ধাপ
অনুগ্রহ করে জানান:
- Production Summary Report: Django Admin-এ কাস্টম রিপোর্ট তৈরি করব, যেমন
TargetVsAchievementথেকে প্রোগ্রেস বাGoodsIssueথেকে ফ্যাব্রিক ব্যবহার? - Validation:
TargetVsAchievementএachieved_quantityটার্গেটের চেয়ে বেশি হলে অ্যালার্ট বাGoodsIssueএর সাথে লিঙ্ক যুক্ত করব? - ER Diagram: Procurement, Inventory, এবং Production Planning এর সম্মিলিত ER Diagram তৈরি করব?
- API এন্ডপয়েন্ট: REST API তৈরি করব (যেমন,
/api/lineplanning/,/api/targetvsachievement/)? - অতিরিক্ত ফিচার: প্রোডাকশন ডাউনটাইম ট্র্যাকিং, মেশিন মেইনটেন্যান্স, বা অপারেটর পারফরম্যান্স রিপোর্ট?
- ডেটা লোড বা সাইডবারে সমস্যা হলে বিস্তারিত শেয়ার করুন।
আশা করি গল্প এবং মডেলগুলো আপনার প্রত্যাশা পূরণ করেছে! 😊 কোনো পরিবর্তন বা অতিরিক্ত ফিচার চাইলে জানান।