Нема описа

views.py 59KB

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