????

Your IP : 18.224.21.26


Current Path : C:/inetpub/vhost/sdoc.gdtsolutions.vn/package/app/controllers/tailieu/
Upload File :
Current File : C:/inetpub/vhost/sdoc.gdtsolutions.vn/package/app/controllers/tailieu/hoso.js

var Database = require('../../models/Database');
var {existsSync} = require('fs');
var fsp = require('fs/promises');
var path = require('path');
const { savePath } = require('../../appconfig');
class HoSoController extends Database {
  constructor(params) {
    super(params);
  }
  static create(params) {
    return new HoSoController(params);
  }
  async selectFile(req, cond) {
    let result = { draw: parseInt(req.draw) || 0, recordsTotal: 0, recordsFiltered: 0 };
    let where = ['[File].[State] = 1'];
    let input = {};
    if (cond) where.push(cond);
    if (req['search'] && req['search']['value']) {
      where.push('CONTAINS([File].*, @search)');
      input['search'] = req['search']['value'].split(' ').join('+');
    }
    const aggrFile = `WITH [AggrFile] AS (
      SELECT [File].[UUID], COUNT(PerformFile.Id) as [countPerform], SUM([Document].[PageAmount]) as [PageTotal]
        FROM [File]
        LEFT JOIN [PerformFile] ON [File].[UUID] = [PerformFile].[FileId]
        LEFT JOIN [Document] ON [File].[UUID] = [Document].[FileId]
        WHERE ${where.join(' AND ')}
        GROUP BY [File].[UUID]
    )`;
    let query = `${aggrFile} SELECT [File].*,[AggrFile].countPerform,[AggrFile].PageTotal,Fond.FondName,Fond.FondNumber,editedAcc.FullName nameEdit, approvedAcc.FullName nameApprove FROM [File]`;
    query += ' INNER JOIN [Fond] ON [Fond].[FondCode] = [File].[FondCode]';
    query += ' INNER JOIN [AggrFile] ON [AggrFile].[UUID] = [File].[UUID]';
    query += ' LEFT JOIN Account editedAcc ON [File].EditedBy = editedAcc.UUID';
    query += ' LEFT JOIN Account approvedAcc ON [File].ApprovedBy = approvedAcc.UUID';
    query += ' ORDER BY FondNumber,FondCode,FileCatalog,BoxNumber,FileNumber';
    input['length'] = parseInt(req['length']) || 0;
    input['start'] = parseInt(req['start']) || 0;
    if (input['length']) query += ' OFFSET @start rows FETCH NEXT @length rows ONLY';
    let recordset = await this.select(query, input);
    let countRS = await this.select(`${aggrFile} SELECT COUNT(*) as count from [AggrFile]`, input);
    if (recordset.length) result['recordsTotal'] = result['recordsFiltered'] = countRS[0]['count'];//recordset[0]['recordsTotal'];
    result.data = recordset;
    return result;
  }
  async addFile(userId, file) {
    let files = await this.select('SELECT UUID FROM [File] WHERE [State] = 1 AND FondCode = @fond AND FileCatalog = @catalog AND FileNumber = @number', { fond: file.fond, catalog: file.catalog, number: file.number.padStart(2, '0') });
    if (files.length) throw new Error(`Đã tồn tại hồ sơ số ${file.number.padStart(2, '0')} trong mục lục ${file.catalog} của phông ${file.fond}`);
    let fonds = await this.select('SELECT OrganId,[State] FROM Fond WHERE FondCode = @code', { code: file.fond });
    if (!fonds.length) throw new Error(`Không tồn tại phông lưu trữ có mã ${file.fond}`);
    let fond = fonds[0];
    let fileCode = `${fond.OrganId}.${file.year}.${file.number}`;
    if (fond.State) fileCode = `${fond.OrganId}.${file.fond}.${file.catalog.padStart(2, '0')}.${file.number.padStart(2, '0')}`;
    let input = {
      code: fileCode,
      fond: file.fond,
      group: parseInt(file.group) || 1,
      catalog: parseInt(file.catalog),
      box: parseInt(file.box),
      number: file.number.padStart(2, '0'),
      year: parseInt(file.year) || null,
      notation: file.notation || null,
      title: file.title || null,
      maintenance: file.maintenance || 0,
      rights: file.rights || null,
      language: file.language ? file.language.toString() : null,
      description: file.description || null,
      inforsign: file.inforsign || null,
      keyword: file.keyword || null,
      sheetnumber: parseInt(file.sheetnumber) || null,
      format: file.format || null,
      createdby: userId
    };
    let query = 'INSERT INTO [File](FileCode,FondCode,GroupId,FileCatalog,BoxNumber,FileNumber,FileYear,FileNotation,Title,Maintenance,Rights,Language,Description,InforSign,Keyword,SheetNumber,Format,CreatedBy) VALUES (@code,@fond,@group,@catalog,@box,@number,@year,@notation,@title,@maintenance,@rights,@language,@description,@inforsign,@keyword,@sheetnumber,@format,@createdby)';
    await this.query(query, input);
    try {
      if (!existsSync(path.join(savePath, fileCode))) 
        await fsp.mkdir(path.join(savePath, fileCode), {recursive: true});
    } catch { }
    return 'Đã tạo thành công 1 hồ sơ';
  }

