Browse Source

QWIK

version2
venkata akhil 1 year ago
parent
commit
12614de7b4
  1. 0
      smart_service/phase_2/doctype/qwik_procedure/__init__.py
  2. 46
      smart_service/phase_2/doctype/qwik_procedure/qwik_procedure.json
  3. 8
      smart_service/phase_2/doctype/qwik_procedure/qwik_procedure.py
  4. 0
      smart_service/phase_2/doctype/qwik_service/__init__.py
  5. 410
      smart_service/phase_2/doctype/qwik_service/qwik_service.js
  6. 156
      smart_service/phase_2/doctype/qwik_service/qwik_service.json
  7. 96
      smart_service/phase_2/doctype/qwik_service/qwik_service.py
  8. 8
      smart_service/phase_2/doctype/qwik_service/test_qwik_service.py
  9. 0
      smart_service/phase_2/doctype/qwik_service_content/__init__.py
  10. 38
      smart_service/phase_2/doctype/qwik_service_content/qwik_service_content.json
  11. 8
      smart_service/phase_2/doctype/qwik_service_content/qwik_service_content.py
  12. 8
      smart_service/phase_2/doctype/special_tool_information/special_tool_information.json

0
smart_service/phase_2/doctype/qwik_procedure/__init__.py

46
smart_service/phase_2/doctype/qwik_procedure/qwik_procedure.json

