fdc4699b11a15f1a1b4e663R130">130
+    # Generate the output filename with a timestamp
131
+    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
132
+    output_path = f"{prefix_filename}_{timestamp}.xlsx"
133
+    workbook.save(output_path)
134
+
135
+    return output_path
136
+
137
+if __name__ == "__main__":
138
+    # Example usage
139
+    data = {
140
+        "customer": "Tum Coder",
141
+        "inspect_date": "2025-01-15",
142
+        "lot_no": "12345",
143
+        "staff_name":  "Tum 8888",
144
+        "man_name":  "Tum 999",
145
+        "size": "Large",
146
+        "pcs": "10 pcs",
147
+        "spec": "Spec-A",
148
+        "hardness.d1_act": "10",
149
+        "hardness.d2_act": "0[24:28]",  # Hide rows 24 to 28 if the prefix is "0"
150
+        "hardness.acc": True,  # Hide rows 24 to 28 if the prefix is "0"
151
+        "hardness.spe_acc": False,  # Hide rows 24 to 28 if the prefix is "0"
152
+        "dimension_app.d1_act": "33",
153
+        "dimension_app.d2_act": "0[26:32]",  # Hide rows 24 to 28 if the prefix is "0"
154
+        "dimension_app.acc": True,  # Hide rows 24 to 28 if the prefix is "0"
155
+        "dimension_app.spe_acc": True,  # Hide rows 24 to 28 if the prefix is "0"
156
+    }
157
+
158
+
159
+
160
+
161
+    output_file = gen_xlsx(
162
+        template_file="./hardness.xlsx",
163
+        selected_sheets=["hardness", "dimension_app"],  # Replace with your actual sheet names
164
+        prefix_filename="./output/output",
165
+        data=data
166
+    )
167
+
168
+    print(f"Generated file: {output_file}")

+ 42 - 0
app/report/views.py

@@ -8,6 +8,10 @@ from .filters import ReportFilter
8 8
 from .forms import ExportOptionsForm
9 9
 from pprint import pprint
10 10
 
11
+from .gen_report import gen_xlsx
12
+from django.core.files.base import File
13
+from pathlib import Path
14
+
11 15
 
12 16
 def index(request):
13 17
     reports = Report.objects.all()
@@ -61,6 +65,44 @@ class ReportCRUDView(ConfigurableCRUDView):
61 65
 def coi_view(request):
62 66
     pprint(f"xxxx method = xxx {request.method}")
63 67
     if request.method == "POST":
68
+        pprint(request.POST)
69
+        if 'export' in request.POST:
70
+
71
+            data = {
72
+                "customer": "Tum Coder",
73
+                "inspect_date": "2025-01-15",
74
+                "lot_no": "12345",
75
+                "staff_name":  "Tum 8888",
76
+                "man_name":  "Tum 999",
77
+                "size": "Large",
78
+                "pcs": "10 pcs",
79
+                "spec": "Spec-A",
80
+                "hardness.d1_act": "10",
81
+                "hardness.d2_act": "0[24:28]",  # Hide rows 24 to 28 if the prefix is "0"
82
+                "hardness.acc": True,  # Hide rows 24 to 28 if the prefix is "0"
83
+                "hardness.spe_acc": False,  # Hide rows 24 to 28 if the prefix is "0"
84
+                "dimension_app.d1_act": "33",
85
+                "dimension_app.d2_act": "0[26:32]",  # Hide rows 24 to 28 if the prefix is "0"
86
+                "dimension_app.acc": True,  # Hide rows 24 to 28 if the prefix is "0"
87
+                "dimension_app.spe_acc": True,  # Hide rows 24 to 28 if the prefix is "0"
88
+            }
89
+            output_file = gen_xlsx(
90
+                template_file="/app/report/coi_templates.xlsx",
91
+                selected_sheets=["hardness", "dimension_app"],  # Replace with your actual sheet names
92
+                prefix_filename="/app/media/coi",
93
+                data=data
94
+            )
95
+            report = Report.objects.create(
96
+                name=request.POST.get('lot_no','Untitled'),
97
+                created_by=request.user,
98
+                file=None  # Leave this as None or assign a file if required
99
+            )
100
+            output_file_path = Path(output_file)  # Convert to a Path object for convenience
101
+            with open(output_file_path, "rb") as f:
102
+                report.file.save(output_file_path.name, File(f), save=True)
103
+
104
+            pprint(f"outputfile = {output_file}")
105
+
64 106
         if 'search_lot' in request.POST:
65 107
             lot_no = request.POST.get('lot_no', None)
66 108
             if lot_no:

+ 3 - 0
app/sysadmin/apps.py

@@ -4,3 +4,6 @@ from django.apps import AppConfig
4 4
 class SysadminConfig(AppConfig):
5 5
     default_auto_field = 'django.db.models.BigAutoField'
6 6
     name = 'sysadmin'
7
+
8
+    def ready(self):
9
+        import sysadmin.signals

+ 8 - 0
app/sysadmin/forms.py

@@ -14,6 +14,8 @@ class CustomLoginForm(AuthenticationForm):
14 14
 from django.contrib.auth.forms import UserCreationForm
15 15
 from django.contrib.auth.models import User
16 16
 
17
+from .models import UserProfile
18
+
17 19
 class CustomUserCreationForm(UserCreationForm):
18 20
     class Meta:
19 21
         model = User
@@ -33,3 +35,9 @@ class CustomUserCreationForm(UserCreationForm):
33 35
         self.fields['password2'].widget.attrs.update({
34 36
             'placeholder': 'Confirm Password'
35 37
         })
