/*
 * @Overview 품목등록 페이지
 * @History 2024-03-20 / 이원기 / 최초작성
            2024-03-26 / 박민희
            2024-04-03 / 이원기
 */

class Tb_item_class {
  constructor(container) {
    
    let _this = this;
    _this.tbList ="";
    _this.itemData = "";
    _this.ITEM_CD = "";
    this.ajaxUrl = "./item.ajax.php";
    this.container = document.querySelector(container);
    this.table = this.container.querySelector(".hy-table");
    this.addBtn = this.container.querySelector(".add-btn");
    this.removeBtn = this.container.querySelector(".remove-btn");
  }

  // // tableBuild 되었을때 getManList
  getMainList() {

    let _this = this;
    let talert = window.setTimeout(() => { _this.tbList.alert("Loading ...") }, 1000);
    let ITEM_GRP  = document.getElementById("ITEM_GRP").value;      //품목그룹
    let ITEM_CODE  = document.getElementById("ITEM_CD").value;      //품목코드

    ajax_json({
      url: this.ajaxUrl,
      data: { mode: "getItemList", ITEM_GRP:ITEM_GRP, ITEM_CD: ITEM_CODE},
       success: (data) => {
        (data);
        if(data.code) {
          _this.tbList.setData(data.data);
        }else{
          kuls_alert(data.mesg);
        }
      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);
        _this.tbList.clearAlert();
      },
    });

    return true;
  }

  setFilter() {}

  /*
   * @Overview 테이블 행 추가 함수
   * @Parameter 없음
   * @function 기본키, _STATUS_:I 값을 넣은 행 추가
   */
  addRow() {
    this.tbList.deselectRow();
    Tb_routing.itemData = null;
    Tb_routing.getMainList();
    Tb_pic.getMainList();
    Tb_process_check.getMainList();
    this.tbList.addRow({ _STATUS_: "I" }, true);
  }

  /*
   * @Overview 테이블 행 삭제 함수
   * @Parameter 없음
   * @function 선택된 모든 행 STATUS D
   */
  removeRow() {
    const selectedRows = this.tbList.getRows().filter(row=>{
      return row.getData().check ==="Y"
    });

    if(selectedRows.length > 0 ){

      // 선택된 각 행 삭제
      selectedRows.forEach((row) => {
        // STAUS D로 바꾸기
        row.getData()._STATUS_ = row.getData()._STATUS_=="I"?null:"D";
  
        const rowElement = row.getElement();
        rowElement.classList.add("remove-row");
    
        });
    }else{
      kuls_alert("삭제할 행을 선택해주세요.")
    }
  }

  /*
   * @Overview 삭제 취소 함수
   * @Parameter 삭제 행
   * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
   */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){
      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
    }
  }

  /*
  * @Overview ROW 클릭 이벤트
  * @Parameter 클릭한 ROW의 데이터
  * @function  해당 ROW 클릭 시 발생 시킬 메서드
  */
  rowClick(e, tgt) {
    let _this = this;
    let clickRow = tgt._row;         // 클릭한 데이터의 _row 값(tabulator)
    let clickData = clickRow.data;   // _row의 Data 변수
    Tb_routing.itemData = clickData;
    Tb_pic.itemData     = clickData;

    if (tgt.isSelected()) {
      tgt.deselect();
      this.clearRemove(tgt);
    } else {
      Tb_routing.getMainList(Tb_routing.itemData);
      Tb_pic.getMainList(clickData);
      Tb_process_check.getMainList(Tb_routing.itemData);
      this.tbList.deselectRow();
      tgt.select();

    }

  }


  cellClick(e, tgt) {
    var editor = tgt.getColumn().getDefinition().editor;
    // // 체크박스 클릭
     switch (tgt.getField()) {
      case "USE_FLG":
        tgt.setValue(tgt.getValue() == "Y" ? "N" : "Y");
       break;
      case "check":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        this.clearRemove(tgt.getRow())
        break;
      default:
        if (!editor) {
          this.rowClick && this.rowClick(e, tgt.getRow());
        }
        break;
     }
  }

  // 셀 수정
  cellEdited(cell) {
    cell.getData()._STATUS_ = cell.getData()._STATUS_ || "U";
  };

 /*
  * @Overview 추가, 수정 및 삭제 데이터 저장
  * @Parameter 없음
  * @Function _STATUS_ : U, I, D Row 인 것 php 처리.
  */
 putData() {
  let _this = this;

  // 저장 시 상태 변화 없는 row 요청 X
  if(this.tbList.getData().filter(row=> row._STATUS_).length == 0){
    return false;
  }
  const blankObj = this.tbList.getRows().filter(row => {

    return Object.keys(row._row.data).filter(key => key !== '_STATUS_' && key !== 'USE_FLG').every(key => {

      const value = row._row.data[key];
      return (value === undefined || value === '');
    });
  });

  let postdata = {
    'mode': 'putItem',
    'reqdata': JSON.stringify(this.tbList.getData().filter(row=> row._STATUS_)),
  };
  if(blankObj.length !== 0){
    kuls_confirm("비어있는 행을 무시하고 진행하시겠습니까?","",()=>{
      ajax_json({
        url: _this.ajaxUrl,
        data: postdata,
        success: function (data) {
          if (data.code) {
            kuls_success("저장되었습니다.");
            _this.getMainList();
          }else{

            kuls_alert(data.mesg);
          }
        },
        error: function (request, status, error) {
          (request)
          kuls_alert(error.message);
        },
        complete: function () {
        }
      });

    },()=>{
      blankObj.forEach(row=>{
        row.getElement().classList.add("blank-row")
      })
      (blankObj)
    })
  }else{
    ajax_json({
      url: _this.ajaxUrl,
      data: postdata,
      success: function (data) {
        if (data.code) {
          kuls_success("저장되었습니다.");
          _this.getMainList();
        }else{
          kuls_alert(data.mesg);
        }
      },
      error: function (request, status, error) {
        (request)
        kuls_alert(error.message);
      },
      complete: function () {
        _this.tbList.getRows().forEach(row=>{
          row.getCell("ITEM_CD").getElement().addEventListener("click",(e)=>{
            _this.rowClick(e,row);
          })
        });
      }
    }
  );

  
  }
}