@ -0,0 +1,46 @@
{
"actions": [],
"creation": "2023-09-04 11:28:17.372584",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"level",
"content",
"side"
],
"fields": [
{
"fieldname": "level",
"fieldtype": "Select",
"in_filter": 1,
"in_list_view": 1,
"label": "Level",
"options": "Floor Level\nHip Level\nHead Level"
},
{
"fieldname": "content",
"fieldtype": "Text Editor",
"in_list_view": 1,
"label": "Content"
},
{
"fieldname": "side",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Side",
"options": "LHS\nRHS"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-09-05 14:43:56.463049",
"modified_by": "Administrator",
"module": "Phase-2",
"name": "Qwik Procedure",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
}

8
smart_service/phase_2/doctype/qwik_procedure/qwik_procedure.py

@ -0,0 +1,8 @@
# Copyright (c) 2023, Hard n Soft Technologies Pvt Ltd and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class QwikProcedure(Document):
pass

0
smart_service/phase_2/doctype/qwik_service/__init__.py

410
smart_service/phase_2/doctype/qwik_service/qwik_service.js

@ -0,0 +1,410 @@
// Copyright (c) 2023, Hard n Soft Technologies Pvt Ltd and contributors
// For license information, please see license.txt
var vehicle_count = 0;
var original_display_order = 0;
frappe.ui.form.on('Qwik Service', {
refresh: function(frm) {
frm.set_query("variant", function() {
return {
"filters": {
"active_status": "Active",
}
};
});
if (!frm.is_new()) {
custom_tab_html(frm)
}
set_display_order(frm)
},
onload:function(frm){
if (!frm.is_new()) {
custom_tab_html(frm)
}
set_display_order(frm)
},
validate:function(frm){
cur_frm.refresh_fields("display_order")
if (frm.doc.display_order && frm.doc.name && !frm.is_new()) {
//***check if there is same display_order
frappe.db.get_list('Qwik Service', {
fields: ['display_order', 'name'],
filters: {
display_order: frm.doc.display_order,
name: ["!=", frm.doc.name],
vehicle: frm.doc.vehicle,
language: frm.doc.language,
variant: frm.doc.variant,
}
}).then(records => {
if (records.length) {
frappe.db.set_value('Qwik Service', records[0].name, {
display_order: original_display_order
}).then(r => {
let doc = r.message;
frappe.show_alert({
message: __('Swapped display order with: ' + records[0].name),
indicator: 'green'
}, 5);
});
} else {
if (frm.doc.display_order >= vehicle_count) {
let display_vehicle_count = vehicle_count - 1;
msgprint('There are only ' + display_vehicle_count + " " + frm.doc.doctype);
frappe.validated = false;
}
}
});
}
},
after_save: function (frm) {
cur_frm.refresh_fields("display_order")
frm.reload_doc()
},
vehicle: function(frm){
set_display_order(frm)
},
variant: function (frm) {
frappe.call({
method: "smart_service.phase_2.doctype.qwik_service.qwik_service.get_kilometer",
args: {
vehicle: frm.doc.vehicle,
service_kilometers: frm.doc.service_kilometers
},
callback: function (r) {
console.log(r.message)
frm.set_df_property('kilometers', 'options', r.message);
frm.refresh_field('kilometers')
}
})
},
});
function custom_tab_html(frm){
// tab start
var res = $(cur_frm.fields_dict.test_html.wrapper).empty();
var ret = '<div class="main"><div class="custom_tab style="border:10px solid var(--table-border-color);"><ul class="nav nav-tabs" role="tablist">'
ret += '<li class="nav-item">'
ret += '<a class="nav-link active" id="LHS" data-toggle="tab" role="tab" value="LHS">LHS</a>'
ret += '</li>'
ret += '<li class="nav-item">'
ret += '<a class="nav-link active" id="RHS" data-toggle="tab" role="tab" value="RHS">RHS</a>'
ret += '</li>'
ret += '</div>'
$(res).append(ret)
$(res).find('.main').append(`<div class="qwik_probl"></div>`)
res.append(`<style>.custom_tab{border:1px solid var(--table-border-color);}.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {background-color:lavender !important;}.nav-tabs {
border-bottom:none !important;}.qwik_probl{margin:10px;}.main{border: 2px solid var(--table-border-color);margin:15px 0px 15px 0px}</style>`)
if(frm.doc.tab_ref){
$('.nav').find('.nav-link').removeClass('active')
$('.nav').find('#'+frm.doc.tab_ref).addClass('active')
}
// tab end
var qwik_procedure = ""
if (frm.doc.qwik_procedure){
qwik_procedure = frm.doc.qwik_procedure.filter(o => o.side == "LHS")
}
if(frm.doc.tab_ref !='LHS'){
if(qwik_procedure.length>0){
qwik_procedure = frm.doc.qwik_procedure.filter(o => o.side == frm.doc.tab_ref)
// console.log("qwik",qwik_procedure)
}
}
var nav_spec = {}
nav_spec.side = "LHS"
if(frm.doc.tab_ref !='LHS'){
nav_spec.side = "RHS"
}
all_tabs()
$('.main').find('.nav-link').click(function (event){
if ($(this)[0].id == "LHS"){
frm.doc.tab_ref = "LHS"
cur_frm.refresh_fields("tab_ref")
frm.reload_doc()
nav_spec.side = "LHS"
qwik_procedure = frm.doc.qwik_procedure.filter(o => o.side == $(this)[0].id)
frappe.call({
method: "smart_service.phase_2.doctype.qwik_service.qwik_service.insert_tab_ref",
args: {
docname: frm.doc.name,
tab_ref: "LHS"
},
callback: function (r) {
frm.refresh_field('tab_ref')
frm.reload_doc()
}
})
}else{
nav_spec.side = "RHS"
frm.doc.tab_ref = $(this)[0].id
cur_frm.refresh_fields("tab_ref")
frm.reload_doc()
nav_spec.sides = $(this)[0].id
qwik_procedure = frm.doc.qwik_procedure.filter(o => o.sides == $(this)[0].id)
}
frappe.call({
method: "smart_service.phase_2.doctype.qwik_service.qwik_service.insert_tab_ref",
args: {
docname: frm.doc.name,
tab_ref: $(this)[0].id
},
callback: function (r) {
frm.refresh_field('tab_ref')
frm.reload_doc()
}
})
})
all_tabs()
function all_tabs(frm){
// html table
qwik_proce_dt += "<tbody>"
var qwik_proce_dt = ""
qwik_proce_dt += `<label class="control-label">Qwik Procedure</label><table class="table table-bordered table-editable spec-table" style='margin:0px !important'>
<thead>
<tr>
<th style="width: 7%;" class="qwik_procedure"><input type="checkbox" id="checkAll"' class="grid-row-check pull-left"><span class='qwik_check'>No</span></th>
<th>Level</th>
<th>Content</th>
<th><a><svg class="icon icon-sm" style="filter: opacity(0.5)">
<use class="" href="#icon-setting-gear"></use>
</svg></a></th>
</tr>
</thead>`
qwik_proce_dt += "<tbody>"
// to listss
var qwik_procedure_count = 0
if (qwik_procedure.length > 0) {
qwik_procedure.map(val => {
qwik_procedure_count += 1
qwik_proce_dt += '<tr id=' + val.name + ' draggable="true" ondragstart="dragstartFunction(event)" ondragover="dragovertFunction(event)" class="dragclass">'
qwik_proce_dt += '<td style="width: 7%;" id="qwik_count"><input id=' + val.name + ' type="checkbox" class="qwikcheck grid-row-check pull-left"><span class="qwik_check">' + qwik_procedure_count + '</span></td>'
qwik_proce_dt += '<td>' + val.level + '</td>'
qwik_proce_dt += '<td>' + val.content + '</td>'
qwik_proce_dt += '<td id=' + val.name + ' class="qwik_edit_row"><a><svg class="icon icon-xs" style=""><use class="" href="#icon-edit"></use></svg>Edit</a></td>'
qwik_proce_dt += '</tr>'
})
} else {
qwik_proce_dt += '<tr><td></td><td style="text-align:center">No Records Found</td></tr>'
}
// button
qwik_proce_dt += '</tbody>'
qwik_proce_dt += '</table>'
qwik_proce_dt += '<button class="btn btn-xs btn-secondary grid-add-row qwik_custom_delete">Delete</button>'
qwik_proce_dt += '<button class="btn btn-xs btn-secondary btn-primary grid-add-row qwik_custom_add">Add Row</button>'
qwik_proce_dt += '<button class="btn btn-xs btn-secondary grid-add-row qwik_custom_save">Save</button>'
// button end
qwik_proce_dt += '</div>'
// append
var qwik_dialog_value =""
$(res).find('.qwik_probl').empty()
$(res).find('.qwik_probl').append(qwik_proce_dt)
if(nav_spec.side=='LHS'){
$(res).find('#rhs1').hide()
$(res).find('#rhs2').hide()
$(res).find('#rhs3').hide()
}
$(res).append(`<style>th{color:var(--text-muted)}.qwik_check{padding:0px 5px 0px 5px !important}.qwik_custom_save{display:none;margin:10px 0px 0px 10px;background-color:red !important;color:#fff !important;}.qwik_custom_delete{margin:10px 10px 0px 0px;background-color:red !important;color:#fff !important;display:none}</style>`)
//append end
//add button
$(res).find('.qwik_probl').find('.qwik_custom_add').click(function (event) {
qwik_dialog_value = ""
qwik_dialog_value = nav_spec
qwik_dialog_view()
})
//end add button
// save function
$(res).find('.qwik_probl').find('.qwik_custom_save').click(function (event) {
var qwik_id_dis = []
$(document).ready(function () {
$('.qwik_probl').find('table > tbody > tr').each(function (index, tr) {
qwik_id_dis.push(this.id);
});
})
})
//end save function
//edit button
$(res).find('.qwik_probl').find('.qwik_edit_row').click(function (event) {
qwik_dialog_value = frm.doc.qwik_procedure.filter(o => o.name == $(this)[0].id)[0]
qwik_dialog_view()
})
//end edit button
//delete all button
$(res).find('.qwik_probl').find('.qwik_procedure').find('input[type=checkbox]').change(function () {
$(".qwikcheck").prop('checked', $(this).prop('checked'));
if (this.checked) {
$(res).find('.qwik_probl').find('.qwik_custom_delete').css("display", "inline-block")
} else {
$(res).find('.qwik_probl').find('.qwik_custom_delete').css("display", "None")
}
})
//end delete all button
//individual delete button
$(res).find('.qwik_probl').find('.qwik_procedure').change(function () {
if (this.checked) {
$(res).find('.qwik_probl').find('.qwik_custom_delete').css("display", "inline-block")
} else {
$(res).find('.qwik_probl').find('.qwik_custom_delete').css("display", "None")
}
})
//end individual delete button
//delete function
$(res).find('.qwik_probl').find('.qwik_custom_delete').click(function (event) {
var arr = []
$(res).find('.qwik_probl').find("input[type=checkbox]").each(function () {
var self = $(this);
if (self.is(':checked')) {
arr.push(self.attr("id"));
}
});
if (arr[0] == "checkAll") {
arr = arr.slice(1)
}
frappe.call({
method: "smart_service.phase_2.doctype.qwik_service.qwik_service.delete_qwik_data",
args: {
values: arr
},
callback: function (r) {
if (r.message.status == "success") {
cur_frm.reload_doc()
}
}
})
})
//delete function end
function qwik_dialog_view(){
let qwik_dia = new frappe.ui.Dialog({
title: 'Enter details',
fields:[
{
label: 'Name',
fieldname: 'name',
fieldtype: 'Data',
default: qwik_dialog_value.name,
hidden: 1
},
{
label: 'Level',
fieldname: 'level',
fieldtype: 'Select',
options: "Floor Level\nHip Level\nHead Level",
default: qwik_dialog_value.level,
},
{
label: 'Content',
fieldname: 'content',
fieldtype: 'Text Editor',
default: qwik_dialog_value.content
},
],
// size: 'small', // small, large, extra-large
primary_action_label: 'Submit',
primary_action(values) {
if (values && values.level && values.content) {
frappe.call({
method: "smart_service.phase_2.doctype.qwik_service.qwik_service.insert_qwik_data",
args: {
doc_name: cur_frm.doc.name,
values: values,
tab_ref:cur_frm.doc.tab_ref
},
callback: function (r) {
if (r.message.status == "success") {
cur_frm.reload_doc()
cur_frm.refresh()
}
}
})
}
qwik_dia.hide();
}
});
qwik_dia.show();
}
}
}
function set_display_order(frm){
if (frm.is_new()) {
frm.set_df_property('display_order', 'read_only', 1);
} else {
frm.set_df_property('display_order', 'read_only', 0);
}
frappe.db.count('Qwik Service', {
filters: {
"variant": frm.doc.variant,
"language": frm.doc.language,
"vehicle": frm.doc.vehicle,
"kilometers":cur_frm.doc.kilometers
}
}).then(count => {
// console.log("counts",count)
vehicle_count = count + 1;
if (frm.is_new()) {
frm.set_value("display_order", vehicle_count);
} else {
original_display_order = frm.doc.display_order;
}
});
}
frappe.ui.form.on('Qwik Service Content',{
content_type: function (frm, cdt, cdn) {
var select_value = locals[cdt][cdn]
var x = select_value.idx - 1;
let my_row = frm.fields_dict.content.grid.grid_rows[x];
if (select_value.content_type == 'Heading' || select_value.content_type == 'Content'){
cur_frm.get_field("pdf").grid.grid_rows[x].columns.pdf.df.read_only = 0;
cur_frm.get_field("content").grid.grid_rows[x].columns.content.df.read_only = 1;
cur_frm.refresh_fields("pdf")
}
else {
cur_frm.get_field("content").grid.grid_rows[x].columns.pdf.df.read_only = 0;
cur_frm.get_field("pdf").grid.grid_rows[x].columns.content.df.read_only = 1;
cur_frm.refresh_fields("pdf")
}
cur_frm.refresh_field("pdf");
cur_frm.refresh_field();
},
validate:function(frm){
let task_index = row.docfields.findIndex(x => x.fieldname === "pdf");
if (row.doc.content_type == 'Heading' || row.doc.content_type == 'Content') {
row.docfields[task_index].read_only = 0;
// cur_frm.get_field("tool_usage_content").grid.grid_rows[x].columns.content.df.set=[];
} else {
row.docfields[task_index].read_only = 1;
}
row.toggle_editable_row(true);
refresh_field("pdf");
cur_frm.refresh_field("pdf");
refresh_field();
}
})

156
smart_service/phase_2/doctype/qwik_service/qwik_service.json

@ -0,0 +1,156 @@
{
"_liked_by": "[\"Administrator\"]",
"actions": [],
"autoname": "format:{variant}-{kilometers}-{language}",
"creation": "2023-09-04 10:59:50.476936",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"variant",
"kilometers",
"language",
"service_time",
"column_break_vmliz",
"vehicle",
"display_order",
"active_status",
"pdf",
"keywords",
"section_break_mosyy",
"content",
"qwik_procedure",
"test_html",
"my_id",
"tab_ref"
],
"fields": [
{
"fieldname": "variant",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Variant",
"options": "Variant Mapping",
"reqd": 1,
"set_only_once": 1
},
{
"fieldname": "kilometers",
"fieldtype": "Select",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Kilometers"
},
{
"fieldname": "language",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Language",
"options": "Custom Languages",
"reqd": 1,
"set_only_once": 1
},
{
"fieldname": "column_break_vmliz",
"fieldtype": "Column Break"
},
{
"fetch_from": "variant.vehicle",
"fieldname": "vehicle",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Vehicle",
"read_only": 1,
"reqd": 1
},
{
"fieldname": "display_order",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Display Order"
},
{
"fieldname": "active_status",
"fieldtype": "Select",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Active Status",
"options": "Active\nInactive"
},
{
"fieldname": "section_break_mosyy",
"fieldtype": "Section Break"
},
{
"fieldname": "my_id",
"fieldtype": "Int",
"hidden": 1,
"label": "My Id"
},
{
"fieldname": "qwik_procedure",
"fieldtype": "Table",
"label": "Qwik Procedure",
"options": "Qwik Procedure"
},
{
"fieldname": "test_html",
"fieldtype": "HTML",
"label": "Test Html"
},
{
"fieldname": "content",
"fieldtype": "Table",
"label": "Content",
"options": "Qwik Service Content"
},
{
"fieldname": "service_time",
"fieldtype": "Data",
"label": "Service Time",
"reqd": 1
},
{
"fieldname": "pdf",
"fieldtype": "Attach",
"label": "PDF"
},
{
"fieldname": "tab_ref",
"fieldtype": "Data",
"hidden": 1,
"label": "Tab ref"
},
{
"fieldname": "keywords",
"fieldtype": "Small Text",
"label": "Keywords"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-09-15 13:03:18.140036",
"modified_by": "Administrator",
"module": "Phase-2",
"name": "Qwik Service",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC"
}

96
smart_service/phase_2/doctype/qwik_service/qwik_service.py

@ -0,0 +1,96 @@
# Copyright (c) 2023, Hard n Soft Technologies Pvt Ltd and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
import json
class QwikService(Document):
def validate(self):
try:
if self.is_new():
if self.variant and self.language:
check_exe=frappe.db.sql('''select * from `tabQwik Service` where variant='%s' and language ='en' and name !='%s'; '''%(self.variant,self.name),as_dict=1)
if check_exe:
if self.language != "en":
for d in check_exe:
self.display_order = d['display_order']
self.active_status = d['active_status']
if not check_exe:
if self.language != "en":
frappe.throw("First language will be english only")
except Exception as e:
raise e
def on_update(self):
if self.language == "en":
try:
check_exe = frappe.db.get_list("Qwik Service",
filters={"variant": self.variant, "language": ["!=", "en"],
"name": ["!=", self.name]},
fields={"name", "language", "display_order", "active_status"})
if check_exe:
for i in check_exe:
res = frappe.get_doc(
"Qwik Service", i['name'])
res.display_order = self.display_order
res.active_status = self.active_status
res.save()
except Exception as e:
raise e
@frappe.whitelist()
def insert_tab_ref(docname,tab_ref):
try:
if docname and tab_ref:
frappe.db.sql("""UPDATE `tabQwik Service` set tab_ref='%s' WHERE name ='%s'""" %(tab_ref,docname))
frappe.db.commit()
except Exception as e:
frappe.log_error("insert_tab",frappe.get_traceback())
@frappe.whitelist()
def insert_qwik_data(doc_name, values, tab_ref):
try:
val = json.loads(values)
get_count = frappe.db.sql("""select name from `tabQWIK Procedure` where parent='%s'""" %(doc_name),as_dict=1)
get_count = len(get_count)+1
result = frappe.get_doc("Qwik Service", doc_name)
result.tab_ref = tab_ref
result.save()
frappe.db.commit()
if val.get('name') != None:
doc = frappe.get_doc("Qwik Procedure", val['name'])
doc.level = val.get('level')
doc.content = val.get('content')
# doc.active_status = val.get('active_status')
doc.save()
frappe.db.commit()
else:
res = frappe.get_doc("Qwik Service", doc_name)
res.append("qwik_procedure", val)
res.save()
return {"status": "success"}
except Exception as e:
frappe.log_error("insert_qwik_data", str(e))
return {"status": "failure"}
@frappe.whitelist()
def delete_qwik_data(values):
try:
val = json.loads(values)
if len(val) > 0:
for d in val:
frappe.delete_doc("QWIK Procedure", d)
frappe.db.commit()
return {"status": "success"}
except Exception as e:
frappe.log_error("delete_qwik_data", str(e))
@frappe.whitelist()
def get_kilometer(vehicle):
kilometer_list = frappe.db.sql("""select service_kilometers from `tabVehicle_SK` where parent='%s'; """%(vehicle),as_list=1)
return kilometer_list

8
smart_service/phase_2/doctype/qwik_service/test_qwik_service.py

@ -0,0 +1,8 @@
# Copyright (c) 2023, Hard n Soft Technologies Pvt Ltd and Contributors
# See license.txt
# import frappe
import unittest
class TestQwikService(unittest.TestCase):
pass

0
smart_service/phase_2/doctype/qwik_service_content/__init__.py

38
smart_service/phase_2/doctype/qwik_service_content/qwik_service_content.json

@ -0,0 +1,38 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2023-09-04 13:26:03.319418",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"content_type",
"content"
],
"fields": [
{
"fieldname": "content",
"fieldtype": "Text Editor",
"in_list_view": 1,
"label": "Content"
},
{
"fieldname": "content_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Content Type",
"options": "Pre-Work\nConsumables\nTools"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-09-04 17:19:19.054634",
"modified_by": "Administrator",
"module": "Phase-2",
"name": "Qwik Service Content",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
}

8
smart_service/phase_2/doctype/qwik_service_content/qwik_service_content.py

@ -0,0 +1,8 @@
# Copyright (c) 2023, Hard n Soft Technologies Pvt Ltd and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class QwikServiceContent(Document):
pass

8
smart_service/phase_2/doctype/special_tool_information/special_tool_information.json

@ -16,6 +16,7 @@
"sub_category",
"column_break_whk88",
"display_order",
"keywords",
"my_id",
"section_break_e91wx",
"tool_usage_content"
@ -96,11 +97,16 @@
"fieldtype": "Select",
"label": "Active Status",
"options": "Active\nInactive"
},
{
"fieldname": "keywords",
"fieldtype": "Small Text",
"label": "Keywords"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-09-01 17:06:34.665767",
"modified": "2023-09-15 10:43:27.405396",
"modified_by": "Administrator",
"module": "Phase-2",
"name": "Special Tool Information",

Loading…
Cancel
Save