38
+
39
+
40
+class UserProfileForm(forms.ModelForm):
41
+    class Meta:
42
+        model = UserProfile
43
+        fields = ['profile_picture', 'position', 'signed_picture']  # Include the fields you want to manage

+ 29 - 0
app/sysadmin/migrations/0001_initial.py

@@ -0,0 +1,29 @@
1
+# Generated by Django 4.2 on 2025-01-17 04:58
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    initial = True
11
+
12
+    dependencies = [
13
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14
+    ]
15
+
16
+    operations = [
17
+        migrations.CreateModel(
18
+            name='UserProfile',
19
+            fields=[
20
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
+                ('bio', models.TextField(blank=True, null=True)),
22
+                ('profile_picture', models.ImageField(blank=True, null=True, upload_to='profile/%Y/%m/%d/')),
23
+                ('signed_picture', models.ImageField(blank=True, null=True, upload_to='signed/%Y/%m/%d/')),
24
+                ('email', models.EmailField(blank=True, max_length=254, null=True)),
25
+                ('position', models.CharField(blank=True, choices=[('QA_STAFF', 'QA Staff'), ('QA_MANAGER', 'QA Manager')], max_length=20, null=True)),
26
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
27
+            ],
28
+        ),
29
+    ]

+ 17 - 0
app/sysadmin/models.py

@@ -1,3 +1,20 @@
1 1
 from django.db import models
2 2
 
3 3
 # Create your models here.
4
+
5
+from django.contrib.auth.models import User
6
+
7
+class UserProfile(models.Model):
8
+    POSITION_CHOICES = [
9
+        ('QA_STAFF', 'QA Staff'),
10
+        ('QA_MANAGER', 'QA Manager'),
11
+    ]
12
+    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
13
+    bio = models.TextField(blank=True, null=True)
14
+    profile_picture = models.ImageField(upload_to="profile/%Y/%m/%d/", blank=True, null=True)
15
+    signed_picture = models.ImageField(upload_to="signed/%Y/%m/%d/", blank=True, null=True)
16
+    email = models.EmailField(blank=True, null=True)  # New email field
17
+    position = models.CharField(max_length=20, choices=POSITION_CHOICES, blank=True, null=True)  # New position field
18
+
19
+    def __str__(self):
20
+        return self.user.username

+ 13 - 0
app/sysadmin/signals.py

@@ -0,0 +1,13 @@
1
+from django.db.models.signals import post_save
2
+from django.dispatch import receiver
3
+from django.contrib.auth.models import User
4
+from .models import UserProfile
5
+
6
+@receiver(post_save, sender=User)
7
+def create_user_profile(sender, instance, created, **kwargs):
8
+    if created:
9
+        UserProfile.objects.create(user=instance)
10
+
11
+@receiver(post_save, sender=User)
12
+def save_user_profile(sender, instance, **kwargs):
13
+    instance.profile.save()

+ 94 - 0
app/sysadmin/templates/sysadmin/profile.html

@@ -0,0 +1,94 @@
1
+{% extends "base.html" %}
2
+{% load tailwind_filters %}
3
+
4
+{% block title %}Report Dashboard{% endblock %}
5
+{% block content %}
6
+<div class="container mx-auto px-4 py-8">
7
+<h1 class="text-2xl font-bold text-gray-700 mb-6">Your Profile</h1>
8
+
9
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
10
+            <!-- Username -->
11
+            <div class="flex items-center bg-gray-50 p-4 rounded-lg shadow-sm border">
12
+                <div class="flex-shrink-0 bg-indigo-100 rounded-full h-12 w-12 flex items-center justify-center">
13
+                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
14
+  <path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
15
+</svg>
16
+
17
+                </div>
18
+                <div class="ml-4">
19
+                    <h3 class="text-lg font-medium text-gray-900">Username</h3>
20
+                    <p class="text-gray-600">{{ user.username }}</p>
21
+                </div>
22
+            </div>
23
+
24
+            <!-- Email -->
25
+            <div class="flex items-center bg-gray-50 p-4 rounded-lg shadow-sm border">
26
+                <div class="flex-shrink-0 bg-indigo-100 rounded-full h-12 w-12 flex items-center justify-center">
27
+                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
28
+  <path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75" />
29
+</svg>
30
+
31
+                </div>
32
+                <div class="ml-4">
33
+                    <h3 class="text-lg font-medium text-gray-900">Email</h3>
34
+                    <p class="text-gray-600">{{ user.email }}</p>
35
+                </div>
36
+            </div>
37
+        </div>
38
+<form method="POST" enctype="multipart/form-data" class='space-y-4'>
39
+    {% csrf_token %}
40
+              <!-- First Name -->
41
+              <div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
42
+
43
+                <div>
44
+                  <label for="first_name" class="block text-sm font-medium text-gray-700">First Name</label>
45
+                  <input
46
+                      type="text"
47
+                      name="first_name"
48
+                      id="first_name"
49
+                      value="{{ user.first_name }}"
50
+                      class="block w-full mt-2 rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
51
+                      />
52
+                </div>
53
+
54
+                <!-- Last Name -->
55
+                <div>
56
+                  <label for="last_name" class="block text-sm font-medium text-gray-700">Last Name</label>
57
+                  <input
58
+                      type="text"
59
+                      name="last_name"
60
+                      id="last_name"
61
+                      value="{{ user.last_name }}"
62
+                      class="block w-full mt-2 rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
63
+                      />
64
+                </div>
65
+              </div>
66
+    {% if form.instance.profile_picture %}
67
+    <!-- Show uploaded profile picture -->
68
+    <img src="{{ form.instance.profile_picture.url }}" 
69
+         alt="Profile Picture" 
70
+         class="w-32 h-32 rounded-full mb-4 shadow-md">
71
+    {% else %}
72
+    <!-- Placeholder image if no profile picture -->
73
+    <div class="w-32 h-32 rounded-full bg-gray-200 flex items-center justify-center text-gray-500 mb-4">
74
+      <span>No Image</span>
75
+    </div>
76
+    {% endif %}
77
+    {{ form.profile_picture }}
78
+    {% if form.instance.signed_picture %}
79
+    <!-- Show uploaded profile picture -->
80
+    <img src="{{ form.instance.signed_picture.url }}" 
81
+         alt="Profile Picture" 
82
+         class="w-32 mb-4 shadow-md">
83
+    {% else %}
84
+    <!-- Placeholder image if no profile picture -->
85
+    <div class="w-32 h-32 rounded-full bg-gray-200 flex items-center justify-center text-gray-500 mb-4">
86
+      <span>No Image</span>
87
+    </div>
88
+    {% endif %}
89
+    {{ form.signed_picture }}
90
+    {{ form.position | as_crispy_field }}
91
+    <button type="submit" class="px-6 py-2 bg-indigo-600 text-white font-medium rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Save Changes</button>
92
+</form>
93
+</div>
94
+{% endblock %}

