Нема описа

views.py 58KB

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