//값이 존재하는 경우 Circle 출력
  formatterSelCircleIcon(tgt, params) {
    let cell = tgt._cell;
    let em = document.createElement("i");

    if (cell.getValue()) {
      em.className = "bi bi-circle-fill fa-2xs";
    } else {
      em.className = "";
    }

    return em;
  }

    /*
   * @Overview 팝업 오픈
   */
    modalItem() {
      let _this = this;  
      vnLoad( '', './item_pop.php', '', (loadHtml)=>{
        this.putItem = kuls_modal(loadHtml);
        initPopup(),
        //엑셀연결
        document.getElementById('excel_down').addEventListener('click', function (e) {
          getExcel2();
        });
      });

    };



  /*
   * @Overview 최초 실행 함수
   * @Parameter 없음
   */
  init() {
    let _this = this;
    // field 정의
    const fields = [
      { title: "NO", formatter: "rownum", width: '5%'},
      {
        field: "ITEM_CD",
        title: "품목",
        width: '15%',
        editor: tb_custom_editor.pkCode,
        formatter: tb_custom_formatter.pkCode,
        formatterParams: { tableClass: this },
      }, //품목 코드
      {
        field: "ITEM_NM",
        title: "품명",
        width: "40%",
        editor: "input",
        hozAlign: "left",
        cssClass: "editable-cell",
      }, //품목 코드
      {
        field: "ITEM_GRP",
        title: "품목 그룹",
        width: '15%',
        editor: "list",
        editorParams: { values: varsITEM_GRP },
        formatter: tb_common_funtions.formatterSelect,
        formatterParams: { values: varsITEM_GRP },
        cssClass: "user-list",
      }, //품목 그룹 -select
      { field: "MAKE_TM", title: "등록일", width: '10%', formatter:"datetime", formatterParams:{
          inputFormat:"yyyy-MM-dd",
          outputFormat:"yy.MM.dd",
        }
      },
      {
        field: "DRAW_NO",
        title: "도면여부",
        width: '8%',
        editor: tb_custom_editor.clickShow,
        formatter: this.formatterSelCircleIcon,
      }, //도면 번호 - popup
      { field: "DRAW_VER", title: "버전", width: '5%' },
      {
        field: "check",
        title: "삭제",
        width: '5%',
        headerSort: false,
        formatter: tb_common_funtions.formatterCheckboxIcon,
        formatterParams: { checkval: "Y" },
      },
    ];
    const commonFieldData = {
      vertAlign: "middle",
      hozAlign: "center",
      resizable: "header", //Resize 는 헤더에서만 가능
      headerHozAlign: "center", //헤더 정렬
      headerSortTristate: true, //데이터 정렬 => 정/역/초기화
    };

    _this.tbList = new Tabulator(this.table, {
      layout: "fitColumns",
      // selectableRows: 1,
      data: [], //기본 데이터
      columns: fields, //컬럼 설정
      columnDefaults: commonFieldData,
      headerSortElement: "<i class='bi'></i>", //정렬 아이콘
    });

    // 데이터 불러오기
    _this.tbList.on("tableBuilt", (e, tgt) => {
      _this.getMainList(e, tgt);
    });
    // cell 클릭 시에
    _this.tbList.on("cellClick", (e, tgt) => {
      _this.cellClick && Tb_item.cellClick(e, tgt);
    });
    // cell 수정 시에
    _this.tbList.on("cellEdited", (cell) => {
      _this.cellEdited && Tb_item.cellEdited(cell);
    });

    // 복사
    ["click", "keypress"].forEach((evt) => {
      const copyorder = document.querySelector("#copy_item_btn");
      copyorder.addEventListener(evt, () => {

        // 품목 선택행 가져오기
        const selectedRows = this.tbList.getSelectedRows();

        if (selectedRows.length > 0) { //선택행이 있을때
          const ITEM_CD = selectedRows[0].getData().ITEM_CD;

          // 모달 열기
          vnLoad("", "./item_copy_pop.php", "", (loadHtml) => {
            const modal = kuls_modal(loadHtml);
            const data = {ITEM_CD: ITEM_CD}

            const copyItemVue = new CopyItemVueClass(data, modal);
            copyItemVue.init();
          });
          // 모달 종료

        } else {
          kuls_alert("복사할 행을 선택해주세요.");
        }
      });
    });

    // 추가
    ["click", "keypress"].forEach((evt) => {
      _this.addBtn.addEventListener(evt, () => {
        _this.addRow();
      });
    });
    // 삭제
    ["click", "keypress"].forEach((evt) => {
      _this.removeBtn.addEventListener(evt, () => {
        // 삭제 함수
        _this.removeRow && this.removeRow();
      });
    });
    // 조회
    ["click", "keypress"].forEach((evt) => {
      const filterBtn = document.querySelector("#filter_btn");
      filterBtn.addEventListener(evt, () => {
        Tb_routing.tbList.setData([]);
        Tb_pic.tbList.setData([]);
        Tb_process_check.tbList.setData([]);
        _this.getMainList && _this.getMainList();
      });
    });

    //팝업띄우기
    ["click", "keypress"].forEach((evt) =>
      document
        .querySelector("#excel_pop")
        .addEventListener(evt, () => this.modalItem())
    );

    // 저장
    ["click", "keypress"].forEach((evt) => {
      const putBtn = document.querySelector("#put_item");
      putBtn.addEventListener(evt, () => {
        _this.putData();
        Tb_routing.putRouting();
        Tb_process_check.putInspSpec();
        Tb_pic.putFile();
      });
    });
  }
}

// 복사 팝업 뷰 클래스
class CopyItemVueClass {
  constructor(data, modal){
    this.innerData = data;
    this.modal = modal;
  }
  init(){
    const ITEM_CD = this.innerData.ITEM_CD;
    const modal = this.modal;
    // 뷰 페이지 구성
    const vueForm = createApp({
      data() {
        return {
          formData: {
            ITEM_CD: `${ITEM_CD}_copy`,
            BASE_CD: ITEM_CD, //가져오기
            ITEM_NM: "",
          },
          modal: modal
        };
      },
      mounted() {

      },
      watch() {

      },
      methods: {
        submit() {
          let postdata = {
            ...this.formData,
            mode: "copyItem",
          };
          ajax_json({
            url: "./item.ajax.php",
            data: postdata,
            success: function (data) {
              if (data.code) {
                kuls_success("저장되었습니다.");
                this.modal.delete();
                Tb_item.getMainList();
              } else {
                kuls_alert(data.mesg);
              }
            },
            error: function (request, status, error) {
              kuls_alert(error.message);
            },
            complete: function () {},
          });

        },
      },
    }).mount("#popup_item_copy");
    // 뷰 종료
  }
}

// 라우팅 테이블 클래스
class Tb_routing_class {
  constructor(container) {
    let _this = this;
    this.ajaxUrl = "./item.ajax.php";
    _this.tbList = "";
    _this.itemData = "";
    _this.fileData = "";
    this.container = document.querySelector(container);
    this.table = this.container.querySelector(".hy-table");
    this.upBtn = this.container.querySelector(".up-btn") || "";
    this.downBtn = this.container.querySelector(".down-btn") || "";
    this.addBtn = this.container.querySelector(".add-btn");
    this.removeBtn = this.container.querySelector(".remove-btn");

    this.lastNum = 0;
  }

