tum 11 ヶ月 前
コミット
837370063b
共有4 個のファイルを変更した197 個の追加25 個の削除を含む
  1. BIN
      app/report/coi_templates.xlsx
  2. 4 2
      app/report/gen_report.py
  3. 9 5
      app/report/templates/report/coi.html
  4. 184 18
      app/report/views.py

BIN
app/report/coi_templates.xlsx


+ 4 - 2
app/report/gen_report.py

242
                             cell.value = value
242
                             cell.value = value
243
 
243
 
244
         for key, value in data.items():
244
         for key, value in data.items():
245
-            if isinstance(value, str) and re.match(r"^\d+\[\d+:\d+\]$", value):
245
+            # if isinstance(value, str) and re.match(r"^\d+\[\d+:\d+\]$", value):
246
+            if isinstance(value, str) and re.match(r"^[0-9\s]+\[\d+:\d+\]$", value):
246
                 # Parse the prefix and row range
247
                 # Parse the prefix and row range
247
                 prefix, row_range = value.split("[")
248
                 prefix, row_range = value.split("[")
248
                 row_start, row_end = map(int, row_range[:-1].split(":"))
249
                 row_start, row_end = map(int, row_range[:-1].split(":"))
249
                 
250
                 
250
                 # Hide rows if the prefix matches the condition
251
                 # Hide rows if the prefix matches the condition
251
-                if prefix == "0":  # Adjust the condition as needed
252
+                # if prefix == "0":  # Adjust the condition as needed
253
+                if " " in prefix or prefix.strip() == "0":
252
                     sheet.row_dimensions.group(row_start, row_end, hidden=True)
254
                     sheet.row_dimensions.group(row_start, row_end, hidden=True)
253
         
255
         
254
 
256
 

+ 9 - 5
app/report/templates/report/coi.html

18
         🔍
18
         🔍
19
       </button>
19
       </button>
20
     </div>
20
     </div>
21
+  </form>
21
       <button class="bg-blue-100 text-blue-700 px-4 py-2 rounded hover:bg-blue-200">
22
       <button class="bg-blue-100 text-blue-700 px-4 py-2 rounded hover:bg-blue-200">
22
         Option for Export :
23
         Option for Export :
23
       </button>
24
       </button>
73
           </div>
74
           </div>
74
           <!-- TODO: add download here -->
75
           <!-- TODO: add download here -->
75
           <div class=" text-center" x-show="downloadUrl">
76
           <div class=" text-center" x-show="downloadUrl">
76
-            <a :href="downloadUrl"  class="block px-4 py-2 bg-green-600 text-white  rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2" download>
77
-              Download Report
77
+            <a :href="downloadUrl"  class="block px-4 py-2 bg-green-600 text-white  rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2" download x-text="downText">
78
             </a>
78
             </a>
79
           </div>
79
           </div>
80
         </div>
80
         </div>
81
-  </form>
82
   {{ result }}
81
   {{ result }}
83
   
82
   
84
   <div class="bg-white shadow-md rounded-md p-4">
83
   <div class="bg-white shadow-md rounded-md p-4">
157
       gen_report_url: '{% url "report:gen_report" %}', 
156
       gen_report_url: '{% url "report:gen_report" %}', 
158
       acceptStatus: 'accepted', 
157
       acceptStatus: 'accepted', 
159
       downloadUrl: null, // Stores the download link after export success
158
       downloadUrl: null, // Stores the download link after export success
159
+      downText: "Download Excel",
160
       init() {
160
       init() {
161
         //alert("COI Report");
161
         //alert("COI Report");
162
         this.qa1 = '';
162
         this.qa1 = '';
189
                       qa2: this.qa2,
189
                       qa2: this.qa2,
190
                       acceptStatus: this.acceptStatus
190
                       acceptStatus: this.acceptStatus
191
                   });
191
                   });
192
-
192
+                  this.downText = "Processing ..."
193
                   if (response.status === 200) {
193
                   if (response.status === 200) {
194
                       const result = response.data;
194
                       const result = response.data;
195
-                      alert(`Report generated successfully: ${result.file_url}`);
195
+                      //alert(`Report generated successfully: ${result.file_url}`);
196
+                      this.downText = "Download Excel"
196
                       console.log('File URL:', result.file_url);
197
                       console.log('File URL:', result.file_url);
197
                       this.downloadUrl = result.file_url; // Set the download URL
198
                       this.downloadUrl = result.file_url; // Set the download URL
199
+                  }else {
200
+                      this.downText = "Error ..."
198
                   }
201
                   }