  async editFile(user, file) {
    let resultFile = await this.canEdit(user, file.id);
    if (!resultFile) throw new Error('Tài khoản hiện tại không có quyền sửa tài liệu trên');
    let selectInput = {
      fond: file.fond || resultFile.FondCode,
      year: parseInt(file['year']) || resultFile['FileYear'],
      catalog: parseInt(file.catalog) || resultFile['FileCatalog'],
      number: (file.number || resultFile.FileNumber).padStart(2, '0'),
      uuid: file.id
    };
    let fonds = await this.select('SELECT OrganId,[State] FROM Fond WHERE FondCode = @code', { code: selectInput.fond });
    if (!fonds.length) throw new Error(`Không tồn tại phông lưu trữ có mã ${file.fond}`);
    let fond = fonds[0];
    let files = await this.select('SELECT * FROM [File] WHERE [State] = 1 AND FondCode = @fond AND FileCatalog = @catalog AND FileNumber = @number AND UUID != @uuid', selectInput);
    if (files.length) throw new Error(`Đã tồn tại hồ sơ khác với số ${file.number || resultFile.FileNumber} trong mục lục ${file.catalog || resultFile.FileCatalog} của phông ${file.fond || resultFile.FondCode}`);
    let fileCode = `${fond['OrganId']}.${selectInput['year']}.${selectInput['number']}`;
    if (fond['State']) fileCode = `${resultFile.OrganId}.${selectInput.fond}.${selectInput.catalog.toString().padStart(2, '0')}.${selectInput.number}`;
    let oldPath = path.join(savePath, resultFile.FileCode);
    let newPath = path.join(savePath, fileCode);
    let updates = [];
    if (fileCode !== resultFile.FileCode) { updates.push('FileCode=@code'); file['code'] = fileCode }
    if (typeof file.fond !== 'undefined') updates.push('FondCode=@fond');
    if (typeof file.group !== 'undefined') updates.push('GroupId=@group');
    if (typeof file.catalog !== 'undefined') updates.push('FileCatalog = @catalog');
    if (typeof file.box !== 'undefined') updates.push('BoxNumber = @box');
    if (typeof file.number !== 'undefined') { updates.push('FileNumber = @number'); file['number'] = file['number'].padStart(2, '0') }
    if (typeof file.year !== 'undefined') updates.push('FileYear = @year');
    if (typeof file.notation !== 'undefined') updates.push('FileNotation = @notation');
    if (typeof file.title !== 'undefined') updates.push('Title = @title');
    if (typeof file.maintenance !== 'undefined') updates.push('Maintenance = @maintenance');
    if (typeof file.right !== 'undefined') updates.push('Rights = @right');
    if (typeof file.language !== 'undefined') updates.push('Language = @language');
    if (typeof file.description !== 'undefined') updates.push('Description=@description');
    if (typeof file.inforsign !== 'undefined') updates.push('InforSign=@inforsign');
    if (typeof file.keyword !== 'undefined') updates.push('Keyword=@keyword');
    if (typeof file.sheetnumber !== 'undefined') updates.push('SheetNumber=@sheetnumber');
    if (typeof file.format !== 'undefined') updates.push('Format=@format');
    if (!updates.length) return null;
    let query = `UPDATE [File] SET ${updates.join(',')} WHERE UUID = @id`;
    let result = await this.query(query, file);
    if (oldPath != newPath) {
      try {
        if (!existsSync(oldPath)) await fsp.mkdir(newPath, {recursive: true});
        else {
          await fsp.rename(oldPath, newPath);
        }
      } catch (err) { console.log(err) }
    }
    this.updateDocInFile(file.id).then(result => console.log(result)).catch(err => console.log(err));
    return result;
  }