  /*
   * @Overview 데이터 가져오기
   * @Parameter 없음
   * @function 데이터 불러오기
   * @function this.lastNum에 마지막 공순 넣기
   */
  getMainList(clickData,bool) {
    let _this = this;
    let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);
    ajax_json({
      url: this.ajaxUrl,
      data: { mode: "getRoutingList", ITEM_CD :_this.itemData?.ITEM_CD },
      success: (data) => {
        _this.tbList.setData(data.data);

        if(bool){
          this.editingRout(data.data);
        }

        if(data.data.length == 0){
          this.lastNum = 0

        }else{
          this.lastNum = Math.max(...data.data.map(v=>v.OP_SEQ));

        }
      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);
        this.tbList.clearAlert();
      },
    });
  }

  getSortList(clickData) {
    let _this = this;
    let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);

    ajax_json({
      url: this.ajaxUrl,
      data: { mode : "getRoutingList",ITEM_CD :_this.itemData?.ITEM_CD},
      success: (data) => {

        this.tbList.setData(data.data);

        if(data.data.length == 0){
          this.lastNum = 0

        }else{
          this.lastNum = Math.max(...data.data.map(v=>v.OP_SEQ));

        }
      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);
        this.tbList.clearAlert();
      },
    });
  }
  editSort(data){
    let _this = this;
    let temArr = data;

    if(temArr.length === 1){
      temArr[0].OP_SEQ  = 10;
      temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
      temArr[0].LAST_OP_FLG = 'Y'
      temArr[0].PRV_OP_CD   = ''
      temArr[0].NXT_OP_CD   = ''

      if (temArr.some(x => x._STATUS_ === "I" || temArr.some(x => x._STATUS_ === "D"))) {

      } else if (temArr.some(x => x._STATUS_ === "U") || temArr.some(x => x)) {
        temArr[0]._STATUS_ = "U";
      }
    }else {
      for(let i = 0; i < temArr.length; i++) {
        temArr[i].OP_SEQ = (parseInt([i]) + 1) * 10 // 공정 순서의 숫자 채번
        if (parseInt([i]) === 0) {                    // 0인 경우 => 첫번째 공정 순서의 경우
          temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
          temArr[0].LAST_OP_FLG = 'N'                     //  마지막 공정에 대하여 N
          temArr[i].PRV_OP_CD = ''                      //  이전의 공정에 대하여 빈값 부여
        } else {                                            // 0이 아닌경우 => 두번째 공정 순서부터 값 부여
          temArr[i].FRST_OP_FLG = 'N'
          temArr[i].LAST_OP_FLG = 'N'
          temArr[i].PRV_OP_CD = temArr[i - 1].OP_CD;        //  이전의 공정에 대하여 VALUE 바인딩
          temArr[i - 1].NXT_OP_CD = temArr[i].OP_CD;      //  다음의 공정에 대하여 VALUE 바인딩
        }

        if (parseInt([i]) === temArr.length - 1) {
          temArr[temArr.length - 1].FRST_OP_FLG = 'N'
          temArr[temArr.length - 1].LAST_OP_FLG = 'Y'
          temArr[temArr.length-1].NXT_OP_CD   = ''
        }
        // some : I나 D 상태가 하나라도 있으면 TRUE 반환
        if (temArr.some(x => x._STATUS_ === "I" || temArr.some(x => x._STATUS_ === "D"))) {

        } else if (temArr.some(x => x._STATUS_ === "U") || temArr.some(x => x)) {
          temArr[i]._STATUS_ = "U";
        }
      }
    }
    console.log(temArr);
    return temArr
  }
  editingRout(edit) {
    let _this = this;
    console.log(edit);
    if(!_this.editSort(edit).filter( row=> row._STATUS_ )){
       return false;
    }
    let postdata = {
      mode: 'putRouting',
      reqdata: JSON.stringify(_this.editSort(edit).filter( row=> row._STATUS_ )),
    };
    console.log(postdata)
    ajax_json({
      url: this.ajaxUrl,
      data: postdata,
      success: function (data) {
        if (data.code) {
          _this.getSortList(Tb_item.tbList.getSelectedData()[0]);
        }else{
          kuls_alert(data.msg);
        }
      },
      error: function (request, status, error) {
        kuls_alert(error.message);
      },
      complete: function () {
      }
    })

  }


  /*
   * @Overview 라우팅 SORTING
   * @Parameter 없음
   * @function 테이블 데이터 순차적으로 SORTING 하여 데이터 가공
   *
   */

  sortingRouting(){
    let temArr       = this.tbList.getData();           // 테이블 전체 데이터


    if(this.tbList.getData().length === 1){
      temArr[0].OP_SEQ  = 10;
      temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
      temArr[0].LAST_OP_FLG = 'Y'
      temArr[0].PRV_OP_CD   = ''
      temArr[0].NXT_OP_CD   = ''

      if(temArr.some(x=>x._STATUS_ === "I" ||temArr.some(x=>x._STATUS_ === "D" ))){
      }else if(temArr.some(x=>x._STATUS_ === "U")){
        temArr[0]._STATUS_ = "U";
      }
    }else{
      for(let i = 0; i < temArr.length; i++){
        temArr[i].OP_SEQ = (parseInt([i]) + 1) * 10 // 공정 순서의 숫자 채번
        if(parseInt([i]) === 0){                    // 0인 경우 => 첫번째 공정 순서의 경우
          temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
          temArr[0].LAST_OP_FLG = 'N'                     //  마지막 공정에 대하여 N
          temArr[i].PRV_OP_CD   = ''                      //  이전의 공정에 대하여 빈값 부여
        }else{                                            // 0이 아닌경우 => 두번째 공정 순서부터 값 부여
          temArr[i].FRST_OP_FLG = 'N'
          temArr[i].LAST_OP_FLG = 'N'
          temArr[i].PRV_OP_CD = temArr[i-1].OP_CD;        //  이전의 공정에 대하여 VALUE 바인딩
          temArr[i - 1].NXT_OP_CD = temArr[i].OP_CD;      //  다음의 공정에 대하여 VALUE 바인딩
        }

        if(parseInt([i]) === temArr.length-1){
          temArr[temArr.length-1].FRST_OP_FLG = 'N'
          temArr[temArr.length-1].LAST_OP_FLG = 'Y'
          temArr[temArr.length-1].NXT_OP_CD   = ''
        }
        // some : I나 D 상태가 하나라도 있으면 TRUE 반환
        if(temArr.some(x=>x._STATUS_ === "I" ||temArr.some(x=>x._STATUS_ === "D" ))){
        }else if(temArr.some(x=>x._STATUS_ === "U")){
          temArr[i]._STATUS_ = "U";
        }

      }
    }
    return temArr
  }

  /* Overview 공정코드 INSERT, UPDATE, DELETE
   * Parameter

   */



  putRouting(){
    let _this = this;
    let temp =""
    if(this.tbList.getData().filter(row=> row._STATUS_).length === 0 ){
      return false;
    }

      let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);
      ajax_json({
        url: this.ajaxUrl,
        // soringRouting 함수는 모든 공정에 대하여 순서를 부여하고 속성을 부여합니다
        data: { mode: "putRouting", reqdata: JSON.stringify(this.sortingRouting().filter( row=> row._STATUS_ )),},
        success: (data) => {
          if(data.code){
            kuls_success("적용되었습니다");
          }

          if(data.delete){
            temp = true;
          }
          _this.getMainList("",true);
          Tb_process_check.getMainList(Tb_item.tbList.getSelectedData()[0]);
        },
        error: (req, status, err) => {
          kuls_alert(err.message);
        },
        complete: () => {
          window.clearTimeout(talert);
          this.tbList.clearAlert();
        },
      });
  }



  afterDeleting = () =>{
    let _this = this;

    ajax_json({
      url: this.ajaxUrl,
      // soringRouting 함수는 모든 공정에 대하여 순서를 부여하고 속성을 부여합니다
      data: { mode: "putRouting", reqdata: JSON.stringify(_this.afterDeletingSort().filter( row=> row._STATUS_ )),},
      success: (data) => {
      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
    });
  }




  afterDeletingSort=()=>{
    let _this = this;
    let temArr       = this.tbList.getData();           // 테이블 전체 데이터
    if(this.tbList.getData().length === 1){
      temArr[0].OP_SEQ  = 10;
      temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
      temArr[0].LAST_OP_FLG = 'Y'
      temArr[0].PRV_OP_CD   = ''
      temArr[0].NXT_OP_CD   = ''
    }else {
      for (let i = 0; i < temArr.length; i++) {
        temArr[i].OP_SEQ = (parseInt([i]) + 1) * 10 // 공정 순서의 숫자 채번
        if (parseInt([i]) === 0) {                    // 0인 경우 => 첫번째 공정 순서의 경우
          temArr[0].FRST_OP_FLG = 'Y'                     //  첫번째 공정에 대하여 Y
          temArr[0].LAST_OP_FLG = 'N'                     //  마지막 공정에 대하여 N
          temArr[i].PRV_OP_CD = ''                      //  이전의 공정에 대하여 빈값 부여
        } else {                                            // 0이 아닌경우 => 두번째 공정 순서부터 값 부여
          temArr[i].FRST_OP_FLG = 'N'
          temArr[i].LAST_OP_FLG = 'N'
          temArr[i].PRV_OP_CD = temArr[i - 1].OP_CD;        //  이전의 공정에 대하여 VALUE 바인딩
          temArr[i - 1].NXT_OP_CD = temArr[i].OP_CD;      //  다음의 공정에 대하여 VALUE 바인딩
        }

        if (parseInt([i]) === temArr.length - 1) {
          temArr[temArr.length - 1].FRST_OP_FLG = 'N'
          temArr[temArr.length - 1].LAST_OP_FLG = 'Y'
        }
        // some : I나 D 상태가 하나라도 있으면 TRUE 반환
        if (temArr.some(x => x._STATUS_ === "I")) {
        } else if (temArr.some(x => x._STATUS_ === "D") || temArr.some(x => x)) {
          temArr[i]._STATUS_ = "U";
        }
      }
    }
    return temArr
  }

  setFilter() {}

  /*
   * @Overview 테이블 행 추가 함수
   * @Parameter 없음
   * @function 기본키, _STATUS_:I 값을 넣은 행 추가
   */
  addRow(item_cd) {
    let _this = this;

    if(item_cd === undefined){
      kuls_alert("품목코드를 선택해주세요")
      return false;
    }
    this.lastNum += 10;
    this.tbList.addRow({ _STATUS_: "I", OP_SEQ: this.lastNum, ITEM_CD: item_cd });
  }

  /*
   * @Overview 테이블 행 삭제 함수
   * @Parameter 없음
   * @function 선택된 모든 행 STATUS D
   */
  removeRow() {
    const selectedRows = this.tbList.getRows().filter(row=>{
      return row.getData().check ==="Y"
    });

    if(selectedRows.length > 0 ){

      // kuls_confirm("삭제","하시겠습니까?", ()=>{
        // 선택된 각 행 삭제
        selectedRows.forEach((row) => {
          // STAUS D로 바꾸기
          row.getData()._STATUS_ = row.getData()._STATUS_=="I"?null:"D";
    
          const rowElement = row.getElement();
          rowElement.classList.add("remove-row");
    
        });
      // })
    }else{
      kuls_alert("삭제할 행을 선택해주세요.")
    }
  }

  /*
   * @Overview 삭제 취소 함수
   * @Parameter 삭제 행
   * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
   */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){

      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
      // const selectedRows = this.tbList.getSelectedRows(); // 선택된 모든 행 가져오기
    }
  }

  /*
   * @Overview 테이블 행 공순 변경 함수(위로)
   * @Parameter 없음
   * @function 선택된 모든 행 위로
   */
  upRow() {
  }
  /*
   * @Overview 테이블 행 공순 변경 함수(아래로)
   * @Parameter 없음
   * @function 선택된 모든 행 아래로
   */
  downRow() {

  }

  // 클릭 이벤트
  rowClick(e, tgt) {
    // 삭제가 가능하도록 ROW SELECT
    // staus D로 바꾸기?
    if (tgt.isSelected()) {
      
      this.tbList.deselectRow(tgt._row);
  
    } else {
      this.tbList.deselectRow();
      this.tbList.selectRow(tgt);
    }

  }
  cellClick(e, tgt) {
    const editor = tgt.getColumn().getDefinition().editor;
    switch (tgt.getField()) {
      case "OP_CD":
        popOper({
          OP_CD : "OP_CD",
          OP_NM: "OP_NM"
        },tgt.getRow());
        break;
      case "check":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        this.clearRemove(tgt.getRow())
      break;
      default:
        if (!editor) {
          this.rowClick && this.rowClick(e, tgt.getRow());
        }
        break;
    }
  }
  /*
   * @Overview 파일 다운로드 함수
   * @Parameter 없음
   */

  getFileUrl =function(DRAW_NO, SID, FILE_ID, FILE_NM,kind,down){
    let urlStr = "";
    if(kind == "draw"){
      urlStr = '/include/getFile.php'+"?gubun=draw&nid="
          + DRAW_NO +
          "&sid="+ SID +
          "&file_id="+ FILE_ID+
          "&name="+FILE_NM
      if(down === true){
        location.href = urlStr;
      }

    }else{
      urlStr = '/include/getFile.php'+"?gubun=rout&ITEM_CD="
          + DRAW_NO +
          "&ROUT_SQNO="+ SID +
          "&name="+FILE_ID
      if(down === true){
        location.href = urlStr;
      }

    }
    return urlStr;
  }
  /*
   * @Overview 아이콘 함수
   * @Parameter 없음
   */
  downloadIcon = function(cell, formatterParams, onRendered){ //plain text value
    if(!cell.getRow().getData().FILE_NM){
      // kuls_alert("");
      return "<button class='reverse-btn disabled-btn' disabled>다운</button>";
    }
    return "<button class='reverse-btn'>다운</button>";

  };

  // /*
  //  * @Overview file 업로드 함수
  //  * @Parameter 없음
  //  * @function 파일 선택 시 업로드 창 열림 -> 선택 후 임시폴더 업로드 -> putTempFile 함수 통해 해당 ROWDATA에 파일 데이터 업데이트
  //  */
  // 셀 수정
  cellEdited(cell) {
    cell.getData()._STATUS_ = cell.getData()._STATUS_ || "U";
  }

  // /*
  //  * @Overview file 업로드 함수
  //  * @Parameter 없음
  //  * @function 파일 선택 시 업로드 창 열림 -> 선택 후 임시폴더 업로드 -> putTempFile 함수 통해 해당 ROWDATA에 파일 데이터 업데이트
  //  */
  uploadButton = function(cell){ //plain text value
    var button = $("<button class='reverse-btn'>업로드</button>");
    
    button.on("click", function(){

      let editor = document.createElement("input");
      editor.setAttribute("type", "file");
      editor.setAttribute("name", "imgFile");
      editor.setAttribute("id", "imgFile");
      editor.style.padding = "3px";
      editor.style.width = "100%";
      editor.style.boxSizing = "border-box";
      editor.click();
      editor.addEventListener('change', function() {
        cell.getRow().getData().id = Math.floor(Math.random() * 101);
      });

      // var file = this.files[0];



    });


    return button[0];
  };
  deleteButton = function(cell, data, row, options){ //plain text value
    if(!cell.getRow().getData().FILE_NM){
      return "<button class='reverse-btn disabled-btn' disabled>삭제</button>";
    }
    let _this = this;
    var button = $("<button class='reverse-btn'>삭제</button>");
    // value
    button.on("click", function(){

      ajax_json({
        url: "./item.ajax.php",
        data: { mode: "delRoutFile", ITEM_CD:cell.getRow().getData().ITEM_CD , ROUT_SQNO:cell.getRow().getData().ROUT_SQNO},
        success: (data) => {
          if(data.code){
            kuls_success("적용 되었습니다.");
          }
        },
        error: (req, status, err) => {
          kuls_alert(err.message);
        },
        complete: () => {
          _this.getMainList();
        },
      });
    });


    return button[0];
  };


  //팝업 아이콘
  popIcon = function(cell, formatterParams, onRendered) { //plain text value

    return "<button class='reverse-btn fa-solid fa-paperclip padding-1-12'></button>";
  };
  openModal(cell) {

    let clickData = cell.getData();

    vnLoad("", "./reg_rout_pop.inc.php", "", (loadHtml) => {
      this.putPartnerModal = kuls_modal(loadHtml);


      const popFileUpload = new Tb_file_upload_class("#popup_file_upload",clickData);
      popFileUpload.init_insp();

    });
  }
  /*
   * @Overview 최초 실행 함수
   * @Parameter 없음
   */
  init() {
    let _this = this;
    // field 정의


    const fields = [
      { formatter:"rownum", field:"id", title: "NO",     width: 50, visible: false },
      { field: "ITEM_CD", title: "품목코드", visible: false},
      { field: "OP_SEQ", title: "공순", width: 40,movableRows: true},
      { title: "공정", cssClass:"width-200", columns:[
          {field:"OP_CD", width:100, cssClass:"editable-cell"},
          {field:"OP_NM", width:100}
        ]
      },
      { field: "ROUT_SQNO", title: "일련번호", width: 80,visible:false},
      { field: "FRST_OP_FLG", title: "처음 공정" , width: 80, visible: false},
      { field: "LAST_OP_FLG", title: "마지막 공정", width: 80, visible: false },
      { field: "PRV_OP_CD",   title: "이전 공정", width: 80, visible: false },
      { field: "NXT_OP_CD",   title: "다음 공정", width: 80, visible: false },

      { field: "STD_SETUP_TM", title: "준비시간</br>(분)", width: 80, editor: "input", 
        formatterParams:{
          decimal:".",
          precision:0
        },
      },
      { field: "CYCLE_TM", title: "공정시간</br>(분)", width: 80, editor: "input", 
        formatterParams:{
          decimal:".",
          precision:0
        }
      },
      { field: "STD_OP_AMT", title: "공정 단가</br>(원)", width: 80 ,editor: "input",
        formatter:"money",
        formatterParams:{
          decimal:".",
          precision:0
        }
      },
      {
        field: "FILE_MANAGE",
        title: "파일관리",
        width: 70,
        formatter: this.popIcon,
        cellClick:function(e,cell){
          // let _this = this;
          _this.openModal(cell);
        }
      },
      { field:"check", title: "삭제", width: 50, headerSort: false,
        formatter: tb_common_funtions.formatterCheckboxIcon,
        formatterParams: { checkval: "Y" },
      },
    ];
    const commonFieldData = {
      headerSort: false,
      vertAlign: "middle",
      hozAlign: "center",
      resizable: "header", //Resize 는 헤더에서만 가능
      headerHozAlign: "center", //헤더 정렬
      headerSortTristate: true, //데이터 정렬 => 정/역/초기화
    };

    this.tbList = new Tabulator(this.table, {
      layout: "fitColumns",
      movableRows:true,
      // selectableRows: 1,
      data: [], //기본 데이터
      columns: fields, //컬럼 설정
      columnDefaults: commonFieldData,
      headerSortElement: "<i class='bi'></i>", //정렬 아이콘
      selectable: 1
    });

    // row 이동 시에
    this.tbList.on("rowMoved", function(row){
      //row - row component
      if(Tb_routing.sortingRouting().some(x=>x._STATUS_ == "I")){
        kuls_alert("현재 입력 중인 라우팅을 저장 후 공정 순서를 조정해주세요")
        Tb_routing.getMainList(Tb_item.itemData);
      }else{
        const rowElement = row.getElement();
        rowElement.classList.add("edit-row");
        // ""(row._row.getData());
        row._row.getData()._STATUS_ = "U";
      }
    });

    // cell 클릭 시에
    this.tbList.on("cellClick", (e, tgt) => {
      this.cellClick && Tb_routing.cellClick(e, tgt);
      // Tb_process_check.getMainList();
    });
    // cell 수정 시에
    this.tbList.on("cellEdited", (cell) => {
      this.cellEdited && Tb_routing.cellEdited(cell);
      // Tb_process_check.getMainList();
    });

    // 추가
    ["click", "keypress"].forEach((evt) => {
      this.addBtn.addEventListener(evt, () => {
        // ""();

        this.addRow && this.addRow(Tb_item.tbList.getSelectedData()[0]?.ITEM_CD);
      });
    });
    // 삭제
    ["click", "keypress"].forEach((evt) => {
      this.removeBtn.addEventListener(evt, () => {
        this.removeRow && this.removeRow();
      });
    });
    // 위로
    ["click", "keypress"].forEach((evt) => {
      this.upBtn.addEventListener(evt, () => {
        // this.upRow && this.upRow();
      });
    });
    // 아래로
    ["click", "keypress"].forEach((evt) => {
      this.downBtn.addEventListener(evt, () => {
        this.downRow && this.downRow();
      });
    });
  }
}