+ 2 - 0
app/sysadmin/urls.py

@@ -7,4 +7,6 @@ urlpatterns = [
7 7
     path('login/', views.login_view, name='login'),
8 8
     path('register/', views.register_view, name='register'),
9 9
     path('logout/', views.logout_view, name='logout'),
10
+    path('profile/', views.profile_view, name='profile'),  # Add profile view URL
11
+
10 12
 ]

+ 32 - 1
app/sysadmin/views.py

@@ -1,7 +1,10 @@
1 1
 # views.py
2 2
 from django.contrib.auth import authenticate, login, logout
3 3
 from django.shortcuts import render, redirect
4
-from .forms import CustomLoginForm, CustomUserCreationForm
4
+from .forms import CustomLoginForm, CustomUserCreationForm, UserProfileForm
5
+from .models import UserProfile
6
+from django.contrib.auth.decorators import login_required
7
+from django.contrib import messages
5 8
 
6 9
 def login_view(request):
7 10
     if request.method == "POST":
@@ -30,3 +33,31 @@ def register_view(request):
30 33
 def logout_view(request):
31 34
     logout(request)  # Logs out the user
32 35
     return redirect('sysadmin:login')  # Redirect to the login page after logout
36
+
37
+@login_required
38
+def profile_view(request):
39
+    try:
40
+        # Get the profile for the current user
41
+        profile = request.user.profile
42
+    except UserProfile.DoesNotExist:
43
+        # Create a profile if it doesn't exist
44
+        profile = UserProfile.objects.create(user=request.user)
45
+
46
+    if request.method == "POST":
47
+        form = UserProfileForm(request.POST, request.FILES, instance=profile)
48
+
49
+        user = request.user
50
+        user.first_name = request.POST.get('first_name', user.first_name)
51
+        user.last_name = request.POST.get('last_name', user.last_name)
52
+
53
+        if form.is_valid():
54
+            form.save()
55
+            user.save()
56
+            messages.success(request, "Profile Updated")
57
+            return redirect('sysadmin:profile')  # Redirect to the profile page after saving
58
+        else:
59
+            messages.error(request, form.errors)
60
+    else:
61
+        form = UserProfileForm(instance=profile)
62
+
63
+    return render(request, 'sysadmin/profile.html', {'form': form})

+ 2 - 2
app/templates/base.html

@@ -7,7 +7,7 @@
7 7
 <head>
8 8
     <meta charset="UTF-8">
9 9
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
-    <title>{% block title %}My Django App{% endblock %}</title>
10
+    <title>{% block title %}COI System{% endblock %}</title>
11 11
 
12 12
     <!-- TailwindCSS -->
13 13
     <!--
@@ -39,7 +39,7 @@
39 39
 
40 40
                 {% if user.is_authenticated %}
41 41
                     <!-- Logged-in User -->
42
-                    <span class="text-gray-600 dark:text-gray-300">Hello, {{ user.username }}</span>
42
+                    <a href="{% url 'sysadmin:profile' %}"><span class="text-gray-600 dark:text-gray-300">Hello, {{ user.username }}</span></a>
43 43
                     <a href="{% url 'sysadmin:logout' %}" class="text-blue-500 hover:underline">Logout</a>
44 44
                 {% else %}
45 45
                     <!-- Guest User -->

BIN
hardness.xlsx


+ 3 - 1
test_xlsx2.py

@@ -139,6 +139,8 @@ if __name__ == "__main__":
139 139
         "customer": "Tum Coder",
140 140
         "inspect_date": "2025-01-15",
141 141
         "lot_no": "12345",
142
+        "staff_name":  "Tum 8888",
143
+        "man_name":  "Tum 999",
142 144
         "size": "Large",
143 145
         "pcs": "10 pcs",
144 146
         "spec": "Spec-A",
@@ -149,7 +151,7 @@ if __name__ == "__main__":
149 151
         "dimension_app.d1_act": "33",
150 152
         "dimension_app.d2_act": "0[26:32]",  # Hide rows 24 to 28 if the prefix is "0"
151 153
         "dimension_app.acc": True,  # Hide rows 24 to 28 if the prefix is "0"
152
-        "dimension_app.spe_acc": False,  # Hide rows 24 to 28 if the prefix is "0"
154
+        "dimension_app.spe_acc": True,  # Hide rows 24 to 28 if the prefix is "0"
153 155
     }
