Няма описание

views.py 50KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. from django.shortcuts import render, redirect, get_object_or_404
  2. from django.core.paginator import Paginator
  3. from django.contrib import messages
  4. from core.models import Report, AllProductDimensionForInsProcess, CustomerTemplateMapping, \
  5. ProductDrawing, MksCodeMap
  6. from core.forms import ReportForm, CustomerTemplateMappingForm, ProductDrawingForm
  7. from core.utils import ConfigurableCRUDView, queryFromMaster, SHEET_NAMES
  8. from .filters import ReportFilter, CustomerTemplateFilter, ProductDrawingFilter, MksCodeMapFilter
  9. from .forms import ExportOptionsForm
  10. from pprint import pprint
  11. from legacy.models import Data, DataMs, DataRl, DataWb, LotSummary, LotSummaryRl, LotSummaryWb, PressCal, RotateData, TbFgPressinfoLotlist,\
  12. Manualsize
  13. from .gen_report import gen_xlsx
  14. from django.core.files.base import File
  15. from pathlib import Path
  16. from django.views.decorators.csrf import csrf_exempt
  17. from django.http import JsonResponse, HttpResponseBadRequest
  18. import json
  19. from django.contrib.auth.decorators import login_required
  20. from django.contrib.auth.models import User
  21. from legacy.models import Data
  22. from django.conf import settings
  23. from itertools import chain
  24. from django_filters.views import FilterView
  25. from django.db.models import Q
  26. from django.views.generic import (
  27. ListView,)
  28. def index(request):
  29. reports = Report.objects.all()
  30. report_filter = ReportFilter(request.GET, queryset=reports)
  31. # Paginate the filtered queryset
  32. paginator = Paginator(report_filter.qs, 10) # Show 10 reports per page
  33. page_number = request.GET.get('page')
  34. page_obj = paginator.get_page(page_number)
  35. context = {
  36. 'filter': report_filter,
  37. 'page_obj': page_obj,
  38. }
  39. return render(request, 'report/index.html', context)
  40. def report_create_view(request):
  41. if request.method == "POST":
  42. form = ReportForm(request.POST)
  43. if form.is_valid():
  44. form.save()
  45. messages.success(request, "Report created successfully!")
  46. return redirect("report:report_index") # Adjust with your report list view name
  47. else:
  48. form = ReportForm()
  49. return render(request, "report/create.html", {"form": form})
  50. class ReportCRUDView(ConfigurableCRUDView):
  51. model = Report
  52. list_template_name = 'legacy/datacrud_list.html'
  53. detail_template_name = 'legacy/datacrud_detail.html'
  54. form_template_name = 'report/report_form.html'
  55. confirm_delete_template_name = 'legacy/datacrud_confirm_delete.html'
  56. filterset_class = ReportFilter
  57. page_title = "Reports"
  58. # URL name mappings
  59. list_url_name = 'report:report-list'
  60. create_url_name = 'report:report-create'
  61. update_url_name = 'report:report-update'
  62. delete_url_name = 'report:report-delete'
  63. config_fields = ["name", "file", "created_by", "created_at"]
  64. config_field_orders = ["id", "name", "created_by"]
  65. # config_readonly_fields = ["lot_no"]
  66. # config_edit_fields = ["lot_no", "code"]
  67. ordering = ["-created_at", "-id",]
  68. def convert_sheet_data(sheet_data):
  69. """
  70. Convert sheet_data to the required form with prefixed keys.
  71. :param sheet_data: Dictionary with sheet names as keys and their data as values.
  72. :return: Dictionary in the required key-value format.
  73. """
  74. converted_data = {}
  75. for sheet_name, data in sheet_data.items():
  76. for key, value in data.items():
  77. # Prefix each key with the sheet name
  78. converted_key = f"{sheet_name}.{key}"
  79. converted_data[converted_key] = value
  80. return converted_data
  81. def hide_con(placeholders, mark_value, hide_rows):
  82. """
  83. Updates the 'placeholders' dictionary with a mark value and hide rows range.
  84. :param placeholders: The dictionary to update.
  85. :param mark_value: The key to check or update in the placeholders.
  86. :param hide_rows: The row range to append in the format '[start:end]'.
  87. """
  88. if mark_value in placeholders:
  89. placeholders[mark_value] = f"{placeholders[mark_value]}[{hide_rows}]"
  90. else:
  91. placeholders[mark_value] = f"0[{hide_rows}]"
  92. def clear_values(n, m):
  93. placeholders = {}
  94. for i in range(1, n + 1):
  95. for j in range(1, m + 1):
  96. placeholders[f'v{i}_{j}'] = " "
  97. return placeholders
  98. def generate_hardness_out_values(lot_no, code):
  99. """
  100. Generate a dictionary of placeholder values for a given lot_no.
  101. :param lot_no: The lot number to query data for.
  102. :return: A dictionary with placeholders (e.g., v1_1, v1_2, ...) as keys and their respective values.
  103. """
  104. # Query the Data model for records matching the given lot_no
  105. # records = Data.objects.filter(lot_no=lot_no).order_by('row_no')
  106. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  107. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  108. records = list(chain(data_h1, data_h2))
  109. # print(f"records {lot_no} = {records.values()}")
  110. # Initialize an empty dictionary to store placeholder values
  111. placeholders = clear_values(2,5)
  112. # Iterate over the records to populate placeholder values
  113. inspect_date = None
  114. for record_idx, record in enumerate(records, start=1):
  115. if record_idx == 1:
  116. inspect_date = record.created_at
  117. placeholders[f'v{record_idx}_1'] = record.p1 # Checkpoint 1 value
  118. placeholders[f'v{record_idx}_2'] = record.p2 # Checkpoint 2 value
  119. placeholders[f'v{record_idx}_3'] = record.p3 # Checkpoint 3 value
  120. placeholders[f'v{record_idx}_4'] = record.avg # Average value
  121. placeholders[f'v{record_idx}_5'] = record.rgrade # Judgment value
  122. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  123. return placeholders
  124. def generate_hardness_out_in_values(lot_no, code):
  125. # Fetch records from the Data model
  126. # records = Data.objects.filter(lot_no=lot_no).order_by('row_no')
  127. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  128. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  129. records = list(chain(data_h1, data_h2))
  130. out_data = []
  131. in_data = []
  132. # Separate OUT and IN data
  133. for record in records:
  134. if record.r_type.upper() in ["OUT", "TOP", "FA1", "UPP", "UPPE", "RIM"]:
  135. out_data.append(record)
  136. elif record.r_type.upper() in ["IN", "UNDER", "UND", "FA2", "LOW", "LOWE", "BASE", "SOKO", "IN*"]:
  137. in_data.append(record)
  138. # Prepare placeholders
  139. # placeholders = {}
  140. placeholders = clear_values(4,5)
  141. inspect_date = None
  142. for idx, record in enumerate(out_data, start=1):
  143. if idx == 1:
  144. inspect_date = record.created_at
  145. placeholders[f'v{idx}_1'] = record.p1
  146. placeholders[f'v{idx}_2'] = record.p2
  147. placeholders[f'v{idx}_3'] = record.p3
  148. placeholders[f'v{idx}_4'] = record.avg
  149. placeholders[f'v{idx}_5'] = record.rgrade
  150. for idx, record in enumerate(in_data, start=1):
  151. placeholders[f'v{len(out_data) + idx}_1'] = record.p1
  152. placeholders[f'v{len(out_data) + idx}_2'] = record.p2
  153. placeholders[f'v{len(out_data) + idx}_3'] = record.p3
  154. placeholders[f'v{len(out_data) + idx}_4'] = record.avg
  155. placeholders[f'v{len(out_data) + idx}_5'] = record.rgrade
  156. # if "v3_1" in placeholders:
  157. # placeholders["v3_1"] = f"{placeholders['v3_1']}[25:28]"
  158. # else:
  159. # placeholders[f"v3_1"] = "0[25:28]"
  160. hide_con(placeholders, "v3_1", "25:28")
  161. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  162. return placeholders
  163. def generate_hardness_both_size_values(lot_no, ms,code):
  164. # Fetch records from the Data model
  165. # records = Data.objects.filter(lot_no=lot_no).order_by('row_no')
  166. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no', 'sub_order'))
  167. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no', 'sub_order'))
  168. records = list(chain(data_h1, data_h2))
  169. out_data = []
  170. in_data = []
  171. placeholders = clear_values(20,5)
  172. # Separate OUT and IN data
  173. inspect_date = None
  174. for idx, record in enumerate(records, start=0):
  175. if idx == 1:
  176. inspect_date = record.created_at
  177. if record.sub_order == 1:
  178. for i,v in enumerate(["p1", "p2", "p3", "avg", "rgrade"],start=1):
  179. placeholders[f"v{idx*2+1}_{i}"] = getattr(record,v)
  180. if record.sub_order == 2:
  181. for i,v in enumerate(["p1", "p2", "p3", "avg", "rgrade"],start=1):
  182. placeholders[f"v{idx*2+2}_{i}"] = getattr(record,v)
  183. # Prepare placeholders
  184. # placeholders = {}
  185. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  186. return placeholders
  187. # # Example usage:
  188. # placeholders_dict = clear_values(6, 3)
  189. # print(placeholders_dict)
  190. def generate_dimension_values(lot_no, code):
  191. """
  192. Fetch dimension records from manualSize and DataMs models
  193. and generate placeholder values for Standard, Actual, and Judgement.
  194. Supports two row_no entries per lot.
  195. """
  196. # Fetch standard values from manualSize (limit to 2 rows)
  197. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  198. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  199. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  200. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  201. # Prepare placeholders
  202. # placeholders = {}
  203. placeholders = clear_values(7,4)
  204. # for i in range(1,7):
  205. # for j in range(1,4):
  206. # placeholders[f'v{i}_{j}'] = 0
  207. pprint(placeholders)
  208. pprint(manual_size_records)
  209. for m in dimens:
  210. if m.Size_Name == "D":
  211. placeholders['v1_1'] = placeholders['v4_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  212. if m.Size_Name == "T":
  213. placeholders['v2_1'] = placeholders['v5_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  214. if m.Size_Name == "H":
  215. placeholders['v3_1'] = placeholders['v6_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  216. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  217. inspect_date = None
  218. for r in data_ms_records:
  219. if r.row_no == 1:
  220. placeholders[f'v1_2'] = r.dsize
  221. placeholders[f'v1_3'] = r.dsizeok
  222. placeholders[f'v2_2'] = r.tsize
  223. placeholders[f'v2_3'] = r.tsizeok
  224. placeholders[f'v3_2'] = r.hsize
  225. placeholders[f'v3_3'] = r.hsizeok
  226. inspect_date = r.created_at
  227. if r.row_no == 2:
  228. placeholders[f'v4_2'] = r.dsize
  229. placeholders[f'v4_3'] = r.dsizeok
  230. placeholders[f'v5_2'] = r.tsize
  231. placeholders[f'v5_3'] = r.tsizeok
  232. placeholders[f'v6_2'] = r.hsize
  233. placeholders[f'v6_3'] = r.hsizeok
  234. hide_con(placeholders, "v4_1", "24:28")
  235. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  236. return placeholders
  237. def is_ok(instance):
  238. fields_and_values = {}
  239. for field in instance._meta.get_fields():
  240. field_name = field.name
  241. if field_name.endswith('ok'):
  242. v = getattr(instance, field_name)
  243. if v is not None and v != "OK":
  244. return False
  245. return True
  246. def generate_dimension_app_values(lot_no, code):
  247. """
  248. Fetch dimension records from manualSize and DataMs models
  249. and generate placeholder values for Standard, Actual, and Judgement.
  250. Supports two row_no entries per lot.
  251. """
  252. # Fetch standard values from manualSize (limit to 2 rows)
  253. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  254. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  255. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  256. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  257. # Prepare placeholders
  258. # placeholders = {}
  259. placeholders = clear_values(8,3)
  260. # for i in range(1,7):
  261. # for j in range(1,4):
  262. # placeholders[f'v{i}_{j}'] = 0
  263. pprint(placeholders)
  264. pprint(manual_size_records)
  265. # for m in manual_size_records:
  266. # if m.size_name == "D":
  267. # placeholders['v1_1'] = placeholders['v5_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  268. # if m.size_name == "T":
  269. # placeholders['v2_1'] = placeholders['v6_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  270. # if m.size_name == "H":
  271. # placeholders['v3_1'] = placeholders['v7_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  272. for m in dimens: # Changed from manual_size_records to dimens
  273. if m.Size_Name == "D":
  274. placeholders['v1_1'] = placeholders['v5_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  275. if m.Size_Name == "T":
  276. placeholders['v2_1'] = placeholders['v6_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  277. if m.Size_Name == "H":
  278. placeholders['v3_1'] = placeholders['v7_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  279. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  280. inspect_date = None
  281. for r in data_ms_records:
  282. if r.row_no == 1:
  283. placeholders[f'v1_2'] = r.dsize
  284. placeholders[f'v1_3'] = r.dsizeok
  285. placeholders[f'v2_2'] = r.tsize
  286. placeholders[f'v2_3'] = r.tsizeok
  287. placeholders[f'v3_2'] = r.hsize
  288. placeholders[f'v3_3'] = r.hsizeok
  289. inspect_date = r.created_at
  290. # if is_ok(r):
  291. # placeholders[f'v4_1'] = 'OK'
  292. # placeholders[f'v4_2'] = 'OK'
  293. # else:
  294. # placeholders[f'v4_1'] = 'NG'
  295. # placeholders[f'v4_2'] = 'OK'
  296. if r.row_no == 2:
  297. placeholders[f'v5_2'] = r.dsize
  298. placeholders[f'v5_3'] = r.dsizeok
  299. placeholders[f'v6_2'] = r.tsize
  300. placeholders[f'v6_3'] = r.tsizeok
  301. placeholders[f'v7_2'] = r.hsize
  302. placeholders[f'v7_3'] = r.hsizeok
  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'
  309. hide_con(placeholders, "v5_1", "26:32")
  310. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  311. return placeholders
  312. def generate_dimension_app_drawing_values(lot_no, code):
  313. """
  314. Fetch dimension records from manualSize and DataMs models
  315. and generate placeholder values for Standard, Actual, and Judgement.
  316. Supports two row_no entries per lot.
  317. """
  318. # Fetch standard values from manualSize (limit to 2 rows)
  319. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  320. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  321. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  322. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  323. # Prepare placeholders
  324. # placeholders = {}
  325. placeholders = clear_values(8,3)
  326. # for i in range(1,7):
  327. # for j in range(1,4):
  328. # placeholders[f'v{i}_{j}'] = 0
  329. pprint(placeholders)
  330. pprint(manual_size_records)
  331. # for m in manual_size_records:
  332. # if m.size_name == "D":
  333. # placeholders['v1_1'] = placeholders['v5_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  334. # if m.size_name == "T":
  335. # placeholders['v2_1'] = placeholders['v6_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  336. # if m.size_name == "H":
  337. # placeholders['v3_1'] = placeholders['v7_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  338. for m in dimens: # Changed from manual_size_records to dimens
  339. if m.Size_Name == "D":
  340. placeholders['v1_1'] = placeholders['v5_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  341. if m.Size_Name == "T":
  342. placeholders['v2_1'] = placeholders['v6_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  343. if m.Size_Name == "H":
  344. placeholders['v3_1'] = placeholders['v7_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  345. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  346. inspect_date = None
  347. for r in data_ms_records:
  348. if r.row_no == 1:
  349. placeholders[f'v1_2'] = r.dsize
  350. placeholders[f'v1_3'] = r.dsizeok
  351. placeholders[f'v2_2'] = r.tsize
  352. placeholders[f'v2_3'] = r.tsizeok
  353. placeholders[f'v3_2'] = r.hsize
  354. placeholders[f'v3_3'] = r.hsizeok
  355. inspect_date = r.created_at
  356. # if is_ok(r):
  357. # placeholders[f'v4_1'] = 'OK'
  358. # placeholders[f'v4_2'] = 'OK'
  359. # else:
  360. # placeholders[f'v4_1'] = 'NG'
  361. # placeholders[f'v4_2'] = 'OK'
  362. if r.row_no == 2:
  363. placeholders[f'v5_2'] = r.dsize
  364. placeholders[f'v5_3'] = r.dsizeok
  365. placeholders[f'v6_2'] = r.tsize
  366. placeholders[f'v6_3'] = r.tsizeok
  367. placeholders[f'v7_2'] = r.hsize
  368. placeholders[f'v7_3'] = r.hsizeok
  369. # if is_ok(r):
  370. # placeholders[f'v8_1'] = 'OK'
  371. # placeholders[f'v8_2'] = 'OK'
  372. # else:
  373. # placeholders[f'v8_1'] = 'NG'
  374. # placeholders[f'v8_2'] = 'NG'
  375. hide_con(placeholders, "v5_1", "26:32")
  376. drawing_data = ProductDrawing.objects.filter(
  377. Q(lot_no=lot_no) | Q(code_no=code)).first()
  378. pprint(f"1.1 = {drawing_data}")
  379. pprint(f"1.2 = {lot_no} {code}")
  380. if drawing_data:
  381. placeholders["drawing"] = drawing_data.drawing if drawing_data.drawing else "-"
  382. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  383. return placeholders
  384. def generate_dimension_bal_weight_values(lot_no, ms, code):
  385. """
  386. Fetch dimension records from manualSize and DataMs models
  387. and generate placeholder values for Standard, Actual, and Judgement.
  388. Supports two row_no entries per lot.
  389. """
  390. # Fetch standard values from manualSize (limit to 2 rows)
  391. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  392. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  393. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  394. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  395. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  396. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  397. data_ho = list(chain(data_h1, data_h2))
  398. # Prepare placeholders
  399. # placeholders = {}
  400. placeholders = clear_values(10,3)
  401. # for i in range(1,7):
  402. # for j in range(1,4):
  403. # placeholders[f'v{i}_{j}'] = 0
  404. pprint(placeholders)
  405. pprint(manual_size_records)
  406. if ms:
  407. try:
  408. w = ms.PRO6
  409. placeholders['v4_1'] = placeholders['v9_1'] = w
  410. except:
  411. print("no PRO6")
  412. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  413. for m in dimens: # Changed from manual_size_records to dimens
  414. if m.Size_Name == "D":
  415. placeholders['v1_1'] = placeholders['v6_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  416. if m.Size_Name == "T":
  417. placeholders['v2_1'] = placeholders['v7_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  418. if m.Size_Name == "H":
  419. placeholders['v3_1'] = placeholders['v8_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  420. inspect_date = None
  421. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  422. for r in data_ms_records:
  423. if r.row_no == 1:
  424. placeholders[f'v1_2'] = r.dsize
  425. placeholders[f'v1_3'] = r.dsizeok
  426. placeholders[f'v2_2'] = r.tsize
  427. placeholders[f'v2_3'] = r.tsizeok
  428. placeholders[f'v3_2'] = r.hsize
  429. placeholders[f'v3_3'] = r.hsizeok
  430. inspect_date = r.created_at
  431. # if is_ok(r):
  432. # placeholders[f'v4_1'] = 'OK'
  433. # placeholders[f'v4_2'] = 'OK'
  434. # else:
  435. # placeholders[f'v4_1'] = 'NG'
  436. # placeholders[f'v4_2'] = 'OK'
  437. if r.row_no == 2:
  438. placeholders[f'v6_2'] = r.dsize
  439. placeholders[f'v6_3'] = r.dsizeok
  440. placeholders[f'v7_2'] = r.tsize
  441. placeholders[f'v7_3'] = r.tsizeok
  442. placeholders[f'v8_2'] = r.hsize
  443. placeholders[f'v8_3'] = r.hsizeok
  444. # if is_ok(r):
  445. # placeholders[f'v8_1'] = 'OK'
  446. # placeholders[f'v8_2'] = 'OK'
  447. # else:
  448. # placeholders[f'v8_1'] = 'NG'
  449. # placeholders[f'v8_2'] = 'NG'
  450. for r in data_wb:
  451. if r.row_no == 1:
  452. placeholders["v4_2"] = r.result
  453. placeholders["v4_3"] = r.judgement
  454. placeholders["v5_2"] = r.weight
  455. placeholders["v5_3"] = r.judgement
  456. if r.row_no == 2:
  457. placeholders["v9_2"] = r.result
  458. placeholders["v9_3"] = r.judgement
  459. placeholders["v10_2"] = r.weight
  460. placeholders["v10_3"] = r.judgement
  461. # hide_con(placeholders, "v5_1", "26:32")
  462. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  463. return placeholders
  464. def generate_dim_bal_app_hard_values(lot_no, first_result, code):
  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. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  472. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  473. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  474. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  475. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  476. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  477. data_ho = list(chain(data_h1, data_h2))
  478. if first_result:
  479. out_limit = f"Out 外 ({first_result.MI18} - {first_result.MI19})"
  480. in_limit = f"In 内 ({first_result.MI22} - {first_result.MI23})"
  481. mid_limit = f"Middle 中 -"
  482. else:
  483. out_limit = f"Out 外"
  484. in_limit = f"In 内"
  485. mid_limit = f"Middle 中"
  486. # Prepare placeholders
  487. # placeholders = {}
  488. placeholders = clear_values(16,5)
  489. # for i in range(1,7):
  490. # for j in range(1,4):
  491. # placeholders[f'v{i}_{j}'] = 0
  492. placeholders['v6_0'] = placeholders['v14_0'] = out_limit
  493. placeholders['v7_0'] = placeholders['v15_0'] = mid_limit
  494. placeholders['v18_0'] = placeholders['v16_0'] = in_limit
  495. pprint(placeholders)
  496. pprint(manual_size_records)
  497. if first_result:
  498. try:
  499. w = first_result.PRO6
  500. placeholders['v4_1'] = placeholders['v12_1'] = w
  501. except:
  502. print("No PRO6")
  503. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  504. for m in dimens: # Changed from manual_size_records to dimens
  505. if m.Size_Name == "D":
  506. placeholders['v1_1'] = placeholders['v9_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  507. if m.Size_Name == "T":
  508. placeholders['v2_1'] = placeholders['v10_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  509. if m.Size_Name == "H":
  510. placeholders['v3_1'] = placeholders['v11_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  511. inspect_date = None
  512. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  513. for r in data_ms_records:
  514. if r.row_no == 1:
  515. placeholders[f'v1_2'] = r.dsize
  516. placeholders[f'v1_3'] = r.dsizeok
  517. placeholders[f'v2_2'] = r.tsize
  518. placeholders[f'v2_3'] = r.tsizeok
  519. placeholders[f'v3_2'] = r.hsize
  520. placeholders[f'v3_3'] = r.hsizeok
  521. inspect_date = r.created_at
  522. # if is_ok(r):
  523. # placeholders[f'v4_1'] = 'OK'
  524. # placeholders[f'v4_2'] = 'OK'
  525. # else:
  526. # placeholders[f'v4_1'] = 'NG'
  527. # placeholders[f'v4_2'] = 'OK'
  528. if r.row_no == 2:
  529. placeholders[f'v9_2'] = r.dsize
  530. placeholders[f'v9_3'] = r.dsizeok
  531. placeholders[f'v10_2'] = r.tsize
  532. placeholders[f'v10_3'] = r.tsizeok
  533. placeholders[f'v11_2'] = r.hsize
  534. placeholders[f'v11_3'] = r.hsizeok
  535. # if is_ok(r):
  536. # placeholders[f'v8_1'] = 'OK'
  537. # placeholders[f'v8_2'] = 'OK'
  538. # else:
  539. # placeholders[f'v8_1'] = 'NG'
  540. # placeholders[f'v8_2'] = 'NG'
  541. for r in data_wb:
  542. if r.row_no == 1:
  543. placeholders["v4_2"] = r.weight
  544. placeholders["v4_3"] = r.judgement
  545. if r.row_no == 2:
  546. placeholders["v12_2"] = r.weight
  547. placeholders["v12_3"] = r.judgement
  548. for r in data_ho:
  549. if r.row_no == 1:
  550. rmap = {'OUT': 6, 'MID': 7, 'IN': 8}
  551. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  552. idx = rmap.get(r.r_type, None)
  553. if idx:
  554. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  555. if r.row_no == 2:
  556. rmap = {'OUT': 14, 'MID': 15, 'IN': 16}
  557. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  558. idx = rmap.get(r.r_type, None)
  559. if idx:
  560. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  561. # hide_con(placeholders, "v5_1", "26:32")
  562. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  563. return placeholders
  564. def generate_dim_bal_app_rot_hard_values(lot_no, first_result, code):
  565. """
  566. Fetch dimension records from manualSize and DataMs models
  567. and generate placeholder values for Standard, Actual, and Judgement.
  568. Supports two row_no entries per lot.
  569. """
  570. # Fetch standard values from manualSize (limit to 2 rows)
  571. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  572. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  573. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  574. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  575. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  576. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  577. data_ho = list(chain(data_h1, data_h2))
  578. rotates = RotateData.objects.filter(lot_no=lot_no).order_by('row_no')
  579. if first_result:
  580. out_limit = f"Out 外 ({first_result.MI18} - {first_result.MI19})"
  581. in_limit = f"In 内 ({first_result.MI22} - {first_result.MI23})"
  582. mid_limit = f"Middle 中 -"
  583. else:
  584. out_limit = f"Out 外"
  585. in_limit = f"In 内"
  586. mid_limit = f"Middle 中"
  587. # Prepare placeholders
  588. # placeholders = {}
  589. placeholders = clear_values(18,5)
  590. # for i in range(1,7):
  591. # for j in range(1,4):
  592. # placeholders[f'v{i}_{j}'] = 0
  593. placeholders['v6_0'] = placeholders['v14_0'] = out_limit
  594. placeholders['v7_0'] = placeholders['v15_0'] = mid_limit
  595. placeholders['v18_0'] = placeholders['v16_0'] = in_limit
  596. pprint(placeholders)
  597. pprint(manual_size_records)
  598. if first_result:
  599. try:
  600. w = first_result.PRO6
  601. placeholders['v4_1'] = placeholders['v13_1'] = w
  602. except:
  603. print("no PRO6")
  604. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  605. for m in dimens: # Changed from manual_size_records to dimens
  606. if m.Size_Name == "D":
  607. placeholders['v1_1'] = placeholders['v10_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  608. if m.Size_Name == "T":
  609. placeholders['v2_1'] = placeholders['v11_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  610. if m.Size_Name == "H":
  611. placeholders['v3_1'] = placeholders['v12_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  612. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  613. inspect_date = None
  614. for r in data_ms_records:
  615. if r.row_no == 1:
  616. placeholders[f'v1_2'] = r.dsize
  617. placeholders[f'v1_3'] = r.dsizeok
  618. placeholders[f'v2_2'] = r.tsize
  619. placeholders[f'v2_3'] = r.tsizeok
  620. placeholders[f'v3_2'] = r.hsize
  621. placeholders[f'v3_3'] = r.hsizeok
  622. inspect_date = r.created_at
  623. # if is_ok(r):
  624. # placeholders[f'v4_1'] = 'OK'
  625. # placeholders[f'v4_2'] = 'OK'
  626. # else:
  627. # placeholders[f'v4_1'] = 'NG'
  628. # placeholders[f'v4_2'] = 'OK'
  629. if r.row_no == 2:
  630. placeholders[f'v10_2'] = r.dsize
  631. placeholders[f'v10_3'] = r.dsizeok
  632. placeholders[f'v11_2'] = r.tsize
  633. placeholders[f'v11_3'] = r.tsizeok
  634. placeholders[f'v12_2'] = r.hsize
  635. placeholders[f'v12_3'] = r.hsizeok
  636. # if is_ok(r):
  637. # placeholders[f'v8_1'] = 'OK'
  638. # placeholders[f'v8_2'] = 'OK'
  639. # else:
  640. # placeholders[f'v8_1'] = 'NG'
  641. # placeholders[f'v8_2'] = 'NG'
  642. for r in data_wb:
  643. if r.row_no == 1:
  644. placeholders["v4_2"] = r.weight
  645. placeholders["v4_3"] = r.judgement
  646. if r.row_no == 2:
  647. placeholders["v13_2"] = r.weight
  648. placeholders["v13_3"] = r.judgement
  649. for r in data_ho:
  650. if r.row_no == 1:
  651. rmap = {'OUT': 7, 'MID': 8, 'IN': 9}
  652. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  653. idx = rmap.get(r.r_type, None)
  654. if idx:
  655. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  656. if r.row_no == 2:
  657. rmap = {'OUT': 16, 'MID': 17, 'IN': 18}
  658. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  659. idx = rmap.get(r.r_type, None)
  660. if idx:
  661. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  662. for r in rotates:
  663. if r.row_no == 1:
  664. placeholders["v6_1"] = r.speed_spec
  665. placeholders["v6_2"] = r.speed_test
  666. placeholders["v6_3"] = r.speedok
  667. if r.row_no == 2:
  668. placeholders["v15_1"] = r.speed_spec
  669. placeholders["v15_2"] = r.speed_test
  670. placeholders["v15_3"] = r.speedok
  671. # hide_con(placeholders, "v5_1", "26:32")
  672. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  673. return placeholders
  674. def generate_centering_values(lot_no, code):
  675. """
  676. Fetch dimension records from manualSize and DataMs models
  677. and generate placeholder values for Standard, Actual, and Judgement.
  678. Supports two row_no entries per lot.
  679. """
  680. # Fetch standard values from manualSize (limit to 2 rows)
  681. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  682. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  683. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  684. # Prepare placeholders
  685. # placeholders = {}
  686. placeholders = clear_values(10,3)
  687. # for i in range(1,7):
  688. # for j in range(1,4):
  689. # placeholders[f'v{i}_{j}'] = 0
  690. pprint(placeholders)
  691. pprint(manual_size_records)
  692. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  693. inspect_date = None
  694. for i,r in enumerate(data_ms_records, start=1):
  695. if i == 1:
  696. inspect_date = r.created_at
  697. placeholders[f'v{i}_2'] = r.censize
  698. placeholders[f'v{i}_3'] = r.censizeok
  699. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  700. return placeholders
  701. def generate_t8_values(lot_no, code):
  702. """
  703. Fetch dimension records from manualSize and DataMs models
  704. and generate placeholder values for Standard, Actual, and Judgement.
  705. Supports two row_no entries per lot.
  706. """
  707. # Fetch standard values from manualSize (limit to 2 rows)
  708. placeholders = clear_values(8,10)
  709. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  710. # pprint(f"manual_size = {manual_size_records}")
  711. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  712. for m in dimens: # Changed from manual_size_records to dimens
  713. if m.Size_Name == "Thickness":
  714. for i in range(1, 9):
  715. placeholders[f'v{i}_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  716. # pprint("set std")
  717. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  718. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  719. # Prepare placeholders
  720. # placeholders = {}
  721. # for i in range(1,7):
  722. # for j in range(1,4):
  723. # placeholders[f'v{i}_{j}'] = 0
  724. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  725. inspect_date = None
  726. for i,r in enumerate(data_ms_records, start=1):
  727. if i == 1:
  728. inspect_date = r.created_at
  729. placeholders[f'v{i}_2'] = r.tpoint1
  730. placeholders[f'v{i}_3'] = r.tpoint2
  731. placeholders[f'v{i}_4'] = r.tpoint3
  732. placeholders[f'v{i}_5'] = r.tpoint4
  733. placeholders[f'v{i}_10'] = r.tdiff
  734. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  735. return placeholders
  736. def merge_sheet_data_with_data(sheet_data, data):
  737. """
  738. Merge `sheet_data` with `data`.
  739. :param sheet_data: Dictionary containing the sheet-specific data.
  740. :param data: Dictionary containing general data.
  741. :return: A merged dictionary combining both `sheet_data` and `data`.
  742. """
  743. # Merge dictionaries using unpacking
  744. merged_data = {**data, **sheet_data}
  745. return merged_data
  746. def create_coi_file(lot_no, sheets, user, md):
  747. pprint("---- create_coi_file ---")
  748. pprint(md)
  749. qa1 = User.objects.get(pk=md['qa1'])
  750. qa2 = User.objects.get(pk=md['qa2'])
  751. accept = specialAccept = False
  752. if md['acceptStatus'] == "accepted":
  753. accept = True
  754. if md['acceptStatus'] == "special_accepted":
  755. specialAccept = True
  756. pprint(qa1)
  757. pprint(qa2)
  758. results = queryFromMaster(lot_no)
  759. first_result = results[0] if results else None
  760. code = first_result.PRO1 if first_result else None
  761. sheet_data = {}
  762. for sheet_name in sheets:
  763. if sheet_name == 'hardness_out':
  764. sheet_data[sheet_name] = generate_hardness_out_values(lot_no, code)
  765. elif sheet_name == 'hardness_out_in':
  766. sheet_data[sheet_name] = generate_hardness_out_in_values(lot_no, code)
  767. elif sheet_name == 'hardness_both_size':
  768. sheet_data[sheet_name] = generate_hardness_both_size_values(lot_no, first_result, code)
  769. elif sheet_name == 'dimension':
  770. sheet_data[sheet_name] = generate_dimension_values(lot_no, code)
  771. elif sheet_name == 'dimension_app':
  772. sheet_data[sheet_name] = generate_dimension_app_values(lot_no, code)
  773. elif sheet_name == 'dimension_app_drawing':
  774. sheet_data[sheet_name] = generate_dimension_app_drawing_values(lot_no, code)
  775. elif sheet_name == 'dimension_bal_weight':
  776. sheet_data[sheet_name] = generate_dimension_bal_weight_values(lot_no, first_result, code)
  777. elif sheet_name == 'centering':
  778. sheet_data[sheet_name] = generate_centering_values(lot_no, code)
  779. elif sheet_name == 'thickness_8_point':
  780. sheet_data[sheet_name] = generate_t8_values(lot_no, code)
  781. elif sheet_name == 'dim_bal_app_hard':
  782. sheet_data[sheet_name] = generate_dim_bal_app_hard_values(lot_no, first_result, code)
  783. elif sheet_name == 'dim_bal_app_rot_hard':
  784. sheet_data[sheet_name] = generate_dim_bal_app_rot_hard_values(lot_no, first_result, code)
  785. converted_data = convert_sheet_data(sheet_data)
  786. print(f"sheet_data \n {sheet_data}")
  787. print(f"converted_data \n {converted_data}")
  788. # results = queryFromMaster(lot_no)
  789. # first_result = results[0] if results else None
  790. try:
  791. pcs = int(first_result.PRO5) - int(first_result.PRO27)
  792. except:
  793. pcs = 0
  794. if first_result:
  795. size_str = f"{first_result.PRO10}x{first_result.PRO11}x{first_result.PRO12}";
  796. spec = f"{first_result.PRO13} {first_result.PRO14} {first_result.PRO15} {first_result.PRO16} {first_result.PRO17} {first_result.PRO18}"
  797. else:
  798. size_str = ""
  799. spec = ""
  800. mgt_code = first_result.PRO1 if first_result else "-"
  801. mks_map = MksCodeMap.objects.filter(mgt_code=mgt_code).first()
  802. if mks_map:
  803. code = f"{mks_map.mks_code}(MKSコード)  {mgt_code}(参照)"
  804. else:
  805. code = f"{mgt_code}(参照)" or "-"
  806. data = {
  807. # "code": first_result.PRO1 if first_result else "-",
  808. "code": code,
  809. "customer": first_result.PRO1C if first_result else "-",
  810. # "inspect_date": inspect_date.strftime('%Y/%m/%d') if inspect_date else "-",
  811. "lot_no": lot_no,
  812. "size": size_str,
  813. "lot_size": pcs,
  814. "spec": spec,
  815. # "hardness_out.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  816. # "hardness_out.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  817. "acc": accept, # Hide rows 24 to 28 if the prefix is "0"
  818. "spe_acc": specialAccept, # Hide rows 24 to 28 if the prefix is "0"
  819. "tool": first_result.PRO_TOOL if first_result else "-",
  820. # "hardness_out.qa1": f"{qa1.first_name} {qa1.last_name}",
  821. # "hardness_out.qa2": f"{qa2.first_name} {qa2.last_name}",
  822. "qa1": f"{qa1.first_name} {qa1.last_name}",
  823. "qa2": f"{qa2.first_name} {qa2.last_name}",
  824. "sign1": qa1.profile.signed_picture,
  825. "sign2": qa2.profile.signed_picture,
  826. "pos1": qa1.profile.get_position_display(),
  827. "pos2": qa2.profile.get_position_display()
  828. }
  829. merged_data = merge_sheet_data_with_data(converted_data, data)
  830. pprint(f"---- merged_data ---")
  831. pprint(merged_data)
  832. output_file = gen_xlsx(
  833. template_file=f"{settings.BASE_DIR}/report/coi_templates.xlsx",
  834. selected_sheets=sheets, # Replace with your actual sheet names
  835. prefix_filename=f"{settings.BASE_DIR}/media/coi_{lot_no}_",
  836. data=merged_data
  837. )
  838. report = Report.objects.create(
  839. name=lot_no,
  840. created_by=user,
  841. file=None # Leave this as None or assign a file if required
  842. )
  843. output_file_path = Path(output_file) # Convert to a Path object for convenience
  844. with open(output_file_path, "rb") as f:
  845. report.file.save(output_file_path.name, File(f), save=True)
  846. pprint(f"outputfile = {output_file}")
  847. return report
  848. def get_fields(model):
  849. # model_fields = {f.name: f for f in model._meta.get_fields()}
  850. # fields = list(model_fields.values())
  851. # return fields
  852. fields = [f for f in model._meta.get_fields() if not f.auto_created]
  853. return fields
  854. def filter_by_lot_no(lot_no):
  855. models = [Data, DataMs, DataRl, DataWb, LotSummary, LotSummaryRl, LotSummaryWb, PressCal, RotateData ] # List of models to process
  856. results = {}
  857. fields = {}
  858. for model in models:
  859. model_fields = [f.name for f in model._meta.get_fields()]
  860. # Check if "id" and "row_no" are in the model's fields
  861. order_fields = []
  862. if "id" in model_fields:
  863. order_fields.append("id")
  864. if "row_no" in model_fields:
  865. order_fields.append("row_no")
  866. # Dynamically filter and order results
  867. model_name = model.__name__
  868. if order_fields:
  869. results[model_name] = model.objects.filter(lot_no=lot_no).order_by(*order_fields)
  870. else:
  871. results[model_name] = model.objects.filter(lot_no=lot_no) # No
  872. fields[model_name] = get_fields(model)
  873. return results, fields
  874. def coi_view(request):
  875. pprint(f"xxxx method = xxx {request.method}")
  876. users = User.objects.all()
  877. if request.method == "POST":
  878. pprint(request.POST)
  879. exports = request.POST.getlist("exports") # Retrieve the list of selected values
  880. pprint(f"Selected Export Options: {exports}")
  881. if 'export' in request.POST:
  882. data = {
  883. "customer": "Tum Coder",
  884. "inspect_date": "2025-01-15",
  885. "lot_no": "12345",
  886. "staff_name": "Tum 8888",
  887. "man_name": "Tum 999",
  888. "size": "Large",
  889. "lot_size": "10 pcs",
  890. "spec": "Spec-A",
  891. "hardness_out.d1_act": "10",
  892. "hardness_out.d2_act": "0[24:28]", # Hide rows 24 to 28 if the prefix is "0"
  893. "hardness_out.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  894. "hardness_out.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  895. "dimension_app.d1_act": "33",
  896. "dimension_app.d2_act": "0[26:32]", # Hide rows 24 to 28 if the prefix is "0"
  897. "dimension_app.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  898. "dimension_app.spe_acc": True, # Hide rows 24 to 28 if the prefix is "0"
  899. }
  900. output_file = gen_xlsx(
  901. template_file="/app/report/coi_templates.xlsx",
  902. selected_sheets=exports, # Replace with your actual sheet names
  903. prefix_filename="/app/media/coi",
  904. data=data
  905. )
  906. report = Report.objects.create(
  907. name=request.POST.get('lot_no','Untitled'),
  908. created_by=request.user,
  909. file=None # Leave this as None or assign a file if required
  910. )
  911. output_file_path = Path(output_file) # Convert to a Path object for convenience
  912. with open(output_file_path, "rb") as f:
  913. report.file.save(output_file_path.name, File(f), save=True)
  914. pprint(f"outputfile = {output_file}")
  915. if 'search_lot' in request.POST:
  916. lot_no = request.POST.get('lot_no', None)
  917. lot_no = lot_no.strip()
  918. if lot_no:
  919. results = queryFromMaster(lot_no)
  920. first_result = results[0] if results else None
  921. selected_templates = None
  922. try:
  923. pcs = int(first_result.PRO5) - int(first_result.PRO27)
  924. except:
  925. pcs = 0
  926. code = "-"
  927. if first_result:
  928. size_str = f"{first_result.PRO10}x{first_result.PRO11}x{first_result.PRO12}";
  929. spec = f"{first_result.PRO13} {first_result.PRO14} {first_result.PRO15} {first_result.PRO16} {first_result.PRO17} {first_result.PRO18}"
  930. #first_result.PRO1C = "TUM"
  931. #selected_templates = CustomerTemplateMapping.objects.filter(customer_name=first_result.PRO1C).first().template_names
  932. mapping = CustomerTemplateMapping.objects.filter(customer_name=first_result.PRO1C).first()
  933. selected_templates = mapping.template_names if mapping else []
  934. mgt_code = first_result.PRO1 if first_result else "-"
  935. mks_map = MksCodeMap.objects.filter(mgt_code=mgt_code).first()
  936. if mks_map:
  937. code = f"{mks_map.mks_code}(MKSコード)  {mgt_code}(参照)"
  938. else:
  939. code = f"{mgt_code}(参照)" or "-"
  940. else:
  941. size_str = ""
  942. spec = ""
  943. results, fields = filter_by_lot_no(lot_no)
  944. # results1 = Data.objects.filter(lot_no=lot_no).order_by("id", "row_no")
  945. # fields1 = get_fields(Data)
  946. # results2 = DataMs.objects.filter(lot_no=lot_no).order_by("id", "row_no")
  947. # fields2 = get_fields(DataMs)
  948. return render(request, 'report/coi.html', {'result': first_result,
  949. 'pcs':pcs,
  950. 'size_str': size_str,
  951. 'lot_no': lot_no,
  952. 'spec': spec, 'users': users, 'SHEET_NAMES': SHEET_NAMES,
  953. 'results': results, 'fields': fields, 'selected_templates': selected_templates, 'code': code})
  954. messages.success(request, "Request Sent")
  955. return redirect(request.path_info)
  956. return render(request, 'report/coi.html', {'SHEET_NAMES': SHEET_NAMES, 'users': users})
  957. @csrf_exempt # Disable CSRF for API requests (ensure this is secure in production)
  958. @login_required
  959. def gen_report_view(request):
  960. if request.method == "POST":
  961. # try:
  962. # Parse JSON data from the request body
  963. data = json.loads(request.body)
  964. lot_no = data.get("lot_no").strip()
  965. exports = data.get("exports")
  966. qa1 = data.get('qa1')
  967. qa2 = data.get('qa2')
  968. print(f"data = {data}")
  969. if not lot_no:
  970. return HttpResponseBadRequest("Missing 'lot_no' in request data")
  971. # Call the `create_coi_file` function with the provided lot_no
  972. report = create_coi_file(lot_no, exports, request.user, {'qa1': qa1, 'qa2': qa2, \
  973. 'acceptStatus': data.get('acceptStatus')})
  974. # Return a success response with the report details
  975. return JsonResponse({
  976. "message": "Report generated successfully",
  977. "report_id": report.id,
  978. "file_url": report.file.url if report.file else None,
  979. })
  980. # except json.JSONDecodeError:
  981. # return HttpResponseBadRequest("Invalid JSON data")
  982. # except Exception as e:
  983. # pprint(e)
  984. # return JsonResponse({"error": str(e)}, status=500)
  985. else:
  986. return HttpResponseBadRequest("Only POST requests are allowed")
  987. class CustomerTemplateCRUDView(ConfigurableCRUDView):
  988. model = CustomerTemplateMapping
  989. list_template_name = 'report/customer_template_list.html'
  990. detail_template_name = 'legacy/datacrud_detail.html'
  991. form_template_name = 'report/customer_template_form.html'
  992. confirm_delete_template_name = 'legacy/datacrud_confirm_delete.html'
  993. filterset_class = CustomerTemplateFilter
  994. page_title = "Customer Template Mapping"
  995. # URL name mappings
  996. list_url_name = 'report:customer_templates-list'
  997. create_url_name = 'report:customer_templates-create'
  998. update_url_name = 'report:customer_templates-update'
  999. delete_url_name = 'report:customer_templates-delete'
  1000. config_fields = ["id", "customer_name", "template_names", "created_at"]
  1001. config_field_orders = ["id", "customer_name", "template_names", "created_at", "created_by"]
  1002. # config_readonly_fields = ["lot_no"]
  1003. config_edit_fields = None
  1004. ordering = ["-created_at", "-id",]
  1005. form_class = CustomerTemplateMappingForm
  1006. def get_list_view(self):
  1007. class ListViewClass(FilterView, ListView):
  1008. model = self.model
  1009. template_name = self.list_template_name
  1010. paginate_by = self.paginate_by
  1011. filterset_class = self.filterset_class
  1012. ordering = self.ordering
  1013. def get_context_data(inner_self, **kwargs):
  1014. context = super().get_context_data(**kwargs)
  1015. fields = self.get_fields()
  1016. context.update({
  1017. 'fields': [f for f in fields],
  1018. 'sheet_names': SHEET_NAMES,
  1019. # 'fields': [field for field in self.model._meta.get_fields()],
  1020. 'page_title': self.page_title,
  1021. 'list_url': self.list_url_name,
  1022. 'create_url': self.create_url_name,
  1023. 'update_url': self.update_url_name,
  1024. 'delete_url': self.delete_url_name,
  1025. 'bs': self.get_breadcrumbs('list'),
  1026. })
  1027. return context
  1028. return ListViewClass
  1029. class ProductDrawingCRUDView(ConfigurableCRUDView):
  1030. model = ProductDrawing
  1031. list_template_name = 'legacy/datacrud_list.html'
  1032. detail_template_name = 'legacy/datacrud_detail.html'
  1033. form_template_name = 'report/productdrawing_form.html'
  1034. confirm_delete_template_name = 'legacy/datacrud_confirm_delete.html'
  1035. filterset_class = ProductDrawingFilter
  1036. page_title = "Product Drawing"
  1037. # URL name mappings
  1038. list_url_name = 'report:product_drawings-list'
  1039. create_url_name = 'report:product_drawings-create'
  1040. update_url_name = 'report:product_drawings-update'
  1041. delete_url_name = 'report:product_drawings-delete'
  1042. config_fields = ["id", "code_no", "code_no_mks", "lot_no", "drawing", "description", "created_at"]
  1043. #config_field_orders = ["id", "customer_name", "template_names", "created_at", "created_by"]
  1044. # config_readonly_fields = ["lot_no"]
  1045. config_edit_fields = None
  1046. ordering = ["-created_at", "-id",]
  1047. form_class = ProductDrawingForm
  1048. class MksCodeMapCRUDView(ConfigurableCRUDView):
  1049. model = MksCodeMap
  1050. page_title = "MKS Code Mapping"
  1051. filterset_class = MksCodeMapFilter
  1052. list_template_name = "legacy/datacrud_list.html"
  1053. detail_template_name = "legacy/datacrud_detail.html"
  1054. form_template_name = 'legacy/datacrud_form.html'
  1055. confirm_delete_template_name = "legacy/datacrud_confirm_delete.html"
  1056. config_fields = ["id", "mgt_code", "mks_code", "created_at"]
  1057. config_edit_fields = ["mgt_code", "mks_code"]
  1058. list_url_name = "report:code_maps-list"
  1059. create_url_name = "report:code_maps-create"
  1060. update_url_name = "report:code_maps-update"
  1061. delete_url_name = "report:code_maps-delete"
  1062. ordering = ["-created_at", "-id"]