class Tb_process_check_class {
  constructor(container) {
    this.ajaxUrl = "./item.ajax.php";
    this.container = document.querySelector(container);
    this.table = this.container.querySelector(".hy-table");
    this.addBtn = this.container.querySelector(".add-btn");
    this.removeBtn = this.container.querySelector(".remove-btn");
  }

  // tableBuild 되었을때 getManList
  getMainList(clickData) {
    let _this = this;
    let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);
    ajax_json({
      url: this.ajaxUrl,
      data: {
        mode: "getInspSpecList",
        ITEM_CD:clickData?.ITEM_CD,
      },
      success: (data) => {
        _this.tbList.setData(data.data);

      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);
        this.tbList.clearAlert();
      }
    })
  }


  setFilter() {}

  /*
   * @Overview 테이블 행 추가 함수
   * @Parameter 없음
   * @function 기본키, _STATUS_:I 값을 넣은 행 추가
   */
  addRow(ITEM_CD, ROUT_SQNO, OP_CD, OP_SEQ) {
    if(ITEM_CD === undefined){
      kuls_alert("품목 코드를 저장 후 선택해주세요");
      return false;
    }

    if(ITEM_CD === undefined || ROUT_SQNO === undefined){
      kuls_alert("공정 코드를 저장 후 선택해주세요");
      return false;
    }
    const INSP_ITEM = this.tbList.getData().length+1;

    this.tbList.addRow({ _STATUS_: "I", INSP_ITEM: INSP_ITEM, SPEC_ITEM_CD: ITEM_CD, ROUT_SQNO: ROUT_SQNO, OP_CD : OP_CD , OP_SEQ : OP_SEQ},true);
  }

 /*
  * @Overview 추가, 수정 및 삭제 데이터 저장
  * @Parameter 없음
  * @Function _STATUS_ : U, I, D Row 인 것 php 처리.
  */
 putInspSpec() {
  let _this = this;
  // 저장 시 상태 변화 없는 row 요청 X
  if(this.tbList.getData().filter(row=> row._STATUS_).length == 0){

    return false;
  }
  const blankObj = this.tbList.getRows().filter(row => {

    return Object.keys(row._row.data).filter(key => key !== '_STATUS_' && key !== 'USE_FLG' && key !== 'OP_CD' && key !== 'ROUT_SQNO' && key !== 'SPEC_ITEM_CD').every(key => {

      const value = row._row.data[key];
      return (value === undefined || value === '');
    });
  });

  let postdata = {
    'mode': 'putInspSpec',
    'reqdata': JSON.stringify(this.tbList.getData().filter(row=> row._STATUS_)),
  };
  if(blankObj.length !== 0){
    kuls_confirm("비어있는 행을 무시하고 진행하시겠습니까?","",()=>{
      ajax_json({
        url: _this.ajaxUrl,
        data: postdata,
        success: function (data) {
          if (data.code) {
            // _this.getMainList(Tb_item.getSelectedData()[0]);
            kuls_success("저장되었습니다.");
          }else{
            
            kuls_alert(data.mesg);
          }
        },
        error: function (request, status, error) {
          (request)
          kuls_alert(error.message);
        },
        complete: function () {
        }
      });

    },()=>{
      blankObj.forEach(row=>{
        row.getElement().classList.add("blank-row")
      })

    })
  }else{
    ajax_json({
      url: _this.ajaxUrl,
      data: postdata,
      success: function (data) {
        if (data.code) {
          _this.getMainList(Tb_item.tbList.getSelectedData()[0]);
          kuls_success("저장되었습니다.");
        }else{
          kuls_alert(data.mesg);
        }
      },
      error: function (request, status, error) {
        kuls_alert(error.message);
      },
      complete: function () {
      }
    });

  
  }

}

  /*
   * @Overview 테이블 행 삭제 함수
   * @Parameter 없음
   * @function 선택된 모든 행 STATUS D
   */
  removeRow() {
    const selectedRows = this.tbList.getRows().filter(row=>{
      return row.getData().check ==="Y"
    });

    if(selectedRows.length > 0 ){

      // kuls_confirm("삭제","하시겠습니까?", ()=>{
        // 선택된 각 행 삭제
        selectedRows.forEach((row) => {
          // STAUS D로 바꾸기
          row.getData()._STATUS_ = row.getData()._STATUS_=="I"?null:"D";
          const rowElement = row.getElement();
          rowElement.classList.add("remove-row");
        });
    }else{
      kuls_alert("삭제할 행을 선택해주세요.")
    }
  }

  /*
   * @Overview 삭제 취소 함수
   * @Parameter 삭제 행
   * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
   */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){
      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
    }
  }

  /*
   * @Overview 테이블 행 선택 함수
   * @Parameter 없음
   * @function 선택된 모든 행 색 변경
   */
  rowClick(e, tgt) {
    if (tgt.isSelected()) {
      tgt.deselect();
      this.clearRemove(tgt);
    } else {
      tgt.select();
    }
  }

  /*
   * @Overview 삭제 취소 함수
   * @Parameter 삭제 행
   * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
   */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){
      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
    }
  }
  cellClick(e, tgt) {
    var editor = tgt.getColumn().getDefinition().editor;
    
    // 체크박스 클릭
    switch (tgt.getField()) {
      case "INSP_NAME":
        popInsp({
          INSP_NAME: "INSP_NAME",
          INSP_METH: "INSP_METH",
        },tgt.getRow())
        break;
      case "check":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        this.clearRemove(tgt.getRow())
      break;
      case "OKNG_FLG":
        tgt.setValue(tgt.getValue() == "Y" ? "N" : "Y");

        if(tgt.getValue() === "Y"){
         tgt.getRow().update({SPEC_VAL:"",TOL_UPPER:"",TOL_LOWER:""});
        }else{
          tgt.getRow().getCell("SPEC_VAL").getElement().classList.add("tabulator-editable");
          tgt.getRow().getCell("TOL_UPPER").getElement().classList.add("tabulator-editable");
          tgt.getRow().getCell("TOL_LOWER").getElement().classList.add("tabulator-editable");
        }
        tgt.getElement().classList.add("tabulator-editable");
      break;
      default:
        if (!editor) {
          this.rowClick && this.rowClick(e, tgt.getRow());
        }
      break;
    }
  }

  // 셀 수정
  cellEdited(cell) {
    cell.getData()._STATUS_ = cell.getData()._STATUS_ || "U";
  }

  integerMutator = function(value, data, type, params, component) {
    return value ? parseInt(value, 10) : null;
  };
  /*
   * @Overview 최초 실행 함수
   * @Parameter 없음
   */
  init() {
    // field 정의
    const fields = [
      { formatter:"rownum", field:"file_id", title: "NO",     width: 40 },
      { field: "OP_SEQ", title: "공순", width: 40},
      { field:"OP_CD", title: "공정", width:40},
      { field: "INSP_ITEM", title: "검사항목코드",       width: 75, visible: true},
      { field: "INSP_NAME", title: "검사항목",        width: 70, cssClass:"editable-cell" },
      { field: "INSP_METH", title: "검사방법",        width: 70, editor:"list", editorParams:{values: varsINSP_METH},formatter: tb_common_funtions.formatterSelect, formatterParams: {values: varsINSP_METH},cssClass: "user-list" },
      { field: "OKNG_FLG",  title: "OK/NG",          width: 50, cssClass: "tabulator-editable", formatter: tb_common_funtions.formatterToggleboxGreenIcon, formatterParams: { checkval: "Y" }},
      { field: "ROUT_SQNO", title: "라우팅일련번호",  visible:false  },
      { field: "INSP_TOOL", title: "측정기",          width: 110, editor: "list", cssClass:"user-list", editorParams:{values: varsINSP_TOOL}, formatter: tb_common_funtions.formatterSelect, formatterParams: {values: varsINSP_TOOL} },
      { field: "SPEC_VAL",  title: "기준값</br>(㎜)", width: 50, editor: "number",
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal : 3
        },
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },
      },

      { field: "TOL_UPPER", title: "상한값</br>(㎛)",           width: 50,
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal : 0
        },
        editor:"number",
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },

      },
      { field: "TOL_LOWER", title: "하한값</br>(㎛)",           width: 50,
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal : 0
        },
        editor:"number",
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },
      },
      { field: "REMARK", title: "비고",          width: 150, editor: "input" },
      { field:"check", title: "삭제", width: 40, headerSort: false,
        formatter: tb_common_funtions.formatterCheckboxIcon,
        formatterParams: { checkval: "Y" },
      },
    ];
    const commonFieldData = {
      headerSort: false,
      vertAlign: "middle",
      hozAlign: "center",
      resizable: "header", //Resize 는 헤더에서만 가능
      headerHozAlign: "center", //헤더 정렬
      headerSortTristate: true, //데이터 정렬 => 정/역/초기화
    };

    this.tbList = new Tabulator(this.table, {
      layout: "fitColumns",
      data: [], //기본 데이터
      columns: fields, //컬럼 설정
      columnDefaults: commonFieldData,
    });

    // cell 클릭 시에
    this.tbList.on("cellClick", (e, tgt) => {
      this.cellClick && this.cellClick(e, tgt);
    });
    // cell 수정 시에
    this.tbList.on("cellEdited", (cell) => {
      this.cellEdited && this.cellEdited(cell);
    });

    // 추가
    ["click", "keypress"].forEach((evt) => {
      this.addBtn.addEventListener(evt, () => {
        this.addRow(
          Tb_item.tbList.getSelectedData()[0]?.ITEM_CD,
          Tb_routing.tbList.getSelectedData()[0]?.ROUT_SQNO,
          Tb_routing.tbList.getSelectedData()[0]?.OP_CD,
          Tb_routing.tbList.getSelectedData()[0]?.OP_SEQ
        );

      });
    });
    // 삭제 함수
    ["click", "keypress"].forEach((evt) => {
      this.removeBtn.addEventListener(evt, () => {
        this.removeRow && this.removeRow();
      });
    });

  }
}