154 156
 
155 157
 

tum/coi - Gogs: Simplico Git Service

暫無描述

models.py 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. from django.db import models
  2. # Create your models here.
  3. from django.contrib.auth.models import User # Assuming you're using Django's built-in User model
  4. class Report(models.Model):
  5. name = models.CharField(max_length=255) # Name of the report
  6. created_by = models.ForeignKey(
  7. User,
  8. on_delete=models.CASCADE,
  9. related_name="reports"
  10. ) # Reference to the user who created the report
  11. created_at = models.DateTimeField(auto_now_add=True) # Automatically set when created
  12. updated_at = models.DateTimeField(auto_now=True) # Automatically updated when modified
  13. file = models.FileField(upload_to='reports/files/', null=True, blank=True) # File field
  14. def __str__(self):
  15. return self.name
  16. class MgMasterView(models.Model):
  17. # ProcessControl.dbo.[Q-PRO-DATA]
  18. PRO0 = models.CharField(primary_key=True,max_length=255, null=False)
  19. PRO1 = models.CharField(max_length=255, null=True)
  20. PRO1C = models.CharField(max_length=255, null=True)
  21. PRO2 = models.CharField(max_length=255, null=True)
  22. PRO5 = models.CharField(max_length=255, null=True)
  23. PRO8 = models.CharField(max_length=255, null=True)
  24. PRO9 = models.CharField(max_length=255, null=True)
  25. PRO10 = models.CharField(max_length=255, null=True)
  26. PRO11 = models.CharField(max_length=255, null=True)
  27. PRO12 = models.CharField(max_length=255, null=True)
  28. PRO13 = models.CharField(max_length=255, null=True)
  29. PRO14 = models.CharField(max_length=255, null=True)
  30. PRO15 = models.CharField(max_length=255, null=True)
  31. PRO16 = models.CharField(max_length=255, null=True)
  32. PRO17 = models.CharField(max_length=255, null=True)
  33. PRO18 = models.CharField(max_length=255, null=True)
  34. PRO21 = models.CharField(max_length=255, null=True)
  35. PRO25 = models.CharField(max_length=255, null=True)
  36. PRO27 = models.CharField(max_length=255, null=True)
  37. P2 = models.CharField(max_length=255, null=True) # PRO-P2
  38. SPEED = models.CharField(max_length=255, null=True) # PRO-SPEED
  39. PRO_TOOL = models.CharField(max_length=255, null=True) # PRO-TOOL
  40. PRO4 = models.CharField(max_length=255, null=True)
  41. # dbo.[MG-MAS-1]
  42. MC11 = models.CharField(max_length=255, null=True)
  43. MC12 = models.CharField(max_length=255, null=True)
  44. MC14 = models.CharField(max_length=255, null=True)
  45. MC15 = models.CharField(max_length=255, null=True)
  46. MC16 = models.CharField(max_length=255, null=True)
  47. MC19 = models.CharField(max_length=255, null=True)
  48. MC20 = models.CharField(max_length=255, null=True)
  49. MC21 = models.CharField(max_length=255, null=True)
  50. MC22 = models.CharField(max_length=255, null=True)
  51. MC23 = models.CharField(max_length=255, null=True)
  52. MC24 = models.CharField(max_length=255, null=True)
  53. # dbo.[MG-MAS-2]
  54. MP45 = models.CharField(max_length=255, null=True)
  55. MP49 = models.CharField(max_length=255, null=True)
  56. # dbo.[MG-MAS-3]
  57. MI13 = models.CharField(max_length=255, null=True)
  58. TC = models.CharField(max_length=255, null=True)
  59. MI14 = models.CharField(max_length=255, null=True)
  60. MI15 = models.CharField(max_length=255, null=True)
  61. MI16 = models.CharField(max_length=255, null=True)
  62. MI17 = models.CharField(max_length=255, null=True)
  63. MI18 = models.CharField(max_length=255, null=True)
  64. MI19 = models.CharField(max_length=255, null=True)
  65. MI20 = models.CharField(max_length=255, null=True)
  66. MI21 = models.CharField(max_length=255, null=True)
  67. MI22 = models.CharField(max_length=255, null=True)
  68. MI23 = models.CharField(max_length=255, null=True)
  69. MI31 = models.CharField(max_length=255, null=True)
  70. MI33 = models.CharField(max_length=255, null=True)
  71. INSAGM = models.CharField(max_length=255, null=True)
  72. MARAGM = models.CharField(max_length=255, null=True)
  73. MI53 = models.CharField(max_length=255, null=True)
  74. MI55 = models.CharField(max_length=255, null=True)
  75. MI36 = models.CharField(max_length=255, null=True)
  76. MI39 = models.CharField(max_length=255, null=True)
  77. MI24 = models.CharField(max_length=255, null=True)
  78. # MGT_Config.dbo.[TABLE_TI-T1], [TABLE_TI-T5], [TABLE_TI-T6]
  79. Ind1 = models.CharField(max_length=255, null=True) # TIT1NE
  80. Ind2 = models.CharField(max_length=255, null=True) # TIT5NE
  81. Ind3 = models.CharField(max_length=255, null=True) # TIT6NE
  82. # Conditional Fields
  83. AGR1 = models.CharField(max_length=255, null=True)
  84. AGR2 = models.CharField(max_length=255, null=True)
  85. ob_Condition = models.CharField(max_length=255, null=True) # TIT4NE
  86. class Meta:
  87. managed = False
  88. db_table = 'mg_master_view'
  89. app_label = "legacy"
  90. #db_table = 'MgMasterView_Full_Mockup_Data'
  91. class VMasterView(models.Model):
  92. # Fields from ProcessControl.dbo.[Q-PRO-DATA]
  93. PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
  94. PRO1 = models.CharField(max_length=255, null=True)
  95. PRO1C = models.CharField(max_length=255, null=True)
  96. PRO2 = models.CharField(max_length=255, null=True)
  97. PRO5 = models.CharField(max_length=255, null=True)
  98. PRO8 = models.CharField(max_length=255, null=True)
  99. PRO9 = models.CharField(max_length=255, null=True)
  100. PRO10 = models.CharField(max_length=255, null=True)
  101. PRO11 = models.CharField(max_length=255, null=True)
  102. PRO12 = models.CharField(max_length=255, null=True)
  103. PRO13 = models.CharField(max_length=255, null=True)
  104. PRO14 = models.CharField(max_length=255, null=True)
  105. PRO15 = models.CharField(max_length=255, null=True)
  106. PRO16 = models.CharField(max_length=255, null=True)
  107. PRO17 = models.CharField(max_length=255, null=True)
  108. PRO18 = models.CharField(max_length=255, null=True)
  109. PRO21 = models.CharField(max_length=255, null=True)
  110. PRO25 = models.CharField(max_length=255, null=True)
  111. PRO27 = models.CharField(max_length=255, null=True)
  112. P2 = models.CharField(max_length=255, null=True) # PRO-P2
  113. PRO6 = models.CharField(max_length=255, null=True)
  114. SPEED = models.CharField(max_length=255, null=True) # PRO-SPEED
  115. PRO_TOOL = models.CharField(max_length=255, null=True) # PRO-TOOL
  116. PRO4 = models.CharField(max_length=255, null=True)
  117. # Fields from dbo.[V-MAS-1]
  118. MC11 = models.CharField(max_length=255, null=True)
  119. MC12 = models.CharField(max_length=255, null=True)
  120. MC14 = models.CharField(max_length=255, null=True)
  121. MC15 = models.CharField(max_length=255, null=True)
  122. MC16 = models.CharField(max_length=255, null=True)
  123. MC19 = models.CharField(max_length=255, null=True)
  124. MC20 = models.CharField(max_length=255, null=True)
  125. MC21 = models.CharField(max_length=255, null=True)
  126. MC22 = models.CharField(max_length=255, null=True)
  127. MC23 = models.CharField(max_length=255, null=True)
  128. MC24 = models.CharField(max_length=255, null=True)
  129. # Fields from dbo.[V-MAS-2]
  130. MP34 = models.CharField(max_length=255, null=True)
  131. MP39 = models.CharField(max_length=255, null=True)
  132. # Fields from dbo.[V-MAS-3]
  133. MI13 = models.CharField(max_length=255, null=True)
  134. TC = models.CharField(max_length=255, null=True)
  135. MI14 = models.CharField(max_length=255, null=True)
  136. MI15 = models.CharField(max_length=255, null=True)
  137. MI16 = models.CharField(max_length=255, null=True)
  138. MI17 = models.CharField(max_length=255, null=True)
  139. MI18 = models.CharField(max_length=255, null=True)
  140. MI19 = models.CharField(max_length=255, null=True)
  141. MI20 = models.CharField(max_length=255, null=True)
  142. MI21 = models.CharField(max_length=255, null=True)
  143. MI22 = models.CharField(max_length=255, null=True)
  144. MI23 = models.CharField(max_length=255, null=True)
  145. MI31 = models.CharField(max_length=255, null=True)
  146. MI33 = models.CharField(max_length=255, null=True)
  147. INSAGM = models.CharField(max_length=255, null=True)
  148. MARAGM = models.CharField(max_length=255, null=True)
  149. MI53 = models.CharField(max_length=255, null=True)
  150. MI55 = models.CharField(max_length=255, null=True)
  151. MI36 = models.CharField(max_length=255, null=True)
  152. MI39 = models.CharField(max_length=255, null=True)
  153. MI24 = models.CharField(max_length=255, null=True)
  154. # Fields from MGT_Config.dbo.[TABLE_TI-T1], [TABLE_TI-T5], [TABLE_TI-T6]
  155. Ind1 = models.CharField(max_length=255, null=True) # TIT1NE
  156. Ind2 = models.CharField(max_length=255, null=True) # TIT5NE
  157. Ind3 = models.CharField(max_length=255, null=True) # TIT6NE
  158. # Conditional Fields
  159. AGR1 = models.CharField(max_length=255, null=True)
  160. AGR2 = models.CharField(max_length=255, null=True)
  161. ob_Condition = models.CharField(max_length=255, null=True) # TIT4NE
  162. class Meta:
  163. managed = False
  164. #db_table = 'VMasterView_Full_Mockup_Data'
  165. db_table = 'v_master_view'
  166. app_label = "legacy"
  167. class VwRotateLog(models.Model):
  168. # Fields from the SQL view
  169. PROD_CODE = models.CharField(max_length=255, null=True)
  170. LOT_NO = models.CharField(max_length=255, null=True)
  171. SPEED_SPEC = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  172. SPEED_TEST = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  173. SPEED_NG = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  174. CREATED_DT = models.DateTimeField(null=True)
  175. LAST_UPD_DT = models.DateTimeField(null=True)
  176. QTY = models.IntegerField(null=True)
  177. STATION_NO = models.CharField(max_length=255, null=True)
  178. class Meta:
  179. managed = False # This model corresponds to a database view
  180. db_table = 'VwRotateLog_Mockup_Data'
  181. class VwRotateResult(models.Model):
  182. # Fields from the SQL view
  183. PROD_CODE = models.CharField(max_length=255, null=True)
  184. LOT_NO = models.CharField(max_length=255, null=True)
  185. SPEED_SPEC = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  186. QTY = models.IntegerField(null=True)
  187. STATION_NO = models.CharField(max_length=255, null=True)
  188. START_DT = models.DateTimeField(null=True) # T1.TEST_DT as START_DT
  189. TEST_NO = models.CharField(max_length=255, null=True)
  190. SPEED_TEST_VAL = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  191. SPEED_NG_VAL = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  192. TEST_END_DT = models.DateTimeField(null=True) # T2.TEST_DT as TEST_END_DT
  193. class Meta:
  194. managed = False # This model corresponds to a database view
  195. db_table = 'VW_ROTATE_RESULT' # Name of the database view
  196. class BelMasterView(models.Model):
  197. # Fields from ProcessControl.dbo.[Q-PRO-DATA]
  198. PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
  199. PRO1 = models.CharField(max_length=255, null=True)
  200. PRO1C = models.CharField(max_length=255, null=True)
  201. PRO2 = models.CharField(max_length=255, null=True)
  202. PRO5 = models.CharField(max_length=255, null=True)
  203. PRO8 = models.CharField(max_length=255, null=True)
  204. PRO9 = models.CharField(max_length=255, null=True)
  205. PRO10 = models.CharField(max_length=255, null=True)
  206. PRO11 = models.CharField(max_length=255, null=True)
  207. PRO12 = models.CharField(max_length=255, null=True)
  208. PRO13 = models.CharField(max_length=255, null=True)
  209. PRO14 = models.CharField(max_length=255, null=True)
  210. PRO15 = models.CharField(max_length=255, null=True)
  211. PRO16 = models.CharField(max_length=255, null=True)
  212. PRO17 = models.CharField(max_length=255, null=True)
  213. PRO18 = models.CharField(max_length=255, null=True)
  214. PRO21 = models.CharField(max_length=255, null=True)
  215. PRO25 = models.CharField(max_length=255, null=True)
  216. PRO27 = models.CharField(max_length=255, null=True)
  217. P2 = models.CharField(max_length=255, null=True) # PRO-P2
  218. PRO6 = models.CharField(max_length=255, null=True)
  219. SPEED = models.CharField(max_length=255, null=True) # PRO-SPEED
  220. PRO_TOOL = models.CharField(max_length=255, null=True) # PRO-TOOL
  221. PRO4 = models.CharField(max_length=255, null=True)
  222. # Fields from dbo.[BEL-MAS-1]
  223. MC11 = models.CharField(max_length=255, null=True)
  224. MC12 = models.CharField(max_length=255, null=True)
  225. MC14 = models.CharField(max_length=255, null=True)
  226. MC15 = models.CharField(max_length=255, null=True)
  227. MC16 = models.CharField(max_length=255, null=True)
  228. MC19 = models.CharField(max_length=255, null=True)
  229. MC20 = models.CharField(max_length=255, null=True)
  230. MC21 = models.CharField(max_length=255, null=True)
  231. MC22 = models.CharField(max_length=255, null=True)
  232. MC23 = models.CharField(max_length=255, null=True)
  233. MC24 = models.CharField(max_length=255, null=True)
  234. # Fields from dbo.[BEL-MAS-2]
  235. MP45 = models.CharField(max_length=255, null=True)
  236. MP49 = models.CharField(max_length=255, null=True)
  237. # Fields from dbo.[BEL-MAS-3]
  238. MI13 = models.CharField(max_length=255, null=True)
  239. TC = models.CharField(max_length=255, null=True)
  240. MI14 = models.CharField(max_length=255, null=True)
  241. MI15 = models.CharField(max_length=255, null=True)
  242. MI16 = models.CharField(max_length=255, null=True)
  243. MI17 = models.CharField(max_length=255, null=True)
  244. MI18 = models.CharField(max_length=255, null=True)
  245. MI19 = models.CharField(max_length=255, null=True)
  246. MI20 = models.CharField(max_length=255, null=True)
  247. MI21 = models.CharField(max_length=255, null=True)
  248. MI22 = models.CharField(max_length=255, null=True)
  249. MI23 = models.CharField(max_length=255, null=True)
  250. MI31 = models.CharField(max_length=255, null=True)
  251. MI33 = models.CharField(max_length=255, null=True)
  252. INSAGM = models.CharField(max_length=255, null=True)
  253. MARAGM = models.CharField(max_length=255, null=True)
  254. MI53 = models.CharField(max_length=255, null=True)
  255. MI55 = models.CharField(max_length=255, null=True)
  256. MI36 = models.CharField(max_length=255, null=True)
  257. MI39 = models.CharField(max_length=255, null=True)
  258. MI24 = models.CharField(max_length=255, null=True)
  259. # Fields from MGT_Config.dbo.[TABLE_TI-T1], [TABLE_TI-T5], [TABLE_TI-T6]
  260. Ind1 = models.CharField(max_length=255, null=True) # TIT1NE
  261. Ind2 = models.CharField(max_length=255, null=True) # TIT5NE
  262. Ind3 = models.CharField(max_length=255, null=True) # TIT6NE
  263. # Conditional Fields
  264. AGR1 = models.CharField(max_length=255, null=True)
  265. AGR2 = models.CharField(max_length=255, null=True)
  266. ob_Condition = models.CharField(max_length=255, null=True) # TIT4NE
  267. class Meta:
  268. managed = False # This model corresponds to a database view
  269. app_label = "legacy"
  270. db_table = 'bel_master_view' # Name of the database view
  271. class EMasterView(models.Model):
  272. # Fields from ProcessControl.dbo.[Q-PRO-DATA]
  273. PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
  274. PRO1 = models.CharField(max_length=255, null=True)
  275. PRO1C = models.CharField(max_length=255, null=True)
  276. PRO2 = models.CharField(max_length=255, null=True)
  277. PRO5 = models.CharField(max_length=255, null=True)
  278. PRO8 = models.CharField(max_length=255, null=True)
  279. PRO9 = models.CharField(max_length=255, null=True)
  280. PRO10 = models.CharField(max_length=255, null=True)
  281. PRO11 = models.CharField(max_length=255, null=True)
  282. PRO12 = models.CharField(max_length=255, null=True)
  283. PRO13 = models.CharField(max_length=255, null=True)
  284. PRO14 = models.CharField(max_length=255, null=True)
  285. PRO15 = models.CharField(max_length=255, null=True)
  286. PRO16 = models.CharField(max_length=255, null=True)
  287. PRO17 = models.CharField(max_length=255, null=True)
  288. PRO18 = models.CharField(max_length=255, null=True)
  289. PRO21 = models.CharField(max_length=255, null=True)
  290. PRO25 = models.CharField(max_length=255, null=True)
  291. PRO27 = models.CharField(max_length=255, null=True)
  292. P2 = models.CharField(max_length=255, null=True) # PRO-P2
  293. PRO6 = models.CharField(max_length=255, null=True)
  294. SPEED = models.CharField(max_length=255, null=True) # PRO-SPEED
  295. PRO_TOOL = models.CharField(max_length=255, null=True) # PRO-TOOL
  296. PRO4 = models.CharField(max_length=255, null=True)
  297. # Fields from dbo.[E-MAS-1]
  298. MC11 = models.CharField(max_length=255, null=True)
  299. MC12 = models.CharField(max_length=255, null=True)
  300. MC14 = models.CharField(max_length=255, null=True)
  301. MC15 = models.CharField(max_length=255, null=True)
  302. MC16 = models.CharField(max_length=255, null=True)
  303. MC19 = models.CharField(max_length=255, null=True)
  304. MC20 = models.CharField(max_length=255, null=True)
  305. MC21 = models.CharField(max_length=255, null=True)
  306. MC22 = models.CharField(max_length=255, null=True)
  307. MC23 = models.CharField(max_length=255, null=True)
  308. MC24 = models.CharField(max_length=255, null=True)
  309. # Fields from dbo.[E-MAS-2]
  310. MP45 = models.CharField(max_length=255, null=True)
  311. MP49 = models.CharField(max_length=255, null=True)
  312. # Fields from dbo.[E-MAS-3]
  313. MI13 = models.CharField(max_length=255, null=True)
  314. TC = models.CharField(max_length=255, null=True)
  315. MI14 = models.CharField(max_length=255, null=True)
  316. MI15 = models.CharField(max_length=255, null=True)
  317. MI16 = models.CharField(max_length=255, null=True)
  318. MI17 = models.CharField(max_length=255, null=True)
  319. MI18 = models.CharField(max_length=255, null=True)
  320. MI19 = models.CharField(max_length=255, null=True)
  321. MI20 = models.CharField(max_length=255, null=True)
  322. MI21 = models.CharField(max_length=255, null=True)
  323. MI22 = models.CharField(max_length=255, null=True)
  324. MI23 = models.CharField(max_length=255, null=True)
  325. MI31 = models.CharField(max_length=255, null=True)
  326. MI33 = models.CharField(max_length=255, null=True)
  327. INSAGM = models.CharField(max_length=255, null=True)
  328. MARAGM = models.CharField(max_length=255, null=True)
  329. MI53 = models.CharField(max_length=255, null=True)
  330. MI55 = models.CharField(max_length=255, null=True)
  331. MI36 = models.CharField(max_length=255, null=True)
  332. MI39 = models.CharField(max_length=255, null=True)
  333. MI24 = models.CharField(max_length=255, null=True)
  334. # Fields from MGT_Config.dbo.[TABLE_TI-T1], [TABLE_TI-T5], [TABLE_TI-T6]
  335. Ind1 = models.CharField(max_length=255, null=True) # TIT1NE
  336. Ind2 = models.CharField(max_length=255, null=True) # TIT5NE
  337. Ind3 = models.CharField(max_length=255, null=True) # TIT6NE
  338. # Conditional Fields
  339. AGR1 = models.CharField(max_length=255, null=True)
  340. AGR2 = models.CharField(max_length=255, null=True)
  341. ob_Condition = models.CharField(max_length=255, null=True) # TIT4NE
  342. class Meta:
  343. managed = False # This model corresponds to a database view
  344. app_label = "legacy"
  345. db_table = 'e_master_view' # Name of the database view
  346. class AllProductAverageObMinMaxView(models.Model):
  347. ProductCode = models.CharField(max_length=255, null=True) # RE01
  348. out_min = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Minimum of [OB-O]
  349. out_max = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Maximum of [OB-O]
  350. in_min = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Minimum of [OB-I]
  351. in_max = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Maximum of [OB-I]
  352. class Meta:
  353. managed = False # This model corresponds to a database view
  354. app_label = "legacy"
  355. db_table = 'AllProduct_Average_OB_MIN_MAX_view' # Name of the database view
  356. class AllProductDimensionForInsProcess(models.Model):
  357. ProdType = models.CharField(max_length=255, null=True) # Product type (e.g., 'V', 'E', 'BEL', 'MG')
  358. ProductCode = models.CharField(max_length=255, primary_key=True) # Product code# Product code
  359. Size_Id = models.CharField(max_length=255, null=True) # Size ID (e.g., '001', '002')
  360. Size_Name = models.CharField(max_length=255, null=True) # Size name (e.g., 'D', 'T', 'H')
  361. Std = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Standard value
  362. TolUn = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Tolerance lower limit
  363. TolUp = models.DecimalField(max_digits=10, decimal_places=2, null=True) # Tolerance upper limit
  364. class Meta:
  365. managed = False # This model corresponds to a database view
  366. app_label = "legacy"
  367. db_table = 'AllProduct_Dimension_ForInsProcess' # Name of the database view
  368. class AllProductPressPositionPressWeight(models.Model):
  369. ProductCode = models.CharField(max_length=255, null=True)
  370. Lot_No = models.CharField(max_length=255, null=True)
  371. PO_Qty = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  372. UWeight = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  373. Current_ProNo = models.CharField(max_length=255, null=True)
  374. Press_Time = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  375. PressType_1 = models.CharField(max_length=255, null=True)
  376. PressWeight_1 = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  377. PressType_2 = models.CharField(max_length=255, null=True)
  378. PressWeight_2 = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  379. Press_Ton = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  380. Press_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  381. Press_T_Tol = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  382. Mold_D = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  383. Mold_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  384. SegMold_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  385. SegMold_D = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  386. Center_D = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  387. Center_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  388. LowerPlate_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  389. StudPlate_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  390. UpperPlate_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  391. PinPlate_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  392. TopConcave_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  393. BottomConcave_T = models.DecimalField(max_digits=10, decimal_places=2, null=True)
  394. class Meta:
  395. managed = False # This model corresponds to a database view
  396. app_label = "legacy"
  397. db_table = 'AllProduct_PressPosition_PressWeight' # Name of the database view
  398. class RotateBrokenTest(models.Model):
  399. row_no = models.IntegerField(null=True, blank=True)
  400. speed_spec = models.FloatField(null=True, blank=True)
  401. speed_test = models.FloatField(null=True, blank=True)
  402. speedOk = models.CharField(max_length=4, null=True, blank=True)
  403. qty = models.IntegerField()
  404. station_no = models.IntegerField()
  405. created_at = models.DateTimeField(null=True, blank=True)
  406. updated_at = models.DateTimeField(null=True, blank=True)
  407. lot_no = models.CharField(max_length=50, null=True, blank=True)
  408. machine_id = models.IntegerField(null=True, blank=True)
  409. code = models.CharField(max_length=50, null=True, blank=True)
  410. emp_id = models.IntegerField()
  411. devid = models.CharField(max_length=40, null=True, blank=True)
  412. mode = models.CharField(max_length=10, null=True, blank=True)
  413. cal_mode = models.IntegerField(null=True, blank=True)
  414. class Meta:
  415. managed = False # This model corresponds to a database view
  416. app_label = "legacy"
  417. db_table = "rotate_broken_test" # Matches SQL Server table name
  418. class LotType(models.Model):
  419. lot_no = models.CharField(primary_key=True,max_length=20, db_column='LotNo')
  420. group = models.CharField(max_length=10, db_column='Group')
  421. sub_group = models.CharField(max_length=10, db_column='SubGroup')
  422. class Meta:
  423. db_table = 'T-LotType'
  424. managed = False # Since it's an existing table in SQL Server
  425. app_label = "trans"
  426. TEMPLATE_CHOICES = [
  427. "hardness_out",
  428. "hardness_out_in",
  429. "hardness_both_size",
  430. "dimension",
  431. "dimension_app",
  432. "dimension_bal_weight",
  433. "dim_bal_app_hard",
  434. "dim_bal_app_rot_hard",
  435. "thickness_8_point",
  436. "centering"
  437. ]
  438. class CustomerTemplateMapping(models.Model):
  439. customer_name = models.CharField(max_length=255)
  440. template_names = models.JSONField(default=list, blank=True, null=True) # stores list of template names
  441. created_by = models.ForeignKey(
  442. User,
  443. on_delete=models.SET_NULL,
  444. null=True,
  445. blank=True,
  446. ) # Reference to the user who created the report
  447. created_at = models.DateTimeField(auto_now_add=True) # Automatically set when created
  448. updated_at = models.DateTimeField(auto_now=True) # Automatically updated when modified
  449. def __str__(self):
  450. return self.customer_name
  451. class ProductDrawing(models.Model):
  452. code_no = models.CharField(max_length=100, null=True, blank=True)
  453. code_no_mks = models.CharField(max_length=100, null=True, blank=True)
  454. lot_no = models.CharField(max_length=100, null=True, blank=True)
  455. drawing = models.ImageField(upload_to='drawings/')
  456. description = models.TextField(null=True, blank=True)
  457. created_at = models.DateTimeField(auto_now_add=True)
  458. updated_at = models.DateTimeField(auto_now=True)
  459. created_by = models.ForeignKey(
  460. User,
  461. on_delete=models.SET_NULL,
  462. null=True,
  463. blank=True,
  464. ) # Reference to the user who created the report
  465. def __str__(self):
  466. return f"{self.code_no} - {self.lot_no}"
  467. class MksCodeMap(models.Model):
  468. mgt_code = models.CharField(max_length=100)
  469. mks_code = models.CharField(max_length=100)
  470. created_at = models.DateTimeField(auto_now_add=True)
  471. updated_at = models.DateTimeField(auto_now=True)
  472. def __str__(self):
  473. return f"{self.mgt_code} ⇄ {self.mks_code}"