diff --git a/ruoyi-admin/src/main/java/com/ruoyi/quality/controller/QualityManufacturingProcessController.java b/ruoyi-admin/src/main/java/com/ruoyi/quality/controller/QualityManufacturingProcessController.java new file mode 100644 index 00000000..1072fbe1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/quality/controller/QualityManufacturingProcessController.java @@ -0,0 +1,151 @@ +package com.ruoyi.quality.controller; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.quality.domain.QualityManufacturingProcess; +import com.ruoyi.quality.service.IQualityManufacturingProcessService; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 品质管理制程工序Controller + * + * @author 刘晓旭 + * @date 2024-05-10 + */ +@Controller +@RequestMapping("/quality/manufacturingProcess") +public class QualityManufacturingProcessController extends BaseController +{ + private String prefix = "quality/manufacturingProcess"; + + @Autowired + private IQualityManufacturingProcessService qualityManufacturingProcessService; + + @RequiresPermissions("quality:manufacturingProcess:view") + @GetMapping() + public String manufacturingProcess() + { + return prefix + "/manufacturingProcess"; + } + + /** + * 查询品质管理制程工序列表 + */ + @RequiresPermissions("quality:manufacturingProcess:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(QualityManufacturingProcess qualityManufacturingProcess) + { + startPage(); + List list = qualityManufacturingProcessService.selectQualityManufacturingProcessList(qualityManufacturingProcess); + return getDataTable(list); + } + + /** + * 导出品质管理制程工序列表 + */ + @RequiresPermissions("quality:manufacturingProcess:export") + @Log(title = "品质管理制程工序", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(QualityManufacturingProcess qualityManufacturingProcess) + { + List list = qualityManufacturingProcessService.selectQualityManufacturingProcessList(qualityManufacturingProcess); + ExcelUtil util = new ExcelUtil(QualityManufacturingProcess.class); + return util.exportExcel(list, "品质管理制程工序数据"); + } + + /** + * 新增品质管理制程工序 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存品质管理制程工序 + */ + @RequiresPermissions("quality:manufacturingProcess:add") + @Log(title = "品质管理制程工序", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(QualityManufacturingProcess qualityManufacturingProcess) + { + return toAjax(qualityManufacturingProcessService.insertQualityManufacturingProcess(qualityManufacturingProcess)); + } + + /** + * 修改品质管理制程工序 + */ + @GetMapping("/edit/{manufacturingProcessAutoid}") + public String edit(@PathVariable("manufacturingProcessAutoid") Long manufacturingProcessAutoid, ModelMap mmap) + { + QualityManufacturingProcess qualityManufacturingProcess = qualityManufacturingProcessService.selectQualityManufacturingProcessById(manufacturingProcessAutoid); + mmap.put("qualityManufacturingProcess", qualityManufacturingProcess); + return prefix + "/edit"; + } + + /** + * 修改保存品质管理制程工序 + */ + @RequiresPermissions("quality:manufacturingProcess:edit") + @Log(title = "品质管理制程工序", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(QualityManufacturingProcess qualityManufacturingProcess) + { + return toAjax(qualityManufacturingProcessService.updateQualityManufacturingProcess(qualityManufacturingProcess)); + } + + /** + * 删除品质管理制程工序 + */ + @RequiresPermissions("quality:manufacturingProcess:remove") + @Log(title = "品质管理制程工序", businessType = BusinessType.DELETE) + @PostMapping( "/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(qualityManufacturingProcessService.deleteQualityManufacturingProcessByIds(ids)); + } + + /** + * 作废品质管理制程工序 + */ + @RequiresPermissions("quality:manufacturingProcess:cancel") + @Log(title = "品质管理制程工序", businessType = BusinessType.CANCEL) + @GetMapping( "/cancel/{id}") + @ResponseBody + public AjaxResult cancel(@PathVariable("id") Long id){ + return toAjax(qualityManufacturingProcessService.cancelQualityManufacturingProcessById(id)); + } + + /** + * 恢复品质管理制程工序 + */ + @RequiresPermissions("quality:manufacturingProcess:restore") + @Log(title = "品质管理制程工序", businessType = BusinessType.RESTORE) + @GetMapping( "/restore/{id}") + @ResponseBody + public AjaxResult restore(@PathVariable("id")Long id) + { + return toAjax(qualityManufacturingProcessService.restoreQualityManufacturingProcessById(id)); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/quality/domain/QualityManufacturingProcess.java b/ruoyi-admin/src/main/java/com/ruoyi/quality/domain/QualityManufacturingProcess.java new file mode 100644 index 00000000..f3ae7815 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/quality/domain/QualityManufacturingProcess.java @@ -0,0 +1,168 @@ +package com.ruoyi.quality.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 品质管理制程工序对象 quality_manufacturing_process + * + * @author 刘晓旭 + * @date 2024-05-10 + */ +public class QualityManufacturingProcess extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 制程工序自增Id */ + private Long manufacturingProcessAutoid; + + /** 制程工序ID */ + @Excel(name = "制程工序ID") + private String manufacturingProcessId; + + /** 制程工序编号 */ + @Excel(name = "制程工序编号") + private String manufacturingProcessCode; + + /** 制程工序名称 */ + @Excel(name = "制程工序名称") + private String manufacturingProcessName; + + /** 设备名称 */ + @Excel(name = "设备名称") + private String deviceName; + + /** 设备型号 */ + @Excel(name = "设备型号") + private String deviceModelCode; + + /** 工序顺序 */ + @Excel(name = "工序顺序") + private String processSequence; + + /** 车间名称 */ + @Excel(name = "车间名称") + private String workshopName; + + /** 零件名称 */ + @Excel(name = "零件名称") + private String modName; + + /** 工序检验项目 */ + @Excel(name = "工序检验项目") + private String processInspectionItem; + + public void setManufacturingProcessAutoid(Long manufacturingProcessAutoid) + { + this.manufacturingProcessAutoid = manufacturingProcessAutoid; + } + + public Long getManufacturingProcessAutoid() + { + return manufacturingProcessAutoid; + } + public void setManufacturingProcessId(String manufacturingProcessId) + { + this.manufacturingProcessId = manufacturingProcessId; + } + + public String getManufacturingProcessId() + { + return manufacturingProcessId; + } + public void setManufacturingProcessCode(String manufacturingProcessCode) + { + this.manufacturingProcessCode = manufacturingProcessCode; + } + + public String getManufacturingProcessCode() + { + return manufacturingProcessCode; + } + public void setManufacturingProcessName(String manufacturingProcessName) + { + this.manufacturingProcessName = manufacturingProcessName; + } + + public String getManufacturingProcessName() + { + return manufacturingProcessName; + } + public void setDeviceName(String deviceName) + { + this.deviceName = deviceName; + } + + public String getDeviceName() + { + return deviceName; + } + public void setDeviceModelCode(String deviceModelCode) + { + this.deviceModelCode = deviceModelCode; + } + + public String getDeviceModelCode() + { + return deviceModelCode; + } + public void setProcessSequence(String processSequence) + { + this.processSequence = processSequence; + } + + public String getProcessSequence() + { + return processSequence; + } + public void setWorkshopName(String workshopName) + { + this.workshopName = workshopName; + } + + public String getWorkshopName() + { + return workshopName; + } + public void setModName(String modName) + { + this.modName = modName; + } + + public String getModName() + { + return modName; + } + public void setProcessInspectionItem(String processInspectionItem) + { + this.processInspectionItem = processInspectionItem; + } + + public String getProcessInspectionItem() + { + return processInspectionItem; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("manufacturingProcessAutoid", getManufacturingProcessAutoid()) + .append("manufacturingProcessId", getManufacturingProcessId()) + .append("manufacturingProcessCode", getManufacturingProcessCode()) + .append("manufacturingProcessName", getManufacturingProcessName()) + .append("deviceName", getDeviceName()) + .append("deviceModelCode", getDeviceModelCode()) + .append("processSequence", getProcessSequence()) + .append("workshopName", getWorkshopName()) + .append("modName", getModName()) + .append("processInspectionItem", getProcessInspectionItem()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/quality/mapper/QualityManufacturingProcessMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/quality/mapper/QualityManufacturingProcessMapper.java new file mode 100644 index 00000000..7becadab --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/quality/mapper/QualityManufacturingProcessMapper.java @@ -0,0 +1,77 @@ +package com.ruoyi.quality.mapper; + +import java.util.List; +import com.ruoyi.quality.domain.QualityManufacturingProcess; + +/** + * 品质管理制程工序Mapper接口 + * + * @author 刘晓旭 + * @date 2024-05-10 + */ +public interface QualityManufacturingProcessMapper +{ + /** + * 查询品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 品质管理制程工序 + */ + public QualityManufacturingProcess selectQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 查询品质管理制程工序列表 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 品质管理制程工序集合 + */ + public List selectQualityManufacturingProcessList(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 新增品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + public int insertQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 修改品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + public int updateQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 删除品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + public int deleteQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 批量删除品质管理制程工序 + * + * @param manufacturingProcessAutoids 需要删除的数据ID + * @return 结果 + */ + public int deleteQualityManufacturingProcessByIds(String[] manufacturingProcessAutoids); + + /** + * 作废品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + public int cancelQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 恢复品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + public int restoreQualityManufacturingProcessById(Long manufacturingProcessAutoid); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/quality/service/IQualityManufacturingProcessService.java b/ruoyi-admin/src/main/java/com/ruoyi/quality/service/IQualityManufacturingProcessService.java new file mode 100644 index 00000000..79fbaf3c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/quality/service/IQualityManufacturingProcessService.java @@ -0,0 +1,75 @@ +package com.ruoyi.quality.service; + +import java.util.List; +import com.ruoyi.quality.domain.QualityManufacturingProcess; + +/** + * 品质管理制程工序Service接口 + * + * @author 刘晓旭 + * @date 2024-05-10 + */ +public interface IQualityManufacturingProcessService +{ + /** + * 查询品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 品质管理制程工序 + */ + public QualityManufacturingProcess selectQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 查询品质管理制程工序列表 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 品质管理制程工序集合 + */ + public List selectQualityManufacturingProcessList(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 新增品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + public int insertQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 修改品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + public int updateQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess); + + /** + * 批量删除品质管理制程工序 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteQualityManufacturingProcessByIds(String ids); + + /** + * 删除品质管理制程工序信息 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + public int deleteQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 作废品质管理制程工序 + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return + */ + int cancelQualityManufacturingProcessById(Long manufacturingProcessAutoid); + + /** + * 恢复品质管理制程工序 + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return + */ + int restoreQualityManufacturingProcessById(Long manufacturingProcessAutoid); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/quality/service/impl/QualityManufacturingProcessServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/quality/service/impl/QualityManufacturingProcessServiceImpl.java new file mode 100644 index 00000000..fe55cbdb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/quality/service/impl/QualityManufacturingProcessServiceImpl.java @@ -0,0 +1,126 @@ +package com.ruoyi.quality.service.impl; + +import java.util.List; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ShiroUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.quality.mapper.QualityManufacturingProcessMapper; +import com.ruoyi.quality.domain.QualityManufacturingProcess; +import com.ruoyi.quality.service.IQualityManufacturingProcessService; +import com.ruoyi.common.core.text.Convert; + +/** + * 品质管理制程工序Service业务层处理 + * + * @author 刘晓旭 + * @date 2024-05-10 + */ +@Service +public class QualityManufacturingProcessServiceImpl implements IQualityManufacturingProcessService +{ + @Autowired + private QualityManufacturingProcessMapper qualityManufacturingProcessMapper; + + /** + * 查询品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 品质管理制程工序 + */ + @Override + public QualityManufacturingProcess selectQualityManufacturingProcessById(Long manufacturingProcessAutoid) + { + return qualityManufacturingProcessMapper.selectQualityManufacturingProcessById(manufacturingProcessAutoid); + } + + /** + * 查询品质管理制程工序列表 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 品质管理制程工序 + */ + @Override + public List selectQualityManufacturingProcessList(QualityManufacturingProcess qualityManufacturingProcess) + { + return qualityManufacturingProcessMapper.selectQualityManufacturingProcessList(qualityManufacturingProcess); + } + + /** + * 新增品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + @Override + public int insertQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess) + { + String loginName = ShiroUtils.getLoginName(); + qualityManufacturingProcess.setCreateBy(loginName); + qualityManufacturingProcess.setCreateTime(DateUtils.getNowDate()); + return qualityManufacturingProcessMapper.insertQualityManufacturingProcess(qualityManufacturingProcess); + } + + /** + * 修改品质管理制程工序 + * + * @param qualityManufacturingProcess 品质管理制程工序 + * @return 结果 + */ + @Override + public int updateQualityManufacturingProcess(QualityManufacturingProcess qualityManufacturingProcess) + { + String loginName = ShiroUtils.getLoginName(); + qualityManufacturingProcess.setUpdateBy(loginName); + qualityManufacturingProcess.setUpdateTime(DateUtils.getNowDate()); + return qualityManufacturingProcessMapper.updateQualityManufacturingProcess(qualityManufacturingProcess); + } + + /** + * 删除品质管理制程工序对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteQualityManufacturingProcessByIds(String ids) + { + return qualityManufacturingProcessMapper.deleteQualityManufacturingProcessByIds(Convert.toStrArray(ids)); + } + + /** + * 删除品质管理制程工序信息 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + @Override + public int deleteQualityManufacturingProcessById(Long manufacturingProcessAutoid) + { + return qualityManufacturingProcessMapper.deleteQualityManufacturingProcessById(manufacturingProcessAutoid); + } + + /** + * 作废品质管理制程工序 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + @Override + public int cancelQualityManufacturingProcessById(Long manufacturingProcessAutoid) + { + return qualityManufacturingProcessMapper.cancelQualityManufacturingProcessById(manufacturingProcessAutoid); + } + + /** + * 恢复品质管理制程工序信息 + * + * @param manufacturingProcessAutoid 品质管理制程工序ID + * @return 结果 + */ + @Override + public int restoreQualityManufacturingProcessById(Long manufacturingProcessAutoid) + { + return qualityManufacturingProcessMapper.restoreQualityManufacturingProcessById(manufacturingProcessAutoid); + } +} diff --git a/ruoyi-admin/src/main/resources/mapper/quality/QualityManufacturingProcessMapper.xml b/ruoyi-admin/src/main/resources/mapper/quality/QualityManufacturingProcessMapper.xml new file mode 100644 index 00000000..22c978d9 --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/quality/QualityManufacturingProcessMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + select manufacturing_process_autoid, manufacturing_process_id, manufacturing_process_code, manufacturing_process_name, device_name, device_model_code, process_sequence, workshop_name, mod_name, process_inspection_item, remark, create_by, create_time, update_by, update_time from quality_manufacturing_process + + + + + + + + insert into quality_manufacturing_process + + manufacturing_process_id, + manufacturing_process_code, + manufacturing_process_name, + device_name, + device_model_code, + process_sequence, + workshop_name, + mod_name, + process_inspection_item, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{manufacturingProcessId}, + #{manufacturingProcessCode}, + #{manufacturingProcessName}, + #{deviceName}, + #{deviceModelCode}, + #{processSequence}, + #{workshopName}, + #{modName}, + #{processInspectionItem}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update quality_manufacturing_process + + manufacturing_process_id = #{manufacturingProcessId}, + manufacturing_process_code = #{manufacturingProcessCode}, + manufacturing_process_name = #{manufacturingProcessName}, + device_name = #{deviceName}, + device_model_code = #{deviceModelCode}, + process_sequence = #{processSequence}, + workshop_name = #{workshopName}, + mod_name = #{modName}, + process_inspection_item = #{processInspectionItem}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where manufacturing_process_autoid = #{manufacturingProcessAutoid} + + + + delete from quality_manufacturing_process where manufacturing_process_autoid = #{manufacturingProcessAutoid} + + + + delete from quality_manufacturing_process where manufacturing_process_autoid in + + #{manufacturingProcessAutoid} + + + + + update quality_manufacturing_process set del_flag = '1' where manufacturing_process_autoid = #{manufacturingProcessAutoid} + + + + update quality_manufacturing_process set del_flag = '0' where manufacturing_process_autoid = #{manufacturingProcessAutoid} + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/add.html b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/add.html new file mode 100644 index 00000000..edd39b19 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/add.html @@ -0,0 +1,81 @@ + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/edit.html b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/edit.html new file mode 100644 index 00000000..8bd8c8e4 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/edit.html @@ -0,0 +1,82 @@ + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/manufacturingProcess.html b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/manufacturingProcess.html new file mode 100644 index 00000000..5d0865bd --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/quality/manufacturingProcess/manufacturingProcess.html @@ -0,0 +1,170 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + + - + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file