Ei kuvausta

views.py 55KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430
  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, Func, Value, F
  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", "26:29")
  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_2", "25:29")
  235. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  236. return placeholders
  237. def generate_dimension_weight_warp_values(lot_no, code):
  238. """
  239. Fetch dimension records from manualSize and DataMs models
  240. and generate placeholder values for Standard, Actual, and Judgement.
  241. Supports two row_no entries per lot.
  242. """
  243. # Fetch standard values from manualSize (limit to 2 rows)
  244. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  245. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  246. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  247. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  248. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  249. # Prepare placeholders
  250. # placeholders = {}
  251. placeholders = clear_values(7,4)
  252. # for i in range(1,7):
  253. # for j in range(1,4):
  254. # placeholders[f'v{i}_{j}'] = 0
  255. pprint(placeholders)
  256. pprint(manual_size_records)
  257. for m in dimens:
  258. if m.Size_Name == "D":
  259. placeholders['v1_1'] = placeholders['v4_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  260. if m.Size_Name == "T":
  261. placeholders['v2_1'] = placeholders['v5_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  262. if m.Size_Name == "H":
  263. placeholders['v3_1'] = placeholders['v6_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  264. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  265. inspect_date = None
  266. for r in data_ms_records:
  267. if r.row_no == 1:
  268. placeholders[f'v1_2'] = r.dsize
  269. placeholders[f'v1_3'] = r.dsizeok
  270. placeholders[f'v2_2'] = r.tsize
  271. placeholders[f'v2_3'] = r.tsizeok
  272. placeholders[f'v3_2'] = r.hsize
  273. placeholders[f'v3_3'] = r.hsizeok
  274. inspect_date = r.created_at
  275. if r.row_no == 2:
  276. placeholders[f'v4_2'] = r.dsize
  277. placeholders[f'v4_3'] = r.dsizeok
  278. placeholders[f'v5_2'] = r.tsize
  279. placeholders[f'v5_3'] = r.tsizeok
  280. placeholders[f'v6_2'] = r.hsize
  281. placeholders[f'v6_3'] = r.hsizeok
  282. for r in data_wb:
  283. if r.row_no == 1:
  284. placeholders["v7_1"] = r.weight
  285. placeholders["v7_2"] = r.judgement
  286. if r.row_no == 2:
  287. placeholders["v8_1"] = r.weight
  288. placeholders["v8_2"] = r.judgement
  289. hide_con(placeholders, "v4_2", "29:37")
  290. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  291. return placeholders
  292. def is_ok(instance):
  293. fields_and_values = {}
  294. for field in instance._meta.get_fields():
  295. field_name = field.name
  296. if field_name.endswith('ok'):
  297. v = getattr(instance, field_name)
  298. if v is not None and v != "OK":
  299. return False
  300. return True
  301. def generate_dimension_app_values(lot_no, code):
  302. """
  303. Fetch dimension records from manualSize and DataMs models
  304. and generate placeholder values for Standard, Actual, and Judgement.
  305. Supports two row_no entries per lot.
  306. """
  307. # Fetch standard values from manualSize (limit to 2 rows)
  308. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  309. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  310. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  311. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  312. # Prepare placeholders
  313. # placeholders = {}
  314. placeholders = clear_values(8,3)
  315. # for i in range(1,7):
  316. # for j in range(1,4):
  317. # placeholders[f'v{i}_{j}'] = 0
  318. pprint(placeholders)
  319. pprint(manual_size_records)
  320. # for m in manual_size_records:
  321. # if m.size_name == "D":
  322. # placeholders['v1_1'] = placeholders['v5_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  323. # if m.size_name == "T":
  324. # placeholders['v2_1'] = placeholders['v6_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  325. # if m.size_name == "H":
  326. # placeholders['v3_1'] = placeholders['v7_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  327. for m in dimens: # Changed from manual_size_records to dimens
  328. if m.Size_Name == "D":
  329. placeholders['v1_1'] = placeholders['v5_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  330. if m.Size_Name == "T":
  331. placeholders['v2_1'] = placeholders['v6_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  332. if m.Size_Name == "H":
  333. placeholders['v3_1'] = placeholders['v7_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  334. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  335. inspect_date = None
  336. for r in data_ms_records:
  337. if r.row_no == 1:
  338. placeholders[f'v1_2'] = r.dsize
  339. placeholders[f'v1_3'] = r.dsizeok
  340. placeholders[f'v2_2'] = r.tsize
  341. placeholders[f'v2_3'] = r.tsizeok
  342. placeholders[f'v3_2'] = r.hsize
  343. placeholders[f'v3_3'] = r.hsizeok
  344. inspect_date = r.created_at
  345. # if is_ok(r):
  346. # placeholders[f'v4_1'] = 'OK'
  347. # placeholders[f'v4_2'] = 'OK'
  348. # else:
  349. # placeholders[f'v4_1'] = 'NG'
  350. # placeholders[f'v4_2'] = 'OK'
  351. if r.row_no == 2:
  352. placeholders[f'v5_2'] = r.dsize
  353. placeholders[f'v5_3'] = r.dsizeok
  354. placeholders[f'v6_2'] = r.tsize
  355. placeholders[f'v6_3'] = r.tsizeok
  356. placeholders[f'v7_2'] = r.hsize
  357. placeholders[f'v7_3'] = r.hsizeok
  358. # if is_ok(r):
  359. # placeholders[f'v8_1'] = 'OK'
  360. # placeholders[f'v8_2'] = 'OK'
  361. # else:
  362. # placeholders[f'v8_1'] = 'NG'
  363. # placeholders[f'v8_2'] = 'NG'
  364. hide_con(placeholders, "v5_1", "29:37")
  365. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  366. return placeholders
  367. def safe_strip(val):
  368. """Remove '-' or return '' if None."""
  369. return val.replace('-', '') if val else ''
  370. def generate_dimension_app_drawing_values(lot_no, code):
  371. """
  372. Fetch dimension records from manualSize and DataMs models
  373. and generate placeholder values for Standard, Actual, and Judgement.
  374. Supports two row_no entries per lot.
  375. """
  376. # Fetch standard values from manualSize (limit to 2 rows)
  377. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  378. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  379. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  380. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  381. # Prepare placeholders
  382. # placeholders = {}
  383. placeholders = clear_values(8,3)
  384. # for i in range(1,7):
  385. # for j in range(1,4):
  386. # placeholders[f'v{i}_{j}'] = 0
  387. pprint(placeholders)
  388. pprint(manual_size_records)
  389. # for m in manual_size_records:
  390. # if m.size_name == "D":
  391. # placeholders['v1_1'] = placeholders['v5_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  392. # if m.size_name == "T":
  393. # placeholders['v2_1'] = placeholders['v6_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  394. # if m.size_name == "H":
  395. # placeholders['v3_1'] = placeholders['v7_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  396. for m in dimens: # Changed from manual_size_records to dimens
  397. if m.Size_Name == "D":
  398. placeholders['v1_1'] = placeholders['v5_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  399. if m.Size_Name == "T":
  400. placeholders['v2_1'] = placeholders['v6_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  401. if m.Size_Name == "H":
  402. placeholders['v3_1'] = placeholders['v7_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  403. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  404. inspect_date = None
  405. for r in data_ms_records:
  406. if r.row_no == 1:
  407. placeholders[f'v1_2'] = r.dsize
  408. placeholders[f'v1_3'] = r.dsizeok
  409. placeholders[f'v2_2'] = r.tsize
  410. placeholders[f'v2_3'] = r.tsizeok
  411. placeholders[f'v3_2'] = r.hsize
  412. placeholders[f'v3_3'] = r.hsizeok
  413. inspect_date = r.created_at
  414. # if is_ok(r):
  415. # placeholders[f'v4_1'] = 'OK'
  416. # placeholders[f'v4_2'] = 'OK'
  417. # else:
  418. # placeholders[f'v4_1'] = 'NG'
  419. # placeholders[f'v4_2'] = 'OK'
  420. if r.row_no == 2:
  421. placeholders[f'v5_2'] = r.dsize
  422. placeholders[f'v5_3'] = r.dsizeok
  423. placeholders[f'v6_2'] = r.tsize
  424. placeholders[f'v6_3'] = r.tsizeok
  425. placeholders[f'v7_2'] = r.hsize
  426. placeholders[f'v7_3'] = r.hsizeok
  427. # if is_ok(r):
  428. # placeholders[f'v8_1'] = 'OK'
  429. # placeholders[f'v8_2'] = 'OK'
  430. # else:
  431. # placeholders[f'v8_1'] = 'NG'
  432. # placeholders[f'v8_2'] = 'NG'
  433. hide_con(placeholders, "v5_1", "27:33")
  434. norm_lot_no = safe_strip(lot_no)
  435. norm_code = safe_strip(code)
  436. drawing_qs = ProductDrawing.objects.annotate(
  437. norm_lot_no=Func(F('lot_no'), Value('-'), Value(''), function='replace'),
  438. norm_code_no=Func(F('code_no'), Value('-'), Value(''), function='replace')
  439. )
  440. query = Q()
  441. if norm_lot_no:
  442. query |= Q(norm_lot_no=norm_lot_no)
  443. if norm_code:
  444. query |= Q(norm_code_no=norm_code)
  445. drawing_data = drawing_qs.filter(query).first()
  446. pprint(f"1.1 = {drawing_data}")
  447. pprint(f"1.2 = {lot_no} {code}")
  448. if drawing_data:
  449. placeholders["drawing"] = drawing_data.drawing if drawing_data.drawing else "-"
  450. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  451. return placeholders
  452. def generate_dimension_bal_weight_values(lot_no, ms, code):
  453. """
  454. Fetch dimension records from manualSize and DataMs models
  455. and generate placeholder values for Standard, Actual, and Judgement.
  456. Supports two row_no entries per lot.
  457. """
  458. # Fetch standard values from manualSize (limit to 2 rows)
  459. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  460. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  461. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  462. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  463. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  464. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  465. data_ho = list(chain(data_h1, data_h2))
  466. # Prepare placeholders
  467. # placeholders = {}
  468. placeholders = clear_values(10,3)
  469. # for i in range(1,7):
  470. # for j in range(1,4):
  471. # placeholders[f'v{i}_{j}'] = 0
  472. pprint(placeholders)
  473. pprint(manual_size_records)
  474. if ms:
  475. try:
  476. w = ms.PRO6
  477. placeholders['v4_1'] = placeholders['v9_1'] = w
  478. except:
  479. print("no PRO6")
  480. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  481. for m in dimens: # Changed from manual_size_records to dimens
  482. if m.Size_Name == "D":
  483. placeholders['v1_1'] = placeholders['v6_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  484. if m.Size_Name == "T":
  485. placeholders['v2_1'] = placeholders['v7_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  486. if m.Size_Name == "H":
  487. placeholders['v3_1'] = placeholders['v8_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  488. inspect_date = None
  489. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  490. for r in data_ms_records:
  491. if r.row_no == 1:
  492. placeholders[f'v1_2'] = r.dsize
  493. placeholders[f'v1_3'] = r.dsizeok
  494. placeholders[f'v2_2'] = r.tsize
  495. placeholders[f'v2_3'] = r.tsizeok
  496. placeholders[f'v3_2'] = r.hsize
  497. placeholders[f'v3_3'] = r.hsizeok
  498. inspect_date = r.created_at
  499. # if is_ok(r):
  500. # placeholders[f'v4_1'] = 'OK'
  501. # placeholders[f'v4_2'] = 'OK'
  502. # else:
  503. # placeholders[f'v4_1'] = 'NG'
  504. # placeholders[f'v4_2'] = 'OK'
  505. if r.row_no == 2:
  506. placeholders[f'v6_2'] = r.dsize
  507. placeholders[f'v6_3'] = r.dsizeok
  508. placeholders[f'v7_2'] = r.tsize
  509. placeholders[f'v7_3'] = r.tsizeok
  510. placeholders[f'v8_2'] = r.hsize
  511. placeholders[f'v8_3'] = r.hsizeok
  512. # if is_ok(r):
  513. # placeholders[f'v8_1'] = 'OK'
  514. # placeholders[f'v8_2'] = 'OK'
  515. # else:
  516. # placeholders[f'v8_1'] = 'NG'
  517. # placeholders[f'v8_2'] = 'NG'
  518. for r in data_wb:
  519. if r.row_no == 1:
  520. placeholders["v4_2"] = r.result
  521. placeholders["v4_3"] = r.judgement
  522. placeholders["v5_2"] = r.weight
  523. placeholders["v5_3"] = r.judgement
  524. if r.row_no == 2:
  525. placeholders["v9_2"] = r.result
  526. placeholders["v9_3"] = r.judgement
  527. placeholders["v10_2"] = r.weight
  528. placeholders["v10_3"] = r.judgement
  529. # hide_con(placeholders, "v5_1", "26:32")
  530. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  531. return placeholders
  532. def generate_dim_bal_app_hard_values(lot_no, first_result, code):
  533. """
  534. Fetch dimension records from manualSize and DataMs models
  535. and generate placeholder values for Standard, Actual, and Judgement.
  536. Supports two row_no entries per lot.
  537. """
  538. # Fetch standard values from manualSize (limit to 2 rows)
  539. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  540. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  541. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  542. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  543. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  544. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  545. data_ho = list(chain(data_h1, data_h2))
  546. if first_result:
  547. # out_limit = f"Out 外 ({first_result.MI18} - {first_result.MI19})"
  548. # in_limit = f"In 内 ({first_result.MI22} - {first_result.MI23})"
  549. try:
  550. out_limit = f"Out 外 ({float(first_result.MI18):.2f} - {float(first_result.MI19):.2f})"
  551. except (TypeError, ValueError):
  552. out_limit = "Out 外"
  553. try:
  554. in_limit = f"In 内 ({float(first_result.MI22):.2f} - {float(first_result.MI23):.2f})"
  555. except (TypeError, ValueError):
  556. in_limit = "In 内"
  557. mid_limit = f"Middle 中 -"
  558. else:
  559. out_limit = f"Out 外"
  560. in_limit = f"In 内"
  561. mid_limit = f"Middle 中"
  562. # Prepare placeholders
  563. # placeholders = {}
  564. placeholders = clear_values(16,5)
  565. # for i in range(1,7):
  566. # for j in range(1,4):
  567. # placeholders[f'v{i}_{j}'] = 0
  568. placeholders['v6_0'] = placeholders['v14_0'] = out_limit
  569. placeholders['v7_0'] = placeholders['v15_0'] = mid_limit
  570. placeholders['v8_0'] = placeholders['v16_0'] = in_limit
  571. pprint(placeholders)
  572. pprint(manual_size_records)
  573. if first_result:
  574. try:
  575. w = first_result.PRO6
  576. placeholders['v4_1'] = placeholders['v12_1'] = w
  577. except:
  578. print("No PRO6")
  579. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  580. for m in dimens: # Changed from manual_size_records to dimens
  581. if m.Size_Name == "D":
  582. placeholders['v1_1'] = placeholders['v9_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  583. if m.Size_Name == "T":
  584. placeholders['v2_1'] = placeholders['v10_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  585. if m.Size_Name == "H":
  586. placeholders['v3_1'] = placeholders['v11_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  587. inspect_date = None
  588. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  589. for r in data_ms_records:
  590. if r.row_no == 1:
  591. placeholders[f'v1_2'] = r.dsize
  592. placeholders[f'v1_3'] = r.dsizeok
  593. placeholders[f'v2_2'] = r.tsize
  594. placeholders[f'v2_3'] = r.tsizeok
  595. placeholders[f'v3_2'] = r.hsize
  596. placeholders[f'v3_3'] = r.hsizeok
  597. inspect_date = r.created_at
  598. # if is_ok(r):
  599. # placeholders[f'v4_1'] = 'OK'
  600. # placeholders[f'v4_2'] = 'OK'
  601. # else:
  602. # placeholders[f'v4_1'] = 'NG'
  603. # placeholders[f'v4_2'] = 'OK'
  604. if r.row_no == 2:
  605. placeholders[f'v9_2'] = r.dsize
  606. placeholders[f'v9_3'] = r.dsizeok
  607. placeholders[f'v10_2'] = r.tsize
  608. placeholders[f'v10_3'] = r.tsizeok
  609. placeholders[f'v11_2'] = r.hsize
  610. placeholders[f'v11_3'] = r.hsizeok
  611. # if is_ok(r):
  612. # placeholders[f'v8_1'] = 'OK'
  613. # placeholders[f'v8_2'] = 'OK'
  614. # else:
  615. # placeholders[f'v8_1'] = 'NG'
  616. # placeholders[f'v8_2'] = 'NG'
  617. for r in data_wb:
  618. if r.row_no == 1:
  619. placeholders["v4_2"] = r.weight
  620. placeholders["v4_3"] = r.judgement
  621. if r.row_no == 2:
  622. placeholders["v12_2"] = r.weight
  623. placeholders["v12_3"] = r.judgement
  624. for r in data_ho:
  625. if r.row_no == 1:
  626. rmap = {'OUT': 6, 'MID': 7, 'IN': 8}
  627. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  628. idx = rmap.get(r.r_type, None)
  629. if idx:
  630. placeholders[f'v{idx}_{index}'] = getattr(r, v, "-")
  631. if r.row_no == 2:
  632. rmap = {'OUT': 14, 'MID': 15, 'IN': 16}
  633. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  634. idx = rmap.get(r.r_type, None)
  635. if idx:
  636. placeholders[f'v{idx}_{index}'] = getattr(r, v, "-")
  637. # hide_con(placeholders, "v5_1", "26:32")
  638. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  639. return placeholders
  640. def generate_dim_bal_app_rot_hard_values(lot_no, first_result, code):
  641. """
  642. Fetch dimension records from manualSize and DataMs models
  643. and generate placeholder values for Standard, Actual, and Judgement.
  644. Supports two row_no entries per lot.
  645. """
  646. # Fetch standard values from manualSize (limit to 2 rows)
  647. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  648. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  649. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  650. data_wb = DataWb.objects.filter(lot_no=lot_no).order_by('row_no')
  651. data_h1 = list(Data.objects.filter(lot_no=lot_no).order_by('row_no'))
  652. data_h2 = list(DataRl.objects.filter(lot_no=lot_no).order_by('row_no'))
  653. data_ho = list(chain(data_h1, data_h2))
  654. rotates = RotateData.objects.filter(lot_no=lot_no).order_by('row_no')
  655. if first_result:
  656. # out_limit = f"Out 外 ({first_result.MI18} - {first_result.MI19})"
  657. # in_limit = f"In 内 ({first_result.MI22} - {first_result.MI23})"
  658. try:
  659. out_limit = f"Out 外 ({float(first_result.MI18):.2f} - {float(first_result.MI19):.2f})"
  660. except (TypeError, ValueError):
  661. out_limit = "Out 外"
  662. try:
  663. in_limit = f"In 内 ({float(first_result.MI22):.2f} - {float(first_result.MI23):.2f})"
  664. except (TypeError, ValueError):
  665. in_limit = "In 内"
  666. mid_limit = f"Middle 中 -"
  667. else:
  668. out_limit = f"Out 外"
  669. in_limit = f"In 内"
  670. mid_limit = f"Middle 中"
  671. # Prepare placeholders
  672. # placeholders = {}
  673. placeholders = clear_values(18,5)
  674. # for i in range(1,7):
  675. # for j in range(1,4):
  676. # placeholders[f'v{i}_{j}'] = 0
  677. placeholders['v6_0'] = placeholders['v14_0'] = out_limit
  678. placeholders['v7_0'] = placeholders['v15_0'] = mid_limit
  679. placeholders['v18_0'] = placeholders['v16_0'] = in_limit
  680. pprint(placeholders)
  681. pprint(manual_size_records)
  682. if first_result:
  683. try:
  684. w = first_result.PRO6
  685. placeholders['v4_1'] = placeholders['v13_1'] = w
  686. except:
  687. print("no PRO6")
  688. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  689. for m in dimens: # Changed from manual_size_records to dimens
  690. if m.Size_Name == "D":
  691. placeholders['v1_1'] = placeholders['v10_1'] = f'D{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  692. if m.Size_Name == "T":
  693. placeholders['v2_1'] = placeholders['v11_1'] = f'T{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  694. if m.Size_Name == "H":
  695. placeholders['v3_1'] = placeholders['v12_1'] = f'H{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  696. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  697. inspect_date = None
  698. for r in data_ms_records:
  699. if r.row_no == 1:
  700. placeholders[f'v1_2'] = r.dsize
  701. placeholders[f'v1_3'] = r.dsizeok
  702. placeholders[f'v2_2'] = r.tsize
  703. placeholders[f'v2_3'] = r.tsizeok
  704. placeholders[f'v3_2'] = r.hsize
  705. placeholders[f'v3_3'] = r.hsizeok
  706. inspect_date = r.created_at
  707. # if is_ok(r):
  708. # placeholders[f'v4_1'] = 'OK'
  709. # placeholders[f'v4_2'] = 'OK'
  710. # else:
  711. # placeholders[f'v4_1'] = 'NG'
  712. # placeholders[f'v4_2'] = 'OK'
  713. if r.row_no == 2:
  714. placeholders[f'v10_2'] = r.dsize
  715. placeholders[f'v10_3'] = r.dsizeok
  716. placeholders[f'v11_2'] = r.tsize
  717. placeholders[f'v11_3'] = r.tsizeok
  718. placeholders[f'v12_2'] = r.hsize
  719. placeholders[f'v12_3'] = r.hsizeok
  720. # if is_ok(r):
  721. # placeholders[f'v8_1'] = 'OK'
  722. # placeholders[f'v8_2'] = 'OK'
  723. # else:
  724. # placeholders[f'v8_1'] = 'NG'
  725. # placeholders[f'v8_2'] = 'NG'
  726. for r in data_wb:
  727. if r.row_no == 1:
  728. placeholders["v4_2"] = r.weight
  729. placeholders["v4_3"] = r.judgement
  730. if r.row_no == 2:
  731. placeholders["v13_2"] = r.weight
  732. placeholders["v13_3"] = r.judgement
  733. for r in data_ho:
  734. if r.row_no == 1:
  735. rmap = {'OUT': 7, 'MID': 8, 'IN': 9}
  736. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  737. idx = rmap.get(r.r_type, None)
  738. if idx:
  739. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  740. if r.row_no == 2:
  741. rmap = {'OUT': 16, 'MID': 17, 'IN': 18}
  742. for index, v in enumerate(["p1", "p2", "p3", "avg", "rgrade"], start=1):
  743. idx = rmap.get(r.r_type, None)
  744. if idx:
  745. placeholders[f'v{idx}_{index}'] = getattr(r, v)
  746. for r in rotates:
  747. if r.row_no == 1:
  748. placeholders["v6_1"] = r.speed_spec
  749. placeholders["v6_2"] = r.speed_test
  750. placeholders["v6_3"] = r.speedok
  751. if r.row_no == 2:
  752. placeholders["v15_1"] = r.speed_spec
  753. placeholders["v15_2"] = r.speed_test
  754. placeholders["v15_3"] = r.speedok
  755. # hide_con(placeholders, "v5_1", "26:32")
  756. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  757. return placeholders
  758. def generate_centering_values(lot_no, code):
  759. """
  760. Fetch dimension records from manualSize and DataMs models
  761. and generate placeholder values for Standard, Actual, and Judgement.
  762. Supports two row_no entries per lot.
  763. """
  764. # Fetch standard values from manualSize (limit to 2 rows)
  765. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  766. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  767. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  768. # Prepare placeholders
  769. # placeholders = {}
  770. placeholders = clear_values(10,3)
  771. # for i in range(1,7):
  772. # for j in range(1,4):
  773. # placeholders[f'v{i}_{j}'] = 0
  774. pprint(placeholders)
  775. pprint(manual_size_records)
  776. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  777. inspect_date = None
  778. for i,r in enumerate(data_ms_records, start=1):
  779. if i == 1:
  780. inspect_date = r.created_at
  781. placeholders[f'v{i}_2'] = r.censize
  782. placeholders[f'v{i}_3'] = r.censizeok
  783. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  784. return placeholders
  785. def generate_t8_values(lot_no, code):
  786. """
  787. Fetch dimension records from manualSize and DataMs models
  788. and generate placeholder values for Standard, Actual, and Judgement.
  789. Supports two row_no entries per lot.
  790. """
  791. # Fetch standard values from manualSize (limit to 2 rows)
  792. placeholders = clear_values(8,10)
  793. manual_size_records = Manualsize.objects.filter(lotno=lot_no)
  794. # pprint(f"manual_size = {manual_size_records}")
  795. dimens = AllProductDimensionForInsProcess.objects.filter(ProductCode=code)
  796. for m in dimens: # Changed from manual_size_records to dimens
  797. if m.Size_Name == "Thickness":
  798. for i in range(1, 9):
  799. placeholders[f'v{i}_1'] = f'{m.Std:.2f} +{m.TolUp:.2f} {m.TolUn:.2f}'
  800. # pprint("set std")
  801. # Fetch actual and judgement values from DataMs ordered by row_no (limit to 2 rows)
  802. data_ms_records = DataMs.objects.filter(lot_no=lot_no).order_by('row_no')
  803. # Prepare placeholders
  804. # placeholders = {}
  805. # for i in range(1,7):
  806. # for j in range(1,4):
  807. # placeholders[f'v{i}_{j}'] = 0
  808. # Ensure that we map each manualSize entry to a corresponding DataMs entry
  809. inspect_date = None
  810. for i,r in enumerate(data_ms_records, start=1):
  811. if i == 1:
  812. inspect_date = r.created_at
  813. placeholders[f'v{i}_2'] = r.tpoint1
  814. placeholders[f'v{i}_3'] = r.tpoint2
  815. placeholders[f'v{i}_4'] = r.tpoint3
  816. placeholders[f'v{i}_5'] = r.tpoint4
  817. placeholders[f'v{i}_10'] = r.tdiff
  818. placeholders['inspect_date'] = inspect_date.strftime('%Y/%m/%d') if inspect_date else "-"
  819. return placeholders
  820. def merge_sheet_data_with_data(sheet_data, data):
  821. """
  822. Merge `sheet_data` with `data`.
  823. :param sheet_data: Dictionary containing the sheet-specific data.
  824. :param data: Dictionary containing general data.
  825. :return: A merged dictionary combining both `sheet_data` and `data`.
  826. """
  827. # Merge dictionaries using unpacking
  828. merged_data = {**data, **sheet_data}
  829. return merged_data
  830. def create_coi_file(lot_no, sheets, user, md):
  831. pprint("---- create_coi_file ---")
  832. pprint(md)
  833. qa1 = User.objects.get(pk=md['qa1'])
  834. qa2 = User.objects.get(pk=md['qa2'])
  835. accept = specialAccept = False
  836. if md['acceptStatus'] == "accepted":
  837. accept = True
  838. if md['acceptStatus'] == "special_accepted":
  839. specialAccept = True
  840. pprint(qa1)
  841. pprint(qa2)
  842. results = queryFromMaster(lot_no)
  843. first_result = results[0] if results else None
  844. code = first_result.PRO1 if first_result else None
  845. sheet_data = {}
  846. for sheet_name in sheets:
  847. if sheet_name == 'hardness_out':
  848. sheet_data[sheet_name] = generate_hardness_out_values(lot_no, code)
  849. elif sheet_name == 'hardness_out_in':
  850. sheet_data[sheet_name] = generate_hardness_out_in_values(lot_no, code)
  851. elif sheet_name == 'hardness_both_size':
  852. sheet_data[sheet_name] = generate_hardness_both_size_values(lot_no, first_result, code)
  853. elif sheet_name == 'dimension':
  854. sheet_data[sheet_name] = generate_dimension_values(lot_no, code)
  855. elif sheet_name == 'dimension_weight_warp':
  856. sheet_data[sheet_name] = generate_dimension_weight_warp_values(lot_no, code)
  857. elif sheet_name == 'dimension_app':
  858. sheet_data[sheet_name] = generate_dimension_app_values(lot_no, code)
  859. elif sheet_name == 'dimension_app_drawing':
  860. sheet_data[sheet_name] = generate_dimension_app_drawing_values(lot_no, code)
  861. elif sheet_name == 'dimension_bal_weight':
  862. sheet_data[sheet_name] = generate_dimension_bal_weight_values(lot_no, first_result, code)
  863. elif sheet_name == 'centering':
  864. sheet_data[sheet_name] = generate_centering_values(lot_no, code)
  865. elif sheet_name == 'thickness_8_point':
  866. sheet_data[sheet_name] = generate_t8_values(lot_no, code)
  867. elif sheet_name == 'dim_bal_app_hard':
  868. sheet_data[sheet_name] = generate_dim_bal_app_hard_values(lot_no, first_result, code)
  869. elif sheet_name == 'dim_bal_app_hard_stamp':
  870. sheet_data[sheet_name] = generate_dim_bal_app_hard_values(lot_no, first_result, code)
  871. elif sheet_name == 'dim_bal_app_rot_hard':
  872. sheet_data[sheet_name] = generate_dim_bal_app_rot_hard_values(lot_no, first_result, code)
  873. converted_data = convert_sheet_data(sheet_data)
  874. print(f"sheet_data \n {sheet_data}")
  875. print(f"converted_data \n {converted_data}")
  876. # results = queryFromMaster(lot_no)
  877. # first_result = results[0] if results else None
  878. try:
  879. pcs = int(first_result.PRO5) - int(first_result.PRO27)
  880. except:
  881. pcs = 0
  882. # first_result.PRO10 = 12321.1232
  883. # first_result.PRO11 = 1.5
  884. # first_result.PRO12 = 3.5
  885. if first_result:
  886. # size_str = f"{first_result.PRO10}x{first_result.PRO11}x{first_result.PRO12}";
  887. try:
  888. size_str = f"{float(first_result.PRO10):.2f}x{float(first_result.PRO11):.2f}x{float(first_result.PRO12):.2f}"
  889. except (ValueError, TypeError):
  890. size_str = "-"
  891. spec = f"{first_result.PRO13} {first_result.PRO14} {first_result.PRO15} {first_result.PRO16} {first_result.PRO17} {first_result.PRO18}"
  892. else:
  893. size_str = ""
  894. spec = ""
  895. mgt_code = first_result.PRO1 if first_result else "-"
  896. mks_map = MksCodeMap.objects.filter(mgt_code=mgt_code).first()
  897. if mks_map:
  898. code = f"{mks_map.mks_code}(MKSコード)  {mgt_code}(参照)"
  899. else:
  900. code = f"{mgt_code}(参照)" or "-"
  901. # first_result.PRO_TOOL = None
  902. data = {
  903. # "code": first_result.PRO1 if first_result else "-",
  904. "code": code,
  905. "customer": first_result.PRO1C if first_result else "-",
  906. # "inspect_date": inspect_date.strftime('%Y/%m/%d') if inspect_date else "-",
  907. "lot_no": lot_no,
  908. "size": size_str,
  909. "lot_size": pcs,
  910. "spec": spec,
  911. # "hardness_out.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  912. # "hardness_out.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  913. "acc": accept, # Hide rows 24 to 28 if the prefix is "0"
  914. "spe_acc": specialAccept, # Hide rows 24 to 28 if the prefix is "0"
  915. "tool": first_result.PRO_TOOL if first_result and first_result.PRO_TOOL else "-",
  916. # "hardness_out.qa1": f"{qa1.first_name} {qa1.last_name}",
  917. # "hardness_out.qa2": f"{qa2.first_name} {qa2.last_name}",
  918. "qa1": f"{qa1.first_name} {qa1.last_name}",
  919. "qa2": f"{qa2.first_name} {qa2.last_name}",
  920. "sign1": qa1.profile.signed_picture,
  921. "sign2": qa2.profile.signed_picture,
  922. "pos1": qa1.profile.get_position_display(),
  923. "pos2": qa2.profile.get_position_display()
  924. }
  925. merged_data = merge_sheet_data_with_data(converted_data, data)
  926. pprint(f"---- merged_data ---")
  927. pprint(merged_data)
  928. output_file = gen_xlsx(
  929. template_file=f"{settings.BASE_DIR}/report/coi_templates.xlsx",
  930. selected_sheets=sheets, # Replace with your actual sheet names
  931. prefix_filename=f"{settings.BASE_DIR}/media/coi_{lot_no}_",
  932. data=merged_data
  933. )
  934. report = Report.objects.create(
  935. name=lot_no,
  936. created_by=user,
  937. file=None # Leave this as None or assign a file if required
  938. )
  939. output_file_path = Path(output_file) # Convert to a Path object for convenience
  940. with open(output_file_path, "rb") as f:
  941. report.file.save(output_file_path.name, File(f), save=True)
  942. pprint(f"outputfile = {output_file}")
  943. return report
  944. def get_fields(model):
  945. # model_fields = {f.name: f for f in model._meta.get_fields()}
  946. # fields = list(model_fields.values())
  947. # return fields
  948. fields = [f for f in model._meta.get_fields() if not f.auto_created]
  949. return fields
  950. def filter_by_lot_no(lot_no):
  951. models = [Data, DataMs, DataRl, DataWb, LotSummary, LotSummaryRl, LotSummaryWb, PressCal, RotateData ] # List of models to process
  952. results = {}
  953. fields = {}
  954. for model in models:
  955. model_fields = [f.name for f in model._meta.get_fields()]
  956. # Check if "id" and "row_no" are in the model's fields
  957. order_fields = []
  958. if "id" in model_fields:
  959. order_fields.append("id")
  960. if "row_no" in model_fields:
  961. order_fields.append("row_no")
  962. # Dynamically filter and order results
  963. model_name = model.__name__
  964. if order_fields:
  965. results[model_name] = model.objects.filter(lot_no=lot_no).order_by(*order_fields)
  966. else:
  967. results[model_name] = model.objects.filter(lot_no=lot_no) # No
  968. fields[model_name] = get_fields(model)
  969. return results, fields
  970. @login_required
  971. def coi_view(request):
  972. pprint(f"xxxx method = xxx {request.method}")
  973. users = User.objects.all()
  974. if request.method == "POST":
  975. pprint(request.POST)
  976. exports = request.POST.getlist("exports") # Retrieve the list of selected values
  977. pprint(f"Selected Export Options: {exports}")
  978. if 'export' in request.POST:
  979. data = {
  980. "customer": "Tum Coder",
  981. "inspect_date": "2025-01-15",
  982. "lot_no": "12345",
  983. "staff_name": "Tum 8888",
  984. "man_name": "Tum 999",
  985. "size": "Large",
  986. "lot_size": "10 pcs",
  987. "spec": "Spec-A",
  988. "hardness_out.d1_act": "10",
  989. "hardness_out.d2_act": "0[24:28]", # Hide rows 24 to 28 if the prefix is "0"
  990. "hardness_out.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  991. "hardness_out.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  992. "dimension_app.d1_act": "33",
  993. "dimension_app.d2_act": "0[26:32]", # Hide rows 24 to 28 if the prefix is "0"
  994. "dimension_app.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  995. "dimension_app.spe_acc": True, # Hide rows 24 to 28 if the prefix is "0"
  996. }
  997. output_file = gen_xlsx(
  998. template_file="/app/report/coi_templates.xlsx",
  999. selected_sheets=exports, # Replace with your actual sheet names
  1000. prefix_filename="/app/media/coi",
  1001. data=data
  1002. )
  1003. report = Report.objects.create(
  1004. name=request.POST.get('lot_no','Untitled'),
  1005. created_by=request.user,
  1006. file=None # Leave this as None or assign a file if required
  1007. )
  1008. output_file_path = Path(output_file) # Convert to a Path object for convenience
  1009. with open(output_file_path, "rb") as f:
  1010. report.file.save(output_file_path.name, File(f), save=True)
  1011. pprint(f"outputfile = {output_file}")
  1012. if 'search_lot' in request.POST:
  1013. lot_no = request.POST.get('lot_no', None)
  1014. lot_no = lot_no.strip()
  1015. if lot_no:
  1016. results = queryFromMaster(lot_no)
  1017. first_result = results[0] if results else None
  1018. selected_templates = None
  1019. try:
  1020. pcs = int(first_result.PRO5) - int(first_result.PRO27)
  1021. except:
  1022. pcs = 0
  1023. code = "-"
  1024. if first_result:
  1025. size_str = f"{first_result.PRO10}x{first_result.PRO11}x{first_result.PRO12}";
  1026. spec = f"{first_result.PRO13} {first_result.PRO14} {first_result.PRO15} {first_result.PRO16} {first_result.PRO17} {first_result.PRO18}"
  1027. #first_result.PRO1C = "TUM"
  1028. #selected_templates = CustomerTemplateMapping.objects.filter(customer_name=first_result.PRO1C).first().template_names
  1029. # first_result.PRO1C = 'OSAKA SEIMITSU'
  1030. mapping = CustomerTemplateMapping.objects.filter(customer_name__icontains=first_result.PRO1C).first()
  1031. selected_templates = mapping.template_names if mapping else []
  1032. mgt_code = first_result.PRO1 if first_result else "-"
  1033. mks_map = MksCodeMap.objects.filter(mgt_code=mgt_code).first()
  1034. if mks_map:
  1035. code = f"{mks_map.mks_code}(MKSコード)  {mgt_code}(参照)"
  1036. else:
  1037. code = f"{mgt_code}(参照)" or "-"
  1038. else:
  1039. size_str = ""
  1040. spec = ""
  1041. results, fields = filter_by_lot_no(lot_no)
  1042. # results1 = Data.objects.filter(lot_no=lot_no).order_by("id", "row_no")
  1043. # fields1 = get_fields(Data)
  1044. # results2 = DataMs.objects.filter(lot_no=lot_no).order_by("id", "row_no")
  1045. # fields2 = get_fields(DataMs)
  1046. return render(request, 'report/coi.html', {'result': first_result,
  1047. 'pcs':pcs,
  1048. 'size_str': size_str,
  1049. 'lot_no': lot_no,
  1050. 'spec': spec, 'users': users, 'SHEET_NAMES': SHEET_NAMES,
  1051. 'results': results, 'fields': fields, 'selected_templates': selected_templates, 'code': code})
  1052. messages.success(request, "Request Sent")
  1053. return redirect(request.path_info)
  1054. return render(request, 'report/coi.html', {'SHEET_NAMES': SHEET_NAMES, 'users': users})
  1055. @csrf_exempt # Disable CSRF for API requests (ensure this is secure in production)
  1056. @login_required
  1057. def gen_report_view(request):
  1058. if request.method == "POST":
  1059. # try:
  1060. # Parse JSON data from the request body
  1061. data = json.loads(request.body)
  1062. lot_no = data.get("lot_no").strip()
  1063. exports = data.get("exports")
  1064. qa1 = data.get('qa1')
  1065. qa2 = data.get('qa2')
  1066. print(f"data = {data}")
  1067. if not lot_no:
  1068. return HttpResponseBadRequest("Missing 'lot_no' in request data")
  1069. # Call the `create_coi_file` function with the provided lot_no
  1070. report = create_coi_file(lot_no, exports, request.user, {'qa1': qa1, 'qa2': qa2, \
  1071. 'acceptStatus': data.get('acceptStatus')})
  1072. # Return a success response with the report details
  1073. return JsonResponse({
  1074. "message": "Report generated successfully",
  1075. "report_id": report.id,
  1076. "file_url": report.file.url if report.file else None,
  1077. })
  1078. # except json.JSONDecodeError:
  1079. # return HttpResponseBadRequest("Invalid JSON data")
  1080. # except Exception as e:
  1081. # pprint(e)
  1082. # return JsonResponse({"error": str(e)}, status=500)
  1083. else:
  1084. return HttpResponseBadRequest("Only POST requests are allowed")
  1085. class CustomerTemplateCRUDView(ConfigurableCRUDView):
  1086. model = CustomerTemplateMapping
  1087. list_template_name = 'report/customer_template_list.html'
  1088. detail_template_name = 'legacy/datacrud_detail.html'
  1089. form_template_name = 'report/customer_template_form.html'
  1090. confirm_delete_template_name = 'legacy/datacrud_confirm_delete.html'
  1091. filterset_class = CustomerTemplateFilter
  1092. page_title = "Customer Template Mapping"
  1093. # URL name mappings
  1094. list_url_name = 'report:customer_templates-list'
  1095. create_url_name = 'report:customer_templates-create'
  1096. update_url_name = 'report:customer_templates-update'
  1097. delete_url_name = 'report:customer_templates-delete'
  1098. config_fields = ["id", "customer_name", "template_names", "created_at"]
  1099. config_field_orders = ["id", "customer_name", "template_names", "created_at", "created_by"]
  1100. # config_readonly_fields = ["lot_no"]
  1101. config_edit_fields = None
  1102. ordering = ["-created_at", "-id",]
  1103. form_class = CustomerTemplateMappingForm
  1104. def get_list_view(self):
  1105. class ListViewClass(FilterView, ListView):
  1106. model = self.model
  1107. template_name = self.list_template_name
  1108. paginate_by = self.paginate_by
  1109. filterset_class = self.filterset_class
  1110. ordering = self.ordering
  1111. def get_context_data(inner_self, **kwargs):
  1112. context = super().get_context_data(**kwargs)
  1113. fields = self.get_fields()
  1114. context.update({
  1115. 'fields': [f for f in fields],
  1116. 'sheet_names': SHEET_NAMES,
  1117. # 'fields': [field for field in self.model._meta.get_fields()],
  1118. 'page_title': self.page_title,
  1119. 'list_url': self.list_url_name,
  1120. 'create_url': self.create_url_name,
  1121. 'update_url': self.update_url_name,
  1122. 'delete_url': self.delete_url_name,
  1123. 'bs': self.get_breadcrumbs('list'),
  1124. })
  1125. return context
  1126. return ListViewClass
  1127. class ProductDrawingCRUDView(ConfigurableCRUDView):
  1128. model = ProductDrawing
  1129. list_template_name = 'legacy/datacrud_list.html'
  1130. detail_template_name = 'legacy/datacrud_detail.html'
  1131. form_template_name = 'report/productdrawing_form.html'
  1132. confirm_delete_template_name = 'legacy/datacrud_confirm_delete.html'
  1133. filterset_class = ProductDrawingFilter
  1134. page_title = "Product Drawing"
  1135. # URL name mappings
  1136. list_url_name = 'report:product_drawings-list'
  1137. create_url_name = 'report:product_drawings-create'
  1138. update_url_name = 'report:product_drawings-update'
  1139. delete_url_name = 'report:product_drawings-delete'
  1140. config_fields = ["id", "code_no", "code_no_mks", "lot_no", "drawing", "description", "created_at"]
  1141. #config_field_orders = ["id", "customer_name", "template_names", "created_at", "created_by"]
  1142. # config_readonly_fields = ["lot_no"]
  1143. config_edit_fields = None
  1144. ordering = ["-created_at", "-id",]
  1145. form_class = ProductDrawingForm
  1146. class MksCodeMapCRUDView(ConfigurableCRUDView):
  1147. model = MksCodeMap
  1148. page_title = "MKS Code Mapping"
  1149. filterset_class = MksCodeMapFilter
  1150. list_template_name = "legacy/datacrud_list.html"
  1151. detail_template_name = "legacy/datacrud_detail.html"
  1152. form_template_name = 'legacy/datacrud_form.html'
  1153. confirm_delete_template_name = "legacy/datacrud_confirm_delete.html"
  1154. config_fields = ["id", "mgt_code", "mks_code", "created_at"]
  1155. config_edit_fields = ["mgt_code", "mks_code"]
  1156. list_url_name = "report:code_maps-list"
  1157. create_url_name = "report:code_maps-create"
  1158. update_url_name = "report:code_maps-update"
  1159. delete_url_name = "report:code_maps-delete"
  1160. ordering = ["-created_at", "-id"]