class Tb_pic_class {
  constructor(container) {
    let _this = this;
    _this.file = "";
    _this.itemData ="";
    _this.download_url = "/include/getFile.php";
    this.ajaxUrl = "./item.ajax.php";
    this.container = document.querySelector(container);
    this.table = this.container.querySelector(".hy-table");
    this.addBtn = this.container.querySelector(".add-btn");
    this.removeBtn = this.container.querySelector(".remove-btn");
    
  }

  // tableBuild 되었을때 getManList
  getMainList(clickData) {
    let _this = this;
    let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);

    ajax_json({
      url: this.ajaxUrl,
      data: { mode : "getDrawList", ITEM_CD : _this.itemData.ITEM_CD},
      success: (data) => {
        this.tbList.setData(data.data);
      },
      error: (req, status, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);
        this.tbList.clearAlert();
      },
    });
  }

  setFilter() {}

  /*
   * @Overview 테이블 행 추가 함수
   * @Parameter 없음
   * @function 기본키, _STATUS_:I 값을 넣은 행 추가
   */
  addRow() {
    this.tbList.addRow({ _STATUS_: "I" },true);
  }

  /*
   * @Overview 테이블 행 삭제 함수
   * @Parameter 없음
   * @function 선택된 모든 행 STATUS D
   */
  removeRow() {
    const selectedRows = this.tbList.getRows().filter(row=>{
      return row.getData().check ==="Y"
    });

    if(selectedRows.length > 0 ){

      // kuls_confirm("삭제","하시겠습니까?", ()=>{
        // 선택된 각 행 삭제
        selectedRows.forEach((row) => {
          // STAUS D로 바꾸기
          row.getData()._STATUS_ = row.getData()._STATUS_=="I"?null:"D";
    
          const rowElement = row.getElement();
          rowElement.classList.add("remove-row");
    
        });
      // })
    }else{
      kuls_alert("삭제할 행을 선택해주세요.")
    }
  }

  /*
   * @Overview 삭제 취소 함수
   * @Parameter 삭제 행
   * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
   */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){
      // ();
      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
      // const selectedRows = this.tbList.getSelectedRows(); // 선택된 모든 행 가져오기
    }
  }


  putTempFile(file){
    let _this = this;


    let formData = new FormData();
    formData.append('upfile', file);
    formData.append('mode', "putTempFile");
    let talert = window.setTimeout(()=> { this.tbList.alert("Loading ...") }, 1000);
    jQuery.ajax({
      url: _this.ajaxUrl,
      type: 'POST',
      data: formData,
      contentType: false,
      processData: false,
      success: (data)=>{
        if(data.code !== "0") {

          let fdata = JSON.parse(data).data;

          let FILE_NM   = fdata['file_name'];
          let TMP_NAME  = fdata['tmp_name'];
          let FILE_SIZE = fdata['file_size'];
          let FILE_TYPE = fdata['file_type'];

          _this.tbList.addRow({
            _STATUS_:'I',
            ITEM_CD : Tb_item.tbList.getSelectedData()[0]?.ITEM_CD,
            DRAW_VER : parseInt(_this.tbList.getData()[0]?.DRAW_VER) + 1 ||1,
            FILE_NM,
            TMP_NAME,
            FILE_SIZE,
            FILE_TYPE,
            gubun:'temp',
          });
          (_this.tbList.getData());
        }else{
          kuls_alert(data.msg);
        }
      },
      error: (req, stat, err) => {
        kuls_alert(err.message);
      },
      complete: () => {
        window.clearTimeout(talert);

        this.tbList.clearAlert();
      },
    });
    return true;


  }
  putFile() {
    if (this.tbList.getData().filter(row => row._STATUS_).length == 0 ) {
      return false;
    }
    const blankObj = [];
    const reqData = [];

    this.tbList.getRows().forEach(row => {

      if (row.getData()['_STATUS_']) {
        if (Object.keys(row._row.data).filter(key => key !== '_STATUS_' && key !== 'USE_FLG').every(key => {

          const value = row._row.data[key];
          return (value === undefined || value === '');
        })) {
          blankObj.push(row);
        } else {
          reqData.push(row.getData());
        }
      }
    })


    const postdata = reqData.length == 0 ? false : {
      'mode': 'putDraw',
      'reqdata': JSON.stringify(reqData),
    };
    if (blankObj.length !== 0) {
      kuls_confirm("비어있는 행을 무시하고 진행하시겠습니까?", "", () => {
        ajax_json({
          url: this.ajaxUrl,
          data: postdata,
          success: (data) => {
            if (data.code) {
              kuls_success("저장되었습니다.");
              this.getMainList();
            } else {
              kuls_alert(data.mesg);
            }
          },
          error: function (request, status, error) {
            kuls_alert(error.message);
          },
          complete: function () {
          }
        });

      }, () => {
        blankObj.forEach(row => {
          row.getElement().classList.add("blank-row")
        })
      })
    } else {
      ajax_json({
        url: this.ajaxUrl,
        data: postdata,
        success: (data) => {
          if (data.code) {
            kuls_success("저장되었습니다.");
            this.getMainList();
          } else {
            kuls_alert(data.mesg);
          }
        },
        error: function (request, status, error) {
          kuls_alert(error.message);
        },
        complete: function () {
        }
      });

      return true;
    }
  }
  // 클릭 이벤트
  rowClick(e, tgt) {
    // 삭제가 가능하도록 ROW SELECT
    // staus D로 바꾸기?
    let _this = this;
    if (tgt.isSelected()) {

      _this.tbList.deselectRow(tgt._row);

    } else {
      _this.tbList.deselectRow();
    }
  }
 /*
  * @Overview 테이블 행 삭제 함수
  * @Parameter 없음
  * @function 선택된 모든 행 STATUS D
  */
  removeRow() {
    const selectedRows = this.tbList.getRows().filter(row=>{
      return row.getData().check ==="Y"
    });

    if(selectedRows.length > 0 ){

      // 선택된 각 행 삭제
      selectedRows.forEach((row) => {
        // STAUS D로 바꾸기
        row.getData()._STATUS_ = row.getData()._STATUS_=="I"?null:"D";
  
        const rowElement = row.getElement();
        rowElement.classList.add("remove-row");
  
      });
    }else{
      kuls_alert("삭제할 행을 선택해주세요.")
    }
  }
 /*
  * @Overview 삭제 취소 함수
  * @Parameter 삭제 행
  * @function  클릭시 삭제 취소 & STATUS를 공란으로 변경
  */
  clearRemove(tgt){
    if(tgt._row.data._STATUS_ == "D"){
      // ();
      tgt._row.data._STATUS_ = "";
      tgt._row.getElement().classList.remove("remove-row")
      // const selectedRows = this.tbList.getSelectedRows(); // 선택된 모든 행 가져오기
    }
  }
  cellClick(e, tgt) {
    // 체크박스 클릭
    switch (tgt.getField()) {
      case "check":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        this.clearRemove(tgt.getRow())
        break;
      case "USE_FLAG":
        tgt.setValue(tgt.getValue() == "Y" ? "N" : "Y");
        break;
    }
  }
  uploadDraw(e) {

  }
  // 셀 수정
  cellEdited(cell) {
    cell.getData()._STATUS_ = cell.getData()._STATUS_ || "U";
  }
  previewIcon = function(cell, formatterParams, onRendered){ //plain text value
    if(!cell.getRow().getData().FILE_NM){
      return "<button class='reverse-btn disabled-btn padding-1-5' diabled>미리보기</button>";
    }
    return "<button class='reverse-btn padding-1-5'>미리보기</button>";

  };
  downloadIcon = function(cell, formatterParams, onRendered){ //plain text value
    return "<i class='fa-solid fa-download'></i>";
  };
  getFileUrl =function(DRAW_NO, SID, FILE_ID, FILE_NM,down){
    let urlStr = '/include/getFile.php'+"?gubun=draw&nid="
        + DRAW_NO +
        "&sid="+ SID +
        "&file_id="+ FILE_ID+
        "&name="+FILE_NM
    if(down == true){
      location.href = urlStr;
    }
    return urlStr;
  }
  /*
   * @Overview 최초 실행 함수
   * @Parameter 없음
   */
  init() {
    let _this = this
    // field 정의
    const fields = [

      { formatter: "rownum",  title: "NO", width: 50 },

      { field: "DOWNLOAD",    title: "다운로드", width: 100, formatter: this.downloadIcon,
        cellClick:function(e, cell){
          if(!cell.getRow().getData().SID){
            kuls_alert("저장 후 사용 가능합니다")
            return false;
          }
          _this.getFileUrl(
              '',
              cell.getRow().getData().SID,
              cell.getRow().getData().FILE_ID,
              cell.getRow().getData().FILE_NM,
              true
          );

        }
      },
      { field: "DRAW_VER",    title: "버전",    width: 100 },
      { field: "DRAW_NO",     title: "도면번호", width: 150, editor: "input" ,editable:(cell)=>{ let val = cell.getData(); return val._STATUS_ === 'I' },visible: false}, //file의 nid이기도 함
      { field: "FILE_NM",     title: "파일명",  width: 150 },
      { field: "SID",                       visible:false},
      { field: "FILE_ID",                   visible:false},
      { field: "MAKE_TM",     title: "등록일", width: 100, formatter:"datetime", formatterParams:{
          inputFormat:"yyyy-MM-dd",
          outputFormat:"yy.MM.dd",
        }
      },
      { field: "MAKE_USER_ID",title: "등록자", width: 100 },
      { field: "preview",     title: "미리보기", width: 80, formatter: _this.previewIcon,
          cellClick:function(e,cell){
            if(!cell.getRow().getData().DRAW_NO){
              kuls_alert("저장 후 사용 가능합니다")
              return false;
            }
            pop_filedown(
                _this.getFileUrl(
                  '',
                  cell.getRow().getData().SID,
                  cell.getRow().getData().FILE_ID,
                  cell.getRow().getData().FILE_NM
                ), cell.getRow().getData().FILE_NM.split(".").pop()
            );
          }
      },
      {
        field: "USE_FLAG",
        title: "사용",
        width: 50,
        visible: true,
        cssClass: "editable-cell",
        formatter: tb_common_funtions.formatterToggleboxGreenIcon,
        formatterParams: { checkval: "Y" },
      },
      { field:"check", title: "삭제", width: 50, headerSort: false,
        formatter: tb_common_funtions.formatterCheckboxIcon,
        formatterParams: { checkval: "Y" },
      },
    ];
    const commonFieldData = {
      headerSort: false,
      vertAlign: "middle",
      hozAlign: "center",
      resizable: "header", //Resize 는 헤더에서만 가능
      headerHozAlign: "center", //헤더 정렬
      headerSortTristate: true, //데이터 정렬 => 정/역/초기화
    };

    this.tbList = new Tabulator(this.table, {
      layout: "fitColumns",
      selectableRows: true,
      data: [], //기본 데이터
      columns: fields, //컬럼 설정
      columnDefaults: commonFieldData,
    });

    // 데이터 불러오기
    this.tbList.on("tableBuilt", () => {
      // this.getMainList();
    });
    // row 클릭 시에
    this.tbList.on("rowClick", (e, tgt) => {
      // this.rowClick && Tb_item.rowClick(e, tgt);

    });
    // cell 클릭 시에
    this.tbList.on("cellClick", (e, tgt) => {
      this.cellClick && this.cellClick(e, tgt);
    });
    // cell 수정 시에
    this.tbList.on("cellEdited", (cell) => {
      this.cellEdited && this.cellEdited(cell);
    });

    // 삭제
    ["click", "keypress"].forEach((evt) => {
      this.removeBtn.addEventListener(evt, () => {
        this.removeRow && this.removeRow();
      });
    });
    // 추가
    ['click','keypress'].forEach((evt) =>{
        this.addBtn.addEventListener(evt,()=> {
          uploadFile();
        });
    });
    const uploadFile=()=> {
      if(!Tb_item.tbList.getSelectedData()[0]?.ITEM_CD){
        return false;
      }
      document.getElementById('file_input').click();
    }
  }
}