199
               } catch (error) {
202
               } catch (error) {
203
+                  this.downText = "Error ..."
200
                   if (error.response) {
204
                   if (error.response) {
201
                       // Server responded with a status other than 2xx
205
                       // Server responded with a status other than 2xx
202
                       alert(`Error: ${error.response.data.message || 'Failed to generate report'}`);
206
                       alert(`Error: ${error.response.data.message || 'Failed to generate report'}`);

+ 184 - 18
app/report/views.py

22
 from legacy.models import Data
22
 from legacy.models import Data
23
 from django.conf import settings
23
 from django.conf import settings
24
 
24
 
25
+from itertools import chain
26
+
27
+
25
 def index(request):
28
 def index(request):
26
     reports = Report.objects.all()
29
     reports = Report.objects.all()
27
     report_filter = ReportFilter(request.GET, queryset=reports)
30
     report_filter = ReportFilter(request.GET, queryset=reports)
166
     placeholders = {}
169
     placeholders = {}
167
     for i in range(1, n + 1):
170
     for i in range(1, n + 1):
168
         for j in range(1, m + 1):
171
         for j in range(1, m + 1):
169
-            placeholders[f'v{i}_{j}'] = 0
172
+            placeholders[f'v{i}_{j}'] = " "
170
     return placeholders
173
     return placeholders
171
 
174
 
172
 # # Example usage:
175
 # # Example usage:
283
             placeholders[f'v3_2'] = r.hsize
286
             placeholders[f'v3_2'] = r.hsize
284
             placeholders[f'v3_3'] = r.hsizeok
287
             placeholders[f'v3_3'] = r.hsizeok
285
 
288
 
286
-            if is_ok(r):
287
-                placeholders[f'v4_1'] = 'OK'
288
-                placeholders[f'v4_2'] = 'OK'
289
-            else:
290
-                placeholders[f'v4_1'] = 'NG'
291
-                placeholders[f'v4_2'] = 'OK'
289
+            # if is_ok(r):
290
+                # placeholders[f'v4_1'] = 'OK'
291
+                # placeholders[f'v4_2'] = 'OK'
292
+            # else:
293
+                # placeholders[f'v4_1'] = 'NG'
294
+                # placeholders[f'v4_2'] = 'OK'
292
         
295
         
293
         if r.row_no == 2:
296
         if r.row_no == 2:
294
             placeholders[f'v5_2'] = r.dsize
297
             placeholders[f'v5_2'] = r.dsize
300
             placeholders[f'v7_2'] = r.hsize
303
             placeholders[f'v7_2'] = r.hsize
301
             placeholders[f'v7_3'] = r.hsizeok
304
             placeholders[f'v7_3'] = r.hsizeok
302
 
305
 
303
-            if is_ok(r):
304
-                placeholders[f'v8_1'] = 'OK'
305
-                placeholders[f'v8_2'] = 'OK'
306
-            else:
307
-                placeholders[f'v8_1'] = 'NG'
308
-                placeholders[f'v8_2'] = 'NG'
306
+            # if is_ok(r):
307
+                # placeholders[f'v8_1'] = 'OK'
308
+                # placeholders[f'v8_2'] = 'OK'
309
+            # else:
310
+                # placeholders[f'v8_1'] = 'NG'
311
+                # placeholders[f'v8_2'] = 'NG'
309
 
312
 
310
     hide_con(placeholders, "v5_1", "26:32")
313
     hide_con(placeholders, "v5_1", "26:32")
311
     return placeholders
314
     return placeholders
312
 
315
 
316
+def generate_dim_bal_app_hard_values(lot_no, first_result):
317
+    """
318
+    Fetch dimension records from manualSize and DataMs models
319
+    and generate placeholder values for Standard, Actual, and Judgement.
320
+    Supports two row_no entries per lot.
321
+    """
322
+    # Fetch standard values from manualSize (limit to 2 rows)
323
+    manual_size_records = Manualsize.objects.filter(lotno=lot_no)
324
+
325
+    # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
326
+    data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')[:2]
327
+    data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')[:2]
328
+    
329
+    data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no')[:2])
330
+    data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no')[:2])
331
+
332
+    data_ho = list(chain(data_h1, data_h2))
333
+
334
+    if first_result:
335
+        out_limit = f"Out 外  ({first_result.MI18} - {first_result.MI19})"
336
+        in_limit = f"In 内 ({first_result.MI22} - {first_result.MI23})"
337
+        mid_limit = f"Middle   中  -"
338
+    else:
339
+        out_limit = f"Out 外"
340
+        in_limit = f"In 内"
341
+        mid_limit = f"Middle   中"
342
+    
343
+    
344
+
345
+    # Prepare placeholders
346
+
347
+    # placeholders = {}
348
+    placeholders = clear_values(16,5)
349
+    # for i in range(1,7):
350
+        # for j in range(1,4):
351
+            # placeholders[f'v{i}_{j}'] = 0
352
+    placeholders['v6_0'] = placeholders['v14_0'] = out_limit
353
+    placeholders['v7_0'] = placeholders['v15_0'] = mid_limit
354
+    placeholders['v18_0'] = placeholders['v16_0'] = in_limit
355
+
356
+    pprint(placeholders)
357
+    pprint(manual_size_records) 
358
+    if first_result:
359
+        w = first_result.PRO6
360
+        placeholders['v4_1'] = placeholders['v12_1'] = w
361
+
362
+    for m in manual_size_records:
363
+        if m.size_name == "D":
364
+            placeholders['v1_1'] = placeholders['v9_1'] = f'D{m.std} +{m.tolup} {m.tolun}'
365
+        if m.size_name == "T":
366
+            placeholders['v2_1'] = placeholders['v10_1'] = f'T{m.std} +{m.tolup} {m.tolun}'
367
+        if m.size_name == "H":
368
+            placeholders['v3_1'] = placeholders['v11_1'] = f'H{m.std} +{m.tolup} {m.tolun}'
369
+
370
+
371
+
372
+    # Ensure that we map each manualSize entry to a corresponding DataMs entry
373
+    for r in data_ms_records:
374
+        if r.row_no == 1:
375
+            placeholders[f'v1_2'] = r.dsize
376
+            placeholders[f'v1_3'] = r.dsizeok
377
+            
378
+            placeholders[f'v2_2'] = r.tsize
379
+            placeholders[f'v2_3'] = r.tsizeok
380
+            
381
+            placeholders[f'v3_2'] = r.hsize
382
+            placeholders[f'v3_3'] = r.hsizeok
383
+
384
+            # if is_ok(r):
385
+                # placeholders[f'v4_1'] = 'OK'
386
+                # placeholders[f'v4_2'] = 'OK'
387
+            # else:
388
+                # placeholders[f'v4_1'] = 'NG'
389
+                # placeholders[f'v4_2'] = 'OK'
390
+        
391
+        if r.row_no == 2:
392
+            placeholders[f'v9_2'] = r.dsize
393
+            placeholders[f'v9_3'] = r.dsizeok
394
+            
395
+            placeholders[f'v10_2'] = r.tsize
396
+            placeholders[f'v10_3'] = r.tsizeok
397
+            
398
+            placeholders[f'v11_2'] = r.hsize
399
+            placeholders[f'v11_3'] = r.hsizeok
400
+
401
+            # if is_ok(r):
402
+                # placeholders[f'v8_1'] = 'OK'
403
+                # placeholders[f'v8_2'] = 'OK'
404
+            # else:
405
+                # placeholders[f'v8_1'] = 'NG'
406
+                # placeholders[f'v8_2'] = 'NG'
407
+
408
+    for r in data_wb:
409
+        if r.row_no == 1:
410
+            placeholders["v4_2"] = r.weight
411
+            placeholders["v4_3"] = r.judgement
412
+        if r.row_no == 2:
413
+            placeholders["v12_2"] = r.weight
414
+            placeholders["v12_3"] = r.judgement
415
+
416
+    for r in data_ho:
417
+        if r.row_no == 1:
418
+            rmap = {'OUT': 6, 'MID': 7, 'IN': 8}
419
+            for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
420
+                idx = rmap.get(r.r_type, None)
421
+                if idx:
422
+                    placeholders[f'v{idx}_{index}']  = getattr(r, v) 
423
+        if r.row_no == 2:
424
+            rmap = {'OUT': 14, 'MID': 15, 'IN': 16}
425
+            for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
426
+                idx = rmap.get(r.r_type, None)
427
+                if idx:
428
+                    placeholders[f'v{idx}_{index}']  = getattr(r, v)
429
+
430
+    # hide_con(placeholders, "v5_1", "26:32")
431
+    return placeholders
432
+
313
 def generate_centering_values(lot_no):
433
 def generate_centering_values(lot_no):
314
     """
434
     """
315
     Fetch dimension records from manualSize and DataMs models
435
     Fetch dimension records from manualSize and DataMs models
341
 
461
 
342
     return placeholders
462
     return placeholders
343
 
463
 
464
+def generate_t8_values(lot_no):
465
+    """
466
+    Fetch dimension records from manualSize and DataMs models
467
+    and generate placeholder values for Standard, Actual, and Judgement.
468
+    Supports two row_no entries per lot.
469
+    """
470
+    # Fetch standard values from manualSize (limit to 2 rows)
471
+    placeholders = clear_values(8,10)
472
+    
473
+    manual_size_records = Manualsize.objects.filter(lotno=lot_no)
474
+    # pprint(f"manual_size = {manual_size_records}")
475
+    for m in manual_size_records:
476
+        if m.size_name == "Thickness":
477
+            for i in range(1,9):
478
+                placeholders[f'v{i}_1'] = f'{m.std} +{m.tolup} {m.tolun}'
479
+                # pprint("set std")
480
+    # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
481
+    data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
482
+
483
+    # Prepare placeholders
484
+
485
+    # placeholders = {}
486
+    # for i in range(1,7):
487
+        # for j in range(1,4):
488
+            # placeholders[f'v{i}_{j}'] = 0
489
+    
490
+
491
+    # Ensure that we map each manualSize entry to a corresponding DataMs entry
492
+    for i,r in enumerate(data_ms_records, start=1):
493
+        placeholders[f'v{i}_2'] = r.tpoint1
494
+        placeholders[f'v{i}_3'] = r.tpoint2
495
+        placeholders[f'v{i}_4'] = r.tpoint3
496
+        placeholders[f'v{i}_5'] = r.tpoint4
497
+        placeholders[f'v{i}_10'] = r.tdiff
498
+
499
+    return placeholders
500
+
344
 def merge_sheet_data_with_data(sheet_data, data):
501
 def merge_sheet_data_with_data(sheet_data, data):
345
     """
502
     """
346
     Merge `sheet_data` with `data`.
503
     Merge `sheet_data` with `data`.
370
     pprint(qa1)
527
     pprint(qa1)
371
     pprint(qa2)
528
     pprint(qa2)
372
     
529
     
530
+    results = queryFromMaster(lot_no)
531
+    first_result = results[0] if results else None
532
+    
373
     sheet_data = {}
533
     sheet_data = {}
374
     for sheet_name in sheets:
534
     for sheet_name in sheets:
375
         match sheet_name:
535
         match sheet_name:
383
                 sheet_data[sheet_name] = generate_dimension_app_values(lot_no)
543
                 sheet_data[sheet_name] = generate_dimension_app_values(lot_no)
384
             case 'centering':
544
             case 'centering':
385
                 sheet_data[sheet_name] = generate_centering_values(lot_no)
545
                 sheet_data[sheet_name] = generate_centering_values(lot_no)
546
+            case 'centering':
547
+                sheet_data[sheet_name] = generate_centering_values(lot_no)
548
+            case 'thickness_8_point':
549
+                sheet_data[sheet_name] = generate_t8_values(lot_no)
550
+            case 'dim_bal_app_hard':
551
+                sheet_data[sheet_name] = generate_dim_bal_app_hard_values(lot_no, first_result)
386
     
552
     
387
     converted_data = convert_sheet_data(sheet_data)
553
     converted_data = convert_sheet_data(sheet_data)
388
 
554
 
389
     print(f"sheet_data \n {sheet_data}") 
555
     print(f"sheet_data \n {sheet_data}") 
390
     print(f"converted_data \n {converted_data}")
556
     print(f"converted_data \n {converted_data}")
391
 
557
 
392
-    results = queryFromMaster(lot_no)
393
-    first_result = results[0] if results else None
558
+    # results = queryFromMaster(lot_no)
559
+    # first_result = results[0] if results else None
394
     try:
560
     try:
395
         pcs = int(first_result.PRO5) - int(first_result.PRO27)
561
         pcs = int(first_result.PRO5) - int(first_result.PRO27)
396
     except:
562
     except:
403
         spec = ""
569
         spec = ""
404
 
570
 
405
     data = {
571
     data = {
406
-        "code": first_result.PRO1,
407
-        "customer": first_result.PRO1C,
572
+        "code": first_result.PRO1 if first_result else "-",
573
+        "customer": first_result.PRO1C if first_result else "-",
408
         "inspect_date": "2025-01-15",
574
         "inspect_date": "2025-01-15",
409
         "lot_no": lot_no,
575
         "lot_no": lot_no,
410
         "size": size_str,
576
         "size": size_str,
430
     output_file = gen_xlsx(
596
     output_file = gen_xlsx(
431
         template_file=f"{settings.BASE_DIR}/report/coi_templates.xlsx",
597
         template_file=f"{settings.BASE_DIR}/report/coi_templates.xlsx",
432
         selected_sheets=sheets,  # Replace with your actual sheet names
598
         selected_sheets=sheets,  # Replace with your actual sheet names
433
-        prefix_filename=f"{settings.BASE_DIR}/media/coi",
599
+        prefix_filename=f"{settings.BASE_DIR}/media/coi_{lot_no}_",
434
         data=merged_data
600
         data=merged_data
435
     )
601
     )
436
     report = Report.objects.create(
602
     report = Report.objects.create(