tum 10 月之前
父節點
當前提交
f98beedea7

+ 4 - 1
app/coi/urls.py

@@ -19,10 +19,13 @@ from django.contrib import admin
19 19
 from django.urls import path, include
20 20
 from django.conf.urls.static import static
21 21
 from django.conf import settings
22
+from report.views import coi_view
23
+
22 24
 
23 25
 urlpatterns = [
24 26
     path("admin/", admin.site.urls),
25
-    path('', include('dashboard.urls')),  # Include dashboard app's URLs
27
+    # path('', coi_view, name='home'),
28
+    path('', include('dashboard.urls')),  # include dashboard app's urls
26 29
     path('report/', include('report.urls')),  # Include report app's URLs
27 30
     path('sysadmin/', include('sysadmin.urls')),  # Include sysadmin app's URLs
28 31
     path('legacy/', include('legacy.urls')),  # Include legacy app's URLs

+ 23 - 0
app/core/migrations/0009_mkscodemap.py

@@ -0,0 +1,23 @@
1
+# Generated by Django 4.2 on 2025-05-10 06:27
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('core', '0008_productdrawing'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.CreateModel(
14
+            name='MksCodeMap',
15
+            fields=[
16
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17
+                ('mgt_code', models.CharField(max_length=100)),
18
+                ('mks_code', models.CharField(max_length=100)),
19
+                ('created_at', models.DateTimeField(auto_now_add=True)),
20
+                ('updated_at', models.DateTimeField(auto_now=True)),
21
+            ],
22
+        ),
23
+    ]

+ 13 - 4
app/core/models.py

@@ -41,7 +41,7 @@ class MgMasterView(models.Model):
41 41
     PRO27 = models.CharField(max_length=255, null=True)
42 42
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
43 43
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
44
-    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
44
+    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
45 45
     PRO4 = models.CharField(max_length=255, null=True)
46 46
     
47 47
     # dbo.[MG-MAS-1]
@@ -124,7 +124,7 @@ class VMasterView(models.Model):
124 124
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
125 125
     PRO6 = models.CharField(max_length=255, null=True)
126 126
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
127
-    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
127
+    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
128 128
     PRO4 = models.CharField(max_length=255, null=True)
129 129
     
130 130
     # Fields from dbo.[V-MAS-1]
@@ -244,7 +244,7 @@ class BelMasterView(models.Model):
244 244
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
245 245
     PRO6 = models.CharField(max_length=255, null=True)
246 246
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
247
-    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
247
+    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
248 248
     PRO4 = models.CharField(max_length=255, null=True)
249 249
     
250 250
     # Fields from dbo.[BEL-MAS-1]
@@ -326,7 +326,7 @@ class EMasterView(models.Model):
326 326
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
327 327
     PRO6 = models.CharField(max_length=255, null=True)
328 328
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
329
-    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
329
+    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
330 330
     PRO4 = models.CharField(max_length=255, null=True)
331 331
     
332 332
     # Fields from dbo.[E-MAS-1]
@@ -521,3 +521,12 @@ class ProductDrawing(models.Model):
521 521
     
522 522
     def __str__(self):
523 523
         return f"{self.code_no} - {self.lot_no}"
524
+
525
+class MksCodeMap(models.Model):
526
+    mgt_code = models.CharField(max_length=100)
527
+    mks_code = models.CharField(max_length=100)
528
+    created_at = models.DateTimeField(auto_now_add=True)
529
+    updated_at = models.DateTimeField(auto_now=True)
530
+
531
+    def __str__(self):
532
+        return f"{self.mgt_code} ⇄ {self.mks_code}"

+ 25 - 21
app/dashboard/templates/dashboard/index.html

@@ -9,48 +9,52 @@
9 9
         <!-- Card 1 -->
10 10
         <div class="bg-white p-6 rounded-lg shadow-md">
11 11
             <h2 class="text-xl font-semibold text-gray-700">Total Users</h2>
12
-            <p class="text-gray-600 text-lg mt-2">150</p>
12
+            <p class="text-gray-600 text-lg mt-2">{{ total_users }}</p>
13 13
         </div>
14 14
         <!-- Card 2 -->
15 15
         <div class="bg-white p-6 rounded-lg shadow-md">
16 16
             <h2 class="text-xl font-semibold text-gray-700">Reports Generated</h2>
17
-            <p class="text-gray-600 text-lg mt-2">45</p>
17
+            <p class="text-gray-600 text-lg mt-2">{{ total_reports }}</p>
18 18
         </div>
19 19
         <!-- Card 3 -->
20 20
         <div class="bg-white p-6 rounded-lg shadow-md">
21 21
             <h2 class="text-xl font-semibold text-gray-700">Active Sessions</h2>
22
-            <p class="text-gray-600 text-lg mt-2">20</p>
22
+            <p class="text-gray-600 text-lg mt-2">{{ total_sessions }}</p>
23 23
         </div>
24 24
     </div>
25 25
 
26 26
     <div class="mt-8">
27
-        <h2 class="text-2xl font-bold text-gray-800 mb-4">Recent Activities</h2>
27
+        <h2 class="text-2xl font-bold text-gray-800 mb-4">Latest Reports</h2>
28 28
         <div class="bg-white rounded-lg shadow-md overflow-hidden">
29 29
             <table class="w-full border-collapse border border-gray-200">
30 30
                 <thead class="bg-gray-100">
31 31
                     <tr>
32 32
                         <th class="border border-gray-200 px-4 py-2 text-left">Date</th>
33
-                        <th class="border border-gray-200 px-4 py-2 text-left">Activity</th>
33
+                        <th class="border border-gray-200 px-4 py-2 text-left">Report Name</th>
34
+                        <th class="border border-gray-200 px-4 py-2 text-left">File</th>
34 35
                         <th class="border border-gray-200 px-4 py-2 text-left">User</th>
35 36
                     </tr>
36 37
                 </thead>
37 38
                 <tbody>
38
-                    <tr class="hover:bg-gray-50">
39
-                        <td class="border border-gray-200 px-4 py-2">2024-12-22</td>
40
-                        <td class="border border-gray-200 px-4 py-2">Generated a report</td>
41
-                        <td class="border border-gray-200 px-4 py-2">John Doe</td>
42
-                    </tr>
43
-                    <tr class="hover:bg-gray-50">
44
-                        <td class="border border-gray-200 px-4 py-2">2024-12-21</td>
45
-                        <td class="border border-gray-200 px-4 py-2">Logged in</td>
46
-                        <td class="border border-gray-200 px-4 py-2">Jane Smith</td>
47
-                    </tr>
48
-                    <tr class="hover:bg-gray-50">
49
-                        <td class="border border-gray-200 px-4 py-2">2024-12-20</td>
50
-                        <td class="border border-gray-200 px-4 py-2">Updated profile</td>
51
-                        <td class="border border-gray-200 px-4 py-2">Emily Johnson</td>
52
-                    </tr>
53
-                </tbody>
39
+  {% for report in latest_reports %}
40
+    <tr class="hover:bg-gray-50">
41
+      <td class="border border-gray-200 px-4 py-2">{{ report.created_at|date:"d/m/Y H:i" }}</td>
42
+      <td class="border border-gray-200 px-4 py-2">{{ report.name }}</td>
43
+      <td class="border border-gray-200 px-4 py-2">
44
+        {% if report.file %}
45
+        <a href="{{ report.file.url }}" target="_blank" class="text-blue-600 underline">View</a>
46
+        {% else %}
47
+        <span class="text-gray-400">No file</span>
48
+        {% endif %}
49
+      </td>
50
+      <td class="border border-gray-200 px-4 py-2">{{ report.created_by.username }}</td>
51
+    </tr>
52
+  {% empty %}
53
+    <tr>
54
+      <td colspan="3" class="text-center text-gray-500 py-2">No reports found.</td>
55
+    </tr>
56
+  {% endfor %}
57
+</tbody>
54 58
             </table>
55 59
         </div>
56 60
     </div>

+ 17 - 1
app/dashboard/views.py

@@ -1,6 +1,22 @@
1 1
 from django.contrib.auth.decorators import login_required
2 2
 from django.shortcuts import render
3
+from django.contrib.auth.models import User
4
+from django.contrib.sessions.models import Session
5
+from core.models import Report
6
+from django.utils.timezone import now
7
+
8
+
3 9
 
4 10
 @login_required
5 11
 def index_view(request):
6
-    return render(request, 'dashboard/index.html')
12
+    total_users = User.objects.count()
13
+    total_reports = Report.objects.count()
14
+    total_sessions = Session.objects.filter(expire_date__gt=now()).count()
15
+    latest_reports = Report.objects.order_by('-created_at')[:25]
16
+
17
+    return render(request, 'dashboard/index.html', {
18
+        'total_users': total_users,
19
+        'total_reports': total_reports,
20
+        'total_sessions': total_sessions,
21
+        'latest_reports': latest_reports,
22
+    })

二進制
app/report/coi_templates.xlsx


+ 10 - 1
app/report/filters.py

@@ -1,5 +1,5 @@
1 1
 import django_filters
2
-from core.models import Report, CustomerTemplateMapping, ProductDrawing
2
+from core.models import Report, CustomerTemplateMapping, ProductDrawing, MksCodeMap
3 3
 
4 4
 class ReportFilter(django_filters.FilterSet):
5 5
     name = django_filters.CharFilter(
@@ -55,3 +55,12 @@ class ProductDrawingFilter(django_filters.FilterSet):
55 55
     class Meta:
56 56
         model = ProductDrawing
57 57
         fields = ['code_no', 'code_no_mks', 'lot_no',]
58
+
59
+
60
+class MksCodeMapFilter(django_filters.FilterSet):
61
+    mgt_code = django_filters.CharFilter(lookup_expr='icontains', label='MGT Code')
62
+    mks_code = django_filters.CharFilter(lookup_expr='icontains', label='MKS Code')
63
+
64
+    class Meta:
65
+        model = MksCodeMap
66
+        fields = ['mgt_code', 'mks_code']

+ 8 - 4
app/report/templates/report/coi.html

@@ -6,7 +6,6 @@
6 6
 
7 7
 {% block content %}
8 8
 <div class="container mx-auto px-4 py-8" x-data="COIReport">
9
-
10 9
   <h1 class="text-2xl font-bold text-gray-800">Export Center</h1>
11 10
   <form method='post'>
12 11
     {% csrf_token %}
@@ -21,10 +20,11 @@
21 20
       <button class="bg-blue-100 text-blue-700 px-4 py-2 rounded hover:bg-blue-200">
22 21
         Option for Export :
23 22
       </button>
24
-        <div class="grid grid-cols-4 gap-4">
23
+        <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
25 24
         {% for key,value in SHEET_NAMES.items %}
26 25
         <label class="flex items-center space-x-1">
27
-          <input type="checkbox" class="rounded" name='exports' value='{{ key }}' x-model='exports' required>
26
+          <input type="checkbox" class="rounded" name='exports' value='{{ key }}'
27
+          x-model='exports' required>
28 28
           <span>{{ value }}</span>
29 29
         </label>
30 30
         {% endfor %}
@@ -102,6 +102,10 @@
102 102
                             <td class="border border-gray-300 px-4 py-2 font-medium text-gray-700">Shape | Size :</td>
103 103
                             <td class="border border-gray-300 px-4 py-2 text-gray-700">{{ size_str }}</td>
104 104
                         </tr>
105
+                        <tr class="bg-blue-100">
106
+                            <td class="border border-gray-300 px-4 py-2 font-medium text-gray-700">Tool :</td>
107
+                            <td class="border border-gray-300 px-4 py-2 text-gray-700">{{ result.PRO_TOOL }}</td>
108
+                        </tr>
105 109
                         <tr>
106 110
                             <td class="border border-gray-300 px-4 py-2 font-medium text-gray-700">Specification :</td>
107 111
                             <td class="border border-gray-300 px-4 py-2 text-gray-700">{{ spec }}</td>
@@ -148,7 +152,7 @@ th, td {
148 152
   function COIReport() {
149 153
     return {
150 154
       lot_no: '{{ lot_no }}', // Bind this to the input value
151
-      exports: [],
155
+      exports: {{ selected_templates|safe }},
152 156
       qa1: null,
153 157
       qa2: null,
154 158
       gen_report_url: '{% url "report:gen_report" %}', 

+ 7 - 1
app/report/urls.py

@@ -1,10 +1,11 @@
1 1
 from django.urls import path
2 2
 from . import views
3
-from .views import ReportCRUDView, CustomerTemplateCRUDView, ProductDrawingCRUDView
3
+from .views import ReportCRUDView, CustomerTemplateCRUDView, ProductDrawingCRUDView, MksCodeMapCRUDView
4 4
 
5 5
 report_crud = ReportCRUDView()
6 6
 customer_templates_crud = CustomerTemplateCRUDView()
7 7
 product_drawings_crud = ProductDrawingCRUDView()
8
+code_maps_crud = MksCodeMapCRUDView()
8 9
 
9 10
 app_name = "report"  # Use this namespace for reverse URL lookups
10 11
 
@@ -27,6 +28,11 @@ urlpatterns = [
27 28
     path('product_drawings/create/', product_drawings_crud.get_create_view().as_view(), name='product_drawings-create'),
28 29
     path('product_drawings/<str:pk>/update/', product_drawings_crud.get_update_view().as_view(), name='product_drawings-update'),
29 30
     path('product_drawings/<str:pk>/delete/', product_drawings_crud.get_delete_view().as_view(), name='product_drawings-delete'),
31
+    
32
+    path('code_maps/', code_maps_crud.get_list_view().as_view(), name='code_maps-list'),
33
+    path('code_maps/create/', code_maps_crud.get_create_view().as_view(), name='code_maps-create'),
34
+    path('code_maps/<str:pk>/update/', code_maps_crud.get_update_view().as_view(), name='code_maps-update'),
35
+    path('code_maps/<str:pk>/delete/', code_maps_crud.get_delete_view().as_view(), name='code_maps-delete'),
30 36
     # path('create/', views.create_report, name='create'),  # Create a new report
31 37
     # path('<int:pk>/', views.detail_report, name='detail'),  # View details of a specific report
32 38
     # path('<int:pk>/update/', views.update_report, name='update'),  # Update a specific report

+ 26 - 3
app/report/views.py

@@ -2,10 +2,10 @@ from django.shortcuts import render, redirect, get_object_or_404
2 2
 from django.core.paginator import Paginator
3 3
 from django.contrib import messages
4 4
 from core.models import Report, AllProductDimensionForInsProcess, CustomerTemplateMapping, \
5
-                ProductDrawing
5
+                ProductDrawing, MksCodeMap
6 6
 from core.forms import ReportForm, CustomerTemplateMappingForm, ProductDrawingForm
7 7
 from core.utils import ConfigurableCRUDView, queryFromMaster, SHEET_NAMES
8
-from .filters import ReportFilter, CustomerTemplateFilter, ProductDrawingFilter
8
+from .filters import ReportFilter, CustomerTemplateFilter, ProductDrawingFilter, MksCodeMapFilter
9 9
 from .forms import ExportOptionsForm
10 10
 from pprint import pprint
11 11
 
@@ -896,6 +896,7 @@ def create_coi_file(lot_no, sheets, user, md):
896 896
         # "hardness_out.spe_acc": False,  # Hide rows 24 to 28 if the prefix is "0"
897 897
         "acc": accept,  # Hide rows 24 to 28 if the prefix is "0"
898 898
         "spe_acc": specialAccept,  # Hide rows 24 to 28 if the prefix is "0"
899
+        "tool": first_result.PRO_TOOL,
899 900
         # "hardness_out.qa1": f"{qa1.first_name} {qa1.last_name}",
900 901
         # "hardness_out.qa2": f"{qa2.first_name} {qa2.last_name}",
901 902
         "qa1": f"{qa1.first_name} {qa1.last_name}",
@@ -1011,6 +1012,7 @@ def coi_view(request):
1011 1012
             if lot_no:
1012 1013
                 results = queryFromMaster(lot_no)
1013 1014
                 first_result = results[0] if results else None
1015
+                selected_templates = None
1014 1016
                 try:
1015 1017
                     pcs = int(first_result.PRO5) - int(first_result.PRO27)
1016 1018
                 except:
@@ -1018,6 +1020,8 @@ def coi_view(request):
1018 1020
                 if first_result:
1019 1021
                     size_str = f"{first_result.PRO10}x{first_result.PRO11}x{first_result.PRO12}";
1020 1022
                     spec = f"{first_result.PRO13} {first_result.PRO14} {first_result.PRO15} {first_result.PRO16} {first_result.PRO17} {first_result.PRO18}"
1023
+                    #first_result.PRO1C = "TUM"
1024
+                    selected_templates  = CustomerTemplateMapping.objects.filter(customer_name=first_result.PRO1C).first().template_names
1021 1025
                 else:
1022 1026
                     size_str = ""
1023 1027
                     spec = ""
@@ -1036,7 +1040,7 @@ def coi_view(request):
1036 1040
                                                            'size_str': size_str,
1037 1041
                                                            'lot_no': lot_no,
1038 1042
                                                            'spec': spec, 'users': users, 'SHEET_NAMES': SHEET_NAMES, 
1039
-                                                           'results': results, 'fields': fields})
1043
+                                                           'results': results, 'fields': fields, 'selected_templates': selected_templates})
1040 1044
 
1041 1045
         messages.success(request, "Request Sent")
1042 1046
         return redirect(request.path_info)
@@ -1155,3 +1159,22 @@ class ProductDrawingCRUDView(ConfigurableCRUDView):
1155 1159
     form_class = ProductDrawingForm
1156 1160
 
1157 1161
 
1162
+class MksCodeMapCRUDView(ConfigurableCRUDView):
1163
+    model = MksCodeMap
1164
+    page_title = "MKS Code Mapping"
1165
+    filterset_class = MksCodeMapFilter
1166
+
1167
+    list_template_name = "legacy/datacrud_list.html"
1168
+    detail_template_name = "legacy/datacrud_detail.html"
1169
+    form_template_name = 'legacy/datacrud_form.html'
1170
+    confirm_delete_template_name = "legacy/datacrud_confirm_delete.html"
1171
+
1172
+    config_fields = ["id", "mgt_code", "mks_code", "created_at"]
1173
+    config_edit_fields = ["mgt_code", "mks_code"]
1174
+
1175
+    list_url_name = "report:code_maps-list"
1176
+    create_url_name = "report:code_maps-create"
1177
+    update_url_name = "report:code_maps-update"
1178
+    delete_url_name = "report:code_maps-delete"
1179
+
1180
+    ordering = ["-created_at", "-id"]

二進制
app/report/~$coi_templates.xlsx


File diff suppressed because it is too large
+ 45 - 10
app/templates/base.html