Nenhuma Descrição

views.py 43KB

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