  async deleteFile(user, fileId) {
    let capBool = await this.canDelete(user, fileId);
    if (!capBool) throw new Error('Không được quyền xóa hồ sơ');
    return await this.query('UPDATE [File] SET [State] = 0 WHERE UUID = @uuid', { uuid: fileId });
  }

  async updateDocInFile(fileId) {
    let file = (await this.select('SELECT * FROM [File] WHERE UUID = @uuid', { uuid: fileId }))[0];
    if (file) {
      let filePath = path.join(savePath, file.FileCode);
      let docs = await this.select('SELECT Document.*,[File].FileCode FROM Document INNER JOIN [File] ON [File].UUID = Document.FileId WHERE FileId = @uuid', { uuid: fileId })
      for (let i = 0; i < docs.length; i++) {
        let doc = docs[i];
        let docCode = `${doc.FileCode}.${doc.DocOrdinal.toString().padStart(2, '0')}`;
        if (docCode == doc.DocCode) continue;
        try {
          await this.query('UPDATE Document SET DocCode = @docCode where UUID = @uuid', { docCode: docCode, uuid: doc.UUID });
          await fsp.rename(path.join(filePath, doc.DocCode + '.pdf'), path.join(filePath, docCode + '.pdf'));
        } catch (err) { console.log(err) }
      }
    }
    return;
  }
  // Lưu nhật ký nộp, duyệt hồ sơ
  getPerformNote(fileId) {
    return this.select('SELECT Account.FullName,PerformFile.[Job],PerformFile.[State],PerformFile.[Date],PerformFile.[Note] FROM PerformFile LEFT JOIN Account ON Account.UUID = PerformFile.PerformedBy WHERE PerformFile.FileId = @fileId', { fileId: fileId })
  }
  async performFile(accId, data, kind, note) {
    let job = 0;
    if (kind == 2 || kind == 0) {
      job = 1;
    }
    let recordset = await this.select('SELECT UUID FROM [File] WHERE UUID = @uuid AND [State] = 1', { uuid: data })
    if (recordset.length > 0) {
      let query = 'INSERT INTO PerformFile(PerformedBy,Job,FileId,[State],Note) VALUES (@accId,@job,@data,@kind,@note)';
      let input = {
        accId: accId,
        job: job,
        data: data,
        kind: kind,
        note: note
      }
      return await this.query(query, input)
    } else { throw new Error('Không tồn tại hồ sơ cần duyệt') }
  }

  //Kiểm tra quyền hồ sơ
  async canEdit(user, id) {
    let recordset = await this.select('SELECT [File].*,Fond.OrganId FROM [File] LEFT JOIN Fond ON Fond.FondCode = [File].FondCode WHERE [File].UUID = @uuid', { uuid: id })
    let file = recordset[0];
    if (!file) return null;
    let userTasks = user['Tasks'].split(',');
    if (userTasks.indexOf('306') > -1) return file;
    if (userTasks.indexOf('104') > -1 && file.JobState == 1) return file;
    if (userTasks.indexOf('103') > -1 && file.EditedBy == user.UUID && !file.JobState) return file;
    if (userTasks.indexOf('101') > -1 && file.CreatedBy == user.UUID && !file.EditedBy) return file;
    return null;
  }
  async canDelete(user, id) {
    let recordset = await this.select('SELECT * FROM [File] WHERE UUID = @uuid', { uuid: id });
    let file = recordset[0];
    if (!file) return null
    let userTasks = user['Tasks'].split(',');
    if (userTasks.indexOf('307') > -1) return file;
    if (userTasks.indexOf('104') > -1 && file.State == 1) return file;
    if (userTasks.indexOf('103') > -1 && file.EditedBy == user.UUID && !file.JobState) return file;
    if (userTasks.indexOf('101') > -1 && file.CreatedBy == user.UUID && !file.EditedBy) return file;
    return null;
  }
}

module.exports = HoSoController;