class Tb_pop_class {
  constructor(container) {
    this.ajaxUrl = "./item.ajax.php";
    this.tbList = "";
    this.itemData = "";
    this.fileData = "";
    this.container = document.querySelector(container);
    this.table = this.container;
    this.lastNum = 0;
  }
  addRow() {
    this.tbList.addRow();
  }
  uploadExcel(){
    let _this = this;
    let postdata = {
      mode : 'uploadData',
      reqdata : JSON.stringify(this.tbList.getData().filter(row=>{
        return row.check ==="Y" && row._STATUS_
      }))

    }
    ajax_json({
      url: this.ajaxUrl,
      data: postdata,
      success: function (data) {
        if (data.code) {
          _this.tbList.setData("");
          kuls_success("저장되었습니다.");
        }else if(data.code == 0){

          _this.tbList.setData(data.mesg);

        }
      },
      error: function (request, status, error) {
        (request)
        kuls_alert(error.message);
      },
      complete: function () {
      }
    });
  }
  cellClick(e, tgt) {
    let editor = tgt.getColumn().getDefinition().editor;
    // // 체크박스 클릭
    switch (tgt.getField()) {
      case "check":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        break;
      case "OKNG_FLG":
        tgt.setValue(tgt.getValue() == "Y" ? "" : "Y");
        this.clearRemove(tgt.getRow())
        break;
      default:
        if (!editor) {
          this.rowClick && this.rowClick(e, tgt.getRow());
        }
        break;
    }
  }
  init() {
    let _this = this;

    const fields = [
      { field:"check", title: "삭제", width: 50, headerSort: false,
        formatter: tb_common_funtions.formatterCheckboxIcon,
        formatterParams: { checkval: "Y" },
      },
      { formatter:"rownum", field:"id", title: "NO", width: 50},
      { field: "ITEM_CD", title: "품목코드",width: 100, },
      { field: "ITEM_NM", title: "품목(명)",width: 140, },
      { field: "ITEM_GRP", title: "품목그룹",width: 80, editor: "input",},
      { field: "OP_SEQ", title: "공순", width: 65, editor: "input",},
      { field: "OP_CD", title: "공정코드", width: 65, editor: "input",},
      { field: "STD_SETUP_TM", title: "준비시간</br>(분)", width: 80, editor: "input",
      formatterParams:{
        decimal:".",
        precision:0
      },
      },
      { field: "CYCLE_TM", title: "공정시간</br>(분)", width: 80, editor: "input",
        formatterParams:{
          decimal:".",
          precision:0
        }
      },
      { field: "STD_OP_AMT", title: "공정 단가</br>(원)", width: 80 , editor: "input",
        formatterParams:{
          decimal:".",
          precision:0
        }
      },
      { field: "INSP_NAME", title: "검사항목",        width: 80, cssClass:"editable-cell", editor: "input", },
      { field: "INSP_METH", title: "검사방법",        width: 80, editor: "list", cssClass:"user-list", editorParams:{values: varsINSP_METH}, formatter: tb_common_funtions.formatterSelect, formatterParams: {values: varsINSP_METH} },
      { field: "OKNG_FLG",  title: "OK/NG",          width: 50, cssClass: "tabulator-editable", formatter: tb_common_funtions.formatterToggleboxGreenIcon, formatterParams: { checkval: "Y" }},
      { field: "INSP_TOOL", title: "측정기",          width: 150, editor: "list", cssClass:"user-list", editorParams:{values: varsINSP_TOOL}, formatter: tb_common_funtions.formatterSelect, formatterParams: {values: varsINSP_TOOL} },
      { field: "SPEC_VAL",  title: "기준값</br>(㎜)", width: 70, editor: "input",
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal: 3
        },
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
            cell.setValue(0)
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },
      },
      { field: "TOL_UPPER", title: "상한값</br>(㎛)", width: 70,
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal: 0
        },
        editor:"input",
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
            cell.setValue(0)
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },

      },
      { field: "TOL_LOWER", title: "하한값</br>(㎛)", width: 70,
        formatter: tb_custom_formatter.limitValue,
        formatterParams: {
          checkPoint : "OKNG_FLG",
          decimal: 0
        },
        editor:"input",
        editable:(cell) => {
          if(cell.getData().OKNG_FLG == 'Y'){
            cell.setValue(0)
          }
          return cell.getData().OKNG_FLG !== 'Y';
        },
      },
      {field:"RS_MSG", title:"업로드 여부", width:200 }
    ];
    const commonFieldData = {
      headerSort: false,
      vertAlign: "middle",
      hozAlign: "center",
      resizable: "header",
      headerHozAlign: "center",
      headerSortTristate: true,
    };

    this.tbList = new Tabulator(this.table, {
      layout: "fitColumns",
      movableRows:true,
      data: [],
      columns: fields,
      columnDefaults: commonFieldData,
      headerSortElement: "<i class='bi'></i>",
      selectable: 1
    });
    // cell 클릭 시에
    this.tbList.on("cellClick", (e, tgt) => {
      this.cellClick && this.cellClick(e, tgt);
    });
    ["click", "keypress"].forEach((evt) => {
      const saveBtn = document.querySelector(".save-btn");
      saveBtn.addEventListener(evt, () => {
        this.uploadExcel();
        Tb_item.getMainList();
        Tb_routing.getMainList();
        Tb_pic.getMainList();
        Tb_process_check.getMainList();

        Tb_item.putItem.delete();
      });
    });
  }
}


