Ei kuvausta

views.py 44KB

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