const Tb_item = new Tb_item_class("#item_ifo_table");
Tb_item.init();
const Tb_routing = new Tb_routing_class("#routing_table");
Tb_routing.init();
const Tb_process_check = new Tb_process_check_class("#process_check_table");
Tb_process_check.init();
const Tb_pic = new Tb_pic_class("#second-tab-container");
Tb_pic.init();
document.getElementById('file_input').addEventListener('change', function() {
  // 파일 정보 가져오기
  var file = this.files[0];

  Tb_pic.putTempFile(file);
  document.getElementById('file_input').value = "";
});

 // 팝업 초기화는 팝업이 열릴 때 수행
 function initPopup() {
  const Tb_pop = new Tb_pop_class('#pop_excel_item');
  Tb_pop.init();
  //엑셀업로드
  document.getElementById('excel_up').addEventListener('click', function (e) {
    document.getElementById('fileInput').click();
  });
  document.getElementById('fileInput').addEventListener('change', function (e) {
    let file = e.target.files[0];
    if (!file) {
        return;
    } 
    let reader = new FileReader();
    reader.onload = (e) => { 
        let data = new Uint8Array(e.target.result);
        let workbook = XLSX.read(data, { type: 'array' });
  
        workbook.SheetNames.forEach((sheetName) => {
          let rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { header:1 });

            rows.slice(1).forEach((row,index) => {
              if(row.length !== 0){

                let rowToAdd = {
                  check:"Y",
                  ITEM_CD     : row[0],
                  ITEM_NM     : row[1],
                  ITEM_GRP    : row[2],
                  OP_SEQ      : row[3],
                  OP_CD       : row[4],
                  STD_SETUP_TM: row[5],
                  CYCLE_TM    : row[6],
                  STD_OP_AMT  : row[7],
                  INSP_NAME   : row[8],
                  INSP_TOOL   : row[9],
                  INSP_METH   : row[10],
                  OKNG_FLG    : row[11],
                  SPEC_VAL    : row[12],
                  TOL_UPPER   : row[13],
                  TOL_LOWER   : row[14],
                  _STATUS_    : "I"
                };

                Tb_pop.tbList.addRow(rowToAdd);
              }
            });



        });
    };
    reader.readAsArrayBuffer(file